aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--CREDITS2
-rw-r--r--Documentation/DMA-mapping.txt4
-rw-r--r--Documentation/HOWTO2
-rw-r--r--Documentation/block/00-INDEX20
-rw-r--r--Documentation/block/as-iosched.txt21
-rw-r--r--Documentation/block/biodoc.txt4
-rw-r--r--Documentation/block/deadline-iosched.txt25
-rw-r--r--Documentation/block/ioprio.txt2
-rw-r--r--Documentation/block/request.txt2
-rw-r--r--Documentation/block/switching-sched.txt21
-rw-r--r--Documentation/cachetlb.txt6
-rw-r--r--Documentation/cpusets.txt24
-rw-r--r--Documentation/fb/00-INDEX46
-rw-r--r--Documentation/fb/uvesafb.txt188
-rw-r--r--Documentation/filesystems/Locking9
-rw-r--r--Documentation/filesystems/vfs.txt51
-rw-r--r--Documentation/kernel-parameters.txt10
-rw-r--r--Documentation/spi/spi-summary25
-rw-r--r--Documentation/spi/spidev_test.c6
-rw-r--r--Documentation/vm/numa_memory_policy.txt33
-rw-r--r--Documentation/x86_64/mm.txt1
-rw-r--r--arch/alpha/Makefile83
-rw-r--r--arch/alpha/kernel/entry.S9
-rw-r--r--arch/alpha/kernel/ptrace.c46
-rw-r--r--arch/alpha/kernel/vmlinux.lds.S260
-rw-r--r--arch/alpha/mm/fault.c2
-rw-r--r--arch/arm/kernel/ptrace.c4
-rw-r--r--arch/arm/mach-s3c2410/mach-amlm5900.c54
-rw-r--r--arch/arm/mach-s3c2410/mach-bast.c83
-rw-r--r--arch/arm/mach-s3c2410/mach-h1940.c56
-rw-r--r--arch/arm/mach-s3c2410/mach-qt2410.c219
-rw-r--r--arch/arm/mach-s3c2440/mach-rx3715.c72
-rw-r--r--arch/arm/mach-s3c2440/mach-smdk2440.c78
-rw-r--r--arch/arm/mm/fault.c2
-rw-r--r--arch/avr32/kernel/kprobes.c2
-rw-r--r--arch/avr32/kernel/ptrace.c5
-rw-r--r--arch/avr32/mm/fault.c2
-rw-r--r--arch/blackfin/kernel/ptrace.c6
-rw-r--r--arch/cris/arch-v10/kernel/ptrace.c4
-rw-r--r--arch/cris/arch-v10/kernel/time.c8
-rw-r--r--arch/cris/arch-v32/kernel/ptrace.c4
-rw-r--r--arch/cris/arch-v32/kernel/smp.c8
-rw-r--r--arch/cris/mm/fault.c2
-rw-r--r--arch/frv/kernel/time.c5
-rw-r--r--arch/frv/mm/fault.c2
-rw-r--r--arch/ia64/Kconfig9
-rw-r--r--arch/ia64/hp/common/sba_iommu.c14
-rw-r--r--arch/ia64/hp/sim/simscsi.c1
-rw-r--r--arch/ia64/kernel/gate.lds.S135
-rw-r--r--arch/ia64/kernel/kprobes.c2
-rw-r--r--arch/ia64/kernel/setup.c12
-rw-r--r--arch/ia64/kernel/smpboot.c18
-rw-r--r--arch/ia64/kernel/uncached.c4
-rw-r--r--arch/ia64/mm/discontig.c8
-rw-r--r--arch/ia64/mm/fault.c2
-rw-r--r--arch/ia64/mm/hugetlbpage.c4
-rw-r--r--arch/ia64/mm/init.c20
-rw-r--r--arch/ia64/sn/pci/pci_dma.c11
-rw-r--r--arch/m32r/kernel/ptrace.c50
-rw-r--r--arch/m32r/kernel/time.c8
-rw-r--r--arch/m32r/mm/fault.c2
-rw-r--r--arch/m68k/kernel/ptrace.c4
-rw-r--r--arch/m68k/mm/fault.c2
-rw-r--r--arch/mips/jmr3927/rbhma3100/setup.c2
-rw-r--r--arch/mips/kernel/ptrace.c4
-rw-r--r--arch/mips/mm/fault.c2
-rw-r--r--arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c2
-rw-r--r--arch/parisc/kernel/ptrace.c4
-rw-r--r--arch/parisc/mm/fault.c2
-rw-r--r--arch/powerpc/Kconfig1
-rw-r--r--arch/powerpc/kernel/dma_64.c5
-rw-r--r--arch/powerpc/kernel/ibmebus.c11
-rw-r--r--arch/powerpc/kernel/iommu.c23
-rw-r--r--arch/powerpc/kernel/kprobes.c2
-rw-r--r--arch/powerpc/kernel/ptrace.c4
-rw-r--r--arch/powerpc/kernel/setup-common.c20
-rw-r--r--arch/powerpc/kernel/setup_64.c3
-rw-r--r--arch/powerpc/kernel/smp.c4
-rw-r--r--arch/powerpc/kernel/vdso32/vdso32.lds.S219
-rw-r--r--arch/powerpc/kernel/vdso64/vdso64.lds.S225
-rw-r--r--arch/powerpc/mm/init_64.c67
-rw-r--r--arch/powerpc/mm/mem.c45
-rw-r--r--arch/powerpc/platforms/cell/cbe_cpufreq.c2
-rw-r--r--arch/powerpc/platforms/ps3/system-bus.c7
-rw-r--r--arch/ppc/mm/fault.c2
-rw-r--r--arch/s390/kernel/kprobes.c2
-rw-r--r--arch/s390/kernel/ptrace.c5
-rw-r--r--arch/s390/mm/fault.c2
-rw-r--r--arch/sh/kernel/ptrace.c4
-rw-r--r--arch/sh/kernel/vsyscall/vsyscall.lds.S77
-rw-r--r--arch/sh/mm/fault.c2
-rw-r--r--arch/sh/mm/init.c6
-rw-r--r--arch/sh64/kernel/ptrace.c4
-rw-r--r--arch/sh64/mm/fault.c2
-rw-r--r--arch/sparc/kernel/ioport.c25
-rw-r--r--arch/sparc/mm/fault.c2
-rw-r--r--arch/sparc/mm/io-unit.c12
-rw-r--r--arch/sparc/mm/iommu.c10
-rw-r--r--arch/sparc/mm/sun4c.c10
-rw-r--r--arch/sparc64/Kconfig2
-rw-r--r--arch/sparc64/kernel/iommu.c39
-rw-r--r--arch/sparc64/kernel/kprobes.c2
-rw-r--r--arch/sparc64/kernel/ktlb.S16
-rw-r--r--arch/sparc64/kernel/pci_sun4v.c32
-rw-r--r--arch/sparc64/kernel/smp.c17
-rw-r--r--arch/sparc64/mm/fault.c2
-rw-r--r--arch/sparc64/mm/init.c57
-rw-r--r--arch/um/Kconfig244
-rw-r--r--arch/um/Kconfig.char141
-rw-r--r--arch/um/Kconfig.debug47
-rw-r--r--arch/um/Kconfig.i38614
-rw-r--r--arch/um/Kconfig.net22
-rw-r--r--arch/um/Kconfig.x86_6414
-rw-r--r--arch/um/Makefile35
-rw-r--r--arch/um/Makefile-i3866
-rw-r--r--arch/um/defconfig11
-rw-r--r--arch/um/drivers/Makefile11
-rw-r--r--arch/um/drivers/chan_kern.c211
-rw-r--r--arch/um/drivers/chan_user.c211
-rw-r--r--arch/um/drivers/cow_user.c133
-rw-r--r--arch/um/drivers/daemon.h20
-rw-r--r--arch/um/drivers/daemon_kern.c34
-rw-r--r--arch/um/drivers/daemon_user.c92
-rw-r--r--arch/um/drivers/fd.c69
-rw-r--r--arch/um/drivers/harddog_kern.c2
-rw-r--r--arch/um/drivers/harddog_user.c58
-rw-r--r--arch/um/drivers/hostaudio_kern.c118
-rw-r--r--arch/um/drivers/line.c237
-rw-r--r--arch/um/drivers/mcast.h16
-rw-r--r--arch/um/drivers/mcast_kern.c56
-rw-r--r--arch/um/drivers/mcast_user.c73
-rw-r--r--arch/um/drivers/mconsole_kern.c289
-rw-r--r--arch/um/drivers/mconsole_user.c119
-rw-r--r--arch/um/drivers/mmapper_kern.c64
-rw-r--r--arch/um/drivers/net_kern.c278
-rw-r--r--arch/um/drivers/net_user.c126
-rw-r--r--arch/um/drivers/null.c28
-rw-r--r--arch/um/drivers/pcap_kern.c38
-rw-r--r--arch/um/drivers/pcap_user.c58
-rw-r--r--arch/um/drivers/port_kern.c86
-rw-r--r--arch/um/drivers/port_user.c73
-rw-r--r--arch/um/drivers/pty.c30
-rw-r--r--arch/um/drivers/slip_kern.c38
-rw-r--r--arch/um/drivers/slip_user.c129
-rw-r--r--arch/um/drivers/slirp_kern.c59
-rw-r--r--arch/um/drivers/slirp_user.c74
-rw-r--r--arch/um/drivers/tty.c37
-rw-r--r--arch/um/drivers/ubd_kern.c2
-rw-r--r--arch/um/drivers/vde.h32
-rw-r--r--arch/um/drivers/vde_kern.c129
-rw-r--r--arch/um/drivers/vde_user.c127
-rw-r--r--arch/um/drivers/xterm.c28
-rw-r--r--arch/um/include/arch.h4
-rw-r--r--arch/um/include/as-layout.h27
-rw-r--r--arch/um/include/choose-mode.h38
-rw-r--r--arch/um/include/common-offsets.h10
-rw-r--r--arch/um/include/irq_user.h10
-rw-r--r--arch/um/include/kern_util.h30
-rw-r--r--arch/um/include/mconsole.h15
-rw-r--r--arch/um/include/mem.h21
-rw-r--r--arch/um/include/mode.h30
-rw-r--r--arch/um/include/mode_kern.h17
-rw-r--r--arch/um/include/net_kern.h13
-rw-r--r--arch/um/include/net_user.h4
-rw-r--r--arch/um/include/os.h69
-rw-r--r--arch/um/include/registers.h10
-rw-r--r--arch/um/include/skas/mmu-skas.h23
-rw-r--r--arch/um/include/skas/mode-skas.h9
-rw-r--r--arch/um/include/skas/mode_kern_skas.h41
-rw-r--r--arch/um/include/skas/skas.h5
-rw-r--r--arch/um/include/skas/uaccess-skas.h21
-rw-r--r--arch/um/include/sysdep-i386/kernel-offsets.h1
-rw-r--r--arch/um/include/sysdep-i386/ptrace.h133
-rw-r--r--arch/um/include/sysdep-i386/sigcontext.h30
-rw-r--r--arch/um/include/sysdep-i386/stub.h14
-rw-r--r--arch/um/include/sysdep-i386/thread.h11
-rw-r--r--arch/um/include/sysdep-x86_64/ptrace.h277
-rw-r--r--arch/um/include/sysdep-x86_64/sigcontext.h28
-rw-r--r--arch/um/include/sysdep-x86_64/stub.h13
-rw-r--r--arch/um/include/sysdep-x86_64/thread.h10
-rw-r--r--arch/um/include/task.h2
-rw-r--r--arch/um/include/tlb.h27
-rw-r--r--arch/um/include/tt/debug.h18
-rw-r--r--arch/um/include/tt/mmu-tt.h12
-rw-r--r--arch/um/include/tt/mode-tt.h23
-rw-r--r--arch/um/include/tt/mode_kern_tt.h40
-rw-r--r--arch/um/include/tt/tt.h37
-rw-r--r--arch/um/include/tt/uaccess-tt.h46
-rw-r--r--arch/um/include/um_mmu.h40
-rw-r--r--arch/um/include/um_uaccess.h64
-rw-r--r--arch/um/include/uml_uaccess.h24
-rw-r--r--arch/um/include/user.h8
-rw-r--r--arch/um/kernel/Makefile7
-rw-r--r--arch/um/kernel/dyn.lds.S2
-rw-r--r--arch/um/kernel/exec.c58
-rw-r--r--arch/um/kernel/init_task.c13
-rw-r--r--arch/um/kernel/irq.c113
-rw-r--r--arch/um/kernel/ksyms.c41
-rw-r--r--arch/um/kernel/mem.c2
-rw-r--r--arch/um/kernel/physmem.c69
-rw-r--r--arch/um/kernel/process.c226
-rw-r--r--arch/um/kernel/ptrace.c141
-rw-r--r--arch/um/kernel/reboot.c57
-rw-r--r--arch/um/kernel/signal.c59
-rw-r--r--arch/um/kernel/skas/Makefile4
-rw-r--r--arch/um/kernel/skas/clone.c6
-rw-r--r--arch/um/kernel/skas/exec.c40
-rw-r--r--arch/um/kernel/skas/mem.c22
-rw-r--r--arch/um/kernel/skas/mmu.c81
-rw-r--r--arch/um/kernel/skas/process.c187
-rw-r--r--arch/um/kernel/skas/syscall.c21
-rw-r--r--arch/um/kernel/skas/tlb.c164
-rw-r--r--arch/um/kernel/skas/uaccess.c146
-rw-r--r--arch/um/kernel/smp.c36
-rw-r--r--arch/um/kernel/syscall.c40
-rw-r--r--arch/um/kernel/time.c223
-rw-r--r--arch/um/kernel/tlb.c418
-rw-r--r--arch/um/kernel/trap.c129
-rw-r--r--arch/um/kernel/tt/Makefile14
-rw-r--r--arch/um/kernel/tt/exec_kern.c84
-rw-r--r--arch/um/kernel/tt/exec_user.c56
-rw-r--r--arch/um/kernel/tt/gdb.c280
-rw-r--r--arch/um/kernel/tt/gdb_kern.c40
-rw-r--r--arch/um/kernel/tt/include/mode-tt.h34
-rw-r--r--arch/um/kernel/tt/ksyms.c29
-rw-r--r--arch/um/kernel/tt/mem.c34
-rw-r--r--arch/um/kernel/tt/mem_user.c49
-rw-r--r--arch/um/kernel/tt/process_kern.c461
-rw-r--r--arch/um/kernel/tt/ptproxy/Makefile10
-rw-r--r--arch/um/kernel/tt/ptproxy/proxy.c377
-rw-r--r--arch/um/kernel/tt/ptproxy/ptproxy.h61
-rw-r--r--arch/um/kernel/tt/ptproxy/ptrace.c237
-rw-r--r--arch/um/kernel/tt/ptproxy/sysdep.c70
-rw-r--r--arch/um/kernel/tt/ptproxy/sysdep.h25
-rw-r--r--arch/um/kernel/tt/ptproxy/wait.c85
-rw-r--r--arch/um/kernel/tt/ptproxy/wait.h15
-rw-r--r--arch/um/kernel/tt/syscall_kern.c46
-rw-r--r--arch/um/kernel/tt/syscall_user.c60
-rw-r--r--arch/um/kernel/tt/tlb.c120
-rw-r--r--arch/um/kernel/tt/tracer.c461
-rw-r--r--arch/um/kernel/tt/trap_user.c70
-rw-r--r--arch/um/kernel/tt/uaccess.c73
-rw-r--r--arch/um/kernel/tt/uaccess_user.c105
-rw-r--r--arch/um/kernel/uaccess.c2
-rw-r--r--arch/um/kernel/um_arch.c217
-rw-r--r--arch/um/kernel/uml.lds.S7
-rw-r--r--arch/um/os-Linux/Makefile15
-rw-r--r--arch/um/os-Linux/aio.c122
-rw-r--r--arch/um/os-Linux/drivers/etap.h16
-rw-r--r--arch/um/os-Linux/drivers/ethertap_kern.c52
-rw-r--r--arch/um/os-Linux/drivers/ethertap_user.c132
-rw-r--r--arch/um/os-Linux/drivers/tuntap.h13
-rw-r--r--arch/um/os-Linux/drivers/tuntap_kern.c35
-rw-r--r--arch/um/os-Linux/drivers/tuntap_user.c102
-rw-r--r--arch/um/os-Linux/file.c130
-rw-r--r--arch/um/os-Linux/helper.c8
-rw-r--r--arch/um/os-Linux/irq.c6
-rw-r--r--arch/um/os-Linux/main.c120
-rw-r--r--arch/um/os-Linux/mem.c6
-rw-r--r--arch/um/os-Linux/process.c175
-rw-r--r--arch/um/os-Linux/registers.c57
-rw-r--r--arch/um/os-Linux/signal.c131
-rw-r--r--arch/um/os-Linux/skas/mem.c109
-rw-r--r--arch/um/os-Linux/skas/process.c316
-rw-r--r--arch/um/os-Linux/skas/trap.c51
-rw-r--r--arch/um/os-Linux/start_up.c218
-rw-r--r--arch/um/os-Linux/sys-i386/Makefile4
-rw-r--r--arch/um/os-Linux/sys-i386/registers.c129
-rw-r--r--arch/um/os-Linux/sys-x86_64/Makefile4
-rw-r--r--arch/um/os-Linux/sys-x86_64/registers.c75
-rw-r--r--arch/um/os-Linux/time.c111
-rw-r--r--arch/um/os-Linux/tls.c40
-rw-r--r--arch/um/os-Linux/trap.c23
-rw-r--r--arch/um/os-Linux/tt.c196
-rw-r--r--arch/um/os-Linux/uaccess.c2
-rw-r--r--arch/um/os-Linux/umid.c137
-rw-r--r--arch/um/os-Linux/util.c38
-rw-r--r--arch/um/scripts/Makefile.rules2
-rw-r--r--arch/um/sys-i386/Makefile14
-rw-r--r--arch/um/sys-i386/bugs.c108
-rw-r--r--arch/um/sys-i386/fault.c10
-rw-r--r--arch/um/sys-i386/ldt.c306
-rw-r--r--arch/um/sys-i386/ptrace.c368
-rw-r--r--arch/um/sys-i386/ptrace_user.c100
-rw-r--r--arch/um/sys-i386/sigcontext.c71
-rw-r--r--arch/um/sys-i386/signal.c409
-rw-r--r--arch/um/sys-i386/stub.S9
-rw-r--r--arch/um/sys-i386/stub_segv.c4
-rw-r--r--arch/um/sys-i386/tls.c101
-rw-r--r--arch/um/sys-i386/unmap.c25
-rw-r--r--arch/um/sys-i386/user-offsets.c6
-rw-r--r--arch/um/sys-x86_64/Makefile11
-rw-r--r--arch/um/sys-x86_64/bugs.c2
-rw-r--r--arch/um/sys-x86_64/fault.c9
-rw-r--r--arch/um/sys-x86_64/ptrace.c154
-rw-r--r--arch/um/sys-x86_64/sigcontext.c39
-rw-r--r--arch/um/sys-x86_64/signal.c297
-rw-r--r--arch/um/sys-x86_64/stub.S9
-rw-r--r--arch/um/sys-x86_64/stub_segv.c3
-rw-r--r--arch/um/sys-x86_64/syscalls.c108
-rw-r--r--arch/um/sys-x86_64/tls.c4
-rw-r--r--arch/um/sys-x86_64/unmap.c25
-rw-r--r--arch/um/sys-x86_64/user-offsets.c9
-rw-r--r--arch/v850/kernel/fpga85e2c.c5
-rw-r--r--arch/v850/kernel/time.c11
-rw-r--r--arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/p4-clockmod.c2
-rw-r--r--arch/x86/kernel/cpu/cpufreq/powernow-k8.c10
-rw-r--r--arch/x86/kernel/cpu/cpufreq/speedstep-ich.c2
-rw-r--r--arch/x86/kernel/cpu/proc.c3
-rw-r--r--arch/x86/kernel/io_apic_32.c4
-rw-r--r--arch/x86/kernel/kprobes_32.c10
-rw-r--r--arch/x86/kernel/kprobes_64.c8
-rw-r--r--arch/x86/kernel/mce_amd_64.c6
-rw-r--r--arch/x86/kernel/pci-calgary_64.c24
-rw-r--r--arch/x86/kernel/pci-gart_64.c65
-rw-r--r--arch/x86/kernel/pci-nommu_64.c5
-rw-r--r--arch/x86/kernel/process_64.c2
-rw-r--r--arch/x86/kernel/ptrace_32.c5
-rw-r--r--arch/x86/kernel/ptrace_64.c5
-rw-r--r--arch/x86/kernel/setup_64.c3
-rw-r--r--arch/x86/kernel/smpboot_32.c68
-rw-r--r--arch/x86/kernel/smpboot_64.c48
-rw-r--r--arch/x86/mm/fault_32.c45
-rw-r--r--arch/x86/mm/fault_64.c44
-rw-r--r--arch/x86/mm/init_32.c5
-rw-r--r--arch/x86/mm/init_64.c51
-rw-r--r--arch/x86/oprofile/op_model_p4.c2
-rw-r--r--arch/x86/xen/smp.c18
-rw-r--r--arch/x86_64/Kconfig1
-rw-r--r--arch/xtensa/kernel/ptrace.c4
-rw-r--r--arch/xtensa/mm/fault.c2
-rw-r--r--block/blktrace.c2
-rw-r--r--block/bsg.c2
-rw-r--r--block/elevator.c17
-rw-r--r--block/ll_rw_blk.c320
-rw-r--r--crypto/digest.c2
-rw-r--r--crypto/scatterwalk.c2
-rw-r--r--crypto/scatterwalk.h2
-rw-r--r--drivers/Kconfig2
-rw-r--r--drivers/Makefile1
-rw-r--r--drivers/ata/libata-core.c35
-rw-r--r--drivers/ata/libata-scsi.c4
-rw-r--r--drivers/base/memory.c6
-rw-r--r--drivers/base/node.c91
-rw-r--r--drivers/block/cciss.c2
-rw-r--r--drivers/block/cpqarray.c3
-rw-r--r--drivers/block/loop.c73
-rw-r--r--drivers/block/pktcdvd.c7
-rw-r--r--drivers/block/ps3disk.c21
-rw-r--r--drivers/char/Kconfig4
-rw-r--r--drivers/char/agp/Kconfig2
-rw-r--r--drivers/char/drm/Kconfig2
-rw-r--r--drivers/char/drm/radeon_irq.c4
-rw-r--r--drivers/char/mem.c125
-rw-r--r--drivers/char/mspec.c2
-rw-r--r--drivers/char/vt.c13
-rw-r--r--drivers/char/vt_ioctl.c15
-rw-r--r--drivers/dca/Kconfig7
-rw-r--r--drivers/dca/Makefile2
-rw-r--r--drivers/dca/dca-core.c200
-rw-r--r--drivers/dca/dca-sysfs.c88
-rw-r--r--drivers/dma/Kconfig60
-rw-r--r--drivers/dma/Makefile1
-rw-r--r--drivers/dma/ioat.c211
-rw-r--r--drivers/dma/ioat_dca.c263
-rw-r--r--drivers/dma/ioat_dma.c (renamed from drivers/dma/ioatdma.c)653
-rw-r--r--drivers/dma/ioatdma.h35
-rw-r--r--drivers/dma/ioatdma_hw.h2
-rw-r--r--drivers/dma/ioatdma_registers.h6
-rw-r--r--drivers/ide/cris/ide-cris.c3
-rw-r--r--drivers/ide/ide-disk.c29
-rw-r--r--drivers/ide/ide-dma.c2
-rw-r--r--drivers/ide/ide-io.c38
-rw-r--r--drivers/ide/ide-probe.c2
-rw-r--r--drivers/ide/ide-taskfile.c18
-rw-r--r--drivers/ide/mips/au1xxx-ide.c2
-rw-r--r--drivers/ide/pci/sgiioc4.c3
-rw-r--r--drivers/ide/ppc/pmac.c2
-rw-r--r--drivers/infiniband/hw/ipath/ipath_dma.c10
-rw-r--r--drivers/infiniband/ulp/iser/iser_memory.c75
-rw-r--r--drivers/isdn/capi/capidrv.c5
-rw-r--r--drivers/isdn/capi/kcapi.c2
-rw-r--r--drivers/isdn/gigaset/bas-gigaset.c9
-rw-r--r--drivers/isdn/gigaset/i4l.c12
-rw-r--r--drivers/isdn/gigaset/proc.c8
-rw-r--r--drivers/isdn/gigaset/usb-gigaset.c7
-rw-r--r--drivers/isdn/i4l/isdn_common.c26
-rw-r--r--drivers/md/dm-crypt.c31
-rw-r--r--drivers/md/dm-table.c28
-rw-r--r--drivers/md/dm.c16
-rw-r--r--drivers/md/dm.h1
-rw-r--r--drivers/md/linear.c20
-rw-r--r--drivers/md/md.c1
-rw-r--r--drivers/md/multipath.c30
-rw-r--r--drivers/md/raid0.c21
-rw-r--r--drivers/md/raid1.c31
-rw-r--r--drivers/md/raid10.c31
-rw-r--r--drivers/md/raid5.c31
-rw-r--r--drivers/message/fusion/mptscsih.c16
-rw-r--r--drivers/message/i2o/i2o_block.c24
-rw-r--r--drivers/mmc/card/queue.c6
-rw-r--r--drivers/mmc/host/mmc_spi.c4
-rw-r--r--drivers/pcmcia/Kconfig6
-rw-r--r--drivers/pcmcia/au1000_xxs1500.c5
-rw-r--r--drivers/pcmcia/cistpl.c48
-rw-r--r--drivers/pcmcia/ds.c4
-rw-r--r--drivers/pcmcia/pxa2xx_base.c2
-rw-r--r--drivers/ps3/ps3av.c387
-rw-r--r--drivers/ps3/ps3av_cmd.c83
-rw-r--r--drivers/rtc/Kconfig11
-rw-r--r--drivers/rtc/Makefile1
-rw-r--r--drivers/rtc/class.c1
-rw-r--r--drivers/rtc/interface.c122
-rw-r--r--drivers/rtc/rtc-cmos.c64
-rw-r--r--drivers/rtc/rtc-dev.c44
-rw-r--r--drivers/rtc/rtc-ds1374.c449
-rw-r--r--drivers/rtc/rtc-ds1553.c2
-rw-r--r--drivers/rtc/rtc-ds1742.c2
-rw-r--r--drivers/rtc/rtc-pcf8583.c3
-rw-r--r--drivers/rtc/rtc-sysfs.c24
-rw-r--r--drivers/s390/scsi/zfcp_def.h1
-rw-r--r--drivers/s390/scsi/zfcp_qdio.c6
-rw-r--r--drivers/scsi/3w-9xxx.c1
-rw-r--r--drivers/scsi/3w-xxxx.c1
-rw-r--r--drivers/scsi/BusLogic.c1
-rw-r--r--drivers/scsi/NCR53c406a.c3
-rw-r--r--drivers/scsi/a100u2w.c1
-rw-r--r--drivers/scsi/aacraid/linit.c1
-rw-r--r--drivers/scsi/aha1542.c32
-rw-r--r--drivers/scsi/aha1740.c1
-rw-r--r--drivers/scsi/aic7xxx/aic79xx_osm.c1
-rw-r--r--drivers/scsi/aic7xxx/aic7xxx_osm.c1
-rw-r--r--drivers/scsi/aic7xxx_old.c1
-rw-r--r--drivers/scsi/aic94xx/aic94xx_task.c6
-rw-r--r--drivers/scsi/arcmsr/arcmsr_hba.c1
-rw-r--r--drivers/scsi/dc395x.c1
-rw-r--r--drivers/scsi/dpt_i2o.c1
-rw-r--r--drivers/scsi/eata.c3
-rw-r--r--drivers/scsi/hosts.c1
-rw-r--r--drivers/scsi/hptiop.c1
-rw-r--r--drivers/scsi/ibmmca.c1
-rw-r--r--drivers/scsi/ibmvscsi/ibmvscsi.c1
-rw-r--r--drivers/scsi/ide-scsi.c32
-rw-r--r--drivers/scsi/initio.c1
-rw-r--r--drivers/scsi/ips.c14
-rw-r--r--drivers/scsi/lpfc/lpfc_scsi.c2
-rw-r--r--drivers/scsi/mac53c94.c1
-rw-r--r--drivers/scsi/mac_scsi.c9
-rw-r--r--drivers/scsi/megaraid.c1
-rw-r--r--drivers/scsi/megaraid/megaraid_mbox.c1
-rw-r--r--drivers/scsi/megaraid/megaraid_sas.c1
-rw-r--r--drivers/scsi/mesh.c1
-rw-r--r--drivers/scsi/nsp32.c1
-rw-r--r--drivers/scsi/pcmcia/sym53c500_cs.c1
-rw-r--r--drivers/scsi/qla1280.c70
-rw-r--r--drivers/scsi/qla2xxx/qla_os.c2
-rw-r--r--drivers/scsi/qla4xxx/ql4_os.c1
-rw-r--r--drivers/scsi/qlogicfas.c1
-rw-r--r--drivers/scsi/qlogicpti.c15
-rw-r--r--drivers/scsi/scsi_debug.c30
-rw-r--r--drivers/scsi/scsi_lib.c238
-rw-r--r--drivers/scsi/scsi_tgt_lib.c4
-rw-r--r--drivers/scsi/sd.c22
-rw-r--r--drivers/scsi/sg.c16
-rw-r--r--drivers/scsi/stex.c1
-rw-r--r--drivers/scsi/sym53c416.c1
-rw-r--r--drivers/scsi/sym53c8xx_2/sym_glue.c1
-rw-r--r--drivers/scsi/u14-34f.c3
-rw-r--r--drivers/scsi/ultrastor.c1
-rw-r--r--drivers/scsi/wd7000.c1
-rw-r--r--drivers/serial/8250_pci.c120
-rw-r--r--drivers/serial/8250_pnp.c2
-rw-r--r--drivers/serial/crisv10.c67
-rw-r--r--drivers/serial/m32r_sio.c2
-rw-r--r--drivers/serial/m32r_sio.h6
-rw-r--r--drivers/serial/serial_core.c40
-rw-r--r--drivers/serial/serial_cs.c1
-rw-r--r--drivers/serial/serial_txx9.c30
-rw-r--r--drivers/spi/Kconfig13
-rw-r--r--drivers/spi/atmel_spi.c14
-rw-r--r--drivers/spi/mpc52xx_psc_spi.c2
-rw-r--r--drivers/spi/omap2_mcspi.c4
-rw-r--r--drivers/spi/omap_uwire.c9
-rw-r--r--drivers/spi/pxa2xx_spi.c14
-rw-r--r--drivers/spi/spi.c36
-rw-r--r--drivers/spi/spi_bfin5xx.c3
-rw-r--r--drivers/spi/spi_bitbang.c2
-rw-r--r--drivers/spi/spi_imx.c13
-rw-r--r--drivers/spi/spi_lm70llp.c2
-rw-r--r--drivers/spi/spi_mpc83xx.c7
-rw-r--r--drivers/spi/spi_s3c24xx.c9
-rw-r--r--drivers/spi/spi_txx9.c2
-rw-r--r--drivers/usb/core/hub.c6
-rw-r--r--drivers/usb/misc/sisusbvga/sisusb_con.c3
-rw-r--r--drivers/usb/storage/alauda.c16
-rw-r--r--drivers/usb/storage/datafab.c10
-rw-r--r--drivers/usb/storage/jumpshot.c10
-rw-r--r--drivers/usb/storage/protocol.c20
-rw-r--r--drivers/usb/storage/protocol.h2
-rw-r--r--drivers/usb/storage/sddr09.c16
-rw-r--r--drivers/usb/storage/sddr55.c16
-rw-r--r--drivers/usb/storage/shuttle_usbat.c17
-rw-r--r--drivers/video/Kconfig59
-rw-r--r--drivers/video/Makefile2
-rw-r--r--drivers/video/amifb.c2
-rw-r--r--drivers/video/arcfb.c2
-rw-r--r--drivers/video/atafb.c2
-rw-r--r--drivers/video/aty/ati_ids.h1
-rw-r--r--drivers/video/aty/aty128fb.c2
-rw-r--r--drivers/video/aty/atyfb.h1
-rw-r--r--drivers/video/aty/atyfb_base.c6
-rw-r--r--drivers/video/aty/mach64_cursor.c1
-rw-r--r--drivers/video/aty/radeon_base.c5
-rw-r--r--drivers/video/aty/radeonfb.h4
-rw-r--r--drivers/video/backlight/cr_bllcd.c1
-rw-r--r--drivers/video/backlight/progear_bl.c1
-rw-r--r--drivers/video/bf54x-lq043fb.c786
-rw-r--r--drivers/video/cfbcopyarea.c103
-rw-r--r--drivers/video/cfbfillrect.c20
-rw-r--r--drivers/video/cfbimgblt.c17
-rw-r--r--drivers/video/cirrusfb.c2050
-rw-r--r--drivers/video/clps711xfb.c2
-rw-r--r--drivers/video/console/fbcon.c5
-rw-r--r--drivers/video/console/font_10x18.c14
-rw-r--r--drivers/video/console/font_6x11.c13
-rw-r--r--drivers/video/console/font_7x14.c12
-rw-r--r--drivers/video/console/font_8x16.c14
-rw-r--r--drivers/video/console/font_8x8.c12
-rw-r--r--drivers/video/console/font_acorn_8x8.c14
-rw-r--r--drivers/video/console/font_mini_4x6.c12
-rw-r--r--drivers/video/console/font_pearl_8x8.c12
-rw-r--r--drivers/video/console/font_sun12x22.c14
-rw-r--r--drivers/video/console/font_sun8x16.c14
-rw-r--r--drivers/video/console/newport_con.c20
-rw-r--r--drivers/video/console/softcursor.c1
-rw-r--r--drivers/video/console/vgacon.c7
-rw-r--r--drivers/video/cyber2000fb.c1
-rw-r--r--drivers/video/epson1355fb.c2
-rw-r--r--drivers/video/fb_defio.c1
-rw-r--r--drivers/video/fb_draw.h94
-rw-r--r--drivers/video/fb_sys_fops.c2
-rw-r--r--drivers/video/fbcmap.c3
-rw-r--r--drivers/video/fbmem.c5
-rw-r--r--drivers/video/fbmon.c4
-rw-r--r--drivers/video/geode/lxfb_core.c7
-rw-r--r--drivers/video/hecubafb.c2
-rw-r--r--drivers/video/imsttfb.c2
-rw-r--r--drivers/video/imxfb.c4
-rw-r--r--drivers/video/intelfb/intelfb.h17
-rw-r--r--drivers/video/intelfb/intelfb_i2c.c60
-rw-r--r--drivers/video/intelfb/intelfbdrv.c178
-rw-r--r--drivers/video/intelfb/intelfbhw.c318
-rw-r--r--drivers/video/intelfb/intelfbhw.h52
-rw-r--r--drivers/video/kyro/fbdev.c2
-rw-r--r--drivers/video/logo/logo.c7
-rw-r--r--drivers/video/matrox/matroxfb_base.c2
-rw-r--r--drivers/video/matrox/matroxfb_crtc2.c2
-rw-r--r--drivers/video/matrox/matroxfb_g450.c1
-rw-r--r--drivers/video/matrox/matroxfb_maven.c1
-rw-r--r--drivers/video/mbx/mbxfb.c344
-rw-r--r--drivers/video/mbx/reg_bits.h87
-rw-r--r--drivers/video/mbx/regs.h2
-rw-r--r--drivers/video/modedb.c58
-rw-r--r--drivers/video/neofb.c1
-rw-r--r--drivers/video/nvidia/nv_i2c.c10
-rw-r--r--drivers/video/nvidia/nv_type.h1
-rw-r--r--drivers/video/nvidia/nvidia.c6
-rw-r--r--drivers/video/pm2fb.c883
-rw-r--r--drivers/video/pm3fb.c557
-rw-r--r--drivers/video/pmag-ba-fb.c34
-rw-r--r--drivers/video/pmagb-b-fb.c34
-rw-r--r--drivers/video/pnx4008/pnxrgbfb.c1
-rw-r--r--drivers/video/ps3fb.c511
-rw-r--r--drivers/video/pvr2fb.c2
-rw-r--r--drivers/video/pxafb.c65
-rw-r--r--drivers/video/pxafb.h2
-rw-r--r--drivers/video/s3c2410fb.c783
-rw-r--r--drivers/video/s3c2410fb.h13
-rw-r--r--drivers/video/s3fb.c24
-rw-r--r--drivers/video/sa1100fb.c1
-rw-r--r--drivers/video/savage/savagefb_driver.c1
-rw-r--r--drivers/video/sis/sis_main.c2
-rw-r--r--drivers/video/skeletonfb.c2
-rw-r--r--drivers/video/sm501fb.c49
-rw-r--r--drivers/video/sstfb.c2
-rw-r--r--drivers/video/svgalib.c47
-rw-r--r--drivers/video/tdfxfb.c1255
-rw-r--r--drivers/video/tgafb.c20
-rw-r--r--drivers/video/tridentfb.c1075
-rw-r--r--drivers/video/uvesafb.c2066
-rw-r--r--drivers/video/vermilion/vermilion.c1
-rw-r--r--drivers/video/vfb.c79
-rw-r--r--fs/adfs/inode.c14
-rw-r--r--fs/affs/file.c101
-rw-r--r--fs/bfs/file.c12
-rw-r--r--fs/binfmt_elf.c2
-rw-r--r--fs/binfmt_elf_fdpic.c2
-rw-r--r--fs/bio.c23
-rw-r--r--fs/block_dev.c24
-rw-r--r--fs/buffer.c723
-rw-r--r--fs/configfs/inode.c4
-rw-r--r--fs/dcache.c2
-rw-r--r--fs/debugfs/file.c41
-rw-r--r--fs/direct-io.c4
-rw-r--r--fs/ecryptfs/Makefile2
-rw-r--r--fs/ecryptfs/crypto.c989
-rw-r--r--fs/ecryptfs/debug.c2
-rw-r--r--fs/ecryptfs/ecryptfs_kernel.h183
-rw-r--r--fs/ecryptfs/file.c97
-rw-r--r--fs/ecryptfs/inode.c231
-rw-r--r--fs/ecryptfs/keystore.c1078
-rw-r--r--fs/ecryptfs/main.c260
-rw-r--r--fs/ecryptfs/messaging.c5
-rw-r--r--fs/ecryptfs/mmap.c704
-rw-r--r--fs/ecryptfs/read_write.c358
-rw-r--r--fs/ecryptfs/super.c39
-rw-r--r--fs/ext2/dir.c55
-rw-r--r--fs/ext2/ext2.h3
-rw-r--r--fs/ext2/inode.c40
-rw-r--r--fs/ext3/dir.c2
-rw-r--r--fs/ext3/inode.c163
-rw-r--r--fs/ext4/dir.c2
-rw-r--r--fs/ext4/inode.c174
-rw-r--r--fs/fat/inode.c27
-rw-r--r--fs/fuse/file.c46
-rw-r--r--fs/gfs2/ops_address.c211
-rw-r--r--fs/hfs/extent.c19
-rw-r--r--fs/hfs/inode.c18
-rw-r--r--fs/hfsplus/extents.c21
-rw-r--r--fs/hfsplus/inode.c18
-rw-r--r--fs/hostfs/hostfs.h9
-rw-r--r--fs/hostfs/hostfs_kern.c301
-rw-r--r--fs/hostfs/hostfs_user.c141
-rw-r--r--fs/hpfs/file.c18
-rw-r--r--fs/hugetlbfs/inode.c149
-rw-r--r--fs/inode.c18
-rw-r--r--fs/jbd/journal.c4
-rw-r--r--fs/jbd/revoke.c6
-rw-r--r--fs/jffs2/file.c105
-rw-r--r--fs/jfs/inode.c16
-rw-r--r--fs/libfs.c44
-rw-r--r--fs/minix/dir.c49
-rw-r--r--fs/minix/inode.c23
-rw-r--r--fs/minix/minix.h3
-rw-r--r--fs/mpage.c10
-rw-r--r--fs/namei.c46
-rw-r--r--fs/nfs/file.c80
-rw-r--r--fs/nfsd/export.c17
-rw-r--r--fs/ocfs2/aops.c14
-rw-r--r--fs/ocfs2/aops.h8
-rw-r--r--fs/ocfs2/file.c266
-rw-r--r--fs/proc/base.c13
-rw-r--r--fs/proc/generic.c2
-rw-r--r--fs/proc/proc_misc.c14
-rw-r--r--fs/qnx4/inode.c19
-rw-r--r--fs/ramfs/file-mmu.c4
-rw-r--r--fs/ramfs/file-nommu.c4
-rw-r--r--fs/reiserfs/file.c1240
-rw-r--r--fs/reiserfs/inode.c187
-rw-r--r--fs/reiserfs/ioctl.c10
-rw-r--r--fs/reiserfs/xattr.c16
-rw-r--r--fs/smbfs/file.c32
-rw-r--r--fs/splice.c73
-rw-r--r--fs/sysfs/inode.c4
-rw-r--r--fs/sysv/dir.c50
-rw-r--r--fs/sysv/itree.c23
-rw-r--r--fs/sysv/sysv.h3
-rw-r--r--fs/udf/file.c35
-rw-r--r--fs/udf/inode.c13
-rw-r--r--fs/ufs/dir.c55
-rw-r--r--fs/ufs/inode.c23
-rw-r--r--fs/ufs/util.h3
-rw-r--r--fs/xfs/linux-2.6/xfs_aops.c19
-rw-r--r--fs/xfs/linux-2.6/xfs_lrw.c35
-rw-r--r--include/asm-alpha/page.h3
-rw-r--r--include/asm-alpha/ptrace.h2
-rw-r--r--include/asm-arm/arch-imx/imxfb.h1
-rw-r--r--include/asm-arm/arch-pxa/pxa-regs.h11
-rw-r--r--include/asm-arm/arch-pxa/pxafb.h7
-rw-r--r--include/asm-arm/arch-s3c2410/fb.h42
-rw-r--r--include/asm-avr32/kdebug.h16
-rw-r--r--include/asm-avr32/kprobes.h2
-rw-r--r--include/asm-blackfin/mach-bf548/bf54x-lq043.h30
-rw-r--r--include/asm-frv/thread_info.h5
-rw-r--r--include/asm-frv/tlbflush.h3
-rw-r--r--include/asm-generic/memory_model.h6
-rw-r--r--include/asm-generic/pgtable.h4
-rw-r--r--include/asm-ia64/dma-mapping.h2
-rw-r--r--include/asm-ia64/kdebug.h15
-rw-r--r--include/asm-ia64/kprobes.h2
-rw-r--r--include/asm-ia64/pgtable.h50
-rw-r--r--include/asm-ia64/scatterlist.h2
-rw-r--r--include/asm-ia64/smp.h2
-rw-r--r--include/asm-ia64/topology.h2
-rw-r--r--include/asm-m32r/ptrace.h5
-rw-r--r--include/asm-m32r/thread_info.h5
-rw-r--r--include/asm-m68knommu/system.h3
-rw-r--r--include/asm-mips/xxs1500.h35
-rw-r--r--include/asm-powerpc/dma-mapping.h158
-rw-r--r--include/asm-powerpc/kdebug.h19
-rw-r--r--include/asm-powerpc/kprobes.h2
-rw-r--r--include/asm-powerpc/pgtable-ppc64.h8
-rw-r--r--include/asm-powerpc/ps3av.h33
-rw-r--r--include/asm-powerpc/scatterlist.h2
-rw-r--r--include/asm-powerpc/smp.h4
-rw-r--r--include/asm-powerpc/topology.h2
-rw-r--r--include/asm-s390/kdebug.h15
-rw-r--r--include/asm-s390/kprobes.h2
-rw-r--r--include/asm-sh/kdebug.h2
-rw-r--r--include/asm-sparc/scatterlist.h2
-rw-r--r--include/asm-sparc64/kdebug.h18
-rw-r--r--include/asm-sparc64/kprobes.h3
-rw-r--r--include/asm-sparc64/pgtable.h3
-rw-r--r--include/asm-sparc64/scatterlist.h2
-rw-r--r--include/asm-sparc64/smp.h3
-rw-r--r--include/asm-sparc64/topology.h2
-rw-r--r--include/asm-um/a.out.h12
-rw-r--r--include/asm-um/elf-i386.h12
-rw-r--r--include/asm-um/elf-x86_64.h56
-rw-r--r--include/asm-um/ldt.h4
-rw-r--r--include/asm-um/mmu_context.h43
-rw-r--r--include/asm-um/page.h1
-rw-r--r--include/asm-um/pgalloc.h2
-rw-r--r--include/asm-um/pgtable-3level.h2
-rw-r--r--include/asm-um/processor-generic.h48
-rw-r--r--include/asm-um/processor-x86_64.h2
-rw-r--r--include/asm-um/ptrace-generic.h17
-rw-r--r--include/asm-um/ptrace-i386.h42
-rw-r--r--include/asm-um/ptrace-x86_64.h13
-rw-r--r--include/asm-um/smp.h2
-rw-r--r--include/asm-um/tlbflush.h19
-rw-r--r--include/asm-um/uaccess.h2
-rw-r--r--include/asm-x86/cpufeature_32.h1
-rw-r--r--include/asm-x86/dma-mapping_32.h13
-rw-r--r--include/asm-x86/dma-mapping_64.h3
-rw-r--r--include/asm-x86/kdebug_32.h6
-rw-r--r--include/asm-x86/kdebug_64.h6
-rw-r--r--include/asm-x86/kprobes_32.h4
-rw-r--r--include/asm-x86/kprobes_64.h2
-rw-r--r--include/asm-x86/page_64.h1
-rw-r--r--include/asm-x86/pgtable_64.h1
-rw-r--r--include/asm-x86/scatterlist_32.h2
-rw-r--r--include/asm-x86/scatterlist_64.h2
-rw-r--r--include/asm-x86/smp_32.h4
-rw-r--r--include/asm-x86/smp_64.h11
-rw-r--r--include/asm-x86/topology_32.h4
-rw-r--r--include/asm-x86/topology_64.h4
-rw-r--r--include/linux/bio.h19
-rw-r--r--include/linux/bitops.h6
-rw-r--r--include/linux/blkdev.h8
-rw-r--r--include/linux/buffer_head.h26
-rw-r--r--include/linux/connector.h7
-rw-r--r--include/linux/console.h3
-rw-r--r--include/linux/console_struct.h1
-rw-r--r--include/linux/cpuset.h2
-rw-r--r--include/linux/dca.h47
-rw-r--r--include/linux/dma-mapping.h7
-rw-r--r--include/linux/fb.h3
-rw-r--r--include/linux/fs.h78
-rw-r--r--include/linux/gfp.h62
-rw-r--r--include/linux/hugetlb.h1
-rw-r--r--include/linux/i2o.h3
-rw-r--r--include/linux/ide.h7
-rw-r--r--include/linux/init.h2
-rw-r--r--include/linux/interrupt.h9
-rw-r--r--include/linux/ioport.h3
-rw-r--r--include/linux/isdn.h3
-rw-r--r--include/linux/jbd.h1
-rw-r--r--include/linux/jiffies.h2
-rw-r--r--include/linux/kernel.h1
-rw-r--r--include/linux/kprobes.h6
-rw-r--r--include/linux/libata.h16
-rw-r--r--include/linux/memory_hotplug.h18
-rw-r--r--include/linux/mempolicy.h7
-rw-r--r--include/linux/mm.h97
-rw-r--r--include/linux/mm_types.h158
-rw-r--r--include/linux/mmzone.h68
-rw-r--r--include/linux/nfsd/export.h11
-rw-r--r--include/linux/nodemask.h94
-rw-r--r--include/linux/page-isolation.h37
-rw-r--r--include/linux/pageblock-flags.h75
-rw-r--r--include/linux/pagemap.h36
-rw-r--r--include/linux/pci_ids.h4
-rw-r--r--include/linux/radix-tree.h40
-rw-r--r--include/linux/scatterlist.h84
-rw-r--r--include/linux/sched.h77
-rw-r--r--include/linux/selection.h1
-rw-r--r--include/linux/serial_core.h3
-rw-r--r--include/linux/slab.h4
-rw-r--r--include/linux/slub_def.h71
-rw-r--r--include/linux/sm501-regs.h18
-rw-r--r--include/linux/spi/spi.h12
-rw-r--r--include/linux/usb/gadget.h4
-rw-r--r--include/pcmcia/ds.h1
-rw-r--r--include/scsi/scsi.h7
-rw-r--r--include/scsi/scsi_cmnd.h7
-rw-r--r--include/scsi/scsi_host.h13
-rw-r--r--include/video/Kbuild2
-rw-r--r--include/video/mbxfb.h53
-rw-r--r--include/video/permedia2.h17
-rw-r--r--include/video/pm3fb.h1272
-rw-r--r--include/video/tdfx.h270
-rw-r--r--include/video/uvesafb.h193
-rw-r--r--init/calibrate.c2
-rw-r--r--kernel/cpuset.c142
-rw-r--r--kernel/kprobes.c62
-rw-r--r--kernel/printk.c59
-rw-r--r--kernel/profile.c4
-rw-r--r--kernel/ptrace.c13
-rw-r--r--kernel/resource.c26
-rw-r--r--kernel/sched.c37
-rw-r--r--kernel/sysctl.c8
-rw-r--r--kernel/time.c6
-rw-r--r--kernel/time/timekeeping.c7
-rw-r--r--lib/Kconfig.debug18
-rw-r--r--lib/radix-tree.c132
-rw-r--r--lib/swiotlb.c19
-rw-r--r--mm/Kconfig18
-rw-r--r--mm/Makefile3
-rw-r--r--mm/bounce.c6
-rw-r--r--mm/filemap.c766
-rw-r--r--mm/filemap.h103
-rw-r--r--mm/filemap_xip.c17
-rw-r--r--mm/hugetlb.c398
-rw-r--r--mm/internal.h10
-rw-r--r--mm/memory.c161
-rw-r--r--mm/memory_hotplug.c312
-rw-r--r--mm/mempolicy.c60
-rw-r--r--mm/migrate.c4
-rw-r--r--mm/mprotect.c1
-rw-r--r--mm/oom_kill.c9
-rw-r--r--mm/page-writeback.c10
-rw-r--r--mm/page_alloc.c731
-rw-r--r--mm/page_isolation.c138
-rw-r--r--mm/readahead.c88
-rw-r--r--mm/rmap.c1
-rw-r--r--mm/shmem.c62
-rw-r--r--mm/slab.c21
-rw-r--r--mm/slob.c7
-rw-r--r--mm/slub.c490
-rw-r--r--mm/sparse-vmemmap.c148
-rw-r--r--mm/sparse.c105
-rw-r--r--mm/swap.c106
-rw-r--r--mm/swap_state.c5
-rw-r--r--mm/util.c6
-rw-r--r--mm/vmalloc.c5
-rw-r--r--mm/vmscan.c59
-rw-r--r--mm/vmstat.c305
-rw-r--r--net/sunrpc/xprtrdma/verbs.c3
850 files changed, 28516 insertions, 24638 deletions
diff --git a/CREDITS b/CREDITS
index cf919aaacc9f..08feda2667d0 100644
--- a/CREDITS
+++ b/CREDITS
@@ -2702,7 +2702,7 @@ S: Canada K2P 0X8
2702 2702
2703N: Mikael Pettersson 2703N: Mikael Pettersson
2704E: mikpe@it.uu.se 2704E: mikpe@it.uu.se
2705W: http://www.csd.uu.se/~mikpe/ 2705W: http://user.it.uu.se/~mikpe/linux/
2706D: Miscellaneous fixes 2706D: Miscellaneous fixes
2707 2707
2708N: Reed H. Petty 2708N: Reed H. Petty
diff --git a/Documentation/DMA-mapping.txt b/Documentation/DMA-mapping.txt
index e07f2530326b..3c8ae020b6a7 100644
--- a/Documentation/DMA-mapping.txt
+++ b/Documentation/DMA-mapping.txt
@@ -514,7 +514,7 @@ With scatterlists, you map a region gathered from several regions by:
514 int i, count = pci_map_sg(dev, sglist, nents, direction); 514 int i, count = pci_map_sg(dev, sglist, nents, direction);
515 struct scatterlist *sg; 515 struct scatterlist *sg;
516 516
517 for (i = 0, sg = sglist; i < count; i++, sg++) { 517 for_each_sg(sglist, sg, count, i) {
518 hw_address[i] = sg_dma_address(sg); 518 hw_address[i] = sg_dma_address(sg);
519 hw_len[i] = sg_dma_len(sg); 519 hw_len[i] = sg_dma_len(sg);
520 } 520 }
@@ -782,5 +782,5 @@ following people:
782 Jay Estabrook <Jay.Estabrook@compaq.com> 782 Jay Estabrook <Jay.Estabrook@compaq.com>
783 Thomas Sailer <sailer@ife.ee.ethz.ch> 783 Thomas Sailer <sailer@ife.ee.ethz.ch>
784 Andrea Arcangeli <andrea@suse.de> 784 Andrea Arcangeli <andrea@suse.de>
785 Jens Axboe <axboe@suse.de> 785 Jens Axboe <jens.axboe@oracle.com>
786 David Mosberger-Tang <davidm@hpl.hp.com> 786 David Mosberger-Tang <davidm@hpl.hp.com>
diff --git a/Documentation/HOWTO b/Documentation/HOWTO
index c64e969dc33b..dceb30921498 100644
--- a/Documentation/HOWTO
+++ b/Documentation/HOWTO
@@ -330,7 +330,7 @@ Here is a list of some of the different kernel trees available:
330 - ACPI development tree, Len Brown <len.brown@intel.com> 330 - ACPI development tree, Len Brown <len.brown@intel.com>
331 git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git 331 git.kernel.org:/pub/scm/linux/kernel/git/lenb/linux-acpi-2.6.git
332 332
333 - Block development tree, Jens Axboe <axboe@suse.de> 333 - Block development tree, Jens Axboe <jens.axboe@oracle.com>
334 git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git 334 git.kernel.org:/pub/scm/linux/kernel/git/axboe/linux-2.6-block.git
335 335
336 - DRM development tree, Dave Airlie <airlied@linux.ie> 336 - DRM development tree, Dave Airlie <airlied@linux.ie>
diff --git a/Documentation/block/00-INDEX b/Documentation/block/00-INDEX
new file mode 100644
index 000000000000..961a0513f8c3
--- /dev/null
+++ b/Documentation/block/00-INDEX
@@ -0,0 +1,20 @@
100-INDEX
2 - This file
3as-iosched.txt
4 - Anticipatory IO scheduler
5barrier.txt
6 - I/O Barriers
7biodoc.txt
8 - Notes on the Generic Block Layer Rewrite in Linux 2.5
9capability.txt
10 - Generic Block Device Capability (/sys/block/<disk>/capability)
11deadline-iosched.txt
12 - Deadline IO scheduler tunables
13ioprio.txt
14 - Block io priorities (in CFQ scheduler)
15request.txt
16 - The members of struct request (in include/linux/blkdev.h)
17stat.txt
18 - Block layer statistics in /sys/block/<dev>/stat
19switching-sched.txt
20 - Switching I/O schedulers at runtime
diff --git a/Documentation/block/as-iosched.txt b/Documentation/block/as-iosched.txt
index a598fe10a297..738b72be128e 100644
--- a/Documentation/block/as-iosched.txt
+++ b/Documentation/block/as-iosched.txt
@@ -20,15 +20,10 @@ actually has a head for each physical device in the logical RAID device.
20However, setting the antic_expire (see tunable parameters below) produces 20However, setting the antic_expire (see tunable parameters below) produces
21very similar behavior to the deadline IO scheduler. 21very similar behavior to the deadline IO scheduler.
22 22
23
24Selecting IO schedulers 23Selecting IO schedulers
25----------------------- 24-----------------------
26To choose IO schedulers at boot time, use the argument 'elevator=deadline'. 25Refer to Documentation/block/switching-sched.txt for information on
27'noop', 'as' and 'cfq' (the default) are also available. IO schedulers are 26selecting an io scheduler on a per-device basis.
28assigned globally at boot time only presently. It's also possible to change
29the IO scheduler for a determined device on the fly, as described in
30Documentation/block/switching-sched.txt.
31
32 27
33Anticipatory IO scheduler Policies 28Anticipatory IO scheduler Policies
34---------------------------------- 29----------------------------------
@@ -115,7 +110,7 @@ statistics (average think time, average seek distance) on the process
115that submitted the just completed request are examined. If it seems 110that submitted the just completed request are examined. If it seems
116likely that that process will submit another request soon, and that 111likely that that process will submit another request soon, and that
117request is likely to be near the just completed request, then the IO 112request is likely to be near the just completed request, then the IO
118scheduler will stop dispatching more read requests for up time (antic_expire) 113scheduler will stop dispatching more read requests for up to (antic_expire)
119milliseconds, hoping that process will submit a new request near the one 114milliseconds, hoping that process will submit a new request near the one
120that just completed. If such a request is made, then it is dispatched 115that just completed. If such a request is made, then it is dispatched
121immediately. If the antic_expire wait time expires, then the IO scheduler 116immediately. If the antic_expire wait time expires, then the IO scheduler
@@ -165,3 +160,13 @@ The parameters are:
165 for big seek time devices though not a linear correspondence - most 160 for big seek time devices though not a linear correspondence - most
166 processes have only a few ms thinktime. 161 processes have only a few ms thinktime.
167 162
163In addition to the tunables above there is a read-only file named est_time
164which, when read, will show:
165
166 - The probability of a task exiting without a cooperating task
167 submitting an anticipated IO.
168
169 - The current mean think time.
170
171 - The seek distance used to determine if an incoming IO is better.
172
diff --git a/Documentation/block/biodoc.txt b/Documentation/block/biodoc.txt
index dc3f49e3e539..93f223b9723f 100644
--- a/Documentation/block/biodoc.txt
+++ b/Documentation/block/biodoc.txt
@@ -2,7 +2,7 @@
2 ===================================================== 2 =====================================================
3 3
4Notes Written on Jan 15, 2002: 4Notes Written on Jan 15, 2002:
5 Jens Axboe <axboe@suse.de> 5 Jens Axboe <jens.axboe@oracle.com>
6 Suparna Bhattacharya <suparna@in.ibm.com> 6 Suparna Bhattacharya <suparna@in.ibm.com>
7 7
8Last Updated May 2, 2002 8Last Updated May 2, 2002
@@ -21,7 +21,7 @@ Credits:
21--------- 21---------
22 22
232.5 bio rewrite: 232.5 bio rewrite:
24 Jens Axboe <axboe@suse.de> 24 Jens Axboe <jens.axboe@oracle.com>
25 25
26Many aspects of the generic block layer redesign were driven by and evolved 26Many aspects of the generic block layer redesign were driven by and evolved
27over discussions, prior patches and the collective experience of several 27over discussions, prior patches and the collective experience of several
diff --git a/Documentation/block/deadline-iosched.txt b/Documentation/block/deadline-iosched.txt
index be08ffd1e9b8..c23cab13c3d1 100644
--- a/Documentation/block/deadline-iosched.txt
+++ b/Documentation/block/deadline-iosched.txt
@@ -5,16 +5,10 @@ This little file attempts to document how the deadline io scheduler works.
5In particular, it will clarify the meaning of the exposed tunables that may be 5In particular, it will clarify the meaning of the exposed tunables that may be
6of interest to power users. 6of interest to power users.
7 7
8Each io queue has a set of io scheduler tunables associated with it. These 8Selecting IO schedulers
9tunables control how the io scheduler works. You can find these entries 9-----------------------
10in: 10Refer to Documentation/block/switching-sched.txt for information on
11 11selecting an io scheduler on a per-device basis.
12/sys/block/<device>/queue/iosched
13
14assuming that you have sysfs mounted on /sys. If you don't have sysfs mounted,
15you can do so by typing:
16
17# mount none /sys -t sysfs
18 12
19 13
20******************************************************************************** 14********************************************************************************
@@ -41,14 +35,11 @@ fifo_batch
41 35
42When a read request expires its deadline, we must move some requests from 36When a read request expires its deadline, we must move some requests from
43the sorted io scheduler list to the block device dispatch queue. fifo_batch 37the sorted io scheduler list to the block device dispatch queue. fifo_batch
44controls how many requests we move, based on the cost of each request. A 38controls how many requests we move.
45request is either qualified as a seek or a stream. The io scheduler knows
46the last request that was serviced by the drive (or will be serviced right
47before this one). See seek_cost and stream_unit.
48 39
49 40
50write_starved (number of dispatches) 41writes_starved (number of dispatches)
51------------- 42--------------
52 43
53When we have to move requests from the io scheduler queue to the block 44When we have to move requests from the io scheduler queue to the block
54device dispatch queue, we always give a preference to reads. However, we 45device dispatch queue, we always give a preference to reads. However, we
@@ -73,6 +64,6 @@ that comes at basically 0 cost we leave that on. We simply disable the
73rbtree front sector lookup when the io scheduler merge function is called. 64rbtree front sector lookup when the io scheduler merge function is called.
74 65
75 66
76Nov 11 2002, Jens Axboe <axboe@suse.de> 67Nov 11 2002, Jens Axboe <jens.axboe@oracle.com>
77 68
78 69
diff --git a/Documentation/block/ioprio.txt b/Documentation/block/ioprio.txt
index 35e516b0b8a9..8ed8c59380b4 100644
--- a/Documentation/block/ioprio.txt
+++ b/Documentation/block/ioprio.txt
@@ -180,4 +180,4 @@ int main(int argc, char *argv[])
180---> snip ionice.c tool <--- 180---> snip ionice.c tool <---
181 181
182 182
183March 11 2005, Jens Axboe <axboe@suse.de> 183March 11 2005, Jens Axboe <jens.axboe@oracle.com>
diff --git a/Documentation/block/request.txt b/Documentation/block/request.txt
index fff58acb40a3..754e104ed369 100644
--- a/Documentation/block/request.txt
+++ b/Documentation/block/request.txt
@@ -1,7 +1,7 @@
1 1
2struct request documentation 2struct request documentation
3 3
4Jens Axboe <axboe@suse.de> 27/05/02 4Jens Axboe <jens.axboe@oracle.com> 27/05/02
5 5
61.0 61.0
7Index 7Index
diff --git a/Documentation/block/switching-sched.txt b/Documentation/block/switching-sched.txt
index 5fa130a67531..634c952e1964 100644
--- a/Documentation/block/switching-sched.txt
+++ b/Documentation/block/switching-sched.txt
@@ -1,3 +1,18 @@
1To choose IO schedulers at boot time, use the argument 'elevator=deadline'.
2'noop', 'as' and 'cfq' (the default) are also available. IO schedulers are
3assigned globally at boot time only presently.
4
5Each io queue has a set of io scheduler tunables associated with it. These
6tunables control how the io scheduler works. You can find these entries
7in:
8
9/sys/block/<device>/queue/iosched
10
11assuming that you have sysfs mounted on /sys. If you don't have sysfs mounted,
12you can do so by typing:
13
14# mount none /sys -t sysfs
15
1As of the Linux 2.6.10 kernel, it is now possible to change the 16As of the Linux 2.6.10 kernel, it is now possible to change the
2IO scheduler for a given block device on the fly (thus making it possible, 17IO scheduler for a given block device on the fly (thus making it possible,
3for instance, to set the CFQ scheduler for the system default, but 18for instance, to set the CFQ scheduler for the system default, but
@@ -20,3 +35,9 @@ noop anticipatory deadline [cfq]
20# echo anticipatory > /sys/block/hda/queue/scheduler 35# echo anticipatory > /sys/block/hda/queue/scheduler
21# cat /sys/block/hda/queue/scheduler 36# cat /sys/block/hda/queue/scheduler
22noop [anticipatory] deadline cfq 37noop [anticipatory] deadline cfq
38
39Each io queue has a set of io scheduler tunables associated with it. These
40tunables control how the io scheduler works. You can find these entries
41in:
42
43/sys/block/<device>/queue/iosched
diff --git a/Documentation/cachetlb.txt b/Documentation/cachetlb.txt
index 866b76139420..552cabac0608 100644
--- a/Documentation/cachetlb.txt
+++ b/Documentation/cachetlb.txt
@@ -133,12 +133,6 @@ changes occur:
133 The ia64 sn2 platform is one example of a platform 133 The ia64 sn2 platform is one example of a platform
134 that uses this interface. 134 that uses this interface.
135 135
1368) void lazy_mmu_prot_update(pte_t pte)
137 This interface is called whenever the protection on
138 any user PTEs change. This interface provides a notification
139 to architecture specific code to take appropriate action.
140
141
142Next, we have the cache flushing interfaces. In general, when Linux 136Next, we have the cache flushing interfaces. In general, when Linux
143is changing an existing virtual-->physical mapping to a new value, 137is changing an existing virtual-->physical mapping to a new value,
144the sequence will be in one of the following forms: 138the sequence will be in one of the following forms:
diff --git a/Documentation/cpusets.txt b/Documentation/cpusets.txt
index f2c0a6842930..ec9de6917f01 100644
--- a/Documentation/cpusets.txt
+++ b/Documentation/cpusets.txt
@@ -35,7 +35,8 @@ CONTENTS:
35---------------------- 35----------------------
36 36
37Cpusets provide a mechanism for assigning a set of CPUs and Memory 37Cpusets provide a mechanism for assigning a set of CPUs and Memory
38Nodes to a set of tasks. 38Nodes to a set of tasks. In this document "Memory Node" refers to
39an on-line node that contains memory.
39 40
40Cpusets constrain the CPU and Memory placement of tasks to only 41Cpusets constrain the CPU and Memory placement of tasks to only
41the resources within a tasks current cpuset. They form a nested 42the resources within a tasks current cpuset. They form a nested
@@ -86,9 +87,6 @@ This can be especially valuable on:
86 and a database), or 87 and a database), or
87 * NUMA systems running large HPC applications with demanding 88 * NUMA systems running large HPC applications with demanding
88 performance characteristics. 89 performance characteristics.
89 * Also cpu_exclusive cpusets are useful for servers running orthogonal
90 workloads such as RT applications requiring low latency and HPC
91 applications that are throughput sensitive
92 90
93These subsets, or "soft partitions" must be able to be dynamically 91These subsets, or "soft partitions" must be able to be dynamically
94adjusted, as the job mix changes, without impacting other concurrently 92adjusted, as the job mix changes, without impacting other concurrently
@@ -131,8 +129,6 @@ Cpusets extends these two mechanisms as follows:
131 - A cpuset may be marked exclusive, which ensures that no other 129 - A cpuset may be marked exclusive, which ensures that no other
132 cpuset (except direct ancestors and descendents) may contain 130 cpuset (except direct ancestors and descendents) may contain
133 any overlapping CPUs or Memory Nodes. 131 any overlapping CPUs or Memory Nodes.
134 Also a cpu_exclusive cpuset would be associated with a sched
135 domain.
136 - You can list all the tasks (by pid) attached to any cpuset. 132 - You can list all the tasks (by pid) attached to any cpuset.
137 133
138The implementation of cpusets requires a few, simple hooks 134The implementation of cpusets requires a few, simple hooks
@@ -144,9 +140,6 @@ into the rest of the kernel, none in performance critical paths:
144 allowed in that tasks cpuset. 140 allowed in that tasks cpuset.
145 - in sched.c migrate_all_tasks(), to keep migrating tasks within 141 - in sched.c migrate_all_tasks(), to keep migrating tasks within
146 the CPUs allowed by their cpuset, if possible. 142 the CPUs allowed by their cpuset, if possible.
147 - in sched.c, a new API partition_sched_domains for handling
148 sched domain changes associated with cpu_exclusive cpusets
149 and related changes in both sched.c and arch/ia64/kernel/domain.c
150 - in the mbind and set_mempolicy system calls, to mask the requested 143 - in the mbind and set_mempolicy system calls, to mask the requested
151 Memory Nodes by what's allowed in that tasks cpuset. 144 Memory Nodes by what's allowed in that tasks cpuset.
152 - in page_alloc.c, to restrict memory to allowed nodes. 145 - in page_alloc.c, to restrict memory to allowed nodes.
@@ -220,8 +213,8 @@ and name space for cpusets, with a minimum of additional kernel code.
220The cpus and mems files in the root (top_cpuset) cpuset are 213The cpus and mems files in the root (top_cpuset) cpuset are
221read-only. The cpus file automatically tracks the value of 214read-only. The cpus file automatically tracks the value of
222cpu_online_map using a CPU hotplug notifier, and the mems file 215cpu_online_map using a CPU hotplug notifier, and the mems file
223automatically tracks the value of node_online_map using the 216automatically tracks the value of node_states[N_MEMORY]--i.e.,
224cpuset_track_online_nodes() hook. 217nodes with memory--using the cpuset_track_online_nodes() hook.
225 218
226 219
2271.4 What are exclusive cpusets ? 2201.4 What are exclusive cpusets ?
@@ -231,15 +224,6 @@ If a cpuset is cpu or mem exclusive, no other cpuset, other than
231a direct ancestor or descendent, may share any of the same CPUs or 224a direct ancestor or descendent, may share any of the same CPUs or
232Memory Nodes. 225Memory Nodes.
233 226
234A cpuset that is cpu_exclusive has a scheduler (sched) domain
235associated with it. The sched domain consists of all CPUs in the
236current cpuset that are not part of any exclusive child cpusets.
237This ensures that the scheduler load balancing code only balances
238against the CPUs that are in the sched domain as defined above and
239not all of the CPUs in the system. This removes any overhead due to
240load balancing code trying to pull tasks outside of the cpu_exclusive
241cpuset only to be prevented by the tasks' cpus_allowed mask.
242
243A cpuset that is mem_exclusive restricts kernel allocations for 227A cpuset that is mem_exclusive restricts kernel allocations for
244page, buffer and other data commonly shared by the kernel across 228page, buffer and other data commonly shared by the kernel across
245multiple users. All cpusets, whether mem_exclusive or not, restrict 229multiple users. All cpusets, whether mem_exclusive or not, restrict
diff --git a/Documentation/fb/00-INDEX b/Documentation/fb/00-INDEX
index 92e89aeef52e..caabbd395e61 100644
--- a/Documentation/fb/00-INDEX
+++ b/Documentation/fb/00-INDEX
@@ -5,21 +5,49 @@ please mail me.
5 5
600-INDEX 600-INDEX
7 - this file 7 - this file
8arkfb.txt
9 - info on the fbdev driver for ARK Logic chips.
10aty128fb.txt
11 - info on the ATI Rage128 frame buffer driver.
12cirrusfb.txt
13 - info on the driver for Cirrus Logic chipsets.
14cyblafb/
15 - directory with documentation files related to the cyblafb driver.
16deferred_io.txt
17 - an introduction to deferred IO.
18fbcon.txt
19 - intro to and usage guide for the framebuffer console (fbcon).
8framebuffer.txt 20framebuffer.txt
9 - introduction to frame buffer devices 21 - introduction to frame buffer devices.
22imacfb.txt
23 - info on the generic EFI platform driver for Intel based Macs.
24intel810.txt
25 - documentation for the Intel 810/815 framebuffer driver.
26intelfb.txt
27 - docs for Intel 830M/845G/852GM/855GM/865G/915G/945G fb driver.
10internals.txt 28internals.txt
11 - quick overview of frame buffer device internals 29 - quick overview of frame buffer device internals.
30matroxfb.txt
31 - info on the Matrox framebuffer driver for Alpha, Intel and PPC.
12modedb.txt 32modedb.txt
13 - info on the video mode database 33 - info on the video mode database.
14aty128fb.txt
15 - info on the ATI Rage128 frame buffer driver
16clgenfb.txt
17 - info on the Cirrus Logic frame buffer driver
18matroxfb.txt 34matroxfb.txt
19 - info on the Matrox frame buffer driver 35 - info on the Matrox frame buffer driver.
20pvr2fb.txt 36pvr2fb.txt
21 - info on the PowerVR 2 frame buffer driver 37 - info on the PowerVR 2 frame buffer driver.
38pxafb.txt
39 - info on the driver for the PXA25x LCD controller.
40s3fb.txt
41 - info on the fbdev driver for S3 Trio/Virge chips.
42sa1100fb.txt
43 - information about the driver for the SA-1100 LCD controller.
44sisfb.txt
45 - info on the framebuffer device driver for various SiS chips.
46sstfb.txt
47 - info on the frame buffer driver for 3dfx' Voodoo Graphics boards.
22tgafb.txt 48tgafb.txt
23 - info on the TGA (DECChip 21030) frame buffer driver 49 - info on the TGA (DECChip 21030) frame buffer driver
24vesafb.txt 50vesafb.txt
25 - info on the VESA frame buffer device 51 - info on the VESA frame buffer device
52vt8623fb.txt
53 - info on the fb driver for the graphics core in VIA VT8623 chipsets.
diff --git a/Documentation/fb/uvesafb.txt b/Documentation/fb/uvesafb.txt
new file mode 100644
index 000000000000..bcfc233a0080
--- /dev/null
+++ b/Documentation/fb/uvesafb.txt
@@ -0,0 +1,188 @@
1
2uvesafb - A Generic Driver for VBE2+ compliant video cards
3==========================================================
4
51. Requirements
6---------------
7
8uvesafb should work with any video card that has a Video BIOS compliant
9with the VBE 2.0 standard.
10
11Unlike other drivers, uvesafb makes use of a userspace helper called
12v86d. v86d is used to run the x86 Video BIOS code in a simulated and
13controlled environment. This allows uvesafb to function on arches other
14than x86. Check the v86d documentation for a list of currently supported
15arches.
16
17v86d source code can be downloaded from the following website:
18 http://dev.gentoo.org/~spock/projects/uvesafb
19
20Please refer to the v86d documentation for detailed configuration and
21installation instructions.
22
23Note that the v86d userspace helper has to be available at all times in
24order for uvesafb to work properly. If you want to use uvesafb during
25early boot, you will have to include v86d into an initramfs image, and
26either compile it into the kernel or use it as an initrd.
27
282. Caveats and limitations
29--------------------------
30
31uvesafb is a _generic_ driver which supports a wide variety of video
32cards, but which is ultimately limited by the Video BIOS interface.
33The most important limitations are:
34
35- Lack of any type of acceleration.
36- A strict and limited set of supported video modes. Often the native
37 or most optimal resolution/refresh rate for your setup will not work
38 with uvesafb, simply because the Video BIOS doesn't support the
39 video mode you want to use. This can be especially painful with
40 widescreen panels, where native video modes don't have the 4:3 aspect
41 ratio, which is what most BIOS-es are limited to.
42- Adjusting the refresh rate is only possible with a VBE 3.0 compliant
43 Video BIOS. Note that many nVidia Video BIOS-es claim to be VBE 3.0
44 compliant, while they simply ignore any refresh rate settings.
45
463. Configuration
47----------------
48
49uvesafb can be compiled either as a module, or directly into the kernel.
50In both cases it supports the same set of configuration options, which
51are either given on the kernel command line or as module parameters, e.g.:
52
53 video=uvesafb:1024x768-32,mtrr:3,ywrap (compiled into the kernel)
54
55 # modprobe uvesafb mode=1024x768-32 mtrr=3 scroll=ywrap (module)
56
57Accepted options:
58
59ypan Enable display panning using the VESA protected mode
60 interface. The visible screen is just a window of the
61 video memory, console scrolling is done by changing the
62 start of the window. Available on x86 only.
63
64ywrap Same as ypan, but assumes your gfx board can wrap-around
65 the video memory (i.e. starts reading from top if it
66 reaches the end of video memory). Faster than ypan.
67 Available on x86 only.
68
69redraw Scroll by redrawing the affected part of the screen, this
70 is the safe (and slow) default.
71
72(If you're using uvesafb as a module, the above three options are
73 used a parameter of the scroll option, e.g. scroll=ypan.)
74
75vgapal Use the standard VGA registers for palette changes.
76
77pmipal Use the protected mode interface for palette changes.
78 This is the default if the protected mode interface is
79 available. Available on x86 only.
80
81mtrr:n Setup memory type range registers for the framebuffer
82 where n:
83 0 - disabled (equivalent to nomtrr) (default)
84 1 - uncachable
85 2 - write-back
86 3 - write-combining
87 4 - write-through
88
89 If you see the following in dmesg, choose the type that matches
90 the old one. In this example, use "mtrr:2".
91...
92mtrr: type mismatch for e0000000,8000000 old: write-back new: write-combining
93...
94
95nomtrr Do not use memory type range registers.
96
97vremap:n
98 Remap 'n' MiB of video RAM. If 0 or not specified, remap memory
99 according to video mode.
100
101vtotal:n
102 If the video BIOS of your card incorrectly determines the total
103 amount of video RAM, use this option to override the BIOS (in MiB).
104
105<mode> The mode you want to set, in the standard modedb format. Refer to
106 modedb.txt for a detailed description. When uvesafb is compiled as
107 a module, the mode string should be provided as a value of the
108 'mode' option.
109
110vbemode:x
111 Force the use of VBE mode x. The mode will only be set if it's
112 found in the VBE-provided list of supported modes.
113 NOTE: The mode number 'x' should be specified in VESA mode number
114 notation, not the Linux kernel one (eg. 257 instead of 769).
115 HINT: If you use this option because normal <mode> parameter does
116 not work for you and you use a X server, you'll probably want to
117 set the 'nocrtc' option to ensure that the video mode is properly
118 restored after console <-> X switches.
119
120nocrtc Do not use CRTC timings while setting the video mode. This option
121 has any effect only if the Video BIOS is VBE 3.0 compliant. Use it
122 if you have problems with modes set the standard way. Note that
123 using this option implies that any refresh rate adjustments will
124 be ignored and the refresh rate will stay at your BIOS default (60 Hz).
125
126noedid Do not try to fetch and use EDID-provided modes.
127
128noblank Disable hardware blanking.
129
130v86d:path
131 Set path to the v86d executable. This option is only available as
132 a module parameter, and not as a part of the video= string. If you
133 need to use it and have uvesafb built into the kernel, use
134 uvesafb.v86d="path".
135
136Additionally, the following parameters may be provided. They all override the
137EDID-provided values and BIOS defaults. Refer to your monitor's specs to get
138the correct values for maxhf, maxvf and maxclk for your hardware.
139
140maxhf:n Maximum horizontal frequency (in kHz).
141maxvf:n Maximum vertical frequency (in Hz).
142maxclk:n Maximum pixel clock (in MHz).
143
1444. The sysfs interface
145----------------------
146
147uvesafb provides several sysfs nodes for configurable parameters and
148additional information.
149
150Driver attributes:
151
152/sys/bus/platform/drivers/uvesafb
153 - v86d (default: /sbin/v86d)
154 Path to the v86d executable. v86d is started by uvesafb
155 if an instance of the daemon isn't already running.
156
157Device attributes:
158
159/sys/bus/platform/drivers/uvesafb/uvesafb.0
160 - nocrtc
161 Use the default refresh rate (60 Hz) if set to 1.
162
163 - oem_product_name
164 - oem_product_rev
165 - oem_string
166 - oem_vendor
167 Information about the card and its maker.
168
169 - vbe_modes
170 A list of video modes supported by the Video BIOS along with their
171 VBE mode numbers in hex.
172
173 - vbe_version
174 A BCD value indicating the implemented VBE standard.
175
1765. Miscellaneous
177----------------
178
179Uvesafb will set a video mode with the default refresh rate and timings
180from the Video BIOS if you set pixclock to 0 in fb_var_screeninfo.
181
182
183--
184 Michal Januszewski <spock@gentoo.org>
185 Last updated: 2007-06-16
186
187 Documentation of the uvesafb options is loosely based on vesafb.txt.
188
diff --git a/Documentation/filesystems/Locking b/Documentation/filesystems/Locking
index f0f825808ca4..fe26cc978523 100644
--- a/Documentation/filesystems/Locking
+++ b/Documentation/filesystems/Locking
@@ -178,15 +178,18 @@ prototypes:
178locking rules: 178locking rules:
179 All except set_page_dirty may block 179 All except set_page_dirty may block
180 180
181 BKL PageLocked(page) 181 BKL PageLocked(page) i_sem
182writepage: no yes, unlocks (see below) 182writepage: no yes, unlocks (see below)
183readpage: no yes, unlocks 183readpage: no yes, unlocks
184sync_page: no maybe 184sync_page: no maybe
185writepages: no 185writepages: no
186set_page_dirty no no 186set_page_dirty no no
187readpages: no 187readpages: no
188prepare_write: no yes 188prepare_write: no yes yes
189commit_write: no yes 189commit_write: no yes yes
190write_begin: no locks the page yes
191write_end: no yes, unlocks yes
192perform_write: no n/a yes
190bmap: yes 193bmap: yes
191invalidatepage: no yes 194invalidatepage: no yes
192releasepage: no yes 195releasepage: no yes
diff --git a/Documentation/filesystems/vfs.txt b/Documentation/filesystems/vfs.txt
index 045f3e055a28..6f8e16e3d6c0 100644
--- a/Documentation/filesystems/vfs.txt
+++ b/Documentation/filesystems/vfs.txt
@@ -537,6 +537,12 @@ struct address_space_operations {
537 struct list_head *pages, unsigned nr_pages); 537 struct list_head *pages, unsigned nr_pages);
538 int (*prepare_write)(struct file *, struct page *, unsigned, unsigned); 538 int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
539 int (*commit_write)(struct file *, struct page *, unsigned, unsigned); 539 int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
540 int (*write_begin)(struct file *, struct address_space *mapping,
541 loff_t pos, unsigned len, unsigned flags,
542 struct page **pagep, void **fsdata);
543 int (*write_end)(struct file *, struct address_space *mapping,
544 loff_t pos, unsigned len, unsigned copied,
545 struct page *page, void *fsdata);
540 sector_t (*bmap)(struct address_space *, sector_t); 546 sector_t (*bmap)(struct address_space *, sector_t);
541 int (*invalidatepage) (struct page *, unsigned long); 547 int (*invalidatepage) (struct page *, unsigned long);
542 int (*releasepage) (struct page *, int); 548 int (*releasepage) (struct page *, int);
@@ -615,11 +621,7 @@ struct address_space_operations {
615 any basic-blocks on storage, then those blocks should be 621 any basic-blocks on storage, then those blocks should be
616 pre-read (if they haven't been read already) so that the 622 pre-read (if they haven't been read already) so that the
617 updated blocks can be written out properly. 623 updated blocks can be written out properly.
618 The page will be locked. If prepare_write wants to unlock the 624 The page will be locked.
619 page it, like readpage, may do so and return
620 AOP_TRUNCATED_PAGE.
621 In this case the prepare_write will be retried one the lock is
622 regained.
623 625
624 Note: the page _must not_ be marked uptodate in this function 626 Note: the page _must not_ be marked uptodate in this function
625 (or anywhere else) unless it actually is uptodate right now. As 627 (or anywhere else) unless it actually is uptodate right now. As
@@ -633,6 +635,45 @@ struct address_space_operations {
633 operations. It should avoid returning an error if possible - 635 operations. It should avoid returning an error if possible -
634 errors should have been handled by prepare_write. 636 errors should have been handled by prepare_write.
635 637
638 write_begin: This is intended as a replacement for prepare_write. The
639 key differences being that:
640 - it returns a locked page (in *pagep) rather than being
641 given a pre locked page;
642 - it must be able to cope with short writes (where the
643 length passed to write_begin is greater than the number
644 of bytes copied into the page).
645
646 Called by the generic buffered write code to ask the filesystem to
647 prepare to write len bytes at the given offset in the file. The
648 address_space should check that the write will be able to complete,
649 by allocating space if necessary and doing any other internal
650 housekeeping. If the write will update parts of any basic-blocks on
651 storage, then those blocks should be pre-read (if they haven't been
652 read already) so that the updated blocks can be written out properly.
653
654 The filesystem must return the locked pagecache page for the specified
655 offset, in *pagep, for the caller to write into.
656
657 flags is a field for AOP_FLAG_xxx flags, described in
658 include/linux/fs.h.
659
660 A void * may be returned in fsdata, which then gets passed into
661 write_end.
662
663 Returns 0 on success; < 0 on failure (which is the error code), in
664 which case write_end is not called.
665
666 write_end: After a successful write_begin, and data copy, write_end must
667 be called. len is the original len passed to write_begin, and copied
668 is the amount that was able to be copied (copied == len is always true
669 if write_begin was called with the AOP_FLAG_UNINTERRUPTIBLE flag).
670
671 The filesystem must take care of unlocking the page and releasing it
672 refcount, and updating i_size.
673
674 Returns < 0 on failure, otherwise the number of bytes (<= 'copied')
675 that were able to be copied into pagecache.
676
636 bmap: called by the VFS to map a logical block offset within object to 677 bmap: called by the VFS to map a logical block offset within object to
637 physical block number. This method is used by the FIBMAP 678 physical block number. This method is used by the FIBMAP
638 ioctl and for working with swap-files. To be able to swap to 679 ioctl and for working with swap-files. To be able to swap to
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 085e4a095eaa..eb247997f679 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -349,6 +349,11 @@ and is between 256 and 4096 characters. It is defined in the file
349 blkmtd_bs= 349 blkmtd_bs=
350 blkmtd_count= 350 blkmtd_count=
351 351
352 boot_delay= Milliseconds to delay each printk during boot.
353 Values larger than 10 seconds (10000) are changed to
354 no delay (0).
355 Format: integer
356
352 bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards) 357 bttv.card= [HW,V4L] bttv (bt848 + bt878 based grabber cards)
353 bttv.radio= Most important insmod options are available as 358 bttv.radio= Most important insmod options are available as
354 kernel args too. 359 kernel args too.
@@ -906,6 +911,11 @@ and is between 256 and 4096 characters. It is defined in the file
906 n must be a power of two. The default size 911 n must be a power of two. The default size
907 is set in the kernel config file. 912 is set in the kernel config file.
908 913
914 logo.nologo [FB] Disables display of the built-in Linux logo.
915 This may be used to provide more screen space for
916 kernel log messages and is useful when debugging
917 kernel boot problems.
918
909 lp=0 [LP] Specify parallel ports to use, e.g, 919 lp=0 [LP] Specify parallel ports to use, e.g,
910 lp=port[,port...] lp=none,parport0 (lp0 not configured, lp1 uses 920 lp=port[,port...] lp=none,parport0 (lp0 not configured, lp1 uses
911 lp=reset first parallel port). 'lp=0' disables the 921 lp=reset first parallel port). 'lp=0' disables the
diff --git a/Documentation/spi/spi-summary b/Documentation/spi/spi-summary
index 76ea6c837be5..8861e47e5a2d 100644
--- a/Documentation/spi/spi-summary
+++ b/Documentation/spi/spi-summary
@@ -156,21 +156,29 @@ using the driver model to connect controller and protocol drivers using
156device tables provided by board specific initialization code. SPI 156device tables provided by board specific initialization code. SPI
157shows up in sysfs in several locations: 157shows up in sysfs in several locations:
158 158
159 /sys/devices/.../CTLR ... physical node for a given SPI controller
160
159 /sys/devices/.../CTLR/spiB.C ... spi_device on bus "B", 161 /sys/devices/.../CTLR/spiB.C ... spi_device on bus "B",
160 chipselect C, accessed through CTLR. 162 chipselect C, accessed through CTLR.
161 163
164 /sys/bus/spi/devices/spiB.C ... symlink to that physical
165 .../CTLR/spiB.C device
166
162 /sys/devices/.../CTLR/spiB.C/modalias ... identifies the driver 167 /sys/devices/.../CTLR/spiB.C/modalias ... identifies the driver
163 that should be used with this device (for hotplug/coldplug) 168 that should be used with this device (for hotplug/coldplug)
164 169
165 /sys/bus/spi/devices/spiB.C ... symlink to the physical
166 spiB.C device
167
168 /sys/bus/spi/drivers/D ... driver for one or more spi*.* devices 170 /sys/bus/spi/drivers/D ... driver for one or more spi*.* devices
169 171
170 /sys/class/spi_master/spiB ... class device for the controller 172 /sys/class/spi_master/spiB ... symlink (or actual device node) to
171 managing bus "B". All the spiB.* devices share the same 173 a logical node which could hold class related state for the
174 controller managing bus "B". All spiB.* devices share one
172 physical SPI bus segment, with SCLK, MOSI, and MISO. 175 physical SPI bus segment, with SCLK, MOSI, and MISO.
173 176
177Note that the actual location of the controller's class state depends
178on whether you enabled CONFIG_SYSFS_DEPRECATED or not. At this time,
179the only class-specific state is the bus number ("B" in "spiB"), so
180those /sys/class entries are only useful to quickly identify busses.
181
174 182
175How does board-specific init code declare SPI devices? 183How does board-specific init code declare SPI devices?
176------------------------------------------------------ 184------------------------------------------------------
@@ -337,7 +345,8 @@ SPI protocol drivers somewhat resemble platform device drivers:
337 345
338The driver core will autmatically attempt to bind this driver to any SPI 346The driver core will autmatically attempt to bind this driver to any SPI
339device whose board_info gave a modalias of "CHIP". Your probe() code 347device whose board_info gave a modalias of "CHIP". Your probe() code
340might look like this unless you're creating a class_device: 348might look like this unless you're creating a device which is managing
349a bus (appearing under /sys/class/spi_master).
341 350
342 static int __devinit CHIP_probe(struct spi_device *spi) 351 static int __devinit CHIP_probe(struct spi_device *spi)
343 { 352 {
@@ -442,7 +451,7 @@ An SPI controller will probably be registered on the platform_bus; write
442a driver to bind to the device, whichever bus is involved. 451a driver to bind to the device, whichever bus is involved.
443 452
444The main task of this type of driver is to provide an "spi_master". 453The main task of this type of driver is to provide an "spi_master".
445Use spi_alloc_master() to allocate the master, and class_get_devdata() 454Use spi_alloc_master() to allocate the master, and spi_master_get_devdata()
446to get the driver-private data allocated for that device. 455to get the driver-private data allocated for that device.
447 456
448 struct spi_master *master; 457 struct spi_master *master;
@@ -452,7 +461,7 @@ to get the driver-private data allocated for that device.
452 if (!master) 461 if (!master)
453 return -ENODEV; 462 return -ENODEV;
454 463
455 c = class_get_devdata(&master->cdev); 464 c = spi_master_get_devdata(master);
456 465
457The driver will initialize the fields of that spi_master, including the 466The driver will initialize the fields of that spi_master, including the
458bus number (maybe the same as the platform device ID) and three methods 467bus number (maybe the same as the platform device ID) and three methods
diff --git a/Documentation/spi/spidev_test.c b/Documentation/spi/spidev_test.c
index 218e86215297..cf0e3ce0d526 100644
--- a/Documentation/spi/spidev_test.c
+++ b/Documentation/spi/spidev_test.c
@@ -29,7 +29,7 @@ static void pabort(const char *s)
29 abort(); 29 abort();
30} 30}
31 31
32static char *device = "/dev/spidev1.1"; 32static const char *device = "/dev/spidev1.1";
33static uint8_t mode; 33static uint8_t mode;
34static uint8_t bits = 8; 34static uint8_t bits = 8;
35static uint32_t speed = 500000; 35static uint32_t speed = 500000;
@@ -69,7 +69,7 @@ static void transfer(int fd)
69 puts(""); 69 puts("");
70} 70}
71 71
72void print_usage(char *prog) 72void print_usage(const char *prog)
73{ 73{
74 printf("Usage: %s [-DsbdlHOLC3]\n", prog); 74 printf("Usage: %s [-DsbdlHOLC3]\n", prog);
75 puts(" -D --device device to use (default /dev/spidev1.1)\n" 75 puts(" -D --device device to use (default /dev/spidev1.1)\n"
@@ -88,7 +88,7 @@ void print_usage(char *prog)
88void parse_opts(int argc, char *argv[]) 88void parse_opts(int argc, char *argv[])
89{ 89{
90 while (1) { 90 while (1) {
91 static struct option lopts[] = { 91 static const struct option lopts[] = {
92 { "device", 1, 0, 'D' }, 92 { "device", 1, 0, 'D' },
93 { "speed", 1, 0, 's' }, 93 { "speed", 1, 0, 's' },
94 { "delay", 1, 0, 'd' }, 94 { "delay", 1, 0, 'd' },
diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt
index 8242f52d0f22..dd4986497996 100644
--- a/Documentation/vm/numa_memory_policy.txt
+++ b/Documentation/vm/numa_memory_policy.txt
@@ -302,31 +302,30 @@ MEMORY POLICIES AND CPUSETS
302 302
303Memory policies work within cpusets as described above. For memory policies 303Memory policies work within cpusets as described above. For memory policies
304that require a node or set of nodes, the nodes are restricted to the set of 304that require a node or set of nodes, the nodes are restricted to the set of
305nodes whose memories are allowed by the cpuset constraints. If the 305nodes whose memories are allowed by the cpuset constraints. If the nodemask
306intersection of the set of nodes specified for the policy and the set of nodes 306specified for the policy contains nodes that are not allowed by the cpuset, or
307allowed by the cpuset is the empty set, the policy is considered invalid and 307the intersection of the set of nodes specified for the policy and the set of
308cannot be installed. 308nodes with memory is the empty set, the policy is considered invalid
309and cannot be installed.
309 310
310The interaction of memory policies and cpusets can be problematic for a 311The interaction of memory policies and cpusets can be problematic for a
311couple of reasons: 312couple of reasons:
312 313
3131) the memory policy APIs take physical node id's as arguments. However, the 3141) the memory policy APIs take physical node id's as arguments. As mentioned
314 memory policy APIs do not provide a way to determine what nodes are valid 315 above, it is illegal to specify nodes that are not allowed in the cpuset.
315 in the context where the application is running. An application MAY consult 316 The application must query the allowed nodes using the get_mempolicy()
316 the cpuset file system [directly or via an out of tree, and not generally 317 API with the MPOL_F_MEMS_ALLOWED flag to determine the allowed nodes and
317 available, libcpuset API] to obtain this information, but then the 318 restrict itself to those nodes. However, the resources available to a
318 application must be aware that it is running in a cpuset and use what are 319 cpuset can be changed by the system administrator, or a workload manager
319 intended primarily as administrative APIs. 320 application, at any time. So, a task may still get errors attempting to
320 321 specify policy nodes, and must query the allowed memories again.
321 However, as long as the policy specifies at least one node that is valid
322 in the controlling cpuset, the policy can be used.
323 322
3242) when tasks in two cpusets share access to a memory region, such as shared 3232) when tasks in two cpusets share access to a memory region, such as shared
325 memory segments created by shmget() of mmap() with the MAP_ANONYMOUS and 324 memory segments created by shmget() of mmap() with the MAP_ANONYMOUS and
326 MAP_SHARED flags, and any of the tasks install shared policy on the region, 325 MAP_SHARED flags, and any of the tasks install shared policy on the region,
327 only nodes whose memories are allowed in both cpusets may be used in the 326 only nodes whose memories are allowed in both cpusets may be used in the
328 policies. Again, obtaining this information requires "stepping outside" 327 policies. Obtaining this information requires "stepping outside" the
329 the memory policy APIs, as well as knowing in what cpusets other task might 328 memory policy APIs to use the cpuset information and requires that one
330 be attaching to the shared region, to use the cpuset information. 329 know in what cpusets other task might be attaching to the shared region.
331 Furthermore, if the cpusets' allowed memory sets are disjoint, "local" 330 Furthermore, if the cpusets' allowed memory sets are disjoint, "local"
332 allocation is the only valid policy. 331 allocation is the only valid policy.
diff --git a/Documentation/x86_64/mm.txt b/Documentation/x86_64/mm.txt
index f42798ed1c54..b89b6d2bebfa 100644
--- a/Documentation/x86_64/mm.txt
+++ b/Documentation/x86_64/mm.txt
@@ -9,6 +9,7 @@ ffff800000000000 - ffff80ffffffffff (=40 bits) guard hole
9ffff810000000000 - ffffc0ffffffffff (=46 bits) direct mapping of all phys. memory 9ffff810000000000 - ffffc0ffffffffff (=46 bits) direct mapping of all phys. memory
10ffffc10000000000 - ffffc1ffffffffff (=40 bits) hole 10ffffc10000000000 - ffffc1ffffffffff (=40 bits) hole
11ffffc20000000000 - ffffe1ffffffffff (=45 bits) vmalloc/ioremap space 11ffffc20000000000 - ffffe1ffffffffff (=45 bits) vmalloc/ioremap space
12ffffe20000000000 - ffffe2ffffffffff (=40 bits) virtual memory map (1TB)
12... unused hole ... 13... unused hole ...
13ffffffff80000000 - ffffffff82800000 (=40 MB) kernel text mapping, from phys 0 14ffffffff80000000 - ffffffff82800000 (=40 MB) kernel text mapping, from phys 0
14... unused hole ... 15... unused hole ...
diff --git a/arch/alpha/Makefile b/arch/alpha/Makefile
index 1b704ee54bf3..d1004b4d942f 100644
--- a/arch/alpha/Makefile
+++ b/arch/alpha/Makefile
@@ -12,73 +12,22 @@ NM := $(NM) -B
12 12
13LDFLAGS_vmlinux := -static -N #-relax 13LDFLAGS_vmlinux := -static -N #-relax
14CHECKFLAGS += -D__alpha__ -m64 14CHECKFLAGS += -D__alpha__ -m64
15cflags-y := -pipe -mno-fp-regs -ffixed-8 15cflags-y := -pipe -mno-fp-regs -ffixed-8 -msmall-data
16 16
17# Determine if we can use the BWX instructions with GAS. 17cpuflags-$(CONFIG_ALPHA_EV67) := -mcpu=ev67
18old_gas := $(shell if $(AS) --version 2>&1 | grep 'version 2.7' > /dev/null; then echo y; else echo n; fi) 18cpuflags-$(CONFIG_ALPHA_EV6) := -mcpu=ev6
19 19cpuflags-$(CONFIG_ALPHA_POLARIS) := -mcpu=pca56
20ifeq ($(old_gas),y) 20cpuflags-$(CONFIG_ALPHA_SX164) := -mcpu=pca56
21$(error The assembler '$(AS)' does not support the BWX instruction) 21cpuflags-$(CONFIG_ALPHA_EV56) := -mcpu=ev56
22endif 22cpuflags-$(CONFIG_ALPHA_EV5) := -mcpu=ev5
23 23cpuflags-$(CONFIG_ALPHA_EV4) := -mcpu=ev4
24# Determine if GCC understands the -mcpu= option. 24# If GENERIC, make sure to turn off any instruction set extensions that
25have_mcpu := $(call cc-option-yn, -mcpu=ev5) 25# the host compiler might have on by default. Given that EV4 and EV5
26have_mcpu_pca56 := $(call cc-option-yn, -mcpu=pca56) 26# have the same instruction set, prefer EV5 because an EV5 schedule is
27have_mcpu_ev6 := $(call cc-option-yn, -mcpu=ev6) 27# more likely to keep an EV4 processor busy than vice-versa.
28have_mcpu_ev67 := $(call cc-option-yn, -mcpu=ev67) 28cpuflags-$(CONFIG_ALPHA_GENERIC) := -mcpu=ev5
29have_msmall_data := $(call cc-option-yn, -msmall-data) 29
30 30cflags-y += $(cpuflags-y)
31cflags-$(have_msmall_data) += -msmall-data
32
33# Turn on the proper cpu optimizations.
34ifeq ($(have_mcpu),y)
35 mcpu_done := n
36 # If GENERIC, make sure to turn off any instruction set extensions that
37 # the host compiler might have on by default. Given that EV4 and EV5
38 # have the same instruction set, prefer EV5 because an EV5 schedule is
39 # more likely to keep an EV4 processor busy than vice-versa.
40 ifeq ($(CONFIG_ALPHA_GENERIC),y)
41 mcpu := ev5
42 mcpu_done := y
43 endif
44 ifeq ($(mcpu_done)$(CONFIG_ALPHA_SX164)$(have_mcpu_pca56),nyy)
45 mcpu := pca56
46 mcpu_done := y
47 endif
48 ifeq ($(mcpu_done)$(CONFIG_ALPHA_POLARIS)$(have_mcpu_pca56),nyy)
49 mcpu := pca56
50 mcpu_done := y
51 endif
52 ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV4),ny)
53 mcpu := ev4
54 mcpu_done := y
55 endif
56 ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV56),ny)
57 mcpu := ev56
58 mcpu_done := y
59 endif
60 ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV5),ny)
61 mcpu := ev5
62 mcpu_done := y
63 endif
64 ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV67)$(have_mcpu_ev67),nyy)
65 mcpu := ev67
66 mcpu_done := y
67 endif
68 ifeq ($(mcpu_done)$(CONFIG_ALPHA_EV6),ny)
69 ifeq ($(have_mcpu_ev6),y)
70 mcpu := ev6
71 else
72 ifeq ($(have_mcpu_pca56),y)
73 mcpu := pca56
74 else
75 mcpu=ev56
76 endif
77 endif
78 mcpu_done := y
79 endif
80 cflags-$(mcpu_done) += -mcpu=$(mcpu)
81endif
82 31
83 32
84# For TSUNAMI, we must have the assembler not emulate our instructions. 33# For TSUNAMI, we must have the assembler not emulate our instructions.
diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S
index debc8f03886c..5fc61e281ac7 100644
--- a/arch/alpha/kernel/entry.S
+++ b/arch/alpha/kernel/entry.S
@@ -917,15 +917,6 @@ sys_pipe:
917.end sys_pipe 917.end sys_pipe
918 918
919 .align 4 919 .align 4
920 .globl sys_ptrace
921 .ent sys_ptrace
922sys_ptrace:
923 .prologue 0
924 mov $sp, $20
925 jmp $31, do_sys_ptrace
926.end sys_ptrace
927
928 .align 4
929 .globl sys_execve 920 .globl sys_execve
930 .ent sys_execve 921 .ent sys_execve
931sys_execve: 922sys_execve:
diff --git a/arch/alpha/kernel/ptrace.c b/arch/alpha/kernel/ptrace.c
index 83a781842266..1e9ad52c460e 100644
--- a/arch/alpha/kernel/ptrace.c
+++ b/arch/alpha/kernel/ptrace.c
@@ -260,38 +260,12 @@ void ptrace_disable(struct task_struct *child)
260 ptrace_cancel_bpt(child); 260 ptrace_cancel_bpt(child);
261} 261}
262 262
263asmlinkage long 263long arch_ptrace(struct task_struct *child, long request, long addr, long data)
264do_sys_ptrace(long request, long pid, long addr, long data,
265 struct pt_regs *regs)
266{ 264{
267 struct task_struct *child;
268 unsigned long tmp; 265 unsigned long tmp;
269 size_t copied; 266 size_t copied;
270 long ret; 267 long ret;
271 268
272 lock_kernel();
273 DBG(DBG_MEM, ("request=%ld pid=%ld addr=0x%lx data=0x%lx\n",
274 request, pid, addr, data));
275 if (request == PTRACE_TRACEME) {
276 ret = ptrace_traceme();
277 goto out_notsk;
278 }
279
280 child = ptrace_get_task_struct(pid);
281 if (IS_ERR(child)) {
282 ret = PTR_ERR(child);
283 goto out_notsk;
284 }
285
286 if (request == PTRACE_ATTACH) {
287 ret = ptrace_attach(child);
288 goto out;
289 }
290
291 ret = ptrace_check_attach(child, request == PTRACE_KILL);
292 if (ret < 0)
293 goto out;
294
295 switch (request) { 269 switch (request) {
296 /* When I and D space are separate, these will need to be fixed. */ 270 /* When I and D space are separate, these will need to be fixed. */
297 case PTRACE_PEEKTEXT: /* read word at location addr. */ 271 case PTRACE_PEEKTEXT: /* read word at location addr. */
@@ -301,13 +275,13 @@ do_sys_ptrace(long request, long pid, long addr, long data,
301 if (copied != sizeof(tmp)) 275 if (copied != sizeof(tmp))
302 break; 276 break;
303 277
304 regs->r0 = 0; /* special return: no errors */ 278 force_successful_syscall_return();
305 ret = tmp; 279 ret = tmp;
306 break; 280 break;
307 281
308 /* Read register number ADDR. */ 282 /* Read register number ADDR. */
309 case PTRACE_PEEKUSR: 283 case PTRACE_PEEKUSR:
310 regs->r0 = 0; /* special return: no errors */ 284 force_successful_syscall_return();
311 ret = get_reg(child, addr); 285 ret = get_reg(child, addr);
312 DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret)); 286 DBG(DBG_MEM, ("peek $%ld->%#lx\n", addr, ret));
313 break; 287 break;
@@ -353,7 +327,7 @@ do_sys_ptrace(long request, long pid, long addr, long data,
353 /* make sure single-step breakpoint is gone. */ 327 /* make sure single-step breakpoint is gone. */
354 ptrace_cancel_bpt(child); 328 ptrace_cancel_bpt(child);
355 wake_up_process(child); 329 wake_up_process(child);
356 goto out; 330 break;
357 331
358 case PTRACE_SINGLESTEP: /* execute single instruction. */ 332 case PTRACE_SINGLESTEP: /* execute single instruction. */
359 ret = -EIO; 333 ret = -EIO;
@@ -366,20 +340,12 @@ do_sys_ptrace(long request, long pid, long addr, long data,
366 wake_up_process(child); 340 wake_up_process(child);
367 /* give it a chance to run. */ 341 /* give it a chance to run. */
368 ret = 0; 342 ret = 0;
369 goto out; 343 break;
370
371 case PTRACE_DETACH: /* detach a process that was attached. */
372 ret = ptrace_detach(child, data);
373 goto out;
374 344
375 default: 345 default:
376 ret = ptrace_request(child, request, addr, data); 346 ret = ptrace_request(child, request, addr, data);
377 goto out; 347 break;
378 } 348 }
379 out:
380 put_task_struct(child);
381 out_notsk:
382 unlock_kernel();
383 return ret; 349 return ret;
384} 350}
385 351
diff --git a/arch/alpha/kernel/vmlinux.lds.S b/arch/alpha/kernel/vmlinux.lds.S
index 7af07d3ad5f0..55c05b511f4c 100644
--- a/arch/alpha/kernel/vmlinux.lds.S
+++ b/arch/alpha/kernel/vmlinux.lds.S
@@ -1,4 +1,5 @@
1#include <asm-generic/vmlinux.lds.h> 1#include <asm-generic/vmlinux.lds.h>
2#include <asm/page.h>
2 3
3OUTPUT_FORMAT("elf64-alpha") 4OUTPUT_FORMAT("elf64-alpha")
4OUTPUT_ARCH(alpha) 5OUTPUT_ARCH(alpha)
@@ -8,138 +9,145 @@ jiffies = jiffies_64;
8SECTIONS 9SECTIONS
9{ 10{
10#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS 11#ifdef CONFIG_ALPHA_LEGACY_START_ADDRESS
11 . = 0xfffffc0000310000; 12 . = 0xfffffc0000310000;
12#else 13#else
13 . = 0xfffffc0001010000; 14 . = 0xfffffc0001010000;
14#endif 15#endif
15 16
16 _text = .; /* Text and read-only data */ 17 _text = .; /* Text and read-only data */
17 .text : { 18 .text : {
18 *(.text.head) 19 *(.text.head)
19 TEXT_TEXT 20 TEXT_TEXT
20 SCHED_TEXT 21 SCHED_TEXT
21 LOCK_TEXT 22 LOCK_TEXT
22 *(.fixup) 23 *(.fixup)
23 *(.gnu.warning) 24 *(.gnu.warning)
24 } :kernel 25 } :kernel
25 _etext = .; /* End of text section */ 26 _etext = .; /* End of text section */
26 27
27 . = ALIGN(16); 28 /* Exception table */
28 __start___ex_table = .; /* Exception table */ 29 . = ALIGN(16);
29 __ex_table : { *(__ex_table) } 30 __ex_table : {
30 __stop___ex_table = .; 31 __start___ex_table = .;
31 32 *(__ex_table)
32 NOTES :kernel :note 33 __stop___ex_table = .;
33 .dummy : { *(.dummy) } :kernel 34 }
34 35
35 RODATA 36 NOTES :kernel :note
36 37 .dummy : {
37 /* Will be freed after init */ 38 *(.dummy)
38 . = ALIGN(8192); /* Init code and data */ 39 } :kernel
39 __init_begin = .; 40
40 .init.text : { 41 RODATA
41 _sinittext = .; 42
42 *(.init.text) 43 /* Will be freed after init */
43 _einittext = .; 44 . = ALIGN(PAGE_SIZE);
44 } 45 /* Init code and data */
45 .init.data : { *(.init.data) } 46 __init_begin = .;
46 47 .init.text : {
47 . = ALIGN(16); 48 _sinittext = .;
48 __setup_start = .; 49 *(.init.text)
49 .init.setup : { *(.init.setup) } 50 _einittext = .;
50 __setup_end = .; 51 }
51 52 .init.data : {
52 . = ALIGN(8); 53 *(.init.data)
53 __initcall_start = .; 54 }
54 .initcall.init : { 55
55 INITCALLS 56 . = ALIGN(16);
56 } 57 .init.setup : {
57 __initcall_end = .; 58 __setup_start = .;
59 *(.init.setup)
60 __setup_end = .;
61 }
62
63 . = ALIGN(8);
64 .initcall.init : {
65 __initcall_start = .;
66 INITCALLS
67 __initcall_end = .;
68 }
58 69
59#ifdef CONFIG_BLK_DEV_INITRD 70#ifdef CONFIG_BLK_DEV_INITRD
60 . = ALIGN(8192); 71 . = ALIGN(PAGE_SIZE);
61 __initramfs_start = .; 72 .init.ramfs : {
62 .init.ramfs : { *(.init.ramfs) } 73 __initramfs_start = .;
63 __initramfs_end = .; 74 *(.init.ramfs)
75 __initramfs_end = .;
76 }
64#endif 77#endif
65 78
66 . = ALIGN(8); 79 . = ALIGN(8);
67 .con_initcall.init : { 80 .con_initcall.init : {
68 __con_initcall_start = .; 81 __con_initcall_start = .;
69 *(.con_initcall.init) 82 *(.con_initcall.init)
70 __con_initcall_end = .; 83 __con_initcall_end = .;
71 } 84 }
72 85
73 . = ALIGN(8); 86 . = ALIGN(8);
74 SECURITY_INIT 87 SECURITY_INIT
75 88
76 PERCPU(8192) 89 PERCPU(PAGE_SIZE)
77 90
78 . = ALIGN(2*8192); 91 . = ALIGN(2 * PAGE_SIZE);
79 __init_end = .; 92 __init_end = .;
80 /* Freed after init ends here */ 93 /* Freed after init ends here */
81 94
82 /* Note 2 page alignment above. */ 95 /* Note 2 page alignment above. */
83 .data.init_thread : { *(.data.init_thread) } 96 .data.init_thread : {
84 97 *(.data.init_thread)
85 . = ALIGN(8192); 98 }
86 .data.page_aligned : { *(.data.page_aligned) } 99
87 100 . = ALIGN(PAGE_SIZE);
88 . = ALIGN(64); 101 .data.page_aligned : {
89 .data.cacheline_aligned : { *(.data.cacheline_aligned) } 102 *(.data.page_aligned)
90 103 }
91 _data = .; 104
92 .data : { /* Data */ 105 . = ALIGN(64);
93 DATA_DATA 106 .data.cacheline_aligned : {
94 CONSTRUCTORS 107 *(.data.cacheline_aligned)
95 } 108 }
96 109
97 .got : { *(.got) } 110 _data = .;
98 .sdata : { *(.sdata) } 111 /* Data */
99 112 .data : {
100 _edata = .; /* End of data section */ 113 DATA_DATA
101 114 CONSTRUCTORS
102 __bss_start = .; 115 }
103 .sbss : { *(.sbss) *(.scommon) } 116
104 .bss : { *(.bss) *(COMMON) } 117 .got : {
105 __bss_stop = .; 118 *(.got)
106 119 }
107 _end = .; 120 .sdata : {
108 121 *(.sdata)
109 /* Sections to be discarded */ 122 }
110 /DISCARD/ : { *(.exit.text) *(.exit.data) *(.exitcall.exit) } 123 _edata = .; /* End of data section */
111 124
112 .mdebug 0 : { *(.mdebug) } 125 __bss_start = .;
113 .note 0 : { *(.note) } 126 .sbss : {
114 .comment 0 : { *(.comment) } 127 *(.sbss)
115 128 *(.scommon)
116 /* Stabs debugging sections */ 129 }
117 .stab 0 : { *(.stab) } 130 .bss : {
118 .stabstr 0 : { *(.stabstr) } 131 *(.bss)
119 .stab.excl 0 : { *(.stab.excl) } 132 *(COMMON)
120 .stab.exclstr 0 : { *(.stab.exclstr) } 133 }
121 .stab.index 0 : { *(.stab.index) } 134 __bss_stop = .;
122 .stab.indexstr 0 : { *(.stab.indexstr) } 135 _end = .;
123 /* DWARF 1 */ 136
124 .debug 0 : { *(.debug) } 137 /* Sections to be discarded */
125 .line 0 : { *(.line) } 138 /DISCARD/ : {
126 /* GNU DWARF 1 extensions */ 139 *(.exit.text)
127 .debug_srcinfo 0 : { *(.debug_srcinfo) } 140 *(.exit.data)
128 .debug_sfnames 0 : { *(.debug_sfnames) } 141 *(.exitcall.exit)
129 /* DWARF 1.1 and DWARF 2 */ 142 }
130 .debug_aranges 0 : { *(.debug_aranges) } 143
131 .debug_pubnames 0 : { *(.debug_pubnames) } 144 .mdebug 0 : {
132 /* DWARF 2 */ 145 *(.mdebug)
133 .debug_info 0 : { *(.debug_info) } 146 }
134 .debug_abbrev 0 : { *(.debug_abbrev) } 147 .note 0 : {
135 .debug_line 0 : { *(.debug_line) } 148 *(.note)
136 .debug_frame 0 : { *(.debug_frame) } 149 }
137 .debug_str 0 : { *(.debug_str) } 150
138 .debug_loc 0 : { *(.debug_loc) } 151 STABS_DEBUG
139 .debug_macinfo 0 : { *(.debug_macinfo) } 152 DWARF_DEBUG
140 /* SGI/MIPS DWARF 2 extensions */
141 .debug_weaknames 0 : { *(.debug_weaknames) }
142 .debug_funcnames 0 : { *(.debug_funcnames) }
143 .debug_typenames 0 : { *(.debug_typenames) }
144 .debug_varnames 0 : { *(.debug_varnames) }
145} 153}
diff --git a/arch/alpha/mm/fault.c b/arch/alpha/mm/fault.c
index a0e18da594d9..25154df3055a 100644
--- a/arch/alpha/mm/fault.c
+++ b/arch/alpha/mm/fault.c
@@ -197,7 +197,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
197 current->comm, current->pid); 197 current->comm, current->pid);
198 if (!user_mode(regs)) 198 if (!user_mode(regs))
199 goto no_context; 199 goto no_context;
200 do_exit(SIGKILL); 200 do_group_exit(SIGKILL);
201 201
202 do_sigbus: 202 do_sigbus:
203 /* Send a sigbus, regardless of whether we were in kernel 203 /* Send a sigbus, regardless of whether we were in kernel
diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c
index 78c9f1a3d41f..5feee722ea98 100644
--- a/arch/arm/kernel/ptrace.c
+++ b/arch/arm/kernel/ptrace.c
@@ -731,10 +731,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
731 ret = 0; 731 ret = 0;
732 break; 732 break;
733 733
734 case PTRACE_DETACH:
735 ret = ptrace_detach(child, data);
736 break;
737
738 case PTRACE_GETREGS: 734 case PTRACE_GETREGS:
739 ret = ptrace_getregs(child, (void __user *)data); 735 ret = ptrace_getregs(child, (void __user *)data);
740 break; 736 break;
diff --git a/arch/arm/mach-s3c2410/mach-amlm5900.c b/arch/arm/mach-s3c2410/mach-amlm5900.c
index 43bb5e106302..a67a0685664d 100644
--- a/arch/arm/mach-s3c2410/mach-amlm5900.c
+++ b/arch/arm/mach-s3c2410/mach-amlm5900.c
@@ -168,13 +168,31 @@ static void __init amlm5900_map_io(void)
168} 168}
169 169
170#ifdef CONFIG_FB_S3C2410 170#ifdef CONFIG_FB_S3C2410
171static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = { 171static struct s3c2410fb_display __initdata amlm5900_lcd_info = {
172 .width = 160, 172 .width = 160,
173 .height = 160, 173 .height = 160,
174 174
175/* commented out until stn patch is submitted 175 .type = S3C2410_LCDCON1_STN4,
176* .type = S3C2410_LCDCON1_STN4, 176
177*/ 177 .pixclock = 680000, /* HCLK = 100MHz */
178 .xres = 160,
179 .yres = 160,
180 .bpp = 4,
181 .left_margin = 1 << (4 + 3),
182 .right_margin = 8 << 3,
183 .hsync_len = 48,
184 .upper_margin = 0,
185 .lower_margin = 0,
186
187 .lcdcon5 = 0x00000001,
188};
189
190static struct s3c2410fb_mach_info __initdata amlm5900_fb_info = {
191
192 .displays = &amlm5900_lcd_info,
193 .num_displays = 1,
194 .default_display = 0,
195
178 .gpccon = 0xaaaaaaaa, 196 .gpccon = 0xaaaaaaaa,
179 .gpccon_mask = 0xffffffff, 197 .gpccon_mask = 0xffffffff,
180 .gpcup = 0x0000ffff, 198 .gpcup = 0x0000ffff,
@@ -184,32 +202,6 @@ static struct s3c2410fb_mach_info __initdata amlm5900_lcd_info = {
184 .gpdcon_mask = 0xffffffff, 202 .gpdcon_mask = 0xffffffff,
185 .gpdup = 0x0000ffff, 203 .gpdup = 0x0000ffff,
186 .gpdup_mask = 0xffffffff, 204 .gpdup_mask = 0xffffffff,
187
188 .xres = {
189 .min = 160,
190 .max = 160,
191 .defval = 160,
192 },
193
194 .yres = {
195 .min = 160,
196 .max = 160,
197 .defval = 160,
198 },
199
200 .bpp = {
201 .min = 4,
202 .max = 4,
203 .defval = 4,
204 },
205
206 .regs = {
207 .lcdcon1 = 0x00008225,
208 .lcdcon2 = 0x0027c000,
209 .lcdcon3 = 0x00182708,
210 .lcdcon4 = 0x00000002,
211 .lcdcon5 = 0x00000001,
212 }
213}; 205};
214#endif 206#endif
215 207
@@ -239,7 +231,7 @@ static void __init amlm5900_init(void)
239{ 231{
240 amlm5900_init_pm(); 232 amlm5900_init_pm();
241#ifdef CONFIG_FB_S3C2410 233#ifdef CONFIG_FB_S3C2410
242 s3c24xx_fb_set_platdata(&amlm5900_lcd_info); 234 s3c24xx_fb_set_platdata(&amlm5900_fb_info);
243#endif 235#endif
244 platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices)); 236 platform_add_devices(amlm5900_devices, ARRAY_SIZE(amlm5900_devices));
245} 237}
diff --git a/arch/arm/mach-s3c2410/mach-bast.c b/arch/arm/mach-s3c2410/mach-bast.c
index bc926992b4e4..587864fe25fb 100644
--- a/arch/arm/mach-s3c2410/mach-bast.c
+++ b/arch/arm/mach-s3c2410/mach-bast.c
@@ -467,35 +467,70 @@ static struct platform_device bast_device_axpp = {
467 467
468/* LCD/VGA controller */ 468/* LCD/VGA controller */
469 469
470static struct s3c2410fb_mach_info __initdata bast_lcd_info = { 470static struct s3c2410fb_display __initdata bast_lcd_info[] = {
471 .width = 640, 471 {
472 .height = 480, 472 .type = S3C2410_LCDCON1_TFT,
473 473 .width = 640,
474 .xres = { 474 .height = 480,
475 .min = 320, 475
476 .max = 1024, 476 .pixclock = 33333,
477 .defval = 640, 477 .xres = 640,
478 }, 478 .yres = 480,
479 .bpp = 4,
480 .left_margin = 40,
481 .right_margin = 20,
482 .hsync_len = 88,
483 .upper_margin = 30,
484 .lower_margin = 32,
485 .vsync_len = 3,
479 486
480 .yres = { 487 .lcdcon5 = 0x00014b02,
481 .min = 240,
482 .max = 600,
483 .defval = 480,
484 }, 488 },
489 {
490 .type = S3C2410_LCDCON1_TFT,
491 .width = 640,
492 .height = 480,
493
494 .pixclock = 33333,
495 .xres = 640,
496 .yres = 480,
497 .bpp = 8,
498 .left_margin = 40,
499 .right_margin = 20,
500 .hsync_len = 88,
501 .upper_margin = 30,
502 .lower_margin = 32,
503 .vsync_len = 3,
485 504
486 .bpp = { 505 .lcdcon5 = 0x00014b02,
487 .min = 4,
488 .max = 16,
489 .defval = 8,
490 }, 506 },
507 {
508 .type = S3C2410_LCDCON1_TFT,
509 .width = 640,
510 .height = 480,
511
512 .pixclock = 33333,
513 .xres = 640,
514 .yres = 480,
515 .bpp = 16,
516 .left_margin = 40,
517 .right_margin = 20,
518 .hsync_len = 88,
519 .upper_margin = 30,
520 .lower_margin = 32,
521 .vsync_len = 3,
491 522
492 .regs = {
493 .lcdcon1 = 0x00000176,
494 .lcdcon2 = 0x1d77c7c2,
495 .lcdcon3 = 0x013a7f13,
496 .lcdcon4 = 0x00000057,
497 .lcdcon5 = 0x00014b02, 523 .lcdcon5 = 0x00014b02,
498 } 524 },
525};
526
527/* LCD/VGA controller */
528
529static struct s3c2410fb_mach_info __initdata bast_fb_info = {
530
531 .displays = bast_lcd_info,
532 .num_displays = ARRAY_SIZE(bast_lcd_info),
533 .default_display = 4,
499}; 534};
500 535
501/* Standard BAST devices */ 536/* Standard BAST devices */
@@ -552,7 +587,7 @@ static void __init bast_map_io(void)
552 587
553static void __init bast_init(void) 588static void __init bast_init(void)
554{ 589{
555 s3c24xx_fb_set_platdata(&bast_lcd_info); 590 s3c24xx_fb_set_platdata(&bast_fb_info);
556 platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices)); 591 platform_add_devices(bast_devices, ARRAY_SIZE(bast_devices));
557} 592}
558 593
diff --git a/arch/arm/mach-s3c2410/mach-h1940.c b/arch/arm/mach-s3c2410/mach-h1940.c
index 9a172b4ad720..7c1145e87c12 100644
--- a/arch/arm/mach-s3c2410/mach-h1940.c
+++ b/arch/arm/mach-s3c2410/mach-h1940.c
@@ -133,29 +133,31 @@ static struct s3c2410_udc_mach_info h1940_udc_cfg __initdata = {
133/** 133/**
134 * Set lcd on or off 134 * Set lcd on or off
135 **/ 135 **/
136static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = { 136static struct s3c2410fb_display h1940_lcd __initdata = {
137 .fixed_syncs= 1, 137 .lcdcon5= S3C2410_LCDCON5_FRM565 | \
138 .regs={ 138 S3C2410_LCDCON5_INVVLINE | \
139 .lcdcon1= S3C2410_LCDCON1_TFT16BPP | \ 139 S3C2410_LCDCON5_HWSWP,
140 S3C2410_LCDCON1_TFT | \ 140
141 S3C2410_LCDCON1_CLKVAL(0x0C), 141 .type = S3C2410_LCDCON1_TFT,
142 142 .width = 240,
143 .lcdcon2= S3C2410_LCDCON2_VBPD(7) | \ 143 .height = 320,
144 S3C2410_LCDCON2_LINEVAL(319) | \ 144 .pixclock = 260000,
145 S3C2410_LCDCON2_VFPD(6) | \ 145 .xres = 240,
146 S3C2410_LCDCON2_VSPW(0), 146 .yres = 320,
147 147 .bpp = 16,
148 .lcdcon3= S3C2410_LCDCON3_HBPD(19) | \ 148 .left_margin = 20,
149 S3C2410_LCDCON3_HOZVAL(239) | \ 149 .right_margin = 8,
150 S3C2410_LCDCON3_HFPD(7), 150 .hsync_len = 4,
151 151 .upper_margin = 8,
152 .lcdcon4= S3C2410_LCDCON4_MVAL(0) | \ 152 .lower_margin = 7,
153 S3C2410_LCDCON4_HSPW(3), 153 .vsync_len = 1,
154 154};
155 .lcdcon5= S3C2410_LCDCON5_FRM565 | \ 155
156 S3C2410_LCDCON5_INVVLINE | \ 156static struct s3c2410fb_mach_info h1940_fb_info __initdata = {
157 S3C2410_LCDCON5_HWSWP, 157 .displays = &h1940_lcd,
158 }, 158 .num_displays = 1,
159 .default_display = 0,
160
159 .lpcsel= 0x02, 161 .lpcsel= 0x02,
160 .gpccon= 0xaa940659, 162 .gpccon= 0xaa940659,
161 .gpccon_mask= 0xffffffff, 163 .gpccon_mask= 0xffffffff,
@@ -165,12 +167,6 @@ static struct s3c2410fb_mach_info h1940_lcdcfg __initdata = {
165 .gpdcon_mask= 0xffffffff, 167 .gpdcon_mask= 0xffffffff,
166 .gpdup= 0x0000faff, 168 .gpdup= 0x0000faff,
167 .gpdup_mask= 0xffffffff, 169 .gpdup_mask= 0xffffffff,
168
169 .width= 240,
170 .height= 320,
171 .xres= {240,240,240},
172 .yres= {320,320,320},
173 .bpp= {16,16,16},
174}; 170};
175 171
176static struct platform_device s3c_device_leds = { 172static struct platform_device s3c_device_leds = {
@@ -217,7 +213,7 @@ static void __init h1940_init(void)
217{ 213{
218 u32 tmp; 214 u32 tmp;
219 215
220 s3c24xx_fb_set_platdata(&h1940_lcdcfg); 216 s3c24xx_fb_set_platdata(&h1940_fb_info);
221 s3c24xx_udc_set_platdata(&h1940_udc_cfg); 217 s3c24xx_udc_set_platdata(&h1940_udc_cfg);
222 218
223 /* Turn off suspend on both USB ports, and switch the 219 /* Turn off suspend on both USB ports, and switch the
diff --git a/arch/arm/mach-s3c2410/mach-qt2410.c b/arch/arm/mach-s3c2410/mach-qt2410.c
index e670b1e1631b..a1caf4b0adac 100644
--- a/arch/arm/mach-s3c2410/mach-qt2410.c
+++ b/arch/arm/mach-s3c2410/mach-qt2410.c
@@ -95,157 +95,83 @@ static struct s3c2410_uartcfg smdk2410_uartcfgs[] = {
95 95
96/* LCD driver info */ 96/* LCD driver info */
97 97
98/* Configuration for 640x480 SHARP LQ080V3DG01 */ 98static struct s3c2410fb_display qt2410_lcd_cfg[] __initdata = {
99static struct s3c2410fb_mach_info qt2410_biglcd_cfg __initdata = { 99 {
100 .regs = { 100 /* Configuration for 640x480 SHARP LQ080V3DG01 */
101 101 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
102 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | 102 S3C2410_LCDCON5_INVVLINE |
103 S3C2410_LCDCON1_TFT | 103 S3C2410_LCDCON5_INVVFRAME |
104 S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */ 104 S3C2410_LCDCON5_PWREN |
105 105 S3C2410_LCDCON5_HWSWP,
106 .lcdcon2 = S3C2410_LCDCON2_VBPD(18) | /* 19 */ 106
107 S3C2410_LCDCON2_LINEVAL(479) | 107 .type = S3C2410_LCDCON1_TFT,
108 S3C2410_LCDCON2_VFPD(10) | /* 11 */ 108 .width = 640,
109 S3C2410_LCDCON2_VSPW(14), /* 15 */ 109 .height = 480,
110 110
111 .lcdcon3 = S3C2410_LCDCON3_HBPD(43) | /* 44 */ 111 .pixclock = 40000, /* HCLK/4 */
112 S3C2410_LCDCON3_HOZVAL(639) | /* 640 */ 112 .xres = 640,
113 S3C2410_LCDCON3_HFPD(115), /* 116 */ 113 .yres = 480,
114 114 .bpp = 16,
115 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | 115 .left_margin = 44,
116 S3C2410_LCDCON4_HSPW(95), /* 96 */ 116 .right_margin = 116,
117 117 .hsync_len = 96,
118 .lcdcon5 = S3C2410_LCDCON5_FRM565 | 118 .upper_margin = 19,
119 S3C2410_LCDCON5_INVVLINE | 119 .lower_margin = 11,
120 S3C2410_LCDCON5_INVVFRAME | 120 .vsync_len = 15,
121 S3C2410_LCDCON5_PWREN |
122 S3C2410_LCDCON5_HWSWP,
123 }, 121 },
124 122 {
125 .lpcsel = ((0xCE6) & ~7) | 1<<4, 123 /* Configuration for 480x640 toppoly TD028TTEC1 */
126 124 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
127 .width = 640, 125 S3C2410_LCDCON5_INVVLINE |
128 .height = 480, 126 S3C2410_LCDCON5_INVVFRAME |
129 127 S3C2410_LCDCON5_PWREN |
130 .xres = { 128 S3C2410_LCDCON5_HWSWP,
131 .min = 640, 129
132 .max = 640, 130 .type = S3C2410_LCDCON1_TFT,
133 .defval = 640, 131 .width = 480,
134 }, 132 .height = 640,
135 133 .pixclock = 40000, /* HCLK/4 */
136 .yres = { 134 .xres = 480,
137 .min = 480, 135 .yres = 640,
138 .max = 480, 136 .bpp = 16,
139 .defval = 480, 137 .left_margin = 8,
140 }, 138 .right_margin = 24,
141 139 .hsync_len = 8,
142 .bpp = { 140 .upper_margin = 2,
143 .min = 16, 141 .lower_margin = 4,
144 .max = 16, 142 .vsync_len = 2,
145 .defval = 16,
146 },
147};
148
149/* Configuration for 480x640 toppoly TD028TTEC1 */
150static struct s3c2410fb_mach_info qt2410_prodlcd_cfg __initdata = {
151 .regs = {
152
153 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
154 S3C2410_LCDCON1_TFT |
155 S3C2410_LCDCON1_CLKVAL(0x01), /* HCLK/4 */
156
157 .lcdcon2 = S3C2410_LCDCON2_VBPD(1) | /* 2 */
158 S3C2410_LCDCON2_LINEVAL(639) |/* 640 */
159 S3C2410_LCDCON2_VFPD(3) | /* 4 */
160 S3C2410_LCDCON2_VSPW(1), /* 2 */
161
162 .lcdcon3 = S3C2410_LCDCON3_HBPD(7) | /* 8 */
163 S3C2410_LCDCON3_HOZVAL(479) | /* 479 */
164 S3C2410_LCDCON3_HFPD(23), /* 24 */
165
166 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) |
167 S3C2410_LCDCON4_HSPW(7), /* 8 */
168
169 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
170 S3C2410_LCDCON5_INVVLINE |
171 S3C2410_LCDCON5_INVVFRAME |
172 S3C2410_LCDCON5_PWREN |
173 S3C2410_LCDCON5_HWSWP,
174 },
175
176 .lpcsel = ((0xCE6) & ~7) | 1<<4,
177
178 .width = 480,
179 .height = 640,
180
181 .xres = {
182 .min = 480,
183 .max = 480,
184 .defval = 480,
185 }, 143 },
186 144 {
187 .yres = { 145 /* Config for 240x320 LCD */
188 .min = 640, 146 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
189 .max = 640, 147 S3C2410_LCDCON5_INVVLINE |
190 .defval = 640, 148 S3C2410_LCDCON5_INVVFRAME |
191 }, 149 S3C2410_LCDCON5_PWREN |
192 150 S3C2410_LCDCON5_HWSWP,
193 .bpp = { 151
194 .min = 16, 152 .type = S3C2410_LCDCON1_TFT,
195 .max = 16, 153 .width = 240,
196 .defval = 16, 154 .height = 320,
155 .pixclock = 100000, /* HCLK/10 */
156 .xres = 240,
157 .yres = 320,
158 .bpp = 16,
159 .left_margin = 13,
160 .right_margin = 8,
161 .hsync_len = 4,
162 .upper_margin = 2,
163 .lower_margin = 7,
164 .vsync_len = 4,
197 }, 165 },
198}; 166};
199 167
200/* Config for 240x320 LCD */
201static struct s3c2410fb_mach_info qt2410_lcd_cfg __initdata = {
202 .regs = {
203
204 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP |
205 S3C2410_LCDCON1_TFT |
206 S3C2410_LCDCON1_CLKVAL(0x04),
207
208 .lcdcon2 = S3C2410_LCDCON2_VBPD(1) |
209 S3C2410_LCDCON2_LINEVAL(319) |
210 S3C2410_LCDCON2_VFPD(6) |
211 S3C2410_LCDCON2_VSPW(3),
212
213 .lcdcon3 = S3C2410_LCDCON3_HBPD(12) |
214 S3C2410_LCDCON3_HOZVAL(239) |
215 S3C2410_LCDCON3_HFPD(7),
216 168
217 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | 169static struct s3c2410fb_mach_info qt2410_fb_info __initdata = {
218 S3C2410_LCDCON4_HSPW(3), 170 .displays = qt2410_lcd_cfg,
219 171 .num_displays = ARRAY_SIZE(qt2410_lcd_cfg),
220 .lcdcon5 = S3C2410_LCDCON5_FRM565 | 172 .default_display = 0,
221 S3C2410_LCDCON5_INVVLINE |
222 S3C2410_LCDCON5_INVVFRAME |
223 S3C2410_LCDCON5_PWREN |
224 S3C2410_LCDCON5_HWSWP,
225 },
226 173
227 .lpcsel = ((0xCE6) & ~7) | 1<<4, 174 .lpcsel = ((0xCE6) & ~7) | 1<<4,
228
229 .width = 240,
230 .height = 320,
231
232 .xres = {
233 .min = 240,
234 .max = 240,
235 .defval = 240,
236 },
237
238 .yres = {
239 .min = 320,
240 .max = 320,
241 .defval = 320,
242 },
243
244 .bpp = {
245 .min = 16,
246 .max = 16,
247 .defval = 16,
248 },
249}; 175};
250 176
251/* CS8900 */ 177/* CS8900 */
@@ -408,16 +334,17 @@ static void __init qt2410_machine_init(void)
408 334
409 switch (tft_type) { 335 switch (tft_type) {
410 case 'p': /* production */ 336 case 'p': /* production */
411 s3c24xx_fb_set_platdata(&qt2410_prodlcd_cfg); 337 qt2410_fb_info.default_display = 1;
412 break; 338 break;
413 case 'b': /* big */ 339 case 'b': /* big */
414 s3c24xx_fb_set_platdata(&qt2410_biglcd_cfg); 340 qt2410_fb_info.default_display = 0;
415 break; 341 break;
416 case 's': /* small */ 342 case 's': /* small */
417 default: 343 default:
418 s3c24xx_fb_set_platdata(&qt2410_lcd_cfg); 344 qt2410_fb_info.default_display = 2;
419 break; 345 break;
420 } 346 }
347 s3c24xx_fb_set_platdata(&qt2410_fb_info);
421 348
422 s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT); 349 s3c2410_gpio_cfgpin(S3C2410_GPB0, S3C2410_GPIO_OUTPUT);
423 s3c2410_gpio_setpin(S3C2410_GPB0, 1); 350 s3c2410_gpio_setpin(S3C2410_GPB0, 1);
diff --git a/arch/arm/mach-s3c2440/mach-rx3715.c b/arch/arm/mach-s3c2440/mach-rx3715.c
index b59e6d39f2f2..bac40c4878a5 100644
--- a/arch/arm/mach-s3c2440/mach-rx3715.c
+++ b/arch/arm/mach-s3c2440/mach-rx3715.c
@@ -110,28 +110,32 @@ static struct s3c2410_uartcfg rx3715_uartcfgs[] = {
110 110
111/* framebuffer lcd controller information */ 111/* framebuffer lcd controller information */
112 112
113static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = { 113static struct s3c2410fb_display rx3715_lcdcfg __initdata = {
114 .regs = { 114 .lcdcon5 = S3C2410_LCDCON5_INVVLINE |
115 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | \ 115 S3C2410_LCDCON5_FRM565 |
116 S3C2410_LCDCON1_TFT | \ 116 S3C2410_LCDCON5_HWSWP,
117 S3C2410_LCDCON1_CLKVAL(0x0C), 117
118 118 .type = S3C2410_LCDCON1_TFT,
119 .lcdcon2 = S3C2410_LCDCON2_VBPD(5) | \ 119 .width = 240,
120 S3C2410_LCDCON2_LINEVAL(319) | \ 120 .height = 320,
121 S3C2410_LCDCON2_VFPD(6) | \ 121
122 S3C2410_LCDCON2_VSPW(2), 122 .pixclock = 260000,
123 123 .xres = 240,
124 .lcdcon3 = S3C2410_LCDCON3_HBPD(35) | \ 124 .yres = 320,
125 S3C2410_LCDCON3_HOZVAL(239) | \ 125 .bpp = 16,
126 S3C2410_LCDCON3_HFPD(35), 126 .left_margin = 36,
127 127 .right_margin = 36,
128 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | \ 128 .hsync_len = 8,
129 S3C2410_LCDCON4_HSPW(7), 129 .upper_margin = 6,
130 130 .lower_margin = 7,
131 .lcdcon5 = S3C2410_LCDCON5_INVVLINE | 131 .vsync_len = 3,
132 S3C2410_LCDCON5_FRM565 | 132};
133 S3C2410_LCDCON5_HWSWP, 133
134 }, 134static struct s3c2410fb_mach_info rx3715_fb_info __initdata = {
135
136 .displays = &rx3715_lcdcfg,
137 .num_displays = 1,
138 .default_display = 0,
135 139
136 .lpcsel = 0xf82, 140 .lpcsel = 0xf82,
137 141
@@ -144,28 +148,6 @@ static struct s3c2410fb_mach_info rx3715_lcdcfg __initdata = {
144 .gpdcon_mask = 0xffc0fff0, 148 .gpdcon_mask = 0xffc0fff0,
145 .gpdup = 0x0000faff, 149 .gpdup = 0x0000faff,
146 .gpdup_mask = 0xffffffff, 150 .gpdup_mask = 0xffffffff,
147
148 .fixed_syncs = 1,
149 .width = 240,
150 .height = 320,
151
152 .xres = {
153 .min = 240,
154 .max = 240,
155 .defval = 240,
156 },
157
158 .yres = {
159 .max = 320,
160 .min = 320,
161 .defval = 320,
162 },
163
164 .bpp = {
165 .min = 16,
166 .max = 16,
167 .defval = 16,
168 },
169}; 151};
170 152
171static struct mtd_partition rx3715_nand_part[] = { 153static struct mtd_partition rx3715_nand_part[] = {
@@ -224,7 +206,7 @@ static void __init rx3715_init_machine(void)
224#endif 206#endif
225 s3c2410_pm_init(); 207 s3c2410_pm_init();
226 208
227 s3c24xx_fb_set_platdata(&rx3715_lcdcfg); 209 s3c24xx_fb_set_platdata(&rx3715_fb_info);
228 platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices)); 210 platform_add_devices(rx3715_devices, ARRAY_SIZE(rx3715_devices));
229} 211}
230 212
diff --git a/arch/arm/mach-s3c2440/mach-smdk2440.c b/arch/arm/mach-s3c2440/mach-smdk2440.c
index 670115b8a12e..4552828bf800 100644
--- a/arch/arm/mach-s3c2440/mach-smdk2440.c
+++ b/arch/arm/mach-s3c2440/mach-smdk2440.c
@@ -103,31 +103,35 @@ static struct s3c2410_uartcfg smdk2440_uartcfgs[] __initdata = {
103 103
104/* LCD driver info */ 104/* LCD driver info */
105 105
106static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = { 106static struct s3c2410fb_display smdk2440_lcd_cfg __initdata = {
107 .regs = { 107
108 108 .lcdcon5 = S3C2410_LCDCON5_FRM565 |
109 .lcdcon1 = S3C2410_LCDCON1_TFT16BPP | 109 S3C2410_LCDCON5_INVVLINE |
110 S3C2410_LCDCON1_TFT | 110 S3C2410_LCDCON5_INVVFRAME |
111 S3C2410_LCDCON1_CLKVAL(0x04), 111 S3C2410_LCDCON5_PWREN |
112 112 S3C2410_LCDCON5_HWSWP,
113 .lcdcon2 = S3C2410_LCDCON2_VBPD(7) | 113
114 S3C2410_LCDCON2_LINEVAL(319) | 114 .type = S3C2410_LCDCON1_TFT,
115 S3C2410_LCDCON2_VFPD(6) | 115
116 S3C2410_LCDCON2_VSPW(3), 116 .width = 240,
117 117 .height = 320,
118 .lcdcon3 = S3C2410_LCDCON3_HBPD(19) | 118
119 S3C2410_LCDCON3_HOZVAL(239) | 119 .pixclock = 166667, /* HCLK 60 MHz, divisor 10 */
120 S3C2410_LCDCON3_HFPD(7), 120 .xres = 240,
121 121 .yres = 320,
122 .lcdcon4 = S3C2410_LCDCON4_MVAL(0) | 122 .bpp = 16,
123 S3C2410_LCDCON4_HSPW(3), 123 .left_margin = 20,
124 124 .right_margin = 8,
125 .lcdcon5 = S3C2410_LCDCON5_FRM565 | 125 .hsync_len = 4,
126 S3C2410_LCDCON5_INVVLINE | 126 .upper_margin = 8,
127 S3C2410_LCDCON5_INVVFRAME | 127 .lower_margin = 7,
128 S3C2410_LCDCON5_PWREN | 128 .vsync_len = 4,
129 S3C2410_LCDCON5_HWSWP, 129};
130 }, 130
131static struct s3c2410fb_mach_info smdk2440_fb_info __initdata = {
132 .displays = &smdk2440_lcd_cfg,
133 .num_displays = 1,
134 .default_display = 0,
131 135
132#if 0 136#if 0
133 /* currently setup by downloader */ 137 /* currently setup by downloader */
@@ -142,28 +146,6 @@ static struct s3c2410fb_mach_info smdk2440_lcd_cfg __initdata = {
142#endif 146#endif
143 147
144 .lpcsel = ((0xCE6) & ~7) | 1<<4, 148 .lpcsel = ((0xCE6) & ~7) | 1<<4,
145 .type = S3C2410_LCDCON1_TFT16BPP,
146
147 .width = 240,
148 .height = 320,
149
150 .xres = {
151 .min = 240,
152 .max = 240,
153 .defval = 240,
154 },
155
156 .yres = {
157 .min = 320,
158 .max = 320,
159 .defval = 320,
160 },
161
162 .bpp = {
163 .min = 16,
164 .max = 16,
165 .defval = 16,
166 },
167}; 149};
168 150
169static struct platform_device *smdk2440_devices[] __initdata = { 151static struct platform_device *smdk2440_devices[] __initdata = {
@@ -183,7 +165,7 @@ static void __init smdk2440_map_io(void)
183 165
184static void __init smdk2440_machine_init(void) 166static void __init smdk2440_machine_init(void)
185{ 167{
186 s3c24xx_fb_set_platdata(&smdk2440_lcd_cfg); 168 s3c24xx_fb_set_platdata(&smdk2440_fb_info);
187 169
188 platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices)); 170 platform_add_devices(smdk2440_devices, ARRAY_SIZE(smdk2440_devices));
189 smdk_machine_init(); 171 smdk_machine_init();
diff --git a/arch/arm/mm/fault.c b/arch/arm/mm/fault.c
index 846cce48e2b7..59ed1d05b71b 100644
--- a/arch/arm/mm/fault.c
+++ b/arch/arm/mm/fault.c
@@ -266,7 +266,7 @@ do_page_fault(unsigned long addr, unsigned int fsr, struct pt_regs *regs)
266 * the page fault gracefully. 266 * the page fault gracefully.
267 */ 267 */
268 printk("VM: killing process %s\n", tsk->comm); 268 printk("VM: killing process %s\n", tsk->comm);
269 do_exit(SIGKILL); 269 do_group_exit(SIGKILL);
270 return 0; 270 return 0;
271 } 271 }
272 if (fault & VM_FAULT_SIGBUS) { 272 if (fault & VM_FAULT_SIGBUS) {
diff --git a/arch/avr32/kernel/kprobes.c b/arch/avr32/kernel/kprobes.c
index 4942ee662e0b..20b1c9d8f945 100644
--- a/arch/avr32/kernel/kprobes.c
+++ b/arch/avr32/kernel/kprobes.c
@@ -22,6 +22,8 @@ DEFINE_PER_CPU(struct kprobe *, current_kprobe);
22static unsigned long kprobe_status; 22static unsigned long kprobe_status;
23static struct pt_regs jprobe_saved_regs; 23static struct pt_regs jprobe_saved_regs;
24 24
25struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
26
25int __kprobes arch_prepare_kprobe(struct kprobe *p) 27int __kprobes arch_prepare_kprobe(struct kprobe *p)
26{ 28{
27 int ret = 0; 29 int ret = 0;
diff --git a/arch/avr32/kernel/ptrace.c b/arch/avr32/kernel/ptrace.c
index 39060cbeb2a3..9e16b8a447f2 100644
--- a/arch/avr32/kernel/ptrace.c
+++ b/arch/avr32/kernel/ptrace.c
@@ -227,11 +227,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
227 ret = 0; 227 ret = 0;
228 break; 228 break;
229 229
230 /* Detach a process that was attached */
231 case PTRACE_DETACH:
232 ret = ptrace_detach(child, data);
233 break;
234
235 case PTRACE_GETREGS: 230 case PTRACE_GETREGS:
236 ret = ptrace_getregs(child, (void __user *)data); 231 ret = ptrace_getregs(child, (void __user *)data);
237 break; 232 break;
diff --git a/arch/avr32/mm/fault.c b/arch/avr32/mm/fault.c
index ae2d2c593b2b..11472f8701bd 100644
--- a/arch/avr32/mm/fault.c
+++ b/arch/avr32/mm/fault.c
@@ -216,7 +216,7 @@ out_of_memory:
216 } 216 }
217 printk("VM: Killing process %s\n", tsk->comm); 217 printk("VM: Killing process %s\n", tsk->comm);
218 if (user_mode(regs)) 218 if (user_mode(regs))
219 do_exit(SIGKILL); 219 do_group_exit(SIGKILL);
220 goto no_context; 220 goto no_context;
221 221
222do_sigbus: 222do_sigbus:
diff --git a/arch/blackfin/kernel/ptrace.c b/arch/blackfin/kernel/ptrace.c
index 64ce5fea8609..85caf9b711a1 100644
--- a/arch/blackfin/kernel/ptrace.c
+++ b/arch/blackfin/kernel/ptrace.c
@@ -385,12 +385,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
385 break; 385 break;
386 } 386 }
387 387
388 case PTRACE_DETACH:
389 { /* detach a process that was attached. */
390 ret = ptrace_detach(child, data);
391 break;
392 }
393
394 case PTRACE_GETREGS: 388 case PTRACE_GETREGS:
395 { 389 {
396 390
diff --git a/arch/cris/arch-v10/kernel/ptrace.c b/arch/cris/arch-v10/kernel/ptrace.c
index f4f9db698b44..b570ae9b6cad 100644
--- a/arch/cris/arch-v10/kernel/ptrace.c
+++ b/arch/cris/arch-v10/kernel/ptrace.c
@@ -177,10 +177,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
177 ret = 0; 177 ret = 0;
178 break; 178 break;
179 179
180 case PTRACE_DETACH:
181 ret = ptrace_detach(child, data);
182 break;
183
184 /* Get all GP registers from the child. */ 180 /* Get all GP registers from the child. */
185 case PTRACE_GETREGS: { 181 case PTRACE_GETREGS: {
186 int i; 182 int i;
diff --git a/arch/cris/arch-v10/kernel/time.c b/arch/cris/arch-v10/kernel/time.c
index 077e973c33f0..575a14bb1106 100644
--- a/arch/cris/arch-v10/kernel/time.c
+++ b/arch/cris/arch-v10/kernel/time.c
@@ -254,8 +254,12 @@ timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
254 * it needs to be IRQF_DISABLED to make the jiffies update work properly 254 * it needs to be IRQF_DISABLED to make the jiffies update work properly
255 */ 255 */
256 256
257static struct irqaction irq2 = { timer_interrupt, IRQF_SHARED | IRQF_DISABLED, 257static struct irqaction irq2 = {
258 CPU_MASK_NONE, "timer", NULL, NULL}; 258 .handler = timer_interrupt,
259 .flags = IRQF_SHARED | IRQF_DISABLED,
260 .mask = CPU_MASK_NONE,
261 .name = "timer",
262};
259 263
260void __init 264void __init
261time_init(void) 265time_init(void)
diff --git a/arch/cris/arch-v32/kernel/ptrace.c b/arch/cris/arch-v32/kernel/ptrace.c
index 38ece0cd47cb..2df60529a8af 100644
--- a/arch/cris/arch-v32/kernel/ptrace.c
+++ b/arch/cris/arch-v32/kernel/ptrace.c
@@ -245,10 +245,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
245 break; 245 break;
246 246
247 } 247 }
248 case PTRACE_DETACH:
249 ret = ptrace_detach(child, data);
250 break;
251
252 /* Get all GP registers from the child. */ 248 /* Get all GP registers from the child. */
253 case PTRACE_GETREGS: { 249 case PTRACE_GETREGS: {
254 int i; 250 int i;
diff --git a/arch/cris/arch-v32/kernel/smp.c b/arch/cris/arch-v32/kernel/smp.c
index 77e655f26560..697494bc2de1 100644
--- a/arch/cris/arch-v32/kernel/smp.c
+++ b/arch/cris/arch-v32/kernel/smp.c
@@ -63,8 +63,12 @@ static unsigned long irq_regs[NR_CPUS] =
63 63
64static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs); 64static irqreturn_t crisv32_ipi_interrupt(int irq, void *dev_id, struct pt_regs *regs);
65static int send_ipi(int vector, int wait, cpumask_t cpu_mask); 65static int send_ipi(int vector, int wait, cpumask_t cpu_mask);
66static struct irqaction irq_ipi = { crisv32_ipi_interrupt, IRQF_DISABLED, 66static struct irqaction irq_ipi = {
67 CPU_MASK_NONE, "ipi", NULL, NULL}; 67 .handler = crisv32_ipi_interrupt,
68 .flags = IRQF_DISABLED,
69 .mask = CPU_MASK_NONE,
70 .name = "ipi",
71};
68 72
69extern void cris_mmu_init(void); 73extern void cris_mmu_init(void);
70extern void cris_timer_init(void); 74extern void cris_timer_init(void);
diff --git a/arch/cris/mm/fault.c b/arch/cris/mm/fault.c
index 8672ab7d7978..8aab81430695 100644
--- a/arch/cris/mm/fault.c
+++ b/arch/cris/mm/fault.c
@@ -360,7 +360,7 @@ do_page_fault(unsigned long address, struct pt_regs *regs,
360 up_read(&mm->mmap_sem); 360 up_read(&mm->mmap_sem);
361 printk("VM: killing process %s\n", tsk->comm); 361 printk("VM: killing process %s\n", tsk->comm);
362 if (user_mode(regs)) 362 if (user_mode(regs))
363 do_exit(SIGKILL); 363 do_group_exit(SIGKILL);
364 goto no_context; 364 goto no_context;
365 365
366 do_sigbus: 366 do_sigbus:
diff --git a/arch/frv/kernel/time.c b/arch/frv/kernel/time.c
index ed588d73d7d8..e83e0bccfab9 100644
--- a/arch/frv/kernel/time.c
+++ b/arch/frv/kernel/time.c
@@ -43,7 +43,10 @@ unsigned long __delay_loops_MHz;
43static irqreturn_t timer_interrupt(int irq, void *dummy); 43static irqreturn_t timer_interrupt(int irq, void *dummy);
44 44
45static struct irqaction timer_irq = { 45static struct irqaction timer_irq = {
46 timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, "timer", NULL, NULL 46 .handler = timer_interrupt,
47 .flags = IRQF_DISABLED,
48 .mask = CPU_MASK_NONE,
49 .name = "timer",
47}; 50};
48 51
49static inline int set_rtc_mmss(unsigned long nowtime) 52static inline int set_rtc_mmss(unsigned long nowtime)
diff --git a/arch/frv/mm/fault.c b/arch/frv/mm/fault.c
index 6798fa0257b1..05093d41d98e 100644
--- a/arch/frv/mm/fault.c
+++ b/arch/frv/mm/fault.c
@@ -259,7 +259,7 @@ asmlinkage void do_page_fault(int datammu, unsigned long esr0, unsigned long ear
259 up_read(&mm->mmap_sem); 259 up_read(&mm->mmap_sem);
260 printk("VM: killing process %s\n", current->comm); 260 printk("VM: killing process %s\n", current->comm);
261 if (user_mode(__frame)) 261 if (user_mode(__frame))
262 do_exit(SIGKILL); 262 do_group_exit(SIGKILL);
263 goto no_context; 263 goto no_context;
264 264
265 do_sigbus: 265 do_sigbus:
diff --git a/arch/ia64/Kconfig b/arch/ia64/Kconfig
index 2e6310b8eab7..59b91ac861ac 100644
--- a/arch/ia64/Kconfig
+++ b/arch/ia64/Kconfig
@@ -54,6 +54,11 @@ config ARCH_HAS_ILOG2_U64
54 bool 54 bool
55 default n 55 default n
56 56
57config HUGETLB_PAGE_SIZE_VARIABLE
58 bool
59 depends on HUGETLB_PAGE
60 default y
61
57config GENERIC_FIND_NEXT_BIT 62config GENERIC_FIND_NEXT_BIT
58 bool 63 bool
59 default y 64 default y
@@ -300,6 +305,9 @@ config HOTPLUG_CPU
300config ARCH_ENABLE_MEMORY_HOTPLUG 305config ARCH_ENABLE_MEMORY_HOTPLUG
301 def_bool y 306 def_bool y
302 307
308config ARCH_ENABLE_MEMORY_HOTREMOVE
309 def_bool y
310
303config SCHED_SMT 311config SCHED_SMT
304 bool "SMT scheduler support" 312 bool "SMT scheduler support"
305 depends on SMP 313 depends on SMP
@@ -348,6 +356,7 @@ config ARCH_FLATMEM_ENABLE
348config ARCH_SPARSEMEM_ENABLE 356config ARCH_SPARSEMEM_ENABLE
349 def_bool y 357 def_bool y
350 depends on ARCH_DISCONTIGMEM_ENABLE 358 depends on ARCH_DISCONTIGMEM_ENABLE
359 select SPARSEMEM_VMEMMAP_ENABLE
351 360
352config ARCH_DISCONTIGMEM_DEFAULT 361config ARCH_DISCONTIGMEM_DEFAULT
353 def_bool y if (IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB) 362 def_bool y if (IA64_SGI_SN2 || IA64_GENERIC || IA64_HP_ZX1 || IA64_HP_ZX1_SWIOTLB)
diff --git a/arch/ia64/hp/common/sba_iommu.c b/arch/ia64/hp/common/sba_iommu.c
index e980e7aa2306..4338f4123f31 100644
--- a/arch/ia64/hp/common/sba_iommu.c
+++ b/arch/ia64/hp/common/sba_iommu.c
@@ -396,7 +396,7 @@ sba_dump_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
396 printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents, 396 printk(KERN_DEBUG " %d : DMA %08lx/%05x CPU %p\n", nents,
397 startsg->dma_address, startsg->dma_length, 397 startsg->dma_address, startsg->dma_length,
398 sba_sg_address(startsg)); 398 sba_sg_address(startsg));
399 startsg++; 399 startsg = sg_next(startsg);
400 } 400 }
401} 401}
402 402
@@ -409,7 +409,7 @@ sba_check_sg( struct ioc *ioc, struct scatterlist *startsg, int nents)
409 while (the_nents-- > 0) { 409 while (the_nents-- > 0) {
410 if (sba_sg_address(the_sg) == 0x0UL) 410 if (sba_sg_address(the_sg) == 0x0UL)
411 sba_dump_sg(NULL, startsg, nents); 411 sba_dump_sg(NULL, startsg, nents);
412 the_sg++; 412 the_sg = sg_next(the_sg);
413 } 413 }
414} 414}
415 415
@@ -1201,7 +1201,7 @@ sba_fill_pdir(
1201 u32 pide = startsg->dma_address & ~PIDE_FLAG; 1201 u32 pide = startsg->dma_address & ~PIDE_FLAG;
1202 dma_offset = (unsigned long) pide & ~iovp_mask; 1202 dma_offset = (unsigned long) pide & ~iovp_mask;
1203 startsg->dma_address = 0; 1203 startsg->dma_address = 0;
1204 dma_sg++; 1204 dma_sg = sg_next(dma_sg);
1205 dma_sg->dma_address = pide | ioc->ibase; 1205 dma_sg->dma_address = pide | ioc->ibase;
1206 pdirp = &(ioc->pdir_base[pide >> iovp_shift]); 1206 pdirp = &(ioc->pdir_base[pide >> iovp_shift]);
1207 n_mappings++; 1207 n_mappings++;
@@ -1228,7 +1228,7 @@ sba_fill_pdir(
1228 pdirp++; 1228 pdirp++;
1229 } while (cnt > 0); 1229 } while (cnt > 0);
1230 } 1230 }
1231 startsg++; 1231 startsg = sg_next(startsg);
1232 } 1232 }
1233 /* force pdir update */ 1233 /* force pdir update */
1234 wmb(); 1234 wmb();
@@ -1297,7 +1297,7 @@ sba_coalesce_chunks( struct ioc *ioc,
1297 while (--nents > 0) { 1297 while (--nents > 0) {
1298 unsigned long vaddr; /* tmp */ 1298 unsigned long vaddr; /* tmp */
1299 1299
1300 startsg++; 1300 startsg = sg_next(startsg);
1301 1301
1302 /* PARANOID */ 1302 /* PARANOID */
1303 startsg->dma_address = startsg->dma_length = 0; 1303 startsg->dma_address = startsg->dma_length = 0;
@@ -1407,7 +1407,7 @@ int sba_map_sg(struct device *dev, struct scatterlist *sglist, int nents, int di
1407#ifdef ALLOW_IOV_BYPASS_SG 1407#ifdef ALLOW_IOV_BYPASS_SG
1408 ASSERT(to_pci_dev(dev)->dma_mask); 1408 ASSERT(to_pci_dev(dev)->dma_mask);
1409 if (likely((ioc->dma_mask & ~to_pci_dev(dev)->dma_mask) == 0)) { 1409 if (likely((ioc->dma_mask & ~to_pci_dev(dev)->dma_mask) == 0)) {
1410 for (sg = sglist ; filled < nents ; filled++, sg++){ 1410 for_each_sg(sglist, sg, nents, filled) {
1411 sg->dma_length = sg->length; 1411 sg->dma_length = sg->length;
1412 sg->dma_address = virt_to_phys(sba_sg_address(sg)); 1412 sg->dma_address = virt_to_phys(sba_sg_address(sg));
1413 } 1413 }
@@ -1501,7 +1501,7 @@ void sba_unmap_sg (struct device *dev, struct scatterlist *sglist, int nents, in
1501 while (nents && sglist->dma_length) { 1501 while (nents && sglist->dma_length) {
1502 1502
1503 sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir); 1503 sba_unmap_single(dev, sglist->dma_address, sglist->dma_length, dir);
1504 sglist++; 1504 sglist = sg_next(sglist);
1505 nents--; 1505 nents--;
1506 } 1506 }
1507 1507
diff --git a/arch/ia64/hp/sim/simscsi.c b/arch/ia64/hp/sim/simscsi.c
index d62fa76e5a7d..a3a558a06757 100644
--- a/arch/ia64/hp/sim/simscsi.c
+++ b/arch/ia64/hp/sim/simscsi.c
@@ -360,6 +360,7 @@ static struct scsi_host_template driver_template = {
360 .max_sectors = 1024, 360 .max_sectors = 1024,
361 .cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN, 361 .cmd_per_lun = SIMSCSI_REQ_QUEUE_LEN,
362 .use_clustering = DISABLE_CLUSTERING, 362 .use_clustering = DISABLE_CLUSTERING,
363 .use_sg_chaining = ENABLE_SG_CHAINING,
363}; 364};
364 365
365static int __init 366static int __init
diff --git a/arch/ia64/kernel/gate.lds.S b/arch/ia64/kernel/gate.lds.S
index 6d198339bf85..44817d97ab43 100644
--- a/arch/ia64/kernel/gate.lds.S
+++ b/arch/ia64/kernel/gate.lds.S
@@ -1,7 +1,8 @@
1/* 1/*
2 * Linker script for gate DSO. The gate pages are an ELF shared object prelinked to its 2 * Linker script for gate DSO. The gate pages are an ELF shared object
3 * virtual address, with only one read-only segment and one execute-only segment (both fit 3 * prelinked to its virtual address, with only one read-only segment and
4 * in one page). This script controls its layout. 4 * one execute-only segment (both fit in one page). This script controls
5 * its layout.
5 */ 6 */
6 7
7 8
@@ -9,72 +10,80 @@
9 10
10SECTIONS 11SECTIONS
11{ 12{
12 . = GATE_ADDR + SIZEOF_HEADERS; 13 . = GATE_ADDR + SIZEOF_HEADERS;
13 14
14 .hash : { *(.hash) } :readable 15 .hash : { *(.hash) } :readable
15 .gnu.hash : { *(.gnu.hash) } 16 .gnu.hash : { *(.gnu.hash) }
16 .dynsym : { *(.dynsym) } 17 .dynsym : { *(.dynsym) }
17 .dynstr : { *(.dynstr) } 18 .dynstr : { *(.dynstr) }
18 .gnu.version : { *(.gnu.version) } 19 .gnu.version : { *(.gnu.version) }
19 .gnu.version_d : { *(.gnu.version_d) } 20 .gnu.version_d : { *(.gnu.version_d) }
20 .gnu.version_r : { *(.gnu.version_r) } 21 .gnu.version_r : { *(.gnu.version_r) }
21 .dynamic : { *(.dynamic) } :readable :dynamic 22
22 23 .dynamic : { *(.dynamic) } :readable :dynamic
23 /* 24
24 * This linker script is used both with -r and with -shared. For the layouts to match, 25 /*
25 * we need to skip more than enough space for the dynamic symbol table et al. If this 26 * This linker script is used both with -r and with -shared. For
26 * amount is insufficient, ld -shared will barf. Just increase it here. 27 * the layouts to match, we need to skip more than enough space for
27 */ 28 * the dynamic symbol table et al. If this amount is insufficient,
28 . = GATE_ADDR + 0x500; 29 * ld -shared will barf. Just increase it here.
29 30 */
30 .data.patch : { 31 . = GATE_ADDR + 0x500;
31 __start_gate_mckinley_e9_patchlist = .; 32
32 *(.data.patch.mckinley_e9) 33 .data.patch : {
33 __end_gate_mckinley_e9_patchlist = .; 34 __start_gate_mckinley_e9_patchlist = .;
34 35 *(.data.patch.mckinley_e9)
35 __start_gate_vtop_patchlist = .; 36 __end_gate_mckinley_e9_patchlist = .;
36 *(.data.patch.vtop) 37
37 __end_gate_vtop_patchlist = .; 38 __start_gate_vtop_patchlist = .;
38 39 *(.data.patch.vtop)
39 __start_gate_fsyscall_patchlist = .; 40 __end_gate_vtop_patchlist = .;
40 *(.data.patch.fsyscall_table) 41
41 __end_gate_fsyscall_patchlist = .; 42 __start_gate_fsyscall_patchlist = .;
42 43 *(.data.patch.fsyscall_table)
43 __start_gate_brl_fsys_bubble_down_patchlist = .; 44 __end_gate_fsyscall_patchlist = .;
44 *(.data.patch.brl_fsys_bubble_down) 45
45 __end_gate_brl_fsys_bubble_down_patchlist = .; 46 __start_gate_brl_fsys_bubble_down_patchlist = .;
46 } :readable 47 *(.data.patch.brl_fsys_bubble_down)
47 .IA_64.unwind_info : { *(.IA_64.unwind_info*) } 48 __end_gate_brl_fsys_bubble_down_patchlist = .;
48 .IA_64.unwind : { *(.IA_64.unwind*) } :readable :unwind 49 } :readable
50
51 .IA_64.unwind_info : { *(.IA_64.unwind_info*) }
52 .IA_64.unwind : { *(.IA_64.unwind*) } :readable :unwind
49#ifdef HAVE_BUGGY_SEGREL 53#ifdef HAVE_BUGGY_SEGREL
50 .text (GATE_ADDR + PAGE_SIZE) : { *(.text) *(.text.*) } :readable 54 .text (GATE_ADDR + PAGE_SIZE) : { *(.text) *(.text.*) } :readable
51#else 55#else
52 . = ALIGN (PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1)); 56 . = ALIGN(PERCPU_PAGE_SIZE) + (. & (PERCPU_PAGE_SIZE - 1));
53 .text : { *(.text) *(.text.*) } :epc 57 .text : { *(.text) *(.text.*) } :epc
54#endif 58#endif
55 59
56 /DISCARD/ : { 60 /DISCARD/ : {
57 *(.got.plt) *(.got) 61 *(.got.plt) *(.got)
58 *(.data .data.* .gnu.linkonce.d.*) 62 *(.data .data.* .gnu.linkonce.d.*)
59 *(.dynbss) 63 *(.dynbss)
60 *(.bss .bss.* .gnu.linkonce.b.*) 64 *(.bss .bss.* .gnu.linkonce.b.*)
61 *(__ex_table) 65 *(__ex_table)
62 *(__mca_table) 66 *(__mca_table)
63 } 67 }
64} 68}
65 69
66/* 70/*
71 * ld does not recognize this name token; use the constant.
72 */
73#define PT_IA_64_UNWIND 0x70000001
74
75/*
67 * We must supply the ELF program headers explicitly to get just one 76 * We must supply the ELF program headers explicitly to get just one
68 * PT_LOAD segment, and set the flags explicitly to make segments read-only. 77 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
69 */ 78 */
70PHDRS 79PHDRS
71{ 80{
72 readable PT_LOAD FILEHDR PHDRS FLAGS(4); /* PF_R */ 81 readable PT_LOAD FILEHDR PHDRS FLAGS(4); /* PF_R */
73#ifndef HAVE_BUGGY_SEGREL 82#ifndef HAVE_BUGGY_SEGREL
74 epc PT_LOAD FILEHDR PHDRS FLAGS(1); /* PF_X */ 83 epc PT_LOAD FILEHDR PHDRS FLAGS(1); /* PF_X */
75#endif 84#endif
76 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ 85 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
77 unwind 0x70000001; /* PT_IA_64_UNWIND, but ld doesn't match the name */ 86 unwind PT_IA_64_UNWIND;
78} 87}
79 88
80/* 89/*
@@ -82,14 +91,14 @@ PHDRS
82 */ 91 */
83VERSION 92VERSION
84{ 93{
85 LINUX_2.5 { 94 LINUX_2.5 {
86 global: 95 global:
87 __kernel_syscall_via_break; 96 __kernel_syscall_via_break;
88 __kernel_syscall_via_epc; 97 __kernel_syscall_via_epc;
89 __kernel_sigtramp; 98 __kernel_sigtramp;
90 99
91 local: *; 100 local: *;
92 }; 101 };
93} 102}
94 103
95/* The ELF entry point can be used to set the AT_SYSINFO value. */ 104/* The ELF entry point can be used to set the AT_SYSINFO value. */
diff --git a/arch/ia64/kernel/kprobes.c b/arch/ia64/kernel/kprobes.c
index 5dc98b5abcfb..5fd65d8302c8 100644
--- a/arch/ia64/kernel/kprobes.c
+++ b/arch/ia64/kernel/kprobes.c
@@ -40,6 +40,8 @@ extern void jprobe_inst_return(void);
40DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 40DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
41DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 41DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
42 42
43struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
44
43enum instruction_type {A, I, M, F, B, L, X, u}; 45enum instruction_type {A, I, M, F, B, L, X, u};
44static enum instruction_type bundle_encoding[32][3] = { 46static enum instruction_type bundle_encoding[32][3] = {
45 { M, I, I }, /* 00 */ 47 { M, I, I }, /* 00 */
diff --git a/arch/ia64/kernel/setup.c b/arch/ia64/kernel/setup.c
index 9e392a30d197..777c8d8bd5e7 100644
--- a/arch/ia64/kernel/setup.c
+++ b/arch/ia64/kernel/setup.c
@@ -528,10 +528,6 @@ setup_arch (char **cmdline_p)
528 528
529#ifdef CONFIG_SMP 529#ifdef CONFIG_SMP
530 cpu_physical_id(0) = hard_smp_processor_id(); 530 cpu_physical_id(0) = hard_smp_processor_id();
531
532 cpu_set(0, cpu_sibling_map[0]);
533 cpu_set(0, cpu_core_map[0]);
534
535 check_for_logical_procs(); 531 check_for_logical_procs();
536 if (smp_num_cpucores > 1) 532 if (smp_num_cpucores > 1)
537 printk(KERN_INFO 533 printk(KERN_INFO
@@ -873,6 +869,14 @@ cpu_init (void)
873 void *cpu_data; 869 void *cpu_data;
874 870
875 cpu_data = per_cpu_init(); 871 cpu_data = per_cpu_init();
872 /*
873 * insert boot cpu into sibling and core mapes
874 * (must be done after per_cpu area is setup)
875 */
876 if (smp_processor_id() == 0) {
877 cpu_set(0, per_cpu(cpu_sibling_map, 0));
878 cpu_set(0, cpu_core_map[0]);
879 }
876 880
877 /* 881 /*
878 * We set ar.k3 so that assembly code in MCA handler can compute 882 * We set ar.k3 so that assembly code in MCA handler can compute
diff --git a/arch/ia64/kernel/smpboot.c b/arch/ia64/kernel/smpboot.c
index 308772f7cddc..c57dbce25c12 100644
--- a/arch/ia64/kernel/smpboot.c
+++ b/arch/ia64/kernel/smpboot.c
@@ -138,7 +138,9 @@ cpumask_t cpu_possible_map = CPU_MASK_NONE;
138EXPORT_SYMBOL(cpu_possible_map); 138EXPORT_SYMBOL(cpu_possible_map);
139 139
140cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned; 140cpumask_t cpu_core_map[NR_CPUS] __cacheline_aligned;
141cpumask_t cpu_sibling_map[NR_CPUS] __cacheline_aligned; 141DEFINE_PER_CPU_SHARED_ALIGNED(cpumask_t, cpu_sibling_map);
142EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
143
142int smp_num_siblings = 1; 144int smp_num_siblings = 1;
143int smp_num_cpucores = 1; 145int smp_num_cpucores = 1;
144 146
@@ -650,12 +652,12 @@ clear_cpu_sibling_map(int cpu)
650{ 652{
651 int i; 653 int i;
652 654
653 for_each_cpu_mask(i, cpu_sibling_map[cpu]) 655 for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu))
654 cpu_clear(cpu, cpu_sibling_map[i]); 656 cpu_clear(cpu, per_cpu(cpu_sibling_map, i));
655 for_each_cpu_mask(i, cpu_core_map[cpu]) 657 for_each_cpu_mask(i, cpu_core_map[cpu])
656 cpu_clear(cpu, cpu_core_map[i]); 658 cpu_clear(cpu, cpu_core_map[i]);
657 659
658 cpu_sibling_map[cpu] = cpu_core_map[cpu] = CPU_MASK_NONE; 660 per_cpu(cpu_sibling_map, cpu) = cpu_core_map[cpu] = CPU_MASK_NONE;
659} 661}
660 662
661static void 663static void
@@ -666,7 +668,7 @@ remove_siblinginfo(int cpu)
666 if (cpu_data(cpu)->threads_per_core == 1 && 668 if (cpu_data(cpu)->threads_per_core == 1 &&
667 cpu_data(cpu)->cores_per_socket == 1) { 669 cpu_data(cpu)->cores_per_socket == 1) {
668 cpu_clear(cpu, cpu_core_map[cpu]); 670 cpu_clear(cpu, cpu_core_map[cpu]);
669 cpu_clear(cpu, cpu_sibling_map[cpu]); 671 cpu_clear(cpu, per_cpu(cpu_sibling_map, cpu));
670 return; 672 return;
671 } 673 }
672 674
@@ -807,8 +809,8 @@ set_cpu_sibling_map(int cpu)
807 cpu_set(i, cpu_core_map[cpu]); 809 cpu_set(i, cpu_core_map[cpu]);
808 cpu_set(cpu, cpu_core_map[i]); 810 cpu_set(cpu, cpu_core_map[i]);
809 if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) { 811 if (cpu_data(cpu)->core_id == cpu_data(i)->core_id) {
810 cpu_set(i, cpu_sibling_map[cpu]); 812 cpu_set(i, per_cpu(cpu_sibling_map, cpu));
811 cpu_set(cpu, cpu_sibling_map[i]); 813 cpu_set(cpu, per_cpu(cpu_sibling_map, i));
812 } 814 }
813 } 815 }
814 } 816 }
@@ -839,7 +841,7 @@ __cpu_up (unsigned int cpu)
839 841
840 if (cpu_data(cpu)->threads_per_core == 1 && 842 if (cpu_data(cpu)->threads_per_core == 1 &&
841 cpu_data(cpu)->cores_per_socket == 1) { 843 cpu_data(cpu)->cores_per_socket == 1) {
842 cpu_set(cpu, cpu_sibling_map[cpu]); 844 cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
843 cpu_set(cpu, cpu_core_map[cpu]); 845 cpu_set(cpu, cpu_core_map[cpu]);
844 return 0; 846 return 0;
845 } 847 }
diff --git a/arch/ia64/kernel/uncached.c b/arch/ia64/kernel/uncached.c
index c58e933694d5..a7be4f203420 100644
--- a/arch/ia64/kernel/uncached.c
+++ b/arch/ia64/kernel/uncached.c
@@ -196,7 +196,7 @@ unsigned long uncached_alloc_page(int starting_nid)
196 nid = starting_nid; 196 nid = starting_nid;
197 197
198 do { 198 do {
199 if (!node_online(nid)) 199 if (!node_state(nid, N_HIGH_MEMORY))
200 continue; 200 continue;
201 uc_pool = &uncached_pools[nid]; 201 uc_pool = &uncached_pools[nid];
202 if (uc_pool->pool == NULL) 202 if (uc_pool->pool == NULL)
@@ -268,7 +268,7 @@ static int __init uncached_init(void)
268{ 268{
269 int nid; 269 int nid;
270 270
271 for_each_online_node(nid) { 271 for_each_node_state(nid, N_ONLINE) {
272 uncached_pools[nid].pool = gen_pool_create(PAGE_SHIFT, nid); 272 uncached_pools[nid].pool = gen_pool_create(PAGE_SHIFT, nid);
273 mutex_init(&uncached_pools[nid].add_chunk_mutex); 273 mutex_init(&uncached_pools[nid].add_chunk_mutex);
274 } 274 }
diff --git a/arch/ia64/mm/discontig.c b/arch/ia64/mm/discontig.c
index 0d34585058c8..5628067a74d2 100644
--- a/arch/ia64/mm/discontig.c
+++ b/arch/ia64/mm/discontig.c
@@ -715,3 +715,11 @@ void arch_refresh_nodedata(int update_node, pg_data_t *update_pgdat)
715 scatter_node_data(); 715 scatter_node_data();
716} 716}
717#endif 717#endif
718
719#ifdef CONFIG_SPARSEMEM_VMEMMAP
720int __meminit vmemmap_populate(struct page *start_page,
721 unsigned long size, int node)
722{
723 return vmemmap_populate_basepages(start_page, size, node);
724}
725#endif
diff --git a/arch/ia64/mm/fault.c b/arch/ia64/mm/fault.c
index 9150ffaff9e8..32f26253c4e8 100644
--- a/arch/ia64/mm/fault.c
+++ b/arch/ia64/mm/fault.c
@@ -281,6 +281,6 @@ ia64_do_page_fault (unsigned long address, unsigned long isr, struct pt_regs *re
281 } 281 }
282 printk(KERN_CRIT "VM: killing process %s\n", current->comm); 282 printk(KERN_CRIT "VM: killing process %s\n", current->comm);
283 if (user_mode(regs)) 283 if (user_mode(regs))
284 do_exit(SIGKILL); 284 do_group_exit(SIGKILL);
285 goto no_context; 285 goto no_context;
286} 286}
diff --git a/arch/ia64/mm/hugetlbpage.c b/arch/ia64/mm/hugetlbpage.c
index a9ff685aea25..d3ce8f3bcaa6 100644
--- a/arch/ia64/mm/hugetlbpage.c
+++ b/arch/ia64/mm/hugetlbpage.c
@@ -194,6 +194,6 @@ static int __init hugetlb_setup_sz(char *str)
194 * override here with new page shift. 194 * override here with new page shift.
195 */ 195 */
196 ia64_set_rr(HPAGE_REGION_BASE, hpage_shift << 2); 196 ia64_set_rr(HPAGE_REGION_BASE, hpage_shift << 2);
197 return 1; 197 return 0;
198} 198}
199__setup("hugepagesz=", hugetlb_setup_sz); 199early_param("hugepagesz", hugetlb_setup_sz);
diff --git a/arch/ia64/mm/init.c b/arch/ia64/mm/init.c
index c14abefabafa..3e10152abbf0 100644
--- a/arch/ia64/mm/init.c
+++ b/arch/ia64/mm/init.c
@@ -54,15 +54,12 @@ struct page *zero_page_memmap_ptr; /* map entry for zero page */
54EXPORT_SYMBOL(zero_page_memmap_ptr); 54EXPORT_SYMBOL(zero_page_memmap_ptr);
55 55
56void 56void
57lazy_mmu_prot_update (pte_t pte) 57__ia64_sync_icache_dcache (pte_t pte)
58{ 58{
59 unsigned long addr; 59 unsigned long addr;
60 struct page *page; 60 struct page *page;
61 unsigned long order; 61 unsigned long order;
62 62
63 if (!pte_exec(pte))
64 return; /* not an executable page... */
65
66 page = pte_page(pte); 63 page = pte_page(pte);
67 addr = (unsigned long) page_address(page); 64 addr = (unsigned long) page_address(page);
68 65
@@ -721,10 +718,21 @@ int arch_add_memory(int nid, u64 start, u64 size)
721 718
722 return ret; 719 return ret;
723} 720}
724 721#ifdef CONFIG_MEMORY_HOTREMOVE
725int remove_memory(u64 start, u64 size) 722int remove_memory(u64 start, u64 size)
726{ 723{
727 return -EINVAL; 724 unsigned long start_pfn, end_pfn;
725 unsigned long timeout = 120 * HZ;
726 int ret;
727 start_pfn = start >> PAGE_SHIFT;
728 end_pfn = start_pfn + (size >> PAGE_SHIFT);
729 ret = offline_pages(start_pfn, end_pfn, timeout);
730 if (ret)
731 goto out;
732 /* we can free mem_map at this point */
733out:
734 return ret;
728} 735}
729EXPORT_SYMBOL_GPL(remove_memory); 736EXPORT_SYMBOL_GPL(remove_memory);
737#endif /* CONFIG_MEMORY_HOTREMOVE */
730#endif 738#endif
diff --git a/arch/ia64/sn/pci/pci_dma.c b/arch/ia64/sn/pci/pci_dma.c
index d79ddacfba2d..ecd8a52b9b9e 100644
--- a/arch/ia64/sn/pci/pci_dma.c
+++ b/arch/ia64/sn/pci/pci_dma.c
@@ -218,16 +218,17 @@ EXPORT_SYMBOL(sn_dma_unmap_single);
218 * 218 *
219 * Unmap a set of streaming mode DMA translations. 219 * Unmap a set of streaming mode DMA translations.
220 */ 220 */
221void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sg, 221void sn_dma_unmap_sg(struct device *dev, struct scatterlist *sgl,
222 int nhwentries, int direction) 222 int nhwentries, int direction)
223{ 223{
224 int i; 224 int i;
225 struct pci_dev *pdev = to_pci_dev(dev); 225 struct pci_dev *pdev = to_pci_dev(dev);
226 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); 226 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
227 struct scatterlist *sg;
227 228
228 BUG_ON(dev->bus != &pci_bus_type); 229 BUG_ON(dev->bus != &pci_bus_type);
229 230
230 for (i = 0; i < nhwentries; i++, sg++) { 231 for_each_sg(sgl, sg, nhwentries, i) {
231 provider->dma_unmap(pdev, sg->dma_address, direction); 232 provider->dma_unmap(pdev, sg->dma_address, direction);
232 sg->dma_address = (dma_addr_t) NULL; 233 sg->dma_address = (dma_addr_t) NULL;
233 sg->dma_length = 0; 234 sg->dma_length = 0;
@@ -244,11 +245,11 @@ EXPORT_SYMBOL(sn_dma_unmap_sg);
244 * 245 *
245 * Maps each entry of @sg for DMA. 246 * Maps each entry of @sg for DMA.
246 */ 247 */
247int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries, 248int sn_dma_map_sg(struct device *dev, struct scatterlist *sgl, int nhwentries,
248 int direction) 249 int direction)
249{ 250{
250 unsigned long phys_addr; 251 unsigned long phys_addr;
251 struct scatterlist *saved_sg = sg; 252 struct scatterlist *saved_sg = sgl, *sg;
252 struct pci_dev *pdev = to_pci_dev(dev); 253 struct pci_dev *pdev = to_pci_dev(dev);
253 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev); 254 struct sn_pcibus_provider *provider = SN_PCIDEV_BUSPROVIDER(pdev);
254 int i; 255 int i;
@@ -258,7 +259,7 @@ int sn_dma_map_sg(struct device *dev, struct scatterlist *sg, int nhwentries,
258 /* 259 /*
259 * Setup a DMA address for each entry in the scatterlist. 260 * Setup a DMA address for each entry in the scatterlist.
260 */ 261 */
261 for (i = 0; i < nhwentries; i++, sg++) { 262 for_each_sg(sgl, sg, nhwentries, i) {
262 phys_addr = SG_ENT_PHYS_ADDRESS(sg); 263 phys_addr = SG_ENT_PHYS_ADDRESS(sg);
263 sg->dma_address = provider->dma_map(pdev, 264 sg->dma_address = provider->dma_map(pdev,
264 phys_addr, sg->length, 265 phys_addr, sg->length,
diff --git a/arch/m32r/kernel/ptrace.c b/arch/m32r/kernel/ptrace.c
index 62a51429306e..ed4d0756c5db 100644
--- a/arch/m32r/kernel/ptrace.c
+++ b/arch/m32r/kernel/ptrace.c
@@ -570,7 +570,7 @@ withdraw_debug_trap(struct pt_regs *regs)
570 } 570 }
571} 571}
572 572
573static void 573void
574init_debug_traps(struct task_struct *child) 574init_debug_traps(struct task_struct *child)
575{ 575{
576 struct debug_trap *p = &child->thread.debug_trap; 576 struct debug_trap *p = &child->thread.debug_trap;
@@ -593,8 +593,8 @@ void ptrace_disable(struct task_struct *child)
593 /* nothing to do.. */ 593 /* nothing to do.. */
594} 594}
595 595
596static int 596long
597do_ptrace(long request, struct task_struct *child, long addr, long data) 597arch_ptrace(struct task_struct *child, long request, long addr, long data)
598{ 598{
599 int ret; 599 int ret;
600 600
@@ -704,14 +704,6 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
704 break; 704 break;
705 } 705 }
706 706
707 /*
708 * detach a process that was attached.
709 */
710 case PTRACE_DETACH:
711 ret = 0;
712 ret = ptrace_detach(child, data);
713 break;
714
715 case PTRACE_GETREGS: 707 case PTRACE_GETREGS:
716 ret = ptrace_getregs(child, (void __user *)data); 708 ret = ptrace_getregs(child, (void __user *)data);
717 break; 709 break;
@@ -728,42 +720,6 @@ do_ptrace(long request, struct task_struct *child, long addr, long data)
728 return ret; 720 return ret;
729} 721}
730 722
731asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
732{
733 struct task_struct *child;
734 int ret;
735
736 lock_kernel();
737 if (request == PTRACE_TRACEME) {
738 ret = ptrace_traceme();
739 goto out;
740 }
741
742 child = ptrace_get_task_struct(pid);
743 if (IS_ERR(child)) {
744 ret = PTR_ERR(child);
745 goto out;
746 }
747
748 if (request == PTRACE_ATTACH) {
749 ret = ptrace_attach(child);
750 if (ret == 0)
751 init_debug_traps(child);
752 goto out_tsk;
753 }
754
755 ret = ptrace_check_attach(child, request == PTRACE_KILL);
756 if (ret == 0)
757 ret = do_ptrace(request, child, addr, data);
758
759out_tsk:
760 put_task_struct(child);
761out:
762 unlock_kernel();
763
764 return ret;
765}
766
767/* notification of system call entry/exit 723/* notification of system call entry/exit
768 * - triggered by current->work.syscall_trace 724 * - triggered by current->work.syscall_trace
769 */ 725 */
diff --git a/arch/m32r/kernel/time.c b/arch/m32r/kernel/time.c
index 3858c9f39ba5..994cc1556355 100644
--- a/arch/m32r/kernel/time.c
+++ b/arch/m32r/kernel/time.c
@@ -228,8 +228,12 @@ irqreturn_t timer_interrupt(int irq, void *dev_id)
228 return IRQ_HANDLED; 228 return IRQ_HANDLED;
229} 229}
230 230
231struct irqaction irq0 = { timer_interrupt, IRQF_DISABLED, CPU_MASK_NONE, 231struct irqaction irq0 = {
232 "MFT2", NULL, NULL }; 232 .handler = timer_interrupt,
233 .flags = IRQF_DISABLED,
234 .mask = CPU_MASK_NONE,
235 .name = "MFT2",
236};
233 237
234void __init time_init(void) 238void __init time_init(void)
235{ 239{
diff --git a/arch/m32r/mm/fault.c b/arch/m32r/mm/fault.c
index 676a1c443d28..70a766aad3e0 100644
--- a/arch/m32r/mm/fault.c
+++ b/arch/m32r/mm/fault.c
@@ -278,7 +278,7 @@ out_of_memory:
278 } 278 }
279 printk("VM: killing process %s\n", tsk->comm); 279 printk("VM: killing process %s\n", tsk->comm);
280 if (error_code & ACE_USERMODE) 280 if (error_code & ACE_USERMODE)
281 do_exit(SIGKILL); 281 do_group_exit(SIGKILL);
282 goto no_context; 282 goto no_context;
283 283
284do_sigbus: 284do_sigbus:
diff --git a/arch/m68k/kernel/ptrace.c b/arch/m68k/kernel/ptrace.c
index e792d3cba4c7..2075543c2d92 100644
--- a/arch/m68k/kernel/ptrace.c
+++ b/arch/m68k/kernel/ptrace.c
@@ -226,10 +226,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
226 wake_up_process(child); 226 wake_up_process(child);
227 break; 227 break;
228 228
229 case PTRACE_DETACH: /* detach a process that was attached. */
230 ret = ptrace_detach(child, data);
231 break;
232
233 case PTRACE_GETREGS: /* Get all gp regs from the child. */ 229 case PTRACE_GETREGS: /* Get all gp regs from the child. */
234 for (i = 0; i < 19; i++) { 230 for (i = 0; i < 19; i++) {
235 tmp = get_reg(child, i); 231 tmp = get_reg(child, i);
diff --git a/arch/m68k/mm/fault.c b/arch/m68k/mm/fault.c
index 578b48f47b9e..eaa618681159 100644
--- a/arch/m68k/mm/fault.c
+++ b/arch/m68k/mm/fault.c
@@ -188,7 +188,7 @@ out_of_memory:
188 188
189 printk("VM: killing process %s\n", current->comm); 189 printk("VM: killing process %s\n", current->comm);
190 if (user_mode(regs)) 190 if (user_mode(regs))
191 do_exit(SIGKILL); 191 do_group_exit(SIGKILL);
192 192
193no_context: 193no_context:
194 current->thread.signo = SIGBUS; 194 current->thread.signo = SIGBUS;
diff --git a/arch/mips/jmr3927/rbhma3100/setup.c b/arch/mips/jmr3927/rbhma3100/setup.c
index 7f14f70a1b88..0c7aee1682cd 100644
--- a/arch/mips/jmr3927/rbhma3100/setup.c
+++ b/arch/mips/jmr3927/rbhma3100/setup.c
@@ -425,7 +425,7 @@ static int __init jmr3927_rtc_init(void)
425 .flags = IORESOURCE_MEM, 425 .flags = IORESOURCE_MEM,
426 }; 426 };
427 struct platform_device *dev; 427 struct platform_device *dev;
428 dev = platform_device_register_simple("ds1742", -1, &res, 1); 428 dev = platform_device_register_simple("rtc-ds1742", -1, &res, 1);
429 return IS_ERR(dev) ? PTR_ERR(dev) : 0; 429 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
430} 430}
431device_initcall(jmr3927_rtc_init); 431device_initcall(jmr3927_rtc_init);
diff --git a/arch/mips/kernel/ptrace.c b/arch/mips/kernel/ptrace.c
index 58aa6fec1146..999f7853de26 100644
--- a/arch/mips/kernel/ptrace.c
+++ b/arch/mips/kernel/ptrace.c
@@ -435,10 +435,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
435 wake_up_process(child); 435 wake_up_process(child);
436 break; 436 break;
437 437
438 case PTRACE_DETACH: /* detach a process that was attached. */
439 ret = ptrace_detach(child, data);
440 break;
441
442 case PTRACE_GET_THREAD_AREA: 438 case PTRACE_GET_THREAD_AREA:
443 ret = put_user(task_thread_info(child)->tp_value, 439 ret = put_user(task_thread_info(child)->tp_value,
444 (unsigned long __user *) data); 440 (unsigned long __user *) data);
diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c
index 521771b373de..5699c7713e2f 100644
--- a/arch/mips/mm/fault.c
+++ b/arch/mips/mm/fault.c
@@ -180,7 +180,7 @@ out_of_memory:
180 } 180 }
181 printk("VM: killing process %s\n", tsk->comm); 181 printk("VM: killing process %s\n", tsk->comm);
182 if (user_mode(regs)) 182 if (user_mode(regs))
183 do_exit(SIGKILL); 183 do_group_exit(SIGKILL);
184 goto no_context; 184 goto no_context;
185 185
186do_sigbus: 186do_sigbus:
diff --git a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
index acaf613358c7..b97102a1c635 100644
--- a/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
+++ b/arch/mips/tx4927/toshiba_rbtx4927/toshiba_rbtx4927_setup.c
@@ -963,7 +963,7 @@ static int __init toshiba_rbtx4927_rtc_init(void)
963 .flags = IORESOURCE_MEM, 963 .flags = IORESOURCE_MEM,
964 }; 964 };
965 struct platform_device *dev = 965 struct platform_device *dev =
966 platform_device_register_simple("ds1742", -1, &res, 1); 966 platform_device_register_simple("rtc-ds1742", -1, &res, 1);
967 return IS_ERR(dev) ? PTR_ERR(dev) : 0; 967 return IS_ERR(dev) ? PTR_ERR(dev) : 0;
968} 968}
969device_initcall(toshiba_rbtx4927_rtc_init); 969device_initcall(toshiba_rbtx4927_rtc_init);
diff --git a/arch/parisc/kernel/ptrace.c b/arch/parisc/kernel/ptrace.c
index 26ec774c5027..49c637970789 100644
--- a/arch/parisc/kernel/ptrace.c
+++ b/arch/parisc/kernel/ptrace.c
@@ -329,10 +329,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
329 /* give it a chance to run. */ 329 /* give it a chance to run. */
330 goto out_wake; 330 goto out_wake;
331 331
332 case PTRACE_DETACH:
333 ret = ptrace_detach(child, data);
334 goto out_tsk;
335
336 case PTRACE_GETEVENTMSG: 332 case PTRACE_GETEVENTMSG:
337 ret = put_user(child->ptrace_message, (unsigned int __user *) data); 333 ret = put_user(child->ptrace_message, (unsigned int __user *) data);
338 goto out_tsk; 334 goto out_tsk;
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 7899ab87785a..1c091b415cd9 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -263,6 +263,6 @@ no_context:
263 up_read(&mm->mmap_sem); 263 up_read(&mm->mmap_sem);
264 printk(KERN_CRIT "VM: killing process %s\n", current->comm); 264 printk(KERN_CRIT "VM: killing process %s\n", current->comm);
265 if (user_mode(regs)) 265 if (user_mode(regs))
266 do_exit(SIGKILL); 266 do_group_exit(SIGKILL);
267 goto no_context; 267 goto no_context;
268} 268}
diff --git a/arch/powerpc/Kconfig b/arch/powerpc/Kconfig
index 037664d496d7..5e001ad588a7 100644
--- a/arch/powerpc/Kconfig
+++ b/arch/powerpc/Kconfig
@@ -295,6 +295,7 @@ config ARCH_FLATMEM_ENABLE
295config ARCH_SPARSEMEM_ENABLE 295config ARCH_SPARSEMEM_ENABLE
296 def_bool y 296 def_bool y
297 depends on PPC64 297 depends on PPC64
298 select SPARSEMEM_VMEMMAP_ENABLE
298 299
299config ARCH_SPARSEMEM_DEFAULT 300config ARCH_SPARSEMEM_DEFAULT
300 def_bool y 301 def_bool y
diff --git a/arch/powerpc/kernel/dma_64.c b/arch/powerpc/kernel/dma_64.c
index 7b0e754383cf..9001104b56b0 100644
--- a/arch/powerpc/kernel/dma_64.c
+++ b/arch/powerpc/kernel/dma_64.c
@@ -154,12 +154,13 @@ static void dma_direct_unmap_single(struct device *dev, dma_addr_t dma_addr,
154{ 154{
155} 155}
156 156
157static int dma_direct_map_sg(struct device *dev, struct scatterlist *sg, 157static int dma_direct_map_sg(struct device *dev, struct scatterlist *sgl,
158 int nents, enum dma_data_direction direction) 158 int nents, enum dma_data_direction direction)
159{ 159{
160 struct scatterlist *sg;
160 int i; 161 int i;
161 162
162 for (i = 0; i < nents; i++, sg++) { 163 for_each_sg(sgl, sg, nents, i) {
163 sg->dma_address = (page_to_phys(sg->page) + sg->offset) | 164 sg->dma_address = (page_to_phys(sg->page) + sg->offset) |
164 dma_direct_offset; 165 dma_direct_offset;
165 sg->dma_length = sg->length; 166 sg->dma_length = sg->length;
diff --git a/arch/powerpc/kernel/ibmebus.c b/arch/powerpc/kernel/ibmebus.c
index 53bf64623bd8..2e16ca5778a3 100644
--- a/arch/powerpc/kernel/ibmebus.c
+++ b/arch/powerpc/kernel/ibmebus.c
@@ -87,15 +87,16 @@ static void ibmebus_unmap_single(struct device *dev,
87} 87}
88 88
89static int ibmebus_map_sg(struct device *dev, 89static int ibmebus_map_sg(struct device *dev,
90 struct scatterlist *sg, 90 struct scatterlist *sgl,
91 int nents, enum dma_data_direction direction) 91 int nents, enum dma_data_direction direction)
92{ 92{
93 struct scatterlist *sg;
93 int i; 94 int i;
94 95
95 for (i = 0; i < nents; i++) { 96 for_each_sg(sgl, sg, nents, i) {
96 sg[i].dma_address = (dma_addr_t)page_address(sg[i].page) 97 sg->dma_address = (dma_addr_t)page_address(sg->page)
97 + sg[i].offset; 98 + sg->offset;
98 sg[i].dma_length = sg[i].length; 99 sg->dma_length = sg->length;
99 } 100 }
100 101
101 return nents; 102 return nents;
diff --git a/arch/powerpc/kernel/iommu.c b/arch/powerpc/kernel/iommu.c
index e4ec6eee81a8..306a6f75b6c5 100644
--- a/arch/powerpc/kernel/iommu.c
+++ b/arch/powerpc/kernel/iommu.c
@@ -277,7 +277,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
277 dma_addr_t dma_next = 0, dma_addr; 277 dma_addr_t dma_next = 0, dma_addr;
278 unsigned long flags; 278 unsigned long flags;
279 struct scatterlist *s, *outs, *segstart; 279 struct scatterlist *s, *outs, *segstart;
280 int outcount, incount; 280 int outcount, incount, i;
281 unsigned long handle; 281 unsigned long handle;
282 282
283 BUG_ON(direction == DMA_NONE); 283 BUG_ON(direction == DMA_NONE);
@@ -297,7 +297,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
297 297
298 spin_lock_irqsave(&(tbl->it_lock), flags); 298 spin_lock_irqsave(&(tbl->it_lock), flags);
299 299
300 for (s = outs; nelems; nelems--, s++) { 300 for_each_sg(sglist, s, nelems, i) {
301 unsigned long vaddr, npages, entry, slen; 301 unsigned long vaddr, npages, entry, slen;
302 302
303 slen = s->length; 303 slen = s->length;
@@ -341,7 +341,8 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
341 if (novmerge || (dma_addr != dma_next)) { 341 if (novmerge || (dma_addr != dma_next)) {
342 /* Can't merge: create a new segment */ 342 /* Can't merge: create a new segment */
343 segstart = s; 343 segstart = s;
344 outcount++; outs++; 344 outcount++;
345 outs = sg_next(outs);
345 DBG(" can't merge, new segment.\n"); 346 DBG(" can't merge, new segment.\n");
346 } else { 347 } else {
347 outs->dma_length += s->length; 348 outs->dma_length += s->length;
@@ -374,7 +375,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
374 * next entry of the sglist if we didn't fill the list completely 375 * next entry of the sglist if we didn't fill the list completely
375 */ 376 */
376 if (outcount < incount) { 377 if (outcount < incount) {
377 outs++; 378 outs = sg_next(outs);
378 outs->dma_address = DMA_ERROR_CODE; 379 outs->dma_address = DMA_ERROR_CODE;
379 outs->dma_length = 0; 380 outs->dma_length = 0;
380 } 381 }
@@ -385,7 +386,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
385 return outcount; 386 return outcount;
386 387
387 failure: 388 failure:
388 for (s = &sglist[0]; s <= outs; s++) { 389 for_each_sg(sglist, s, nelems, i) {
389 if (s->dma_length != 0) { 390 if (s->dma_length != 0) {
390 unsigned long vaddr, npages; 391 unsigned long vaddr, npages;
391 392
@@ -395,6 +396,8 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
395 s->dma_address = DMA_ERROR_CODE; 396 s->dma_address = DMA_ERROR_CODE;
396 s->dma_length = 0; 397 s->dma_length = 0;
397 } 398 }
399 if (s == outs)
400 break;
398 } 401 }
399 spin_unlock_irqrestore(&(tbl->it_lock), flags); 402 spin_unlock_irqrestore(&(tbl->it_lock), flags);
400 return 0; 403 return 0;
@@ -404,6 +407,7 @@ int iommu_map_sg(struct iommu_table *tbl, struct scatterlist *sglist,
404void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist, 407void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
405 int nelems, enum dma_data_direction direction) 408 int nelems, enum dma_data_direction direction)
406{ 409{
410 struct scatterlist *sg;
407 unsigned long flags; 411 unsigned long flags;
408 412
409 BUG_ON(direction == DMA_NONE); 413 BUG_ON(direction == DMA_NONE);
@@ -413,15 +417,16 @@ void iommu_unmap_sg(struct iommu_table *tbl, struct scatterlist *sglist,
413 417
414 spin_lock_irqsave(&(tbl->it_lock), flags); 418 spin_lock_irqsave(&(tbl->it_lock), flags);
415 419
420 sg = sglist;
416 while (nelems--) { 421 while (nelems--) {
417 unsigned int npages; 422 unsigned int npages;
418 dma_addr_t dma_handle = sglist->dma_address; 423 dma_addr_t dma_handle = sg->dma_address;
419 424
420 if (sglist->dma_length == 0) 425 if (sg->dma_length == 0)
421 break; 426 break;
422 npages = iommu_num_pages(dma_handle,sglist->dma_length); 427 npages = iommu_num_pages(dma_handle, sg->dma_length);
423 __iommu_free(tbl, dma_handle, npages); 428 __iommu_free(tbl, dma_handle, npages);
424 sglist++; 429 sg = sg_next(sg);
425 } 430 }
426 431
427 /* Flush/invalidate TLBs if necessary. As for iommu_free(), we 432 /* Flush/invalidate TLBs if necessary. As for iommu_free(), we
diff --git a/arch/powerpc/kernel/kprobes.c b/arch/powerpc/kernel/kprobes.c
index 440f5a87271f..5338e4855712 100644
--- a/arch/powerpc/kernel/kprobes.c
+++ b/arch/powerpc/kernel/kprobes.c
@@ -38,6 +38,8 @@
38DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 38DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
39DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 39DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
40 40
41struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
42
41int __kprobes arch_prepare_kprobe(struct kprobe *p) 43int __kprobes arch_prepare_kprobe(struct kprobe *p)
42{ 44{
43 int ret = 0; 45 int ret = 0;
diff --git a/arch/powerpc/kernel/ptrace.c b/arch/powerpc/kernel/ptrace.c
index cf7732cdd6c7..3e17d154d0d4 100644
--- a/arch/powerpc/kernel/ptrace.c
+++ b/arch/powerpc/kernel/ptrace.c
@@ -505,10 +505,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
505 ret = ptrace_set_debugreg(child, addr, data); 505 ret = ptrace_set_debugreg(child, addr, data);
506 break; 506 break;
507 507
508 case PTRACE_DETACH:
509 ret = ptrace_detach(child, data);
510 break;
511
512#ifdef CONFIG_PPC64 508#ifdef CONFIG_PPC64
513 case PTRACE_GETREGS64: 509 case PTRACE_GETREGS64:
514#endif 510#endif
diff --git a/arch/powerpc/kernel/setup-common.c b/arch/powerpc/kernel/setup-common.c
index 36c90ba2d312..2de00f870edc 100644
--- a/arch/powerpc/kernel/setup-common.c
+++ b/arch/powerpc/kernel/setup-common.c
@@ -413,16 +413,28 @@ void __init smp_setup_cpu_maps(void)
413 of_node_put(dn); 413 of_node_put(dn);
414 } 414 }
415 415
416 vdso_data->processorCount = num_present_cpus();
417#endif /* CONFIG_PPC64 */
418}
419
420/*
421 * Being that cpu_sibling_map is now a per_cpu array, then it cannot
422 * be initialized until the per_cpu areas have been created. This
423 * function is now called from setup_per_cpu_areas().
424 */
425void __init smp_setup_cpu_sibling_map(void)
426{
427#if defined(CONFIG_PPC64)
428 int cpu;
429
416 /* 430 /*
417 * Do the sibling map; assume only two threads per processor. 431 * Do the sibling map; assume only two threads per processor.
418 */ 432 */
419 for_each_possible_cpu(cpu) { 433 for_each_possible_cpu(cpu) {
420 cpu_set(cpu, cpu_sibling_map[cpu]); 434 cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
421 if (cpu_has_feature(CPU_FTR_SMT)) 435 if (cpu_has_feature(CPU_FTR_SMT))
422 cpu_set(cpu ^ 0x1, cpu_sibling_map[cpu]); 436 cpu_set(cpu ^ 0x1, per_cpu(cpu_sibling_map, cpu));
423 } 437 }
424
425 vdso_data->processorCount = num_present_cpus();
426#endif /* CONFIG_PPC64 */ 438#endif /* CONFIG_PPC64 */
427} 439}
428#endif /* CONFIG_SMP */ 440#endif /* CONFIG_SMP */
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 008ab6823b02..0e014550b83f 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -597,6 +597,9 @@ void __init setup_per_cpu_areas(void)
597 paca[i].data_offset = ptr - __per_cpu_start; 597 paca[i].data_offset = ptr - __per_cpu_start;
598 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start); 598 memcpy(ptr, __per_cpu_start, __per_cpu_end - __per_cpu_start);
599 } 599 }
600
601 /* Now that per_cpu is setup, initialize cpu_sibling_map */
602 smp_setup_cpu_sibling_map();
600} 603}
601#endif 604#endif
602 605
diff --git a/arch/powerpc/kernel/smp.c b/arch/powerpc/kernel/smp.c
index d30f08fa0297..338950aeb6f6 100644
--- a/arch/powerpc/kernel/smp.c
+++ b/arch/powerpc/kernel/smp.c
@@ -61,11 +61,11 @@ struct thread_info *secondary_ti;
61 61
62cpumask_t cpu_possible_map = CPU_MASK_NONE; 62cpumask_t cpu_possible_map = CPU_MASK_NONE;
63cpumask_t cpu_online_map = CPU_MASK_NONE; 63cpumask_t cpu_online_map = CPU_MASK_NONE;
64cpumask_t cpu_sibling_map[NR_CPUS] = { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; 64DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
65 65
66EXPORT_SYMBOL(cpu_online_map); 66EXPORT_SYMBOL(cpu_online_map);
67EXPORT_SYMBOL(cpu_possible_map); 67EXPORT_SYMBOL(cpu_possible_map);
68EXPORT_SYMBOL(cpu_sibling_map); 68EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
69 69
70/* SMP operations for this machine */ 70/* SMP operations for this machine */
71struct smp_ops_t *smp_ops; 71struct smp_ops_t *smp_ops;
diff --git a/arch/powerpc/kernel/vdso32/vdso32.lds.S b/arch/powerpc/kernel/vdso32/vdso32.lds.S
index 26e138c4ce17..9352ab5200e5 100644
--- a/arch/powerpc/kernel/vdso32/vdso32.lds.S
+++ b/arch/powerpc/kernel/vdso32/vdso32.lds.S
@@ -1,130 +1,147 @@
1
2/* 1/*
3 * This is the infamous ld script for the 32 bits vdso 2 * This is the infamous ld script for the 32 bits vdso
4 * library 3 * library
5 */ 4 */
6#include <asm/vdso.h> 5#include <asm/vdso.h>
7 6
8/* Default link addresses for the vDSOs */
9OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc") 7OUTPUT_FORMAT("elf32-powerpc", "elf32-powerpc", "elf32-powerpc")
10OUTPUT_ARCH(powerpc:common) 8OUTPUT_ARCH(powerpc:common)
11ENTRY(_start) 9ENTRY(_start)
12 10
13SECTIONS 11SECTIONS
14{ 12{
15 . = VDSO32_LBASE + SIZEOF_HEADERS; 13 . = VDSO32_LBASE + SIZEOF_HEADERS;
16 .hash : { *(.hash) } :text 14
17 .gnu.hash : { *(.gnu.hash) } 15 .hash : { *(.hash) } :text
18 .dynsym : { *(.dynsym) } 16 .gnu.hash : { *(.gnu.hash) }
19 .dynstr : { *(.dynstr) } 17 .dynsym : { *(.dynsym) }
20 .gnu.version : { *(.gnu.version) } 18 .dynstr : { *(.dynstr) }
21 .gnu.version_d : { *(.gnu.version_d) } 19 .gnu.version : { *(.gnu.version) }
22 .gnu.version_r : { *(.gnu.version_r) } 20 .gnu.version_d : { *(.gnu.version_d) }
23 21 .gnu.version_r : { *(.gnu.version_r) }
24 .note : { *(.note.*) } :text :note 22
25 23 .note : { *(.note.*) } :text :note
26 . = ALIGN (16); 24
27 .text : 25 . = ALIGN(16);
28 { 26 .text : {
29 *(.text .stub .text.* .gnu.linkonce.t.*) 27 *(.text .stub .text.* .gnu.linkonce.t.*)
30 } 28 }
31 PROVIDE (__etext = .); 29 PROVIDE(__etext = .);
32 PROVIDE (_etext = .); 30 PROVIDE(_etext = .);
33 PROVIDE (etext = .); 31 PROVIDE(etext = .);
34 32
35 . = ALIGN(8); 33 . = ALIGN(8);
36 __ftr_fixup : { 34 __ftr_fixup : { *(__ftr_fixup) }
37 *(__ftr_fixup)
38 }
39 35
40#ifdef CONFIG_PPC64 36#ifdef CONFIG_PPC64
41 . = ALIGN(8); 37 . = ALIGN(8);
42 __fw_ftr_fixup : { 38 __fw_ftr_fixup : { *(__fw_ftr_fixup) }
43 *(__fw_ftr_fixup)
44 }
45#endif 39#endif
46 40
47 /* Other stuff is appended to the text segment: */ 41 /*
48 .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } 42 * Other stuff is appended to the text segment:
49 .rodata1 : { *(.rodata1) } 43 */
50 44 .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
51 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr 45 .rodata1 : { *(.rodata1) }
52 .eh_frame : { KEEP (*(.eh_frame)) } :text 46
53 .gcc_except_table : { *(.gcc_except_table) } 47 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
54 .fixup : { *(.fixup) } 48 .eh_frame : { KEEP (*(.eh_frame)) } :text
55 49 .gcc_except_table : { *(.gcc_except_table) }
56 .dynamic : { *(.dynamic) } :text :dynamic 50 .fixup : { *(.fixup) }
57 .got : { *(.got) } 51
58 .plt : { *(.plt) } 52 .dynamic : { *(.dynamic) } :text :dynamic
59 53 .got : { *(.got) }
60 _end = .; 54 .plt : { *(.plt) }
61 __end = .; 55
62 PROVIDE (end = .); 56 _end = .;
63 57 __end = .;
64 58 PROVIDE(end = .);
65 /* Stabs debugging sections are here too 59
66 */ 60 /*
67 .stab 0 : { *(.stab) } 61 * Stabs debugging sections are here too.
68 .stabstr 0 : { *(.stabstr) } 62 */
69 .stab.excl 0 : { *(.stab.excl) } 63 .stab 0 : { *(.stab) }
70 .stab.exclstr 0 : { *(.stab.exclstr) } 64 .stabstr 0 : { *(.stabstr) }
71 .stab.index 0 : { *(.stab.index) } 65 .stab.excl 0 : { *(.stab.excl) }
72 .stab.indexstr 0 : { *(.stab.indexstr) } 66 .stab.exclstr 0 : { *(.stab.exclstr) }
73 .comment 0 : { *(.comment) } 67 .stab.index 0 : { *(.stab.index) }
74 .debug 0 : { *(.debug) } 68 .stab.indexstr 0 : { *(.stab.indexstr) }
75 .line 0 : { *(.line) } 69 .comment 0 : { *(.comment) }
76 70
77 .debug_srcinfo 0 : { *(.debug_srcinfo) } 71 /*
78 .debug_sfnames 0 : { *(.debug_sfnames) } 72 * DWARF debug sections.
79 73 * Symbols in the DWARF debugging sections are relative to the beginning
80 .debug_aranges 0 : { *(.debug_aranges) } 74 * of the section so we begin them at 0.
81 .debug_pubnames 0 : { *(.debug_pubnames) } 75 */
82 76 /* DWARF 1 */
83 .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 77 .debug 0 : { *(.debug) }
84 .debug_abbrev 0 : { *(.debug_abbrev) } 78 .line 0 : { *(.line) }
85 .debug_line 0 : { *(.debug_line) } 79 /* GNU DWARF 1 extensions */
86 .debug_frame 0 : { *(.debug_frame) } 80 .debug_srcinfo 0 : { *(.debug_srcinfo) }
87 .debug_str 0 : { *(.debug_str) } 81 .debug_sfnames 0 : { *(.debug_sfnames) }
88 .debug_loc 0 : { *(.debug_loc) } 82 /* DWARF 1.1 and DWARF 2 */
89 .debug_macinfo 0 : { *(.debug_macinfo) } 83 .debug_aranges 0 : { *(.debug_aranges) }
90 84 .debug_pubnames 0 : { *(.debug_pubnames) }
91 .debug_weaknames 0 : { *(.debug_weaknames) } 85 /* DWARF 2 */
92 .debug_funcnames 0 : { *(.debug_funcnames) } 86 .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
93 .debug_typenames 0 : { *(.debug_typenames) } 87 .debug_abbrev 0 : { *(.debug_abbrev) }
94 .debug_varnames 0 : { *(.debug_varnames) } 88 .debug_line 0 : { *(.debug_line) }
95 89 .debug_frame 0 : { *(.debug_frame) }
96 /DISCARD/ : { *(.note.GNU-stack) } 90 .debug_str 0 : { *(.debug_str) }
97 /DISCARD/ : { *(.data .data.* .gnu.linkonce.d.* .sdata*) } 91 .debug_loc 0 : { *(.debug_loc) }
98 /DISCARD/ : { *(.bss .sbss .dynbss .dynsbss) } 92 .debug_macinfo 0 : { *(.debug_macinfo) }
93 /* SGI/MIPS DWARF 2 extensions */
94 .debug_weaknames 0 : { *(.debug_weaknames) }
95 .debug_funcnames 0 : { *(.debug_funcnames) }
96 .debug_typenames 0 : { *(.debug_typenames) }
97 .debug_varnames 0 : { *(.debug_varnames) }
98
99 /DISCARD/ : {
100 *(.note.GNU-stack)
101 *(.data .data.* .gnu.linkonce.d.* .sdata*)
102 *(.bss .sbss .dynbss .dynsbss)
103 }
99} 104}
100 105
106/*
107 * Very old versions of ld do not recognize this name token; use the constant.
108 */
109#define PT_GNU_EH_FRAME 0x6474e550
101 110
111/*
112 * We must supply the ELF program headers explicitly to get just one
113 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
114 */
102PHDRS 115PHDRS
103{ 116{
104 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ 117 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
105 note PT_NOTE FLAGS(4); /* PF_R */ 118 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
106 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ 119 note PT_NOTE FLAGS(4); /* PF_R */
107 eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ 120 eh_frame_hdr PT_GNU_EH_FRAME;
108} 121}
109 122
110
111/* 123/*
112 * This controls what symbols we export from the DSO. 124 * This controls what symbols we export from the DSO.
113 */ 125 */
114VERSION 126VERSION
115{ 127{
116 VDSO_VERSION_STRING { 128 VDSO_VERSION_STRING {
117 global: 129 global:
118 __kernel_datapage_offset; /* Has to be there for the kernel to find */ 130 /*
119 __kernel_get_syscall_map; 131 * Has to be there for the kernel to find
120 __kernel_gettimeofday; 132 */
121 __kernel_clock_gettime; 133 __kernel_datapage_offset;
122 __kernel_clock_getres; 134
123 __kernel_get_tbfreq; 135 __kernel_get_syscall_map;
124 __kernel_sync_dicache; 136 __kernel_gettimeofday;
125 __kernel_sync_dicache_p5; 137 __kernel_clock_gettime;
126 __kernel_sigtramp32; 138 __kernel_clock_getres;
127 __kernel_sigtramp_rt32; 139 __kernel_get_tbfreq;
128 local: *; 140 __kernel_sync_dicache;
129 }; 141 __kernel_sync_dicache_p5;
142 __kernel_sigtramp32;
143 __kernel_sigtramp_rt32;
144
145 local: *;
146 };
130} 147}
diff --git a/arch/powerpc/kernel/vdso64/vdso64.lds.S b/arch/powerpc/kernel/vdso64/vdso64.lds.S
index 2d70f35d50b5..932b3fdb34b9 100644
--- a/arch/powerpc/kernel/vdso64/vdso64.lds.S
+++ b/arch/powerpc/kernel/vdso64/vdso64.lds.S
@@ -10,100 +10,114 @@ ENTRY(_start)
10 10
11SECTIONS 11SECTIONS
12{ 12{
13 . = VDSO64_LBASE + SIZEOF_HEADERS; 13 . = VDSO64_LBASE + SIZEOF_HEADERS;
14 .hash : { *(.hash) } :text 14
15 .gnu.hash : { *(.gnu.hash) } 15 .hash : { *(.hash) } :text
16 .dynsym : { *(.dynsym) } 16 .gnu.hash : { *(.gnu.hash) }
17 .dynstr : { *(.dynstr) } 17 .dynsym : { *(.dynsym) }
18 .gnu.version : { *(.gnu.version) } 18 .dynstr : { *(.dynstr) }
19 .gnu.version_d : { *(.gnu.version_d) } 19 .gnu.version : { *(.gnu.version) }
20 .gnu.version_r : { *(.gnu.version_r) } 20 .gnu.version_d : { *(.gnu.version_d) }
21 21 .gnu.version_r : { *(.gnu.version_r) }
22 .note : { *(.note.*) } :text :note 22
23 23 .note : { *(.note.*) } :text :note
24 . = ALIGN (16); 24
25 .text : 25 . = ALIGN(16);
26 { 26 .text : {
27 *(.text .stub .text.* .gnu.linkonce.t.*) 27 *(.text .stub .text.* .gnu.linkonce.t.*)
28 *(.sfpr .glink) 28 *(.sfpr .glink)
29 } :text 29 } :text
30 PROVIDE (__etext = .); 30 PROVIDE(__etext = .);
31 PROVIDE (_etext = .); 31 PROVIDE(_etext = .);
32 PROVIDE (etext = .); 32 PROVIDE(etext = .);
33 33
34 . = ALIGN(8); 34 . = ALIGN(8);
35 __ftr_fixup : { 35 __ftr_fixup : { *(__ftr_fixup) }
36 *(__ftr_fixup) 36
37 } 37 . = ALIGN(8);
38 38 __fw_ftr_fixup : { *(__fw_ftr_fixup) }
39 . = ALIGN(8); 39
40 __fw_ftr_fixup : { 40 /*
41 *(__fw_ftr_fixup) 41 * Other stuff is appended to the text segment:
42 } 42 */
43 43 .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) }
44 /* Other stuff is appended to the text segment: */ 44 .rodata1 : { *(.rodata1) }
45 .rodata : { *(.rodata .rodata.* .gnu.linkonce.r.*) } 45
46 .rodata1 : { *(.rodata1) } 46 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr
47 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr 47 .eh_frame : { KEEP (*(.eh_frame)) } :text
48 .eh_frame : { KEEP (*(.eh_frame)) } :text 48 .gcc_except_table : { *(.gcc_except_table) }
49 .gcc_except_table : { *(.gcc_except_table) } 49
50 50 .opd ALIGN(8) : { KEEP (*(.opd)) }
51 .opd ALIGN(8) : { KEEP (*(.opd)) } 51 .got ALIGN(8) : { *(.got .toc) }
52 .got ALIGN(8) : { *(.got .toc) } 52 .rela.dyn ALIGN(8) : { *(.rela.dyn) }
53 .rela.dyn ALIGN(8) : { *(.rela.dyn) } 53
54 54 .dynamic : { *(.dynamic) } :text :dynamic
55 .dynamic : { *(.dynamic) } :text :dynamic 55
56 56 _end = .;
57 _end = .; 57 PROVIDE(end = .);
58 PROVIDE (end = .); 58
59 59 /*
60 /* Stabs debugging sections are here too 60 * Stabs debugging sections are here too.
61 */ 61 */
62 .stab 0 : { *(.stab) } 62 .stab 0 : { *(.stab) }
63 .stabstr 0 : { *(.stabstr) } 63 .stabstr 0 : { *(.stabstr) }
64 .stab.excl 0 : { *(.stab.excl) } 64 .stab.excl 0 : { *(.stab.excl) }
65 .stab.exclstr 0 : { *(.stab.exclstr) } 65 .stab.exclstr 0 : { *(.stab.exclstr) }
66 .stab.index 0 : { *(.stab.index) } 66 .stab.index 0 : { *(.stab.index) }
67 .stab.indexstr 0 : { *(.stab.indexstr) } 67 .stab.indexstr 0 : { *(.stab.indexstr) }
68 .comment 0 : { *(.comment) } 68 .comment 0 : { *(.comment) }
69 /* DWARF debug sectio/ns. 69
70 Symbols in the DWARF debugging sections are relative to the beginning 70 /*
71 of the section so we begin them at 0. */ 71 * DWARF debug sections.
72 /* DWARF 1 */ 72 * Symbols in the DWARF debugging sections are relative to the beginning
73 .debug 0 : { *(.debug) } 73 * of the section so we begin them at 0.
74 .line 0 : { *(.line) } 74 */
75 /* GNU DWARF 1 extensions */ 75 /* DWARF 1 */
76 .debug_srcinfo 0 : { *(.debug_srcinfo) } 76 .debug 0 : { *(.debug) }
77 .debug_sfnames 0 : { *(.debug_sfnames) } 77 .line 0 : { *(.line) }
78 /* DWARF 1.1 and DWARF 2 */ 78 /* GNU DWARF 1 extensions */
79 .debug_aranges 0 : { *(.debug_aranges) } 79 .debug_srcinfo 0 : { *(.debug_srcinfo) }
80 .debug_pubnames 0 : { *(.debug_pubnames) } 80 .debug_sfnames 0 : { *(.debug_sfnames) }
81 /* DWARF 2 */ 81 /* DWARF 1.1 and DWARF 2 */
82 .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) } 82 .debug_aranges 0 : { *(.debug_aranges) }
83 .debug_abbrev 0 : { *(.debug_abbrev) } 83 .debug_pubnames 0 : { *(.debug_pubnames) }
84 .debug_line 0 : { *(.debug_line) } 84 /* DWARF 2 */
85 .debug_frame 0 : { *(.debug_frame) } 85 .debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
86 .debug_str 0 : { *(.debug_str) } 86 .debug_abbrev 0 : { *(.debug_abbrev) }
87 .debug_loc 0 : { *(.debug_loc) } 87 .debug_line 0 : { *(.debug_line) }
88 .debug_macinfo 0 : { *(.debug_macinfo) } 88 .debug_frame 0 : { *(.debug_frame) }
89 /* SGI/MIPS DWARF 2 extensions */ 89 .debug_str 0 : { *(.debug_str) }
90 .debug_weaknames 0 : { *(.debug_weaknames) } 90 .debug_loc 0 : { *(.debug_loc) }
91 .debug_funcnames 0 : { *(.debug_funcnames) } 91 .debug_macinfo 0 : { *(.debug_macinfo) }
92 .debug_typenames 0 : { *(.debug_typenames) } 92 /* SGI/MIPS DWARF 2 extensions */
93 .debug_varnames 0 : { *(.debug_varnames) } 93 .debug_weaknames 0 : { *(.debug_weaknames) }
94 94 .debug_funcnames 0 : { *(.debug_funcnames) }
95 /DISCARD/ : { *(.note.GNU-stack) } 95 .debug_typenames 0 : { *(.debug_typenames) }
96 /DISCARD/ : { *(.branch_lt) } 96 .debug_varnames 0 : { *(.debug_varnames) }
97 /DISCARD/ : { *(.data .data.* .gnu.linkonce.d.*) } 97
98 /DISCARD/ : { *(.bss .sbss .dynbss .dynsbss) } 98 /DISCARD/ : {
99 *(.note.GNU-stack)
100 *(.branch_lt)
101 *(.data .data.* .gnu.linkonce.d.* .sdata*)
102 *(.bss .sbss .dynbss .dynsbss)
103 }
99} 104}
100 105
106/*
107 * Very old versions of ld do not recognize this name token; use the constant.
108 */
109#define PT_GNU_EH_FRAME 0x6474e550
110
111/*
112 * We must supply the ELF program headers explicitly to get just one
113 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
114 */
101PHDRS 115PHDRS
102{ 116{
103 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ 117 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
104 note PT_NOTE FLAGS(4); /* PF_R */ 118 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
105 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ 119 note PT_NOTE FLAGS(4); /* PF_R */
106 eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ 120 eh_frame_hdr PT_GNU_EH_FRAME;
107} 121}
108 122
109/* 123/*
@@ -111,17 +125,22 @@ PHDRS
111 */ 125 */
112VERSION 126VERSION
113{ 127{
114 VDSO_VERSION_STRING { 128 VDSO_VERSION_STRING {
115 global: 129 global:
116 __kernel_datapage_offset; /* Has to be there for the kernel to find */ 130 /*
117 __kernel_get_syscall_map; 131 * Has to be there for the kernel to find
118 __kernel_gettimeofday; 132 */
119 __kernel_clock_gettime; 133 __kernel_datapage_offset;
120 __kernel_clock_getres; 134
121 __kernel_get_tbfreq; 135 __kernel_get_syscall_map;
122 __kernel_sync_dicache; 136 __kernel_gettimeofday;
123 __kernel_sync_dicache_p5; 137 __kernel_clock_gettime;
124 __kernel_sigtramp_rt64; 138 __kernel_clock_getres;
125 local: *; 139 __kernel_get_tbfreq;
126 }; 140 __kernel_sync_dicache;
141 __kernel_sync_dicache_p5;
142 __kernel_sigtramp_rt64;
143
144 local: *;
145 };
127} 146}
diff --git a/arch/powerpc/mm/init_64.c b/arch/powerpc/mm/init_64.c
index fa90f6561b9f..29ed495444f5 100644
--- a/arch/powerpc/mm/init_64.c
+++ b/arch/powerpc/mm/init_64.c
@@ -183,3 +183,70 @@ void pgtable_cache_init(void)
183 zero_ctor); 183 zero_ctor);
184 } 184 }
185} 185}
186
187#ifdef CONFIG_SPARSEMEM_VMEMMAP
188/*
189 * Given an address within the vmemmap, determine the pfn of the page that
190 * represents the start of the section it is within. Note that we have to
191 * do this by hand as the proffered address may not be correctly aligned.
192 * Subtraction of non-aligned pointers produces undefined results.
193 */
194unsigned long __meminit vmemmap_section_start(unsigned long page)
195{
196 unsigned long offset = page - ((unsigned long)(vmemmap));
197
198 /* Return the pfn of the start of the section. */
199 return (offset / sizeof(struct page)) & PAGE_SECTION_MASK;
200}
201
202/*
203 * Check if this vmemmap page is already initialised. If any section
204 * which overlaps this vmemmap page is initialised then this page is
205 * initialised already.
206 */
207int __meminit vmemmap_populated(unsigned long start, int page_size)
208{
209 unsigned long end = start + page_size;
210
211 for (; start < end; start += (PAGES_PER_SECTION * sizeof(struct page)))
212 if (pfn_valid(vmemmap_section_start(start)))
213 return 1;
214
215 return 0;
216}
217
218int __meminit vmemmap_populate(struct page *start_page,
219 unsigned long nr_pages, int node)
220{
221 unsigned long mode_rw;
222 unsigned long start = (unsigned long)start_page;
223 unsigned long end = (unsigned long)(start_page + nr_pages);
224 unsigned long page_size = 1 << mmu_psize_defs[mmu_linear_psize].shift;
225
226 mode_rw = _PAGE_ACCESSED | _PAGE_DIRTY | _PAGE_COHERENT | PP_RWXX;
227
228 /* Align to the page size of the linear mapping. */
229 start = _ALIGN_DOWN(start, page_size);
230
231 for (; start < end; start += page_size) {
232 int mapped;
233 void *p;
234
235 if (vmemmap_populated(start, page_size))
236 continue;
237
238 p = vmemmap_alloc_block(page_size, node);
239 if (!p)
240 return -ENOMEM;
241
242 printk(KERN_WARNING "vmemmap %08lx allocated at %p, "
243 "physical %p.\n", start, p, __pa(p));
244
245 mapped = htab_bolt_mapping(start, start + page_size,
246 __pa(p), mode_rw, mmu_linear_psize);
247 BUG_ON(mapped < 0);
248 }
249
250 return 0;
251}
252#endif
diff --git a/arch/powerpc/mm/mem.c b/arch/powerpc/mm/mem.c
index 32dcfc9b0082..81eb96ec13b2 100644
--- a/arch/powerpc/mm/mem.c
+++ b/arch/powerpc/mm/mem.c
@@ -129,51 +129,6 @@ int __devinit arch_add_memory(int nid, u64 start, u64 size)
129 return __add_pages(zone, start_pfn, nr_pages); 129 return __add_pages(zone, start_pfn, nr_pages);
130} 130}
131 131
132/*
133 * First pass at this code will check to determine if the remove
134 * request is within the RMO. Do not allow removal within the RMO.
135 */
136int __devinit remove_memory(u64 start, u64 size)
137{
138 struct zone *zone;
139 unsigned long start_pfn, end_pfn, nr_pages;
140
141 start_pfn = start >> PAGE_SHIFT;
142 nr_pages = size >> PAGE_SHIFT;
143 end_pfn = start_pfn + nr_pages;
144
145 printk("%s(): Attempting to remove memoy in range "
146 "%lx to %lx\n", __func__, start, start+size);
147 /*
148 * check for range within RMO
149 */
150 zone = page_zone(pfn_to_page(start_pfn));
151
152 printk("%s(): memory will be removed from "
153 "the %s zone\n", __func__, zone->name);
154
155 /*
156 * not handling removing memory ranges that
157 * overlap multiple zones yet
158 */
159 if (end_pfn > (zone->zone_start_pfn + zone->spanned_pages))
160 goto overlap;
161
162 /* make sure it is NOT in RMO */
163 if ((start < lmb.rmo_size) || ((start+size) < lmb.rmo_size)) {
164 printk("%s(): range to be removed must NOT be in RMO!\n",
165 __func__);
166 goto in_rmo;
167 }
168
169 return __remove_pages(zone, start_pfn, nr_pages);
170
171overlap:
172 printk("%s(): memory range to be removed overlaps "
173 "multiple zones!!!\n", __func__);
174in_rmo:
175 return -1;
176}
177#endif /* CONFIG_MEMORY_HOTPLUG */ 132#endif /* CONFIG_MEMORY_HOTPLUG */
178 133
179void show_mem(void) 134void show_mem(void)
diff --git a/arch/powerpc/platforms/cell/cbe_cpufreq.c b/arch/powerpc/platforms/cell/cbe_cpufreq.c
index 5123e9d4164b..13d5a87f13b1 100644
--- a/arch/powerpc/platforms/cell/cbe_cpufreq.c
+++ b/arch/powerpc/platforms/cell/cbe_cpufreq.c
@@ -117,7 +117,7 @@ static int cbe_cpufreq_cpu_init(struct cpufreq_policy *policy)
117 policy->cur = cbe_freqs[cur_pmode].frequency; 117 policy->cur = cbe_freqs[cur_pmode].frequency;
118 118
119#ifdef CONFIG_SMP 119#ifdef CONFIG_SMP
120 policy->cpus = cpu_sibling_map[policy->cpu]; 120 policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
121#endif 121#endif
122 122
123 cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu); 123 cpufreq_frequency_table_get_attr(cbe_freqs, policy->cpu);
diff --git a/arch/powerpc/platforms/ps3/system-bus.c b/arch/powerpc/platforms/ps3/system-bus.c
index 190ff4b59a55..07e64b48e7fc 100644
--- a/arch/powerpc/platforms/ps3/system-bus.c
+++ b/arch/powerpc/platforms/ps3/system-bus.c
@@ -616,17 +616,18 @@ static void ps3_unmap_single(struct device *_dev, dma_addr_t dma_addr,
616 } 616 }
617} 617}
618 618
619static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sg, int nents, 619static int ps3_sb_map_sg(struct device *_dev, struct scatterlist *sgl,
620 enum dma_data_direction direction) 620 int nents, enum dma_data_direction direction)
621{ 621{
622#if defined(CONFIG_PS3_DYNAMIC_DMA) 622#if defined(CONFIG_PS3_DYNAMIC_DMA)
623 BUG_ON("do"); 623 BUG_ON("do");
624 return -EPERM; 624 return -EPERM;
625#else 625#else
626 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev); 626 struct ps3_system_bus_device *dev = ps3_dev_to_system_bus_dev(_dev);
627 struct scatterlist *sg;
627 int i; 628 int i;
628 629
629 for (i = 0; i < nents; i++, sg++) { 630 for_each_sg(sgl, sg, nents, i) {
630 int result = ps3_dma_map(dev->d_region, 631 int result = ps3_dma_map(dev->d_region,
631 page_to_phys(sg->page) + sg->offset, sg->length, 632 page_to_phys(sg->page) + sg->offset, sg->length,
632 &sg->dma_address, 0); 633 &sg->dma_address, 0);
diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c
index b98244e277fb..94913ddcf76e 100644
--- a/arch/ppc/mm/fault.c
+++ b/arch/ppc/mm/fault.c
@@ -297,7 +297,7 @@ out_of_memory:
297 } 297 }
298 printk("VM: killing process %s\n", current->comm); 298 printk("VM: killing process %s\n", current->comm);
299 if (user_mode(regs)) 299 if (user_mode(regs))
300 do_exit(SIGKILL); 300 do_group_exit(SIGKILL);
301 return SIGKILL; 301 return SIGKILL;
302 302
303do_sigbus: 303do_sigbus:
diff --git a/arch/s390/kernel/kprobes.c b/arch/s390/kernel/kprobes.c
index e40373d9fbce..c5549a206284 100644
--- a/arch/s390/kernel/kprobes.c
+++ b/arch/s390/kernel/kprobes.c
@@ -33,6 +33,8 @@
33DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 33DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
34DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 34DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
35 35
36struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
37
36int __kprobes arch_prepare_kprobe(struct kprobe *p) 38int __kprobes arch_prepare_kprobe(struct kprobe *p)
37{ 39{
38 /* Make sure the probe isn't going on a difficult instruction */ 40 /* Make sure the probe isn't going on a difficult instruction */
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index f4503ca27630..1d81bf9488ae 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -683,11 +683,6 @@ do_ptrace(struct task_struct *child, long request, long addr, long data)
683 wake_up_process(child); 683 wake_up_process(child);
684 return 0; 684 return 0;
685 685
686 case PTRACE_DETACH:
687 /* detach a process that was attached. */
688 return ptrace_detach(child, data);
689
690
691 /* Do requests that differ for 31/64 bit */ 686 /* Do requests that differ for 31/64 bit */
692 default: 687 default:
693#ifdef CONFIG_COMPAT 688#ifdef CONFIG_COMPAT
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 4c1ac341ec80..14c241ccdd4d 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -218,7 +218,7 @@ static int do_out_of_memory(struct pt_regs *regs, unsigned long error_code,
218 } 218 }
219 printk("VM: killing process %s\n", tsk->comm); 219 printk("VM: killing process %s\n", tsk->comm);
220 if (regs->psw.mask & PSW_MASK_PSTATE) 220 if (regs->psw.mask & PSW_MASK_PSTATE)
221 do_exit(SIGKILL); 221 do_group_exit(SIGKILL);
222 do_no_context(regs, error_code, address); 222 do_no_context(regs, error_code, address);
223 return 0; 223 return 0;
224} 224}
diff --git a/arch/sh/kernel/ptrace.c b/arch/sh/kernel/ptrace.c
index f64a2d2416d4..ac725f0aeb72 100644
--- a/arch/sh/kernel/ptrace.c
+++ b/arch/sh/kernel/ptrace.c
@@ -211,10 +211,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
211 break; 211 break;
212 } 212 }
213 213
214 case PTRACE_DETACH: /* detach a process that was attached. */
215 ret = ptrace_detach(child, data);
216 break;
217
218#ifdef CONFIG_SH_DSP 214#ifdef CONFIG_SH_DSP
219 case PTRACE_GETDSPREGS: { 215 case PTRACE_GETDSPREGS: {
220 unsigned long dp; 216 unsigned long dp;
diff --git a/arch/sh/kernel/vsyscall/vsyscall.lds.S b/arch/sh/kernel/vsyscall/vsyscall.lds.S
index b13c3d439fee..c9bf2af35d35 100644
--- a/arch/sh/kernel/vsyscall/vsyscall.lds.S
+++ b/arch/sh/kernel/vsyscall/vsyscall.lds.S
@@ -17,45 +17,52 @@ ENTRY(__kernel_vsyscall);
17 17
18SECTIONS 18SECTIONS
19{ 19{
20 . = SIZEOF_HEADERS; 20 . = SIZEOF_HEADERS;
21 21
22 .hash : { *(.hash) } :text 22 .hash : { *(.hash) } :text
23 .gnu.hash : { *(.gnu.hash) } 23 .gnu.hash : { *(.gnu.hash) }
24 .dynsym : { *(.dynsym) } 24 .dynsym : { *(.dynsym) }
25 .dynstr : { *(.dynstr) } 25 .dynstr : { *(.dynstr) }
26 .gnu.version : { *(.gnu.version) } 26 .gnu.version : { *(.gnu.version) }
27 .gnu.version_d : { *(.gnu.version_d) } 27 .gnu.version_d : { *(.gnu.version_d) }
28 .gnu.version_r : { *(.gnu.version_r) } 28 .gnu.version_r : { *(.gnu.version_r) }
29 29
30 /* This linker script is used both with -r and with -shared. 30 /*
31 For the layouts to match, we need to skip more than enough 31 * This linker script is used both with -r and with -shared.
32 space for the dynamic symbol table et al. If this amount 32 * For the layouts to match, we need to skip more than enough
33 is insufficient, ld -shared will barf. Just increase it here. */ 33 * space for the dynamic symbol table et al. If this amount
34 . = 0x400; 34 * is insufficient, ld -shared will barf. Just increase it here.
35 */
36 . = 0x400;
35 37
36 .text : { *(.text) } :text =0x90909090 38 .text : { *(.text) } :text =0x90909090
37 .note : { *(.note.*) } :text :note 39 .note : { *(.note.*) } :text :note
38 .eh_frame_hdr : { *(.eh_frame_hdr) } :text :eh_frame_hdr 40 .eh_frame_hdr : { *(.eh_frame_hdr ) } :text :eh_frame_hdr
39 .eh_frame : { KEEP (*(.eh_frame)) } :text 41 .eh_frame : { KEEP (*(.eh_frame)) } :text
40 .dynamic : { *(.dynamic) } :text :dynamic 42 .dynamic : { *(.dynamic) } :text :dynamic
41 .useless : { 43 .useless : {
42 *(.got.plt) *(.got) 44 *(.got.plt) *(.got)
43 *(.data .data.* .gnu.linkonce.d.*) 45 *(.data .data.* .gnu.linkonce.d.*)
44 *(.dynbss) 46 *(.dynbss)
45 *(.bss .bss.* .gnu.linkonce.b.*) 47 *(.bss .bss.* .gnu.linkonce.b.*)
46 } :text 48 } :text
47} 49}
48 50
49/* 51/*
52 * Very old versions of ld do not recognize this name token; use the constant.
53 */
54#define PT_GNU_EH_FRAME 0x6474e550
55
56/*
50 * We must supply the ELF program headers explicitly to get just one 57 * We must supply the ELF program headers explicitly to get just one
51 * PT_LOAD segment, and set the flags explicitly to make segments read-only. 58 * PT_LOAD segment, and set the flags explicitly to make segments read-only.
52 */ 59 */
53PHDRS 60PHDRS
54{ 61{
55 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */ 62 text PT_LOAD FILEHDR PHDRS FLAGS(5); /* PF_R|PF_X */
56 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */ 63 dynamic PT_DYNAMIC FLAGS(4); /* PF_R */
57 note PT_NOTE FLAGS(4); /* PF_R */ 64 note PT_NOTE FLAGS(4); /* PF_R */
58 eh_frame_hdr 0x6474e550; /* PT_GNU_EH_FRAME, but ld doesn't match the name */ 65 eh_frame_hdr PT_GNU_EH_FRAME;
59} 66}
60 67
61/* 68/*
@@ -63,12 +70,12 @@ PHDRS
63 */ 70 */
64VERSION 71VERSION
65{ 72{
66 LINUX_2.6 { 73 LINUX_2.6 {
67 global: 74 global:
68 __kernel_vsyscall; 75 __kernel_vsyscall;
69 __kernel_sigreturn; 76 __kernel_sigreturn;
70 __kernel_rt_sigreturn; 77 __kernel_rt_sigreturn;
71 78
72 local: *; 79 local: *;
73 }; 80 };
74} 81}
diff --git a/arch/sh/mm/fault.c b/arch/sh/mm/fault.c
index 04a39aa7f1f9..4729668ce5bf 100644
--- a/arch/sh/mm/fault.c
+++ b/arch/sh/mm/fault.c
@@ -214,7 +214,7 @@ out_of_memory:
214 } 214 }
215 printk("VM: killing process %s\n", tsk->comm); 215 printk("VM: killing process %s\n", tsk->comm);
216 if (user_mode(regs)) 216 if (user_mode(regs))
217 do_exit(SIGKILL); 217 do_group_exit(SIGKILL);
218 goto no_context; 218 goto no_context;
219 219
220do_sigbus: 220do_sigbus:
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index 82b68c789a5f..d5e160da64b2 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -294,12 +294,6 @@ int arch_add_memory(int nid, u64 start, u64 size)
294} 294}
295EXPORT_SYMBOL_GPL(arch_add_memory); 295EXPORT_SYMBOL_GPL(arch_add_memory);
296 296
297int remove_memory(u64 start, u64 size)
298{
299 return -EINVAL;
300}
301EXPORT_SYMBOL_GPL(remove_memory);
302
303#ifdef CONFIG_NUMA 297#ifdef CONFIG_NUMA
304int memory_add_physaddr_to_nid(u64 addr) 298int memory_add_physaddr_to_nid(u64 addr)
305{ 299{
diff --git a/arch/sh64/kernel/ptrace.c b/arch/sh64/kernel/ptrace.c
index df06c6477468..8a2d339cf760 100644
--- a/arch/sh64/kernel/ptrace.c
+++ b/arch/sh64/kernel/ptrace.c
@@ -244,10 +244,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
244 break; 244 break;
245 } 245 }
246 246
247 case PTRACE_DETACH: /* detach a process that was attached. */
248 ret = ptrace_detach(child, data);
249 break;
250
251 default: 247 default:
252 ret = ptrace_request(child, request, addr, data); 248 ret = ptrace_request(child, request, addr, data);
253 break; 249 break;
diff --git a/arch/sh64/mm/fault.c b/arch/sh64/mm/fault.c
index 0d069d82141f..dd81c669c79b 100644
--- a/arch/sh64/mm/fault.c
+++ b/arch/sh64/mm/fault.c
@@ -334,7 +334,7 @@ out_of_memory:
334 } 334 }
335 printk("VM: killing process %s\n", tsk->comm); 335 printk("VM: killing process %s\n", tsk->comm);
336 if (user_mode(regs)) 336 if (user_mode(regs))
337 do_exit(SIGKILL); 337 do_group_exit(SIGKILL);
338 goto no_context; 338 goto no_context;
339 339
340do_sigbus: 340do_sigbus:
diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c
index 62182d2d7b0d..9c3ed88853f3 100644
--- a/arch/sparc/kernel/ioport.c
+++ b/arch/sparc/kernel/ioport.c
@@ -35,6 +35,7 @@
35#include <linux/slab.h> 35#include <linux/slab.h>
36#include <linux/pci.h> /* struct pci_dev */ 36#include <linux/pci.h> /* struct pci_dev */
37#include <linux/proc_fs.h> 37#include <linux/proc_fs.h>
38#include <linux/scatterlist.h>
38 39
39#include <asm/io.h> 40#include <asm/io.h>
40#include <asm/vaddrs.h> 41#include <asm/vaddrs.h>
@@ -717,19 +718,19 @@ void pci_unmap_page(struct pci_dev *hwdev,
717 * Device ownership issues as mentioned above for pci_map_single are 718 * Device ownership issues as mentioned above for pci_map_single are
718 * the same here. 719 * the same here.
719 */ 720 */
720int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, 721int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
721 int direction) 722 int direction)
722{ 723{
724 struct scatterlist *sg;
723 int n; 725 int n;
724 726
725 BUG_ON(direction == PCI_DMA_NONE); 727 BUG_ON(direction == PCI_DMA_NONE);
726 /* IIep is write-through, not flushing. */ 728 /* IIep is write-through, not flushing. */
727 for (n = 0; n < nents; n++) { 729 for_each_sg(sgl, sg, nents, n) {
728 BUG_ON(page_address(sg->page) == NULL); 730 BUG_ON(page_address(sg->page) == NULL);
729 sg->dvma_address = 731 sg->dvma_address =
730 virt_to_phys(page_address(sg->page)) + sg->offset; 732 virt_to_phys(page_address(sg->page)) + sg->offset;
731 sg->dvma_length = sg->length; 733 sg->dvma_length = sg->length;
732 sg++;
733 } 734 }
734 return nents; 735 return nents;
735} 736}
@@ -738,19 +739,19 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents,
738 * Again, cpu read rules concerning calls here are the same as for 739 * Again, cpu read rules concerning calls here are the same as for
739 * pci_unmap_single() above. 740 * pci_unmap_single() above.
740 */ 741 */
741void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, 742void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sgl, int nents,
742 int direction) 743 int direction)
743{ 744{
745 struct scatterlist *sg;
744 int n; 746 int n;
745 747
746 BUG_ON(direction == PCI_DMA_NONE); 748 BUG_ON(direction == PCI_DMA_NONE);
747 if (direction != PCI_DMA_TODEVICE) { 749 if (direction != PCI_DMA_TODEVICE) {
748 for (n = 0; n < nents; n++) { 750 for_each_sg(sgl, sg, nents, n) {
749 BUG_ON(page_address(sg->page) == NULL); 751 BUG_ON(page_address(sg->page) == NULL);
750 mmu_inval_dma_area( 752 mmu_inval_dma_area(
751 (unsigned long) page_address(sg->page), 753 (unsigned long) page_address(sg->page),
752 (sg->length + PAGE_SIZE-1) & PAGE_MASK); 754 (sg->length + PAGE_SIZE-1) & PAGE_MASK);
753 sg++;
754 } 755 }
755 } 756 }
756} 757}
@@ -789,34 +790,34 @@ void pci_dma_sync_single_for_device(struct pci_dev *hwdev, dma_addr_t ba, size_t
789 * The same as pci_dma_sync_single_* but for a scatter-gather list, 790 * The same as pci_dma_sync_single_* but for a scatter-gather list,
790 * same rules and usage. 791 * same rules and usage.
791 */ 792 */
792void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) 793void pci_dma_sync_sg_for_cpu(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction)
793{ 794{
795 struct scatterlist *sg;
794 int n; 796 int n;
795 797
796 BUG_ON(direction == PCI_DMA_NONE); 798 BUG_ON(direction == PCI_DMA_NONE);
797 if (direction != PCI_DMA_TODEVICE) { 799 if (direction != PCI_DMA_TODEVICE) {
798 for (n = 0; n < nents; n++) { 800 for_each_sg(sgl, sg, nents, n) {
799 BUG_ON(page_address(sg->page) == NULL); 801 BUG_ON(page_address(sg->page) == NULL);
800 mmu_inval_dma_area( 802 mmu_inval_dma_area(
801 (unsigned long) page_address(sg->page), 803 (unsigned long) page_address(sg->page),
802 (sg->length + PAGE_SIZE-1) & PAGE_MASK); 804 (sg->length + PAGE_SIZE-1) & PAGE_MASK);
803 sg++;
804 } 805 }
805 } 806 }
806} 807}
807 808
808void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) 809void pci_dma_sync_sg_for_device(struct pci_dev *hwdev, struct scatterlist *sgl, int nents, int direction)
809{ 810{
811 struct scatterlist *sg;
810 int n; 812 int n;
811 813
812 BUG_ON(direction == PCI_DMA_NONE); 814 BUG_ON(direction == PCI_DMA_NONE);
813 if (direction != PCI_DMA_TODEVICE) { 815 if (direction != PCI_DMA_TODEVICE) {
814 for (n = 0; n < nents; n++) { 816 for_each_sg(sgl, sg, nents, n) {
815 BUG_ON(page_address(sg->page) == NULL); 817 BUG_ON(page_address(sg->page) == NULL);
816 mmu_inval_dma_area( 818 mmu_inval_dma_area(
817 (unsigned long) page_address(sg->page), 819 (unsigned long) page_address(sg->page),
818 (sg->length + PAGE_SIZE-1) & PAGE_MASK); 820 (sg->length + PAGE_SIZE-1) & PAGE_MASK);
819 sg++;
820 } 821 }
821 } 822 }
822} 823}
diff --git a/arch/sparc/mm/fault.c b/arch/sparc/mm/fault.c
index 50747fe44356..e4d9c8e19df5 100644
--- a/arch/sparc/mm/fault.c
+++ b/arch/sparc/mm/fault.c
@@ -369,7 +369,7 @@ out_of_memory:
369 up_read(&mm->mmap_sem); 369 up_read(&mm->mmap_sem);
370 printk("VM: killing process %s\n", tsk->comm); 370 printk("VM: killing process %s\n", tsk->comm);
371 if (from_user) 371 if (from_user)
372 do_exit(SIGKILL); 372 do_group_exit(SIGKILL);
373 goto no_context; 373 goto no_context;
374 374
375do_sigbus: 375do_sigbus:
diff --git a/arch/sparc/mm/io-unit.c b/arch/sparc/mm/io-unit.c
index 7c89893b1fe8..375b4db63704 100644
--- a/arch/sparc/mm/io-unit.c
+++ b/arch/sparc/mm/io-unit.c
@@ -11,8 +11,8 @@
11#include <linux/mm.h> 11#include <linux/mm.h>
12#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ 12#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */
13#include <linux/bitops.h> 13#include <linux/bitops.h>
14#include <linux/scatterlist.h>
14 15
15#include <asm/scatterlist.h>
16#include <asm/pgalloc.h> 16#include <asm/pgalloc.h>
17#include <asm/pgtable.h> 17#include <asm/pgtable.h>
18#include <asm/sbus.h> 18#include <asm/sbus.h>
@@ -144,8 +144,9 @@ static void iounit_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus
144 spin_lock_irqsave(&iounit->lock, flags); 144 spin_lock_irqsave(&iounit->lock, flags);
145 while (sz != 0) { 145 while (sz != 0) {
146 --sz; 146 --sz;
147 sg[sz].dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg[sz].page) + sg[sz].offset, sg[sz].length); 147 sg->dvma_address = iounit_get_area(iounit, (unsigned long)page_address(sg->page) + sg->offset, sg->length);
148 sg[sz].dvma_length = sg[sz].length; 148 sg->dvma_length = sg->length;
149 sg = sg_next(sg);
149 } 150 }
150 spin_unlock_irqrestore(&iounit->lock, flags); 151 spin_unlock_irqrestore(&iounit->lock, flags);
151} 152}
@@ -173,11 +174,12 @@ static void iounit_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_
173 spin_lock_irqsave(&iounit->lock, flags); 174 spin_lock_irqsave(&iounit->lock, flags);
174 while (sz != 0) { 175 while (sz != 0) {
175 --sz; 176 --sz;
176 len = ((sg[sz].dvma_address & ~PAGE_MASK) + sg[sz].length + (PAGE_SIZE-1)) >> PAGE_SHIFT; 177 len = ((sg->dvma_address & ~PAGE_MASK) + sg->length + (PAGE_SIZE-1)) >> PAGE_SHIFT;
177 vaddr = (sg[sz].dvma_address - IOUNIT_DMA_BASE) >> PAGE_SHIFT; 178 vaddr = (sg->dvma_address - IOUNIT_DMA_BASE) >> PAGE_SHIFT;
178 IOD(("iounit_release %08lx-%08lx\n", (long)vaddr, (long)len+vaddr)); 179 IOD(("iounit_release %08lx-%08lx\n", (long)vaddr, (long)len+vaddr));
179 for (len += vaddr; vaddr < len; vaddr++) 180 for (len += vaddr; vaddr < len; vaddr++)
180 clear_bit(vaddr, iounit->bmap); 181 clear_bit(vaddr, iounit->bmap);
182 sg = sg_next(sg);
181 } 183 }
182 spin_unlock_irqrestore(&iounit->lock, flags); 184 spin_unlock_irqrestore(&iounit->lock, flags);
183} 185}
diff --git a/arch/sparc/mm/iommu.c b/arch/sparc/mm/iommu.c
index 52e907af9d29..283656d9f6ea 100644
--- a/arch/sparc/mm/iommu.c
+++ b/arch/sparc/mm/iommu.c
@@ -12,8 +12,8 @@
12#include <linux/mm.h> 12#include <linux/mm.h>
13#include <linux/slab.h> 13#include <linux/slab.h>
14#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */ 14#include <linux/highmem.h> /* pte_offset_map => kmap_atomic */
15#include <linux/scatterlist.h>
15 16
16#include <asm/scatterlist.h>
17#include <asm/pgalloc.h> 17#include <asm/pgalloc.h>
18#include <asm/pgtable.h> 18#include <asm/pgtable.h>
19#include <asm/sbus.h> 19#include <asm/sbus.h>
@@ -240,7 +240,7 @@ static void iommu_get_scsi_sgl_noflush(struct scatterlist *sg, int sz, struct sb
240 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; 240 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
241 sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; 241 sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
242 sg->dvma_length = (__u32) sg->length; 242 sg->dvma_length = (__u32) sg->length;
243 sg++; 243 sg = sg_next(sg);
244 } 244 }
245} 245}
246 246
@@ -254,7 +254,7 @@ static void iommu_get_scsi_sgl_gflush(struct scatterlist *sg, int sz, struct sbu
254 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; 254 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
255 sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; 255 sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
256 sg->dvma_length = (__u32) sg->length; 256 sg->dvma_length = (__u32) sg->length;
257 sg++; 257 sg = sg_next(sg);
258 } 258 }
259} 259}
260 260
@@ -285,7 +285,7 @@ static void iommu_get_scsi_sgl_pflush(struct scatterlist *sg, int sz, struct sbu
285 285
286 sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset; 286 sg->dvma_address = iommu_get_one(sg->page, n, sbus) + sg->offset;
287 sg->dvma_length = (__u32) sg->length; 287 sg->dvma_length = (__u32) sg->length;
288 sg++; 288 sg = sg_next(sg);
289 } 289 }
290} 290}
291 291
@@ -325,7 +325,7 @@ static void iommu_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_b
325 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT; 325 n = (sg->length + sg->offset + PAGE_SIZE-1) >> PAGE_SHIFT;
326 iommu_release_one(sg->dvma_address & PAGE_MASK, n, sbus); 326 iommu_release_one(sg->dvma_address & PAGE_MASK, n, sbus);
327 sg->dvma_address = 0x21212121; 327 sg->dvma_address = 0x21212121;
328 sg++; 328 sg = sg_next(sg);
329 } 329 }
330} 330}
331 331
diff --git a/arch/sparc/mm/sun4c.c b/arch/sparc/mm/sun4c.c
index 005a3e72d4f2..ee6708fc4492 100644
--- a/arch/sparc/mm/sun4c.c
+++ b/arch/sparc/mm/sun4c.c
@@ -17,8 +17,8 @@
17#include <linux/highmem.h> 17#include <linux/highmem.h>
18#include <linux/fs.h> 18#include <linux/fs.h>
19#include <linux/seq_file.h> 19#include <linux/seq_file.h>
20#include <linux/scatterlist.h>
20 21
21#include <asm/scatterlist.h>
22#include <asm/page.h> 22#include <asm/page.h>
23#include <asm/pgalloc.h> 23#include <asm/pgalloc.h>
24#include <asm/pgtable.h> 24#include <asm/pgtable.h>
@@ -1228,8 +1228,9 @@ static void sun4c_get_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_bus *
1228{ 1228{
1229 while (sz != 0) { 1229 while (sz != 0) {
1230 --sz; 1230 --sz;
1231 sg[sz].dvma_address = (__u32)sun4c_lockarea(page_address(sg[sz].page) + sg[sz].offset, sg[sz].length); 1231 sg->dvma_address = (__u32)sun4c_lockarea(page_address(sg->page) + sg->offset, sg->length);
1232 sg[sz].dvma_length = sg[sz].length; 1232 sg->dvma_length = sg->length;
1233 sg = sg_next(sg);
1233 } 1234 }
1234} 1235}
1235 1236
@@ -1244,7 +1245,8 @@ static void sun4c_release_scsi_sgl(struct scatterlist *sg, int sz, struct sbus_b
1244{ 1245{
1245 while (sz != 0) { 1246 while (sz != 0) {
1246 --sz; 1247 --sz;
1247 sun4c_unlockarea((char *)sg[sz].dvma_address, sg[sz].length); 1248 sun4c_unlockarea((char *)sg->dvma_address, sg->length);
1249 sg = sg_next(sg);
1248 } 1250 }
1249} 1251}
1250 1252
diff --git a/arch/sparc64/Kconfig b/arch/sparc64/Kconfig
index 33dabf588bdd..2f22fa90461a 100644
--- a/arch/sparc64/Kconfig
+++ b/arch/sparc64/Kconfig
@@ -240,10 +240,10 @@ config ARCH_SELECT_MEMORY_MODEL
240 240
241config ARCH_SPARSEMEM_ENABLE 241config ARCH_SPARSEMEM_ENABLE
242 def_bool y 242 def_bool y
243 select SPARSEMEM_VMEMMAP_ENABLE
243 244
244config ARCH_SPARSEMEM_DEFAULT 245config ARCH_SPARSEMEM_DEFAULT
245 def_bool y 246 def_bool y
246 select SPARSEMEM_STATIC
247 247
248source "mm/Kconfig" 248source "mm/Kconfig"
249 249
diff --git a/arch/sparc64/kernel/iommu.c b/arch/sparc64/kernel/iommu.c
index b35a62167e9c..db3ffcf7a120 100644
--- a/arch/sparc64/kernel/iommu.c
+++ b/arch/sparc64/kernel/iommu.c
@@ -10,6 +10,7 @@
10#include <linux/device.h> 10#include <linux/device.h>
11#include <linux/dma-mapping.h> 11#include <linux/dma-mapping.h>
12#include <linux/errno.h> 12#include <linux/errno.h>
13#include <linux/scatterlist.h>
13 14
14#ifdef CONFIG_PCI 15#ifdef CONFIG_PCI
15#include <linux/pci.h> 16#include <linux/pci.h>
@@ -480,7 +481,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
480 unsigned long iopte_protection) 481 unsigned long iopte_protection)
481{ 482{
482 struct scatterlist *dma_sg = sg; 483 struct scatterlist *dma_sg = sg;
483 struct scatterlist *sg_end = sg + nelems; 484 struct scatterlist *sg_end = sg_last(sg, nelems);
484 int i; 485 int i;
485 486
486 for (i = 0; i < nused; i++) { 487 for (i = 0; i < nused; i++) {
@@ -515,7 +516,7 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
515 len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); 516 len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL)));
516 break; 517 break;
517 } 518 }
518 sg++; 519 sg = sg_next(sg);
519 } 520 }
520 521
521 pteval = iopte_protection | (pteval & IOPTE_PAGE); 522 pteval = iopte_protection | (pteval & IOPTE_PAGE);
@@ -528,24 +529,24 @@ static inline void fill_sg(iopte_t *iopte, struct scatterlist *sg,
528 } 529 }
529 530
530 pteval = (pteval & IOPTE_PAGE) + len; 531 pteval = (pteval & IOPTE_PAGE) + len;
531 sg++; 532 sg = sg_next(sg);
532 533
533 /* Skip over any tail mappings we've fully mapped, 534 /* Skip over any tail mappings we've fully mapped,
534 * adjusting pteval along the way. Stop when we 535 * adjusting pteval along the way. Stop when we
535 * detect a page crossing event. 536 * detect a page crossing event.
536 */ 537 */
537 while (sg < sg_end && 538 while (sg != sg_end &&
538 (pteval << (64 - IO_PAGE_SHIFT)) != 0UL && 539 (pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
539 (pteval == SG_ENT_PHYS_ADDRESS(sg)) && 540 (pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
540 ((pteval ^ 541 ((pteval ^
541 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { 542 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
542 pteval += sg->length; 543 pteval += sg->length;
543 sg++; 544 sg = sg_next(sg);
544 } 545 }
545 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) 546 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
546 pteval = ~0UL; 547 pteval = ~0UL;
547 } while (dma_npages != 0); 548 } while (dma_npages != 0);
548 dma_sg++; 549 dma_sg = sg_next(dma_sg);
549 } 550 }
550} 551}
551 552
@@ -606,7 +607,7 @@ static int dma_4u_map_sg(struct device *dev, struct scatterlist *sglist,
606 sgtmp = sglist; 607 sgtmp = sglist;
607 while (used && sgtmp->dma_length) { 608 while (used && sgtmp->dma_length) {
608 sgtmp->dma_address += dma_base; 609 sgtmp->dma_address += dma_base;
609 sgtmp++; 610 sgtmp = sg_next(sgtmp);
610 used--; 611 used--;
611 } 612 }
612 used = nelems - used; 613 used = nelems - used;
@@ -642,6 +643,7 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist,
642 struct strbuf *strbuf; 643 struct strbuf *strbuf;
643 iopte_t *base; 644 iopte_t *base;
644 unsigned long flags, ctx, i, npages; 645 unsigned long flags, ctx, i, npages;
646 struct scatterlist *sg, *sgprv;
645 u32 bus_addr; 647 u32 bus_addr;
646 648
647 if (unlikely(direction == DMA_NONE)) { 649 if (unlikely(direction == DMA_NONE)) {
@@ -654,11 +656,14 @@ static void dma_4u_unmap_sg(struct device *dev, struct scatterlist *sglist,
654 656
655 bus_addr = sglist->dma_address & IO_PAGE_MASK; 657 bus_addr = sglist->dma_address & IO_PAGE_MASK;
656 658
657 for (i = 1; i < nelems; i++) 659 sgprv = NULL;
658 if (sglist[i].dma_length == 0) 660 for_each_sg(sglist, sg, nelems, i) {
661 if (sg->dma_length == 0)
659 break; 662 break;
660 i--; 663 sgprv = sg;
661 npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - 664 }
665
666 npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) -
662 bus_addr) >> IO_PAGE_SHIFT; 667 bus_addr) >> IO_PAGE_SHIFT;
663 668
664 base = iommu->page_table + 669 base = iommu->page_table +
@@ -730,6 +735,7 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev,
730 struct iommu *iommu; 735 struct iommu *iommu;
731 struct strbuf *strbuf; 736 struct strbuf *strbuf;
732 unsigned long flags, ctx, npages, i; 737 unsigned long flags, ctx, npages, i;
738 struct scatterlist *sg, *sgprv;
733 u32 bus_addr; 739 u32 bus_addr;
734 740
735 iommu = dev->archdata.iommu; 741 iommu = dev->archdata.iommu;
@@ -753,11 +759,14 @@ static void dma_4u_sync_sg_for_cpu(struct device *dev,
753 759
754 /* Step 2: Kick data out of streaming buffers. */ 760 /* Step 2: Kick data out of streaming buffers. */
755 bus_addr = sglist[0].dma_address & IO_PAGE_MASK; 761 bus_addr = sglist[0].dma_address & IO_PAGE_MASK;
756 for(i = 1; i < nelems; i++) 762 sgprv = NULL;
757 if (!sglist[i].dma_length) 763 for_each_sg(sglist, sg, nelems, i) {
764 if (sg->dma_length == 0)
758 break; 765 break;
759 i--; 766 sgprv = sg;
760 npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) 767 }
768
769 npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length)
761 - bus_addr) >> IO_PAGE_SHIFT; 770 - bus_addr) >> IO_PAGE_SHIFT;
762 strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction); 771 strbuf_flush(strbuf, iommu, bus_addr, ctx, npages, direction);
763 772
diff --git a/arch/sparc64/kernel/kprobes.c b/arch/sparc64/kernel/kprobes.c
index c93a15b785fa..d94f901d321e 100644
--- a/arch/sparc64/kernel/kprobes.c
+++ b/arch/sparc64/kernel/kprobes.c
@@ -42,6 +42,8 @@
42DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 42DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
43DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 43DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
44 44
45struct kretprobe_blackpoint kretprobe_blacklist[] = {{NULL, NULL}};
46
45int __kprobes arch_prepare_kprobe(struct kprobe *p) 47int __kprobes arch_prepare_kprobe(struct kprobe *p)
46{ 48{
47 p->ainsn.insn[0] = *p->addr; 49 p->ainsn.insn[0] = *p->addr;
diff --git a/arch/sparc64/kernel/ktlb.S b/arch/sparc64/kernel/ktlb.S
index d4024ac0d619..964527d2ffa0 100644
--- a/arch/sparc64/kernel/ktlb.S
+++ b/arch/sparc64/kernel/ktlb.S
@@ -226,6 +226,15 @@ kvmap_dtlb_load:
226 ba,pt %xcc, sun4v_dtlb_load 226 ba,pt %xcc, sun4v_dtlb_load
227 mov %g5, %g3 227 mov %g5, %g3
228 228
229kvmap_vmemmap:
230 sub %g4, %g5, %g5
231 srlx %g5, 22, %g5
232 sethi %hi(vmemmap_table), %g1
233 sllx %g5, 3, %g5
234 or %g1, %lo(vmemmap_table), %g1
235 ba,pt %xcc, kvmap_dtlb_load
236 ldx [%g1 + %g5], %g5
237
229kvmap_dtlb_nonlinear: 238kvmap_dtlb_nonlinear:
230 /* Catch kernel NULL pointer derefs. */ 239 /* Catch kernel NULL pointer derefs. */
231 sethi %hi(PAGE_SIZE), %g5 240 sethi %hi(PAGE_SIZE), %g5
@@ -233,6 +242,13 @@ kvmap_dtlb_nonlinear:
233 bleu,pn %xcc, kvmap_dtlb_longpath 242 bleu,pn %xcc, kvmap_dtlb_longpath
234 nop 243 nop
235 244
245 /* Do not use the TSB for vmemmap. */
246 mov (VMEMMAP_BASE >> 24), %g5
247 sllx %g5, 24, %g5
248 cmp %g4,%g5
249 bgeu,pn %xcc, kvmap_vmemmap
250 nop
251
236 KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load) 252 KERN_TSB_LOOKUP_TL1(%g4, %g6, %g5, %g1, %g2, %g3, kvmap_dtlb_load)
237 253
238kvmap_dtlb_tsbmiss: 254kvmap_dtlb_tsbmiss:
diff --git a/arch/sparc64/kernel/pci_sun4v.c b/arch/sparc64/kernel/pci_sun4v.c
index 95de1444ee67..cacacfae5451 100644
--- a/arch/sparc64/kernel/pci_sun4v.c
+++ b/arch/sparc64/kernel/pci_sun4v.c
@@ -13,6 +13,7 @@
13#include <linux/irq.h> 13#include <linux/irq.h>
14#include <linux/msi.h> 14#include <linux/msi.h>
15#include <linux/log2.h> 15#include <linux/log2.h>
16#include <linux/scatterlist.h>
16 17
17#include <asm/iommu.h> 18#include <asm/iommu.h>
18#include <asm/irq.h> 19#include <asm/irq.h>
@@ -373,7 +374,7 @@ static inline long fill_sg(long entry, struct device *dev,
373 int nused, int nelems, unsigned long prot) 374 int nused, int nelems, unsigned long prot)
374{ 375{
375 struct scatterlist *dma_sg = sg; 376 struct scatterlist *dma_sg = sg;
376 struct scatterlist *sg_end = sg + nelems; 377 struct scatterlist *sg_end = sg_last(sg, nelems);
377 unsigned long flags; 378 unsigned long flags;
378 int i; 379 int i;
379 380
@@ -413,7 +414,7 @@ static inline long fill_sg(long entry, struct device *dev,
413 len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL))); 414 len -= (IO_PAGE_SIZE - (tmp & (IO_PAGE_SIZE - 1UL)));
414 break; 415 break;
415 } 416 }
416 sg++; 417 sg = sg_next(sg);
417 } 418 }
418 419
419 pteval = (pteval & IOPTE_PAGE); 420 pteval = (pteval & IOPTE_PAGE);
@@ -431,24 +432,25 @@ static inline long fill_sg(long entry, struct device *dev,
431 } 432 }
432 433
433 pteval = (pteval & IOPTE_PAGE) + len; 434 pteval = (pteval & IOPTE_PAGE) + len;
434 sg++; 435 sg = sg_next(sg);
435 436
436 /* Skip over any tail mappings we've fully mapped, 437 /* Skip over any tail mappings we've fully mapped,
437 * adjusting pteval along the way. Stop when we 438 * adjusting pteval along the way. Stop when we
438 * detect a page crossing event. 439 * detect a page crossing event.
439 */ 440 */
440 while (sg < sg_end && 441 while ((pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
441 (pteval << (64 - IO_PAGE_SHIFT)) != 0UL &&
442 (pteval == SG_ENT_PHYS_ADDRESS(sg)) && 442 (pteval == SG_ENT_PHYS_ADDRESS(sg)) &&
443 ((pteval ^ 443 ((pteval ^
444 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) { 444 (SG_ENT_PHYS_ADDRESS(sg) + sg->length - 1UL)) >> IO_PAGE_SHIFT) == 0UL) {
445 pteval += sg->length; 445 pteval += sg->length;
446 sg++; 446 if (sg == sg_end)
447 break;
448 sg = sg_next(sg);
447 } 449 }
448 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL) 450 if ((pteval << (64 - IO_PAGE_SHIFT)) == 0UL)
449 pteval = ~0UL; 451 pteval = ~0UL;
450 } while (dma_npages != 0); 452 } while (dma_npages != 0);
451 dma_sg++; 453 dma_sg = sg_next(dma_sg);
452 } 454 }
453 455
454 if (unlikely(iommu_batch_end() < 0L)) 456 if (unlikely(iommu_batch_end() < 0L))
@@ -510,7 +512,7 @@ static int dma_4v_map_sg(struct device *dev, struct scatterlist *sglist,
510 sgtmp = sglist; 512 sgtmp = sglist;
511 while (used && sgtmp->dma_length) { 513 while (used && sgtmp->dma_length) {
512 sgtmp->dma_address += dma_base; 514 sgtmp->dma_address += dma_base;
513 sgtmp++; 515 sgtmp = sg_next(sgtmp);
514 used--; 516 used--;
515 } 517 }
516 used = nelems - used; 518 used = nelems - used;
@@ -545,6 +547,7 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
545 struct pci_pbm_info *pbm; 547 struct pci_pbm_info *pbm;
546 struct iommu *iommu; 548 struct iommu *iommu;
547 unsigned long flags, i, npages; 549 unsigned long flags, i, npages;
550 struct scatterlist *sg, *sgprv;
548 long entry; 551 long entry;
549 u32 devhandle, bus_addr; 552 u32 devhandle, bus_addr;
550 553
@@ -558,12 +561,15 @@ static void dma_4v_unmap_sg(struct device *dev, struct scatterlist *sglist,
558 devhandle = pbm->devhandle; 561 devhandle = pbm->devhandle;
559 562
560 bus_addr = sglist->dma_address & IO_PAGE_MASK; 563 bus_addr = sglist->dma_address & IO_PAGE_MASK;
561 564 sgprv = NULL;
562 for (i = 1; i < nelems; i++) 565 for_each_sg(sglist, sg, nelems, i) {
563 if (sglist[i].dma_length == 0) 566 if (sg->dma_length == 0)
564 break; 567 break;
565 i--; 568
566 npages = (IO_PAGE_ALIGN(sglist[i].dma_address + sglist[i].dma_length) - 569 sgprv = sg;
570 }
571
572 npages = (IO_PAGE_ALIGN(sgprv->dma_address + sgprv->dma_length) -
567 bus_addr) >> IO_PAGE_SHIFT; 573 bus_addr) >> IO_PAGE_SHIFT;
568 574
569 entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT); 575 entry = ((bus_addr - iommu->page_table_map_base) >> IO_PAGE_SHIFT);
diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c
index c73b7a48b036..407d74a8a542 100644
--- a/arch/sparc64/kernel/smp.c
+++ b/arch/sparc64/kernel/smp.c
@@ -52,14 +52,13 @@ int sparc64_multi_core __read_mostly;
52 52
53cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE; 53cpumask_t cpu_possible_map __read_mostly = CPU_MASK_NONE;
54cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE; 54cpumask_t cpu_online_map __read_mostly = CPU_MASK_NONE;
55cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly = 55DEFINE_PER_CPU(cpumask_t, cpu_sibling_map) = CPU_MASK_NONE;
56 { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
57cpumask_t cpu_core_map[NR_CPUS] __read_mostly = 56cpumask_t cpu_core_map[NR_CPUS] __read_mostly =
58 { [0 ... NR_CPUS-1] = CPU_MASK_NONE }; 57 { [0 ... NR_CPUS-1] = CPU_MASK_NONE };
59 58
60EXPORT_SYMBOL(cpu_possible_map); 59EXPORT_SYMBOL(cpu_possible_map);
61EXPORT_SYMBOL(cpu_online_map); 60EXPORT_SYMBOL(cpu_online_map);
62EXPORT_SYMBOL(cpu_sibling_map); 61EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
63EXPORT_SYMBOL(cpu_core_map); 62EXPORT_SYMBOL(cpu_core_map);
64 63
65static cpumask_t smp_commenced_mask; 64static cpumask_t smp_commenced_mask;
@@ -1261,16 +1260,16 @@ void __devinit smp_fill_in_sib_core_maps(void)
1261 for_each_present_cpu(i) { 1260 for_each_present_cpu(i) {
1262 unsigned int j; 1261 unsigned int j;
1263 1262
1264 cpus_clear(cpu_sibling_map[i]); 1263 cpus_clear(per_cpu(cpu_sibling_map, i));
1265 if (cpu_data(i).proc_id == -1) { 1264 if (cpu_data(i).proc_id == -1) {
1266 cpu_set(i, cpu_sibling_map[i]); 1265 cpu_set(i, per_cpu(cpu_sibling_map, i));
1267 continue; 1266 continue;
1268 } 1267 }
1269 1268
1270 for_each_present_cpu(j) { 1269 for_each_present_cpu(j) {
1271 if (cpu_data(i).proc_id == 1270 if (cpu_data(i).proc_id ==
1272 cpu_data(j).proc_id) 1271 cpu_data(j).proc_id)
1273 cpu_set(j, cpu_sibling_map[i]); 1272 cpu_set(j, per_cpu(cpu_sibling_map, i));
1274 } 1273 }
1275 } 1274 }
1276} 1275}
@@ -1342,9 +1341,9 @@ int __cpu_disable(void)
1342 cpu_clear(cpu, cpu_core_map[i]); 1341 cpu_clear(cpu, cpu_core_map[i]);
1343 cpus_clear(cpu_core_map[cpu]); 1342 cpus_clear(cpu_core_map[cpu]);
1344 1343
1345 for_each_cpu_mask(i, cpu_sibling_map[cpu]) 1344 for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu))
1346 cpu_clear(cpu, cpu_sibling_map[i]); 1345 cpu_clear(cpu, per_cpu(cpu_sibling_map, i));
1347 cpus_clear(cpu_sibling_map[cpu]); 1346 cpus_clear(per_cpu(cpu_sibling_map, cpu));
1348 1347
1349 c = &cpu_data(cpu); 1348 c = &cpu_data(cpu);
1350 1349
diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c
index 9f7740eee8d2..e2027f27c0fe 100644
--- a/arch/sparc64/mm/fault.c
+++ b/arch/sparc64/mm/fault.c
@@ -463,7 +463,7 @@ out_of_memory:
463 up_read(&mm->mmap_sem); 463 up_read(&mm->mmap_sem);
464 printk("VM: killing process %s\n", current->comm); 464 printk("VM: killing process %s\n", current->comm);
465 if (!(regs->tstate & TSTATE_PRIV)) 465 if (!(regs->tstate & TSTATE_PRIV))
466 do_exit(SIGKILL); 466 do_group_exit(SIGKILL);
467 goto handle_kernel_fault; 467 goto handle_kernel_fault;
468 468
469intr_or_no_mm: 469intr_or_no_mm:
diff --git a/arch/sparc64/mm/init.c b/arch/sparc64/mm/init.c
index f0ab9aab308f..100c4456ed1e 100644
--- a/arch/sparc64/mm/init.c
+++ b/arch/sparc64/mm/init.c
@@ -1645,6 +1645,58 @@ EXPORT_SYMBOL(_PAGE_E);
1645unsigned long _PAGE_CACHE __read_mostly; 1645unsigned long _PAGE_CACHE __read_mostly;
1646EXPORT_SYMBOL(_PAGE_CACHE); 1646EXPORT_SYMBOL(_PAGE_CACHE);
1647 1647
1648#ifdef CONFIG_SPARSEMEM_VMEMMAP
1649
1650#define VMEMMAP_CHUNK_SHIFT 22
1651#define VMEMMAP_CHUNK (1UL << VMEMMAP_CHUNK_SHIFT)
1652#define VMEMMAP_CHUNK_MASK ~(VMEMMAP_CHUNK - 1UL)
1653#define VMEMMAP_ALIGN(x) (((x)+VMEMMAP_CHUNK-1UL)&VMEMMAP_CHUNK_MASK)
1654
1655#define VMEMMAP_SIZE ((((1UL << MAX_PHYSADDR_BITS) >> PAGE_SHIFT) * \
1656 sizeof(struct page *)) >> VMEMMAP_CHUNK_SHIFT)
1657unsigned long vmemmap_table[VMEMMAP_SIZE];
1658
1659int __meminit vmemmap_populate(struct page *start, unsigned long nr, int node)
1660{
1661 unsigned long vstart = (unsigned long) start;
1662 unsigned long vend = (unsigned long) (start + nr);
1663 unsigned long phys_start = (vstart - VMEMMAP_BASE);
1664 unsigned long phys_end = (vend - VMEMMAP_BASE);
1665 unsigned long addr = phys_start & VMEMMAP_CHUNK_MASK;
1666 unsigned long end = VMEMMAP_ALIGN(phys_end);
1667 unsigned long pte_base;
1668
1669 pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4U |
1670 _PAGE_CP_4U | _PAGE_CV_4U |
1671 _PAGE_P_4U | _PAGE_W_4U);
1672 if (tlb_type == hypervisor)
1673 pte_base = (_PAGE_VALID | _PAGE_SZ4MB_4V |
1674 _PAGE_CP_4V | _PAGE_CV_4V |
1675 _PAGE_P_4V | _PAGE_W_4V);
1676
1677 for (; addr < end; addr += VMEMMAP_CHUNK) {
1678 unsigned long *vmem_pp =
1679 vmemmap_table + (addr >> VMEMMAP_CHUNK_SHIFT);
1680 void *block;
1681
1682 if (!(*vmem_pp & _PAGE_VALID)) {
1683 block = vmemmap_alloc_block(1UL << 22, node);
1684 if (!block)
1685 return -ENOMEM;
1686
1687 *vmem_pp = pte_base | __pa(block);
1688
1689 printk(KERN_INFO "[%p-%p] page_structs=%lu "
1690 "node=%d entry=%lu/%lu\n", start, block, nr,
1691 node,
1692 addr >> VMEMMAP_CHUNK_SHIFT,
1693 VMEMMAP_SIZE >> VMEMMAP_CHUNK_SHIFT);
1694 }
1695 }
1696 return 0;
1697}
1698#endif /* CONFIG_SPARSEMEM_VMEMMAP */
1699
1648static void prot_init_common(unsigned long page_none, 1700static void prot_init_common(unsigned long page_none,
1649 unsigned long page_shared, 1701 unsigned long page_shared,
1650 unsigned long page_copy, 1702 unsigned long page_copy,
@@ -1909,9 +1961,4 @@ void online_page(struct page *page)
1909 num_physpages++; 1961 num_physpages++;
1910} 1962}
1911 1963
1912int remove_memory(u64 start, u64 size)
1913{
1914 return -EINVAL;
1915}
1916
1917#endif /* CONFIG_MEMORY_HOTPLUG */ 1964#endif /* CONFIG_MEMORY_HOTPLUG */
diff --git a/arch/um/Kconfig b/arch/um/Kconfig
index e6ff30266542..740d8a922e48 100644
--- a/arch/um/Kconfig
+++ b/arch/um/Kconfig
@@ -55,6 +55,14 @@ config GENERIC_BUG
55 default y 55 default y
56 depends on BUG 56 depends on BUG
57 57
58config GENERIC_TIME
59 bool
60 default y
61
62config GENERIC_CLOCKEVENTS
63 bool
64 default y
65
58# Used in kernel/irq/manage.c and include/linux/irq.h 66# Used in kernel/irq/manage.c and include/linux/irq.h
59config IRQ_RELEASE_METHOD 67config IRQ_RELEASE_METHOD
60 bool 68 bool
@@ -62,63 +70,25 @@ config IRQ_RELEASE_METHOD
62 70
63menu "UML-specific options" 71menu "UML-specific options"
64 72
65config MODE_TT
66 bool "Tracing thread support (DEPRECATED)"
67 default n
68 depends on BROKEN
69 help
70 This option controls whether tracing thread support is compiled
71 into UML. This option is largely obsolete, given that skas0 provides
72 skas security and performance without needing to patch the host.
73 It is safe to say 'N' here; saying 'Y' may cause additional problems
74 with the resulting binary even if you run UML in SKAS mode, and running
75 in TT mode is strongly *NOT RECOMMENDED*.
76
77config STATIC_LINK 73config STATIC_LINK
78 bool "Force a static link" 74 bool "Force a static link"
79 default n 75 default n
80 depends on !MODE_TT
81 help 76 help
82 If CONFIG_MODE_TT is disabled, then this option gives you the ability 77 This option gives you the ability to force a static link of UML.
83 to force a static link of UML. Normally, if only skas mode is built 78 Normally, UML is linked as a shared binary. This is inconvenient for
84 in to UML, it will be linked as a shared binary. This is inconvenient 79 use in a chroot jail. So, if you intend to run UML inside a chroot,
85 for use in a chroot jail. So, if you intend to run UML inside a 80 you probably want to say Y here.
86 chroot, and you disable CONFIG_MODE_TT, you probably want to say Y 81 Additionally, this option enables using higher memory spaces (up to
87 here. 82 2.75G) for UML.
88 Additionally, this option enables using higher memory spaces (up to
89 2.75G) for UML - disabling CONFIG_MODE_TT and enabling this option leads
90 to best results for this.
91
92config KERNEL_HALF_GIGS
93 int "Kernel address space size (in .5G units)"
94 default "1"
95 depends on MODE_TT
96 help
97 This determines the amount of address space that UML will allocate for
98 its own, measured in half Gigabyte units. The default is 1.
99 Change this only if you need to boot UML with an unusually large amount
100 of physical memory.
101
102config MODE_SKAS
103 bool "Separate Kernel Address Space support" if MODE_TT
104 default y
105 help
106 This option controls whether skas (separate kernel address space)
107 support is compiled in.
108 Unless you have specific needs to use TT mode (which applies almost only
109 to developers), you should say Y here.
110 SKAS mode will make use of the SKAS3 patch if it is applied on the host
111 (and your UML will run in SKAS3 mode), but if no SKAS patch is applied
112 on the host it will run in SKAS0 mode, which is anyway faster than TT
113 mode.
114 83
115source "arch/um/Kconfig.arch" 84source "arch/um/Kconfig.arch"
116source "mm/Kconfig" 85source "mm/Kconfig"
86source "kernel/time/Kconfig"
117 87
118config LD_SCRIPT_STATIC 88config LD_SCRIPT_STATIC
119 bool 89 bool
120 default y 90 default y
121 depends on MODE_TT || STATIC_LINK 91 depends on STATIC_LINK
122 92
123config LD_SCRIPT_DYN 93config LD_SCRIPT_DYN
124 bool 94 bool
@@ -128,18 +98,18 @@ config LD_SCRIPT_DYN
128config NET 98config NET
129 bool "Networking support" 99 bool "Networking support"
130 help 100 help
131 Unless you really know what you are doing, you should say Y here. 101 Unless you really know what you are doing, you should say Y here.
132 The reason is that some programs need kernel networking support even 102 The reason is that some programs need kernel networking support even
133 when running on a stand-alone machine that isn't connected to any 103 when running on a stand-alone machine that isn't connected to any
134 other computer. If you are upgrading from an older kernel, you 104 other computer. If you are upgrading from an older kernel, you
135 should consider updating your networking tools too because changes 105 should consider updating your networking tools too because changes
136 in the kernel and the tools often go hand in hand. The tools are 106 in the kernel and the tools often go hand in hand. The tools are
137 contained in the package net-tools, the location and version number 107 contained in the package net-tools, the location and version number
138 of which are given in <file:Documentation/Changes>. 108 of which are given in <file:Documentation/Changes>.
139 109
140 For a general introduction to Linux networking, it is highly 110 For a general introduction to Linux networking, it is highly
141 recommended to read the NET-HOWTO, available from 111 recommended to read the NET-HOWTO, available from
142 <http://www.tldp.org/docs.html#howto>. 112 <http://www.tldp.org/docs.html#howto>.
143 113
144 114
145source "fs/Kconfig.binfmt" 115source "fs/Kconfig.binfmt"
@@ -147,99 +117,99 @@ source "fs/Kconfig.binfmt"
147config HOSTFS 117config HOSTFS
148 tristate "Host filesystem" 118 tristate "Host filesystem"
149 help 119 help
150 While the User-Mode Linux port uses its own root file system for 120 While the User-Mode Linux port uses its own root file system for
151 booting and normal file access, this module lets the UML user 121 booting and normal file access, this module lets the UML user
152 access files stored on the host. It does not require any 122 access files stored on the host. It does not require any
153 network connection between the Host and UML. An example use of 123 network connection between the Host and UML. An example use of
154 this might be: 124 this might be:
155 125
156 mount none /tmp/fromhost -t hostfs -o /tmp/umlshare 126 mount none /tmp/fromhost -t hostfs -o /tmp/umlshare
157 127
158 where /tmp/fromhost is an empty directory inside UML and 128 where /tmp/fromhost is an empty directory inside UML and
159 /tmp/umlshare is a directory on the host with files the UML user 129 /tmp/umlshare is a directory on the host with files the UML user
160 wishes to access. 130 wishes to access.
161 131
162 For more information, see 132 For more information, see
163 <http://user-mode-linux.sourceforge.net/hostfs.html>. 133 <http://user-mode-linux.sourceforge.net/hostfs.html>.
164 134
165 If you'd like to be able to work with files stored on the host, 135 If you'd like to be able to work with files stored on the host,
166 say Y or M here; otherwise say N. 136 say Y or M here; otherwise say N.
167 137
168config HPPFS 138config HPPFS
169 tristate "HoneyPot ProcFS (EXPERIMENTAL)" 139 tristate "HoneyPot ProcFS (EXPERIMENTAL)"
170 depends on EXPERIMENTAL 140 depends on EXPERIMENTAL
171 help 141 help
172 hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc 142 hppfs (HoneyPot ProcFS) is a filesystem which allows UML /proc
173 entries to be overridden, removed, or fabricated from the host. 143 entries to be overridden, removed, or fabricated from the host.
174 Its purpose is to allow a UML to appear to be a physical machine 144 Its purpose is to allow a UML to appear to be a physical machine
175 by removing or changing anything in /proc which gives away the 145 by removing or changing anything in /proc which gives away the
176 identity of a UML. 146 identity of a UML.
177 147
178 See <http://user-mode-linux.sf.net/hppfs.html> for more information. 148 See <http://user-mode-linux.sf.net/hppfs.html> for more information.
179 149
180 You only need this if you are setting up a UML honeypot. Otherwise, 150 You only need this if you are setting up a UML honeypot. Otherwise,
181 it is safe to say 'N' here. 151 it is safe to say 'N' here.
182 152
183config MCONSOLE 153config MCONSOLE
184 bool "Management console" 154 bool "Management console"
185 default y 155 default y
186 help 156 help
187 The user mode linux management console is a low-level interface to 157 The user mode linux management console is a low-level interface to
188 the kernel, somewhat like the i386 SysRq interface. Since there is 158 the kernel, somewhat like the i386 SysRq interface. Since there is
189 a full-blown operating system running under every user mode linux 159 a full-blown operating system running under every user mode linux
190 instance, there is much greater flexibility possible than with the 160 instance, there is much greater flexibility possible than with the
191 SysRq mechanism. 161 SysRq mechanism.
192 162
193 If you answer 'Y' to this option, to use this feature, you need the 163 If you answer 'Y' to this option, to use this feature, you need the
194 mconsole client (called uml_mconsole) which is present in CVS in 164 mconsole client (called uml_mconsole) which is present in CVS in
195 2.4.5-9um and later (path /tools/mconsole), and is also in the 165 2.4.5-9um and later (path /tools/mconsole), and is also in the
196 distribution RPM package in 2.4.6 and later. 166 distribution RPM package in 2.4.6 and later.
197 167
198 It is safe to say 'Y' here. 168 It is safe to say 'Y' here.
199 169
200config MAGIC_SYSRQ 170config MAGIC_SYSRQ
201 bool "Magic SysRq key" 171 bool "Magic SysRq key"
202 depends on MCONSOLE 172 depends on MCONSOLE
203 ---help--- 173 help
204 If you say Y here, you will have some control over the system even 174 If you say Y here, you will have some control over the system even
205 if the system crashes for example during kernel debugging (e.g., you 175 if the system crashes for example during kernel debugging (e.g., you
206 will be able to flush the buffer cache to disk, reboot the system 176 will be able to flush the buffer cache to disk, reboot the system
207 immediately or dump some status information). A key for each of the 177 immediately or dump some status information). A key for each of the
208 possible requests is provided. 178 possible requests is provided.
209 179
210 This is the feature normally accomplished by pressing a key 180 This is the feature normally accomplished by pressing a key
211 while holding SysRq (Alt+PrintScreen). 181 while holding SysRq (Alt+PrintScreen).
212 182
213 On UML, this is accomplished by sending a "sysrq" command with 183 On UML, this is accomplished by sending a "sysrq" command with
214 mconsole, followed by the letter for the requested command. 184 mconsole, followed by the letter for the requested command.
215 185
216 The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y 186 The keys are documented in <file:Documentation/sysrq.txt>. Don't say Y
217 unless you really know what this hack does. 187 unless you really know what this hack does.
218 188
219config SMP 189config SMP
220 bool "Symmetric multi-processing support (EXPERIMENTAL)" 190 bool "Symmetric multi-processing support (EXPERIMENTAL)"
221 default n 191 default n
222 #SMP_BROKEN is for x86_64. 192 #SMP_BROKEN is for x86_64.
223 depends on MODE_TT && EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN)) 193 depends on EXPERIMENTAL && (!SMP_BROKEN || (BROKEN && SMP_BROKEN))
224 help 194 help
225 This option enables UML SMP support. 195 This option enables UML SMP support.
226 It is NOT related to having a real SMP box. Not directly, at least. 196 It is NOT related to having a real SMP box. Not directly, at least.
227 197
228 UML implements virtual SMP by allowing as many processes to run 198 UML implements virtual SMP by allowing as many processes to run
229 simultaneously on the host as there are virtual processors configured. 199 simultaneously on the host as there are virtual processors configured.
230 200
231 Obviously, if the host is a uniprocessor, those processes will 201 Obviously, if the host is a uniprocessor, those processes will
232 timeshare, but, inside UML, will appear to be running simultaneously. 202 timeshare, but, inside UML, will appear to be running simultaneously.
233 If the host is a multiprocessor, then UML processes may run 203 If the host is a multiprocessor, then UML processes may run
234 simultaneously, depending on the host scheduler. 204 simultaneously, depending on the host scheduler.
235 205
236 This, however, is supported only in TT mode. So, if you use the SKAS 206 This, however, is supported only in TT mode. So, if you use the SKAS
237 patch on your host, switching to TT mode and enabling SMP usually gives 207 patch on your host, switching to TT mode and enabling SMP usually
238 you worse performances. 208 gives you worse performances.
239 Also, since the support for SMP has been under-developed, there could 209 Also, since the support for SMP has been under-developed, there could
240 be some bugs being exposed by enabling SMP. 210 be some bugs being exposed by enabling SMP.
241 211
242 If you don't know what to do, say N. 212 If you don't know what to do, say N.
243 213
244config NR_CPUS 214config NR_CPUS
245 int "Maximum number of CPUs (2-32)" 215 int "Maximum number of CPUs (2-32)"
@@ -251,29 +221,24 @@ config NEST_LEVEL
251 int "Nesting level" 221 int "Nesting level"
252 default "0" 222 default "0"
253 help 223 help
254 This is set to the number of layers of UMLs that this UML will be run 224 This is set to the number of layers of UMLs that this UML will be run
255 in. Normally, this is zero, meaning that it will run directly on the 225 in. Normally, this is zero, meaning that it will run directly on the
256 host. Setting it to one will build a UML that can run inside a UML 226 host. Setting it to one will build a UML that can run inside a UML
257 that is running on the host. Generally, if you intend this UML to run 227 that is running on the host. Generally, if you intend this UML to run
258 inside another UML, set CONFIG_NEST_LEVEL to one more than the host 228 inside another UML, set CONFIG_NEST_LEVEL to one more than the host
259 UML. 229 UML.
260
261 Note that if the hosting UML has its CONFIG_KERNEL_HALF_GIGS set to
262 greater than one, then the guest UML should have its CONFIG_NEST_LEVEL
263 set to the host's CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS.
264 Only change this if you are running nested UMLs.
265 230
266config HIGHMEM 231config HIGHMEM
267 bool "Highmem support (EXPERIMENTAL)" 232 bool "Highmem support (EXPERIMENTAL)"
268 depends on !64BIT && EXPERIMENTAL 233 depends on !64BIT && EXPERIMENTAL
269 default n 234 default n
270 help 235 help
271 This was used to allow UML to run with big amounts of memory. 236 This was used to allow UML to run with big amounts of memory.
272 Currently it is unstable, so if unsure say N. 237 Currently it is unstable, so if unsure say N.
273 238
274 To use big amounts of memory, it is recommended to disable TT mode (i.e. 239 To use big amounts of memory, it is recommended enable static
275 CONFIG_MODE_TT) and enable static linking (i.e. CONFIG_STATIC_LINK) - 240 linking (i.e. CONFIG_STATIC_LINK) - this should allow the
276 this should allow the guest to use up to 2.75G of memory. 241 guest to use up to 2.75G of memory.
277 242
278config KERNEL_STACK_ORDER 243config KERNEL_STACK_ORDER
279 int "Kernel stack size order" 244 int "Kernel stack size order"
@@ -281,20 +246,9 @@ config KERNEL_STACK_ORDER
281 range 1 10 if 64BIT 246 range 1 10 if 64BIT
282 default 0 if !64BIT 247 default 0 if !64BIT
283 help 248 help
284 This option determines the size of UML kernel stacks. They will 249 This option determines the size of UML kernel stacks. They will
285 be 1 << order pages. The default is OK unless you're running Valgrind 250 be 1 << order pages. The default is OK unless you're running Valgrind
286 on UML, in which case, set this to 3. 251 on UML, in which case, set this to 3.
287
288config UML_REAL_TIME_CLOCK
289 bool "Real-time Clock"
290 default y
291 help
292 This option makes UML time deltas match wall clock deltas. This should
293 normally be enabled. The exception would be if you are debugging with
294 UML and spend long times with UML stopped at a breakpoint. In this
295 case, when UML is restarted, it will call the timer enough times to make
296 up for the time spent at the breakpoint. This could result in a
297 noticeable lag. If this is a problem, then disable this option.
298 252
299endmenu 253endmenu
300 254
diff --git a/arch/um/Kconfig.char b/arch/um/Kconfig.char
index a5b079d5e865..9a78d354f0b4 100644
--- a/arch/um/Kconfig.char
+++ b/arch/um/Kconfig.char
@@ -5,7 +5,7 @@ config STDERR_CONSOLE
5 bool "stderr console" 5 bool "stderr console"
6 default y 6 default y
7 help 7 help
8 console driver which dumps all printk messages to stderr. 8 console driver which dumps all printk messages to stderr.
9 9
10config STDIO_CONSOLE 10config STDIO_CONSOLE
11 bool 11 bool
@@ -14,60 +14,58 @@ config STDIO_CONSOLE
14config SSL 14config SSL
15 bool "Virtual serial line" 15 bool "Virtual serial line"
16 help 16 help
17 The User-Mode Linux environment allows you to create virtual serial 17 The User-Mode Linux environment allows you to create virtual serial
18 lines on the UML that are usually made to show up on the host as 18 lines on the UML that are usually made to show up on the host as
19 ttys or ptys. 19 ttys or ptys.
20 20
21 See <http://user-mode-linux.sourceforge.net/input.html> for more 21 See <http://user-mode-linux.sourceforge.net/input.html> for more
22 information and command line examples of how to use this facility. 22 information and command line examples of how to use this facility.
23 23
24 Unless you have a specific reason for disabling this, say Y. 24 Unless you have a specific reason for disabling this, say Y.
25 25
26config NULL_CHAN 26config NULL_CHAN
27 bool "null channel support" 27 bool "null channel support"
28 help 28 help
29 This option enables support for attaching UML consoles and serial 29 This option enables support for attaching UML consoles and serial
30 lines to a device similar to /dev/null. Data written to it disappears 30 lines to a device similar to /dev/null. Data written to it disappears
31 and there is never any data to be read. 31 and there is never any data to be read.
32 32
33config PORT_CHAN 33config PORT_CHAN
34 bool "port channel support" 34 bool "port channel support"
35 help 35 help
36 This option enables support for attaching UML consoles and serial 36 This option enables support for attaching UML consoles and serial
37 lines to host portals. They may be accessed with 'telnet <host> 37 lines to host portals. They may be accessed with 'telnet <host>
38 <port number>'. Any number of consoles and serial lines may be 38 <port number>'. Any number of consoles and serial lines may be
39 attached to a single portal, although what UML device you get when 39 attached to a single portal, although what UML device you get when
40 you telnet to that portal will be unpredictable. 40 you telnet to that portal will be unpredictable.
41 It is safe to say 'Y' here. 41 It is safe to say 'Y' here.
42 42
43config PTY_CHAN 43config PTY_CHAN
44 bool "pty channel support" 44 bool "pty channel support"
45 help 45 help
46 This option enables support for attaching UML consoles and serial 46 This option enables support for attaching UML consoles and serial
47 lines to host pseudo-terminals. Access to both traditional 47 lines to host pseudo-terminals. Access to both traditional
48 pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled 48 pseudo-terminals (/dev/pty*) and pts pseudo-terminals are controlled
49 with this option. The assignment of UML devices to host devices 49 with this option. The assignment of UML devices to host devices
50 will be announced in the kernel message log. 50 will be announced in the kernel message log.
51 It is safe to say 'Y' here. 51 It is safe to say 'Y' here.
52 52
53config TTY_CHAN 53config TTY_CHAN
54 bool "tty channel support" 54 bool "tty channel support"
55 help 55 help
56 This option enables support for attaching UML consoles and serial 56 This option enables support for attaching UML consoles and serial
57 lines to host terminals. Access to both virtual consoles 57 lines to host terminals. Access to both virtual consoles
58 (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and 58 (/dev/tty*) and the slave side of pseudo-terminals (/dev/ttyp* and
59 /dev/pts/*) are controlled by this option. 59 /dev/pts/*) are controlled by this option.
60 It is safe to say 'Y' here. 60 It is safe to say 'Y' here.
61 61
62config XTERM_CHAN 62config XTERM_CHAN
63 bool "xterm channel support" 63 bool "xterm channel support"
64 help 64 help
65 This option enables support for attaching UML consoles and serial 65 This option enables support for attaching UML consoles and serial
66 lines to xterms. Each UML device so assigned will be brought up in 66 lines to xterms. Each UML device so assigned will be brought up in
67 its own xterm. 67 its own xterm.
68 If you disable this option, then CONFIG_PT_PROXY will be disabled as 68 It is safe to say 'Y' here.
69 well, since UML's gdb currently requires an xterm.
70 It is safe to say 'Y' here.
71 69
72config NOCONFIG_CHAN 70config NOCONFIG_CHAN
73 bool 71 bool
@@ -77,39 +75,39 @@ config CON_ZERO_CHAN
77 string "Default main console channel initialization" 75 string "Default main console channel initialization"
78 default "fd:0,fd:1" 76 default "fd:0,fd:1"
79 help 77 help
80 This is the string describing the channel to which the main console 78 This is the string describing the channel to which the main console
81 will be attached by default. This value can be overridden from the 79 will be attached by default. This value can be overridden from the
82 command line. The default value is "fd:0,fd:1", which attaches the 80 command line. The default value is "fd:0,fd:1", which attaches the
83 main console to stdin and stdout. 81 main console to stdin and stdout.
84 It is safe to leave this unchanged. 82 It is safe to leave this unchanged.
85 83
86config CON_CHAN 84config CON_CHAN
87 string "Default console channel initialization" 85 string "Default console channel initialization"
88 default "xterm" 86 default "xterm"
89 help 87 help
90 This is the string describing the channel to which all consoles 88 This is the string describing the channel to which all consoles
91 except the main console will be attached by default. This value can 89 except the main console will be attached by default. This value can
92 be overridden from the command line. The default value is "xterm", 90 be overridden from the command line. The default value is "xterm",
93 which brings them up in xterms. 91 which brings them up in xterms.
94 It is safe to leave this unchanged, although you may wish to change 92 It is safe to leave this unchanged, although you may wish to change
95 this if you expect the UML that you build to be run in environments 93 this if you expect the UML that you build to be run in environments
96 which don't have X or xterm available. 94 which don't have X or xterm available.
97 95
98config SSL_CHAN 96config SSL_CHAN
99 string "Default serial line channel initialization" 97 string "Default serial line channel initialization"
100 default "pty" 98 default "pty"
101 help 99 help
102 This is the string describing the channel to which the serial lines 100 This is the string describing the channel to which the serial lines
103 will be attached by default. This value can be overridden from the 101 will be attached by default. This value can be overridden from the
104 command line. The default value is "pty", which attaches them to 102 command line. The default value is "pty", which attaches them to
105 traditional pseudo-terminals. 103 traditional pseudo-terminals.
106 It is safe to leave this unchanged, although you may wish to change 104 It is safe to leave this unchanged, although you may wish to change
107 this if you expect the UML that you build to be run in environments 105 this if you expect the UML that you build to be run in environments
108 which don't have a set of /dev/pty* devices. 106 which don't have a set of /dev/pty* devices.
109 107
110config UNIX98_PTYS 108config UNIX98_PTYS
111 bool "Unix98 PTY support" 109 bool "Unix98 PTY support"
112 ---help--- 110 help
113 A pseudo terminal (PTY) is a software device consisting of two 111 A pseudo terminal (PTY) is a software device consisting of two
114 halves: a master and a slave. The slave device behaves identical to 112 halves: a master and a slave. The slave device behaves identical to
115 a physical terminal; the master device is used by a process to 113 a physical terminal; the master device is used by a process to
@@ -132,7 +130,7 @@ config UNIX98_PTYS
132config LEGACY_PTYS 130config LEGACY_PTYS
133 bool "Legacy (BSD) PTY support" 131 bool "Legacy (BSD) PTY support"
134 default y 132 default y
135 ---help--- 133 help
136 A pseudo terminal (PTY) is a software device consisting of two 134 A pseudo terminal (PTY) is a software device consisting of two
137 halves: a master and a slave. The slave device behaves identical to 135 halves: a master and a slave. The slave device behaves identical to
138 a physical terminal; the master device is used by a process to 136 a physical terminal; the master device is used by a process to
@@ -170,7 +168,7 @@ config LEGACY_PTY_COUNT
170 int "Maximum number of legacy PTY in use" 168 int "Maximum number of legacy PTY in use"
171 depends on LEGACY_PTYS 169 depends on LEGACY_PTYS
172 default "256" 170 default "256"
173 ---help--- 171 help
174 The maximum number of legacy PTYs that can be used at any one time. 172 The maximum number of legacy PTYs that can be used at any one time.
175 The default is 256, and should be more than enough. Embedded 173 The default is 256, and should be more than enough. Embedded
176 systems may want to reduce this to save memory. 174 systems may want to reduce this to save memory.
@@ -196,10 +194,10 @@ config UML_WATCHDOG
196config UML_SOUND 194config UML_SOUND
197 tristate "Sound support" 195 tristate "Sound support"
198 help 196 help
199 This option enables UML sound support. If enabled, it will pull in 197 This option enables UML sound support. If enabled, it will pull in
200 soundcore and the UML hostaudio relay, which acts as a intermediary 198 soundcore and the UML hostaudio relay, which acts as a intermediary
201 between the host's dsp and mixer devices and the UML sound system. 199 between the host's dsp and mixer devices and the UML sound system.
202 It is safe to say 'Y' here. 200 It is safe to say 'Y' here.
203 201
204config SOUND 202config SOUND
205 tristate 203 tristate
@@ -217,22 +215,21 @@ config HW_RANDOM
217config UML_RANDOM 215config UML_RANDOM
218 tristate "Hardware random number generator" 216 tristate "Hardware random number generator"
219 help 217 help
220 This option enables UML's "hardware" random number generator. It 218 This option enables UML's "hardware" random number generator. It
221 attaches itself to the host's /dev/random, supplying as much entropy 219 attaches itself to the host's /dev/random, supplying as much entropy
222 as the host has, rather than the small amount the UML gets from its 220 as the host has, rather than the small amount the UML gets from its
223 own drivers. It registers itself as a standard hardware random number 221 own drivers. It registers itself as a standard hardware random number
224 generator, major 10, minor 183, and the canonical device name is 222 generator, major 10, minor 183, and the canonical device name is
225 /dev/hwrng. 223 /dev/hwrng.
226 The way to make use of this is to install the rng-tools package 224 The way to make use of this is to install the rng-tools package
227 (check your distro, or download from 225 (check your distro, or download from
228 http://sourceforge.net/projects/gkernel/). rngd periodically reads 226 http://sourceforge.net/projects/gkernel/). rngd periodically reads
229 /dev/hwrng and injects the entropy into /dev/random. 227 /dev/hwrng and injects the entropy into /dev/random.
230 228
231config MMAPPER 229config MMAPPER
232 tristate "iomem emulation driver" 230 tristate "iomem emulation driver"
233 help 231 help
234 This driver allows a host file to be used as emulated IO memory inside 232 This driver allows a host file to be used as emulated IO memory inside
235 UML. 233 UML.
236 234
237endmenu 235endmenu
238
diff --git a/arch/um/Kconfig.debug b/arch/um/Kconfig.debug
index c86f5eb29fd5..1f6462ffd3e8 100644
--- a/arch/um/Kconfig.debug
+++ b/arch/um/Kconfig.debug
@@ -2,50 +2,31 @@ menu "Kernel hacking"
2 2
3source "lib/Kconfig.debug" 3source "lib/Kconfig.debug"
4 4
5config CMDLINE_ON_HOST
6 bool "Show command line arguments on the host in TT mode"
7 depends on MODE_TT
8 default !DEBUG_INFO
9 help
10 This controls whether arguments in guest processes should be shown on
11 the host's ps output.
12 Enabling this option hinders debugging on some recent GDB versions
13 (because GDB gets "confused" when we do an execvp()). So probably you
14 should disable it.
15
16config PT_PROXY
17 bool "Enable ptrace proxy"
18 depends on XTERM_CHAN && DEBUG_INFO && MODE_TT
19 help
20 This option enables a debugging interface which allows gdb to debug
21 the kernel without needing to actually attach to kernel threads.
22 If you want to do kernel debugging, say Y here; otherwise say N.
23
24config GPROF 5config GPROF
25 bool "Enable gprof support" 6 bool "Enable gprof support"
26 depends on DEBUG_INFO && MODE_SKAS && !MODE_TT 7 depends on DEBUG_INFO
27 help 8 help
28 This allows profiling of a User-Mode Linux kernel with the gprof 9 This allows profiling of a User-Mode Linux kernel with the gprof
29 utility. 10 utility.
30 11
31 See <http://user-mode-linux.sourceforge.net/gprof.html> for more 12 See <http://user-mode-linux.sourceforge.net/gprof.html> for more
32 details. 13 details.
33 14
34 If you're involved in UML kernel development and want to use gprof, 15 If you're involved in UML kernel development and want to use gprof,
35 say Y. If you're unsure, say N. 16 say Y. If you're unsure, say N.
36 17
37config GCOV 18config GCOV
38 bool "Enable gcov support" 19 bool "Enable gcov support"
39 depends on DEBUG_INFO && MODE_SKAS 20 depends on DEBUG_INFO
40 help 21 help
41 This option allows developers to retrieve coverage data from a UML 22 This option allows developers to retrieve coverage data from a UML
42 session. 23 session.
43 24
44 See <http://user-mode-linux.sourceforge.net/gprof.html> for more 25 See <http://user-mode-linux.sourceforge.net/gprof.html> for more
45 details. 26 details.
46 27
47 If you're involved in UML kernel development and want to use gcov, 28 If you're involved in UML kernel development and want to use gcov,
48 say Y. If you're unsure, say N. 29 say Y. If you're unsure, say N.
49 30
50config DEBUG_STACK_USAGE 31config DEBUG_STACK_USAGE
51 bool "Stack utilization instrumentation" 32 bool "Stack utilization instrumentation"
diff --git a/arch/um/Kconfig.i386 b/arch/um/Kconfig.i386
index d6cffb27fff8..9876d80d85dd 100644
--- a/arch/um/Kconfig.i386
+++ b/arch/um/Kconfig.i386
@@ -65,20 +65,6 @@ config 3_LEVEL_PGTABLES
65 However, this it experimental on 32-bit architectures, so if unsure say 65 However, this it experimental on 32-bit architectures, so if unsure say
66 N (on x86-64 it's automatically enabled, instead, as it's safe there). 66 N (on x86-64 it's automatically enabled, instead, as it's safe there).
67 67
68config STUB_CODE
69 hex
70 default 0xbfffe000 if !HOST_VMSPLIT_2G
71 default 0x7fffe000 if HOST_VMSPLIT_2G
72
73config STUB_DATA
74 hex
75 default 0xbffff000 if !HOST_VMSPLIT_2G
76 default 0x7ffff000 if HOST_VMSPLIT_2G
77
78config STUB_START
79 hex
80 default STUB_CODE
81
82config ARCH_HAS_SC_SIGNALS 68config ARCH_HAS_SC_SIGNALS
83 bool 69 bool
84 default y 70 default y
diff --git a/arch/um/Kconfig.net b/arch/um/Kconfig.net
index 14a04ebdeae9..66e50026ade9 100644
--- a/arch/um/Kconfig.net
+++ b/arch/um/Kconfig.net
@@ -108,6 +108,28 @@ config UML_NET_DAEMON
108 more than one without conflict. If you don't need UML networking, 108 more than one without conflict. If you don't need UML networking,
109 say N. 109 say N.
110 110
111config UML_NET_VDE
112 bool "VDE transport"
113 depends on UML_NET
114 help
115 This User-Mode Linux network transport allows one or more running
116 UMLs on a single host to communicate with each other and also
117 with the rest of the world using Virtual Distributed Ethernet,
118 an improved fork of uml_switch.
119
120 You must have libvdeplug installed in order to build the vde
121 transport into UML.
122
123 To use this form of networking, you will need to run vde_switch
124 on the host.
125
126 For more information, see <http://wiki.virtualsquare.org/>
127 That site has a good overview of what VDE is and also examples
128 of the UML command line to use to enable VDE networking.
129
130 If you need UML networking with VDE,
131 say Y.
132
111config UML_NET_MCAST 133config UML_NET_MCAST
112 bool "Multicast transport" 134 bool "Multicast transport"
113 depends on UML_NET 135 depends on UML_NET
diff --git a/arch/um/Kconfig.x86_64 b/arch/um/Kconfig.x86_64
index f60e9e506424..d632e9a89cc3 100644
--- a/arch/um/Kconfig.x86_64
+++ b/arch/um/Kconfig.x86_64
@@ -17,24 +17,12 @@ config SEMAPHORE_SLEEPERS
17 17
18config TOP_ADDR 18config TOP_ADDR
19 hex 19 hex
20 default 0x80000000 20 default 0x7fc0000000
21 21
22config 3_LEVEL_PGTABLES 22config 3_LEVEL_PGTABLES
23 bool 23 bool
24 default y 24 default y
25 25
26config STUB_CODE
27 hex
28 default 0x7fbfffe000
29
30config STUB_DATA
31 hex
32 default 0x7fbffff000
33
34config STUB_START
35 hex
36 default STUB_CODE
37
38config ARCH_HAS_SC_SIGNALS 26config ARCH_HAS_SC_SIGNALS
39 bool 27 bool
40 default n 28 default n
diff --git a/arch/um/Makefile b/arch/um/Makefile
index 0666729eb976..ab22fdeedf29 100644
--- a/arch/um/Makefile
+++ b/arch/um/Makefile
@@ -2,7 +2,7 @@
2# This file is included by the global makefile so that you can add your own 2# This file is included by the global makefile so that you can add your own
3# architecture-specific flags and dependencies. 3# architecture-specific flags and dependencies.
4# 4#
5# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 5# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
6# Licensed under the GPL 6# Licensed under the GPL
7# 7#
8 8
@@ -31,18 +31,9 @@ SYMLINK_HEADERS := $(foreach header,$(SYMLINK_HEADERS),include/asm-um/$(header))
31ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \ 31ARCH_SYMLINKS = include/asm-um/arch $(ARCH_DIR)/include/sysdep $(ARCH_DIR)/os \
32 $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h 32 $(SYMLINK_HEADERS) $(ARCH_DIR)/include/uml-config.h
33 33
34um-modes-$(CONFIG_MODE_TT) += tt 34MODE_INCLUDE += -I$(srctree)/$(ARCH_DIR)/include/skas
35um-modes-$(CONFIG_MODE_SKAS) += skas
36 35
37MODE_INCLUDE += $(foreach mode,$(um-modes-y),\ 36include $(srctree)/$(ARCH_DIR)/Makefile-skas
38 -I$(srctree)/$(ARCH_DIR)/include/$(mode))
39
40MAKEFILES-INCL += $(foreach mode,$(um-modes-y),\
41 $(srctree)/$(ARCH_DIR)/Makefile-$(mode))
42
43ifneq ($(MAKEFILES-INCL),)
44 include $(MAKEFILES-INCL)
45endif
46 37
47ARCH_INCLUDE := -I$(ARCH_DIR)/include 38ARCH_INCLUDE := -I$(ARCH_DIR)/include
48ifneq ($(KBUILD_SRC),) 39ifneq ($(KBUILD_SRC),)
@@ -60,7 +51,8 @@ SYS_DIR := $(ARCH_DIR)/include/sysdep-$(SUBARCH)
60 51
61CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \ 52CFLAGS += $(CFLAGS-y) -D__arch_um__ -DSUBARCH=\"$(SUBARCH)\" \
62 $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \ 53 $(ARCH_INCLUDE) $(MODE_INCLUDE) -Dvmap=kernel_vmap \
63 -Din6addr_loopback=kernel_in6addr_loopback 54 -Din6addr_loopback=kernel_in6addr_loopback \
55 -Din6addr_any=kernel_in6addr_any
64 56
65AFLAGS += $(ARCH_INCLUDE) 57AFLAGS += $(ARCH_INCLUDE)
66 58
@@ -88,9 +80,8 @@ CFLAGS += $(call cc-option,-fno-unit-at-a-time,)
88# included; the values here are meaningless 80# included; the values here are meaningless
89 81
90CONFIG_NEST_LEVEL ?= 0 82CONFIG_NEST_LEVEL ?= 0
91CONFIG_KERNEL_HALF_GIGS ?= 0
92 83
93SIZE = (($(CONFIG_NEST_LEVEL) + $(CONFIG_KERNEL_HALF_GIGS)) * 0x20000000) 84SIZE = ($(CONFIG_NEST_LEVEL) * 0x20000000)
94 85
95PHONY += linux 86PHONY += linux
96 87
@@ -123,7 +114,6 @@ CFLAGS_NO_HARDENING := $(call cc-option, -fno-PIC,) $(call cc-option, -fno-pic,)
123 $(call cc-option, -fno-stack-protector,) \ 114 $(call cc-option, -fno-stack-protector,) \
124 $(call cc-option, -fno-stack-protector-all,) 115 $(call cc-option, -fno-stack-protector-all,)
125 116
126CPP_MODE-$(CONFIG_MODE_TT) := -DMODE_TT
127CONFIG_KERNEL_STACK_ORDER ?= 2 117CONFIG_KERNEL_STACK_ORDER ?= 2
128STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] ) 118STACK_SIZE := $(shell echo $$[ 4096 * (1 << $(CONFIG_KERNEL_STACK_ORDER)) ] )
129 119
@@ -131,13 +121,10 @@ ifndef START
131 START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] ) 121 START = $(shell echo $$[ $(TOP_ADDR) - $(SIZE) ] )
132endif 122endif
133 123
134CPPFLAGS_vmlinux.lds = -U$(SUBARCH) \ 124CPPFLAGS_vmlinux.lds = -U$(SUBARCH) -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \
135 -DSTART=$(START) -DELF_ARCH=$(ELF_ARCH) \ 125 -DELF_FORMAT="$(ELF_FORMAT)" -DKERNEL_STACK_SIZE=$(STACK_SIZE)
136 -DELF_FORMAT="$(ELF_FORMAT)" $(CPP_MODE-y) \
137 -DKERNEL_STACK_SIZE=$(STACK_SIZE) \
138 -DUNMAP_PATH=arch/um/sys-$(SUBARCH)/unmap.o
139 126
140#The wrappers will select whether using "malloc" or the kernel allocator. 127# The wrappers will select whether using "malloc" or the kernel allocator.
141LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc 128LINK_WRAPS = -Wl,--wrap,malloc -Wl,--wrap,free -Wl,--wrap,calloc
142 129
143CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS) 130CFLAGS_vmlinux := $(LINK-y) $(LINK_WRAPS)
@@ -150,8 +137,8 @@ define cmd_vmlinux__
150 FORCE ,$^) ; rm -f linux 137 FORCE ,$^) ; rm -f linux
151endef 138endef
152 139
153#When cleaning we don't include .config, so we don't include 140# When cleaning we don't include .config, so we don't include
154#TT or skas makefiles and don't clean skas_ptregs.h. 141# TT or skas makefiles and don't clean skas_ptregs.h.
155CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \ 142CLEAN_FILES += linux x.i gmon.out $(ARCH_DIR)/include/uml-config.h \
156 $(ARCH_DIR)/include/user_constants.h \ 143 $(ARCH_DIR)/include/user_constants.h \
157 $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch 144 $(ARCH_DIR)/include/kern_constants.h $(ARCH_DIR)/Kconfig.arch
diff --git a/arch/um/Makefile-i386 b/arch/um/Makefile-i386
index 60107ed4905b..ae61e3c271e2 100644
--- a/arch/um/Makefile-i386
+++ b/arch/um/Makefile-i386
@@ -2,11 +2,7 @@ core-y += arch/um/sys-i386/ arch/x86/crypto/
2 2
3TOP_ADDR := $(CONFIG_TOP_ADDR) 3TOP_ADDR := $(CONFIG_TOP_ADDR)
4 4
5ifeq ($(CONFIG_MODE_SKAS),y) 5START := 0x8048000
6 ifneq ($(CONFIG_MODE_TT),y)
7 START := 0x8048000
8 endif
9endif
10 6
11LDFLAGS += -m elf_i386 7LDFLAGS += -m elf_i386
12ELF_ARCH := $(SUBARCH) 8ELF_ARCH := $(SUBARCH)
diff --git a/arch/um/defconfig b/arch/um/defconfig
index 1e0f677c2f46..f609edede065 100644
--- a/arch/um/defconfig
+++ b/arch/um/defconfig
@@ -12,9 +12,7 @@ CONFIG_IRQ_RELEASE_METHOD=y
12# 12#
13# UML-specific options 13# UML-specific options
14# 14#
15# CONFIG_MODE_TT is not set
16# CONFIG_STATIC_LINK is not set 15# CONFIG_STATIC_LINK is not set
17CONFIG_MODE_SKAS=y
18 16
19# 17#
20# Host processor type and features 18# Host processor type and features
@@ -61,9 +59,6 @@ CONFIG_SEMAPHORE_SLEEPERS=y
61# CONFIG_HOST_2G_2G is not set 59# CONFIG_HOST_2G_2G is not set
62CONFIG_TOP_ADDR=0xc0000000 60CONFIG_TOP_ADDR=0xc0000000
63# CONFIG_3_LEVEL_PGTABLES is not set 61# CONFIG_3_LEVEL_PGTABLES is not set
64CONFIG_STUB_CODE=0xbfffe000
65CONFIG_STUB_DATA=0xbffff000
66CONFIG_STUB_START=0xbfffe000
67CONFIG_ARCH_HAS_SC_SIGNALS=y 62CONFIG_ARCH_HAS_SC_SIGNALS=y
68CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y 63CONFIG_ARCH_REUSE_HOST_VSYSCALL_AREA=y
69CONFIG_GENERIC_HWEIGHT=y 64CONFIG_GENERIC_HWEIGHT=y
@@ -75,6 +70,9 @@ CONFIG_FLATMEM=y
75CONFIG_FLAT_NODE_MEM_MAP=y 70CONFIG_FLAT_NODE_MEM_MAP=y
76# CONFIG_SPARSEMEM_STATIC is not set 71# CONFIG_SPARSEMEM_STATIC is not set
77CONFIG_SPLIT_PTLOCK_CPUS=4 72CONFIG_SPLIT_PTLOCK_CPUS=4
73CONFIG_TICK_ONESHOT=y
74CONFIG_NO_HZ=y
75CONFIG_HIGH_RES_TIMERS=y
78CONFIG_LD_SCRIPT_DYN=y 76CONFIG_LD_SCRIPT_DYN=y
79CONFIG_NET=y 77CONFIG_NET=y
80CONFIG_BINFMT_ELF=y 78CONFIG_BINFMT_ELF=y
@@ -82,11 +80,10 @@ CONFIG_BINFMT_MISC=m
82# CONFIG_HOSTFS is not set 80# CONFIG_HOSTFS is not set
83# CONFIG_HPPFS is not set 81# CONFIG_HPPFS is not set
84CONFIG_MCONSOLE=y 82CONFIG_MCONSOLE=y
85# CONFIG_MAGIC_SYSRQ is not set 83CONFIG_MAGIC_SYSRQ=y
86CONFIG_NEST_LEVEL=0 84CONFIG_NEST_LEVEL=0
87# CONFIG_HIGHMEM is not set 85# CONFIG_HIGHMEM is not set
88CONFIG_KERNEL_STACK_ORDER=0 86CONFIG_KERNEL_STACK_ORDER=0
89CONFIG_UML_REAL_TIME_CLOCK=y
90 87
91# 88#
92# Code maturity level options 89# Code maturity level options
diff --git a/arch/um/drivers/Makefile b/arch/um/drivers/Makefile
index de17d4c6e02d..634968150bd6 100644
--- a/arch/um/drivers/Makefile
+++ b/arch/um/drivers/Makefile
@@ -19,10 +19,16 @@ harddog-objs := harddog_kern.o harddog_user.o
19 19
20LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a) 20LDFLAGS_pcap.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libpcap.a)
21 21
22targets := pcap_kern.o pcap_user.o 22LDFLAGS_vde.o := -r $(shell $(CC) $(CFLAGS) -print-file-name=libvdeplug.a)
23
24targets := pcap_kern.o pcap_user.o vde_kern.o vde_user.o
23 25
24$(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o 26$(obj)/pcap.o: $(obj)/pcap_kern.o $(obj)/pcap_user.o
25 $(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o) 27 $(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_pcap.o)
28
29$(obj)/vde.o: $(obj)/vde_kern.o $(obj)/vde_user.o
30 $(LD) -r -dp -o $@ $^ $(LDFLAGS) $(LDFLAGS_vde.o)
31
26#XXX: The call below does not work because the flags are added before the 32#XXX: The call below does not work because the flags are added before the
27# object name, so nothing from the library gets linked. 33# object name, so nothing from the library gets linked.
28#$(call if_changed,ld) 34#$(call if_changed,ld)
@@ -37,6 +43,7 @@ obj-$(CONFIG_STDERR_CONSOLE) += stderr_console.o
37obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o 43obj-$(CONFIG_UML_NET_SLIP) += slip.o slip_common.o
38obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o 44obj-$(CONFIG_UML_NET_SLIRP) += slirp.o slip_common.o
39obj-$(CONFIG_UML_NET_DAEMON) += daemon.o 45obj-$(CONFIG_UML_NET_DAEMON) += daemon.o
46obj-$(CONFIG_UML_NET_VDE) += vde.o
40obj-$(CONFIG_UML_NET_MCAST) += mcast.o 47obj-$(CONFIG_UML_NET_MCAST) += mcast.o
41obj-$(CONFIG_UML_NET_PCAP) += pcap.o 48obj-$(CONFIG_UML_NET_PCAP) += pcap.o
42obj-$(CONFIG_UML_NET) += net.o 49obj-$(CONFIG_UML_NET) += net.o
@@ -54,6 +61,6 @@ obj-$(CONFIG_BLK_DEV_COW_COMMON) += cow_user.o
54obj-$(CONFIG_UML_RANDOM) += random.o 61obj-$(CONFIG_UML_RANDOM) += random.o
55 62
56# pcap_user.o must be added explicitly. 63# pcap_user.o must be added explicitly.
57USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o 64USER_OBJS := fd.o null.o pty.o tty.o xterm.o slip_common.o pcap_user.o vde_user.o
58 65
59include arch/um/scripts/Makefile.rules 66include arch/um/scripts/Makefile.rules
diff --git a/arch/um/drivers/chan_kern.c b/arch/um/drivers/chan_kern.c
index 629b00e3b0b0..db3082b4da46 100644
--- a/arch/um/drivers/chan_kern.c
+++ b/arch/um/drivers/chan_kern.c
@@ -1,28 +1,19 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <linux/stddef.h>
7#include <linux/kernel.h>
8#include <linux/list.h>
9#include <linux/slab.h> 6#include <linux/slab.h>
10#include <linux/tty.h> 7#include <linux/tty.h>
11#include <linux/string.h>
12#include <linux/tty_flip.h> 8#include <linux/tty_flip.h>
13#include <asm/irq.h>
14#include "chan_kern.h" 9#include "chan_kern.h"
15#include "kern.h"
16#include "irq_user.h"
17#include "sigio.h"
18#include "line.h"
19#include "os.h" 10#include "os.h"
20 11
21#ifdef CONFIG_NOCONFIG_CHAN 12#ifdef CONFIG_NOCONFIG_CHAN
22static void *not_configged_init(char *str, int device, 13static void *not_configged_init(char *str, int device,
23 const struct chan_opts *opts) 14 const struct chan_opts *opts)
24{ 15{
25 printk("Using a channel type which is configured out of " 16 printk(KERN_ERR "Using a channel type which is configured out of "
26 "UML\n"); 17 "UML\n");
27 return NULL; 18 return NULL;
28} 19}
@@ -30,34 +21,34 @@ static void *not_configged_init(char *str, int device,
30static int not_configged_open(int input, int output, int primary, void *data, 21static int not_configged_open(int input, int output, int primary, void *data,
31 char **dev_out) 22 char **dev_out)
32{ 23{
33 printk("Using a channel type which is configured out of " 24 printk(KERN_ERR "Using a channel type which is configured out of "
34 "UML\n"); 25 "UML\n");
35 return -ENODEV; 26 return -ENODEV;
36} 27}
37 28
38static void not_configged_close(int fd, void *data) 29static void not_configged_close(int fd, void *data)
39{ 30{
40 printk("Using a channel type which is configured out of " 31 printk(KERN_ERR "Using a channel type which is configured out of "
41 "UML\n"); 32 "UML\n");
42} 33}
43 34
44static int not_configged_read(int fd, char *c_out, void *data) 35static int not_configged_read(int fd, char *c_out, void *data)
45{ 36{
46 printk("Using a channel type which is configured out of " 37 printk(KERN_ERR "Using a channel type which is configured out of "
47 "UML\n"); 38 "UML\n");
48 return -EIO; 39 return -EIO;
49} 40}
50 41
51static int not_configged_write(int fd, const char *buf, int len, void *data) 42static int not_configged_write(int fd, const char *buf, int len, void *data)
52{ 43{
53 printk("Using a channel type which is configured out of " 44 printk(KERN_ERR "Using a channel type which is configured out of "
54 "UML\n"); 45 "UML\n");
55 return -EIO; 46 return -EIO;
56} 47}
57 48
58static int not_configged_console_write(int fd, const char *buf, int len) 49static int not_configged_console_write(int fd, const char *buf, int len)
59{ 50{
60 printk("Using a channel type which is configured out of " 51 printk(KERN_ERR "Using a channel type which is configured out of "
61 "UML\n"); 52 "UML\n");
62 return -EIO; 53 return -EIO;
63} 54}
@@ -65,14 +56,14 @@ static int not_configged_console_write(int fd, const char *buf, int len)
65static int not_configged_window_size(int fd, void *data, unsigned short *rows, 56static int not_configged_window_size(int fd, void *data, unsigned short *rows,
66 unsigned short *cols) 57 unsigned short *cols)
67{ 58{
68 printk("Using a channel type which is configured out of " 59 printk(KERN_ERR "Using a channel type which is configured out of "
69 "UML\n"); 60 "UML\n");
70 return -ENODEV; 61 return -ENODEV;
71} 62}
72 63
73static void not_configged_free(void *data) 64static void not_configged_free(void *data)
74{ 65{
75 printk("Using a channel type which is configured out of " 66 printk(KERN_ERR "Using a channel type which is configured out of "
76 "UML\n"); 67 "UML\n");
77} 68}
78 69
@@ -89,64 +80,17 @@ static const struct chan_ops not_configged_ops = {
89}; 80};
90#endif /* CONFIG_NOCONFIG_CHAN */ 81#endif /* CONFIG_NOCONFIG_CHAN */
91 82
92void generic_close(int fd, void *unused)
93{
94 os_close_file(fd);
95}
96
97int generic_read(int fd, char *c_out, void *unused)
98{
99 int n;
100
101 n = os_read_file(fd, c_out, sizeof(*c_out));
102
103 if(n == -EAGAIN)
104 return 0;
105 else if(n == 0)
106 return -EIO;
107 return n;
108}
109
110/* XXX Trivial wrapper around os_write_file */
111
112int generic_write(int fd, const char *buf, int n, void *unused)
113{
114 return os_write_file(fd, buf, n);
115}
116
117int generic_window_size(int fd, void *unused, unsigned short *rows_out,
118 unsigned short *cols_out)
119{
120 int rows, cols;
121 int ret;
122
123 ret = os_window_size(fd, &rows, &cols);
124 if(ret < 0)
125 return ret;
126
127 ret = ((*rows_out != rows) || (*cols_out != cols));
128
129 *rows_out = rows;
130 *cols_out = cols;
131
132 return ret;
133}
134
135void generic_free(void *data)
136{
137 kfree(data);
138}
139
140static void tty_receive_char(struct tty_struct *tty, char ch) 83static void tty_receive_char(struct tty_struct *tty, char ch)
141{ 84{
142 if(tty == NULL) return; 85 if (tty == NULL)
86 return;
143 87
144 if(I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) { 88 if (I_IXON(tty) && !I_IXOFF(tty) && !tty->raw) {
145 if(ch == STOP_CHAR(tty)){ 89 if (ch == STOP_CHAR(tty)) {
146 stop_tty(tty); 90 stop_tty(tty);
147 return; 91 return;
148 } 92 }
149 else if(ch == START_CHAR(tty)){ 93 else if (ch == START_CHAR(tty)) {
150 start_tty(tty); 94 start_tty(tty);
151 return; 95 return;
152 } 96 }
@@ -159,14 +103,14 @@ static int open_one_chan(struct chan *chan)
159{ 103{
160 int fd, err; 104 int fd, err;
161 105
162 if(chan->opened) 106 if (chan->opened)
163 return 0; 107 return 0;
164 108
165 if(chan->ops->open == NULL) 109 if (chan->ops->open == NULL)
166 fd = 0; 110 fd = 0;
167 else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary, 111 else fd = (*chan->ops->open)(chan->input, chan->output, chan->primary,
168 chan->data, &chan->dev); 112 chan->data, &chan->dev);
169 if(fd < 0) 113 if (fd < 0)
170 return fd; 114 return fd;
171 115
172 err = os_set_fd_block(fd, 0); 116 err = os_set_fd_block(fd, 0);
@@ -187,10 +131,10 @@ int open_chan(struct list_head *chans)
187 struct chan *chan; 131 struct chan *chan;
188 int ret, err = 0; 132 int ret, err = 0;
189 133
190 list_for_each(ele, chans){ 134 list_for_each(ele, chans) {
191 chan = list_entry(ele, struct chan, list); 135 chan = list_entry(ele, struct chan, list);
192 ret = open_one_chan(chan); 136 ret = open_one_chan(chan);
193 if(chan->primary) 137 if (chan->primary)
194 err = ret; 138 err = ret;
195 } 139 }
196 return err; 140 return err;
@@ -201,9 +145,9 @@ void chan_enable_winch(struct list_head *chans, struct tty_struct *tty)
201 struct list_head *ele; 145 struct list_head *ele;
202 struct chan *chan; 146 struct chan *chan;
203 147
204 list_for_each(ele, chans){ 148 list_for_each(ele, chans) {
205 chan = list_entry(ele, struct chan, list); 149 chan = list_entry(ele, struct chan, list);
206 if(chan->primary && chan->output && chan->ops->winch){ 150 if (chan->primary && chan->output && chan->ops->winch) {
207 register_winch(chan->fd, tty); 151 register_winch(chan->fd, tty);
208 return; 152 return;
209 } 153 }
@@ -216,7 +160,7 @@ int enable_chan(struct line *line)
216 struct chan *chan; 160 struct chan *chan;
217 int err; 161 int err;
218 162
219 list_for_each(ele, &line->chan_list){ 163 list_for_each(ele, &line->chan_list) {
220 chan = list_entry(ele, struct chan, list); 164 chan = list_entry(ele, struct chan, list);
221 err = open_one_chan(chan); 165 err = open_one_chan(chan);
222 if (err) { 166 if (err) {
@@ -226,7 +170,7 @@ int enable_chan(struct line *line)
226 continue; 170 continue;
227 } 171 }
228 172
229 if(chan->enabled) 173 if (chan->enabled)
230 continue; 174 continue;
231 err = line_setup_irq(chan->fd, chan->input, chan->output, line, 175 err = line_setup_irq(chan->fd, chan->input, chan->output, line,
232 chan); 176 chan);
@@ -263,12 +207,12 @@ void free_irqs(void)
263 list_splice_init(&irqs_to_free, &list); 207 list_splice_init(&irqs_to_free, &list);
264 spin_unlock_irqrestore(&irqs_to_free_lock, flags); 208 spin_unlock_irqrestore(&irqs_to_free_lock, flags);
265 209
266 list_for_each(ele, &list){ 210 list_for_each(ele, &list) {
267 chan = list_entry(ele, struct chan, free_list); 211 chan = list_entry(ele, struct chan, free_list);
268 212
269 if(chan->input) 213 if (chan->input)
270 free_irq(chan->line->driver->read_irq, chan); 214 free_irq(chan->line->driver->read_irq, chan);
271 if(chan->output) 215 if (chan->output)
272 free_irq(chan->line->driver->write_irq, chan); 216 free_irq(chan->line->driver->write_irq, chan);
273 chan->enabled = 0; 217 chan->enabled = 0;
274 } 218 }
@@ -278,22 +222,22 @@ static void close_one_chan(struct chan *chan, int delay_free_irq)
278{ 222{
279 unsigned long flags; 223 unsigned long flags;
280 224
281 if(!chan->opened) 225 if (!chan->opened)
282 return; 226 return;
283 227
284 if(delay_free_irq){ 228 if (delay_free_irq) {
285 spin_lock_irqsave(&irqs_to_free_lock, flags); 229 spin_lock_irqsave(&irqs_to_free_lock, flags);
286 list_add(&chan->free_list, &irqs_to_free); 230 list_add(&chan->free_list, &irqs_to_free);
287 spin_unlock_irqrestore(&irqs_to_free_lock, flags); 231 spin_unlock_irqrestore(&irqs_to_free_lock, flags);
288 } 232 }
289 else { 233 else {
290 if(chan->input) 234 if (chan->input)
291 free_irq(chan->line->driver->read_irq, chan); 235 free_irq(chan->line->driver->read_irq, chan);
292 if(chan->output) 236 if (chan->output)
293 free_irq(chan->line->driver->write_irq, chan); 237 free_irq(chan->line->driver->write_irq, chan);
294 chan->enabled = 0; 238 chan->enabled = 0;
295 } 239 }
296 if(chan->ops->close != NULL) 240 if (chan->ops->close != NULL)
297 (*chan->ops->close)(chan->fd, chan->data); 241 (*chan->ops->close)(chan->fd, chan->data);
298 242
299 chan->opened = 0; 243 chan->opened = 0;
@@ -322,7 +266,7 @@ void deactivate_chan(struct list_head *chans, int irq)
322 list_for_each(ele, chans) { 266 list_for_each(ele, chans) {
323 chan = list_entry(ele, struct chan, list); 267 chan = list_entry(ele, struct chan, list);
324 268
325 if(chan->enabled && chan->input) 269 if (chan->enabled && chan->input)
326 deactivate_fd(chan->fd, irq); 270 deactivate_fd(chan->fd, irq);
327 } 271 }
328} 272}
@@ -335,7 +279,7 @@ void reactivate_chan(struct list_head *chans, int irq)
335 list_for_each(ele, chans) { 279 list_for_each(ele, chans) {
336 chan = list_entry(ele, struct chan, list); 280 chan = list_entry(ele, struct chan, list);
337 281
338 if(chan->enabled && chan->input) 282 if (chan->enabled && chan->input)
339 reactivate_fd(chan->fd, irq); 283 reactivate_fd(chan->fd, irq);
340 } 284 }
341} 285}
@@ -347,10 +291,14 @@ int write_chan(struct list_head *chans, const char *buf, int len,
347 struct chan *chan = NULL; 291 struct chan *chan = NULL;
348 int n, ret = 0; 292 int n, ret = 0;
349 293
294 if (len == 0)
295 return 0;
296
350 list_for_each(ele, chans) { 297 list_for_each(ele, chans) {
351 chan = list_entry(ele, struct chan, list); 298 chan = list_entry(ele, struct chan, list);
352 if (!chan->output || (chan->ops->write == NULL)) 299 if (!chan->output || (chan->ops->write == NULL))
353 continue; 300 continue;
301
354 n = chan->ops->write(chan->fd, buf, len, chan->data); 302 n = chan->ops->write(chan->fd, buf, len, chan->data);
355 if (chan->primary) { 303 if (chan->primary) {
356 ret = n; 304 ret = n;
@@ -367,12 +315,14 @@ int console_write_chan(struct list_head *chans, const char *buf, int len)
367 struct chan *chan; 315 struct chan *chan;
368 int n, ret = 0; 316 int n, ret = 0;
369 317
370 list_for_each(ele, chans){ 318 list_for_each(ele, chans) {
371 chan = list_entry(ele, struct chan, list); 319 chan = list_entry(ele, struct chan, list);
372 if(!chan->output || (chan->ops->console_write == NULL)) 320 if (!chan->output || (chan->ops->console_write == NULL))
373 continue; 321 continue;
322
374 n = chan->ops->console_write(chan->fd, buf, len); 323 n = chan->ops->console_write(chan->fd, buf, len);
375 if(chan->primary) ret = n; 324 if (chan->primary)
325 ret = n;
376 } 326 }
377 return ret; 327 return ret;
378} 328}
@@ -382,10 +332,11 @@ int console_open_chan(struct line *line, struct console *co)
382 int err; 332 int err;
383 333
384 err = open_chan(&line->chan_list); 334 err = open_chan(&line->chan_list);
385 if(err) 335 if (err)
386 return err; 336 return err;
387 337
388 printk("Console initialized on /dev/%s%d\n", co->name, co->index); 338 printk(KERN_INFO "Console initialized on /dev/%s%d\n", co->name,
339 co->index);
389 return 0; 340 return 0;
390} 341}
391 342
@@ -395,10 +346,10 @@ int chan_window_size(struct list_head *chans, unsigned short *rows_out,
395 struct list_head *ele; 346 struct list_head *ele;
396 struct chan *chan; 347 struct chan *chan;
397 348
398 list_for_each(ele, chans){ 349 list_for_each(ele, chans) {
399 chan = list_entry(ele, struct chan, list); 350 chan = list_entry(ele, struct chan, list);
400 if(chan->primary){ 351 if (chan->primary) {
401 if(chan->ops->window_size == NULL) 352 if (chan->ops->window_size == NULL)
402 return 0; 353 return 0;
403 return chan->ops->window_size(chan->fd, chan->data, 354 return chan->ops->window_size(chan->fd, chan->data,
404 rows_out, cols_out); 355 rows_out, cols_out);
@@ -413,10 +364,11 @@ static void free_one_chan(struct chan *chan, int delay_free_irq)
413 364
414 close_one_chan(chan, delay_free_irq); 365 close_one_chan(chan, delay_free_irq);
415 366
416 if(chan->ops->free != NULL) 367 if (chan->ops->free != NULL)
417 (*chan->ops->free)(chan->data); 368 (*chan->ops->free)(chan->data);
418 369
419 if(chan->primary && chan->output) ignore_sigio_fd(chan->fd); 370 if (chan->primary && chan->output)
371 ignore_sigio_fd(chan->fd);
420 kfree(chan); 372 kfree(chan);
421} 373}
422 374
@@ -425,7 +377,7 @@ static void free_chan(struct list_head *chans, int delay_free_irq)
425 struct list_head *ele, *next; 377 struct list_head *ele, *next;
426 struct chan *chan; 378 struct chan *chan;
427 379
428 list_for_each_safe(ele, next, chans){ 380 list_for_each_safe(ele, next, chans) {
429 chan = list_entry(ele, struct chan, list); 381 chan = list_entry(ele, struct chan, list);
430 free_one_chan(chan, delay_free_irq); 382 free_one_chan(chan, delay_free_irq);
431 } 383 }
@@ -436,14 +388,14 @@ static int one_chan_config_string(struct chan *chan, char *str, int size,
436{ 388{
437 int n = 0; 389 int n = 0;
438 390
439 if(chan == NULL){ 391 if (chan == NULL) {
440 CONFIG_CHUNK(str, size, n, "none", 1); 392 CONFIG_CHUNK(str, size, n, "none", 1);
441 return n; 393 return n;
442 } 394 }
443 395
444 CONFIG_CHUNK(str, size, n, chan->ops->type, 0); 396 CONFIG_CHUNK(str, size, n, chan->ops->type, 0);
445 397
446 if(chan->dev == NULL){ 398 if (chan->dev == NULL) {
447 CONFIG_CHUNK(str, size, n, "", 1); 399 CONFIG_CHUNK(str, size, n, "", 1);
448 return n; 400 return n;
449 } 401 }
@@ -463,7 +415,7 @@ static int chan_pair_config_string(struct chan *in, struct chan *out,
463 str += n; 415 str += n;
464 size -= n; 416 size -= n;
465 417
466 if(in == out){ 418 if (in == out) {
467 CONFIG_CHUNK(str, size, n, "", 1); 419 CONFIG_CHUNK(str, size, n, "", 1);
468 return n; 420 return n;
469 } 421 }
@@ -483,13 +435,13 @@ int chan_config_string(struct list_head *chans, char *str, int size,
483 struct list_head *ele; 435 struct list_head *ele;
484 struct chan *chan, *in = NULL, *out = NULL; 436 struct chan *chan, *in = NULL, *out = NULL;
485 437
486 list_for_each(ele, chans){ 438 list_for_each(ele, chans) {
487 chan = list_entry(ele, struct chan, list); 439 chan = list_entry(ele, struct chan, list);
488 if(!chan->primary) 440 if (!chan->primary)
489 continue; 441 continue;
490 if(chan->input) 442 if (chan->input)
491 in = chan; 443 in = chan;
492 if(chan->output) 444 if (chan->output)
493 out = chan; 445 out = chan;
494 } 446 }
495 447
@@ -548,27 +500,27 @@ static struct chan *parse_chan(struct line *line, char *str, int device,
548 500
549 ops = NULL; 501 ops = NULL;
550 data = NULL; 502 data = NULL;
551 for(i = 0; i < ARRAY_SIZE(chan_table); i++){ 503 for(i = 0; i < ARRAY_SIZE(chan_table); i++) {
552 entry = &chan_table[i]; 504 entry = &chan_table[i];
553 if(!strncmp(str, entry->key, strlen(entry->key))){ 505 if (!strncmp(str, entry->key, strlen(entry->key))) {
554 ops = entry->ops; 506 ops = entry->ops;
555 str += strlen(entry->key); 507 str += strlen(entry->key);
556 break; 508 break;
557 } 509 }
558 } 510 }
559 if(ops == NULL){ 511 if (ops == NULL) {
560 *error_out = "No match for configured backends"; 512 *error_out = "No match for configured backends";
561 return NULL; 513 return NULL;
562 } 514 }
563 515
564 data = (*ops->init)(str, device, opts); 516 data = (*ops->init)(str, device, opts);
565 if(data == NULL){ 517 if (data == NULL) {
566 *error_out = "Configuration failed"; 518 *error_out = "Configuration failed";
567 return NULL; 519 return NULL;
568 } 520 }
569 521
570 chan = kmalloc(sizeof(*chan), GFP_ATOMIC); 522 chan = kmalloc(sizeof(*chan), GFP_ATOMIC);
571 if(chan == NULL){ 523 if (chan == NULL) {
572 *error_out = "Memory allocation failed"; 524 *error_out = "Memory allocation failed";
573 return NULL; 525 return NULL;
574 } 526 }
@@ -594,26 +546,26 @@ int parse_chan_pair(char *str, struct line *line, int device,
594 struct chan *new, *chan; 546 struct chan *new, *chan;
595 char *in, *out; 547 char *in, *out;
596 548
597 if(!list_empty(chans)){ 549 if (!list_empty(chans)) {
598 chan = list_entry(chans->next, struct chan, list); 550 chan = list_entry(chans->next, struct chan, list);
599 free_chan(chans, 0); 551 free_chan(chans, 0);
600 INIT_LIST_HEAD(chans); 552 INIT_LIST_HEAD(chans);
601 } 553 }
602 554
603 out = strchr(str, ','); 555 out = strchr(str, ',');
604 if(out != NULL){ 556 if (out != NULL) {
605 in = str; 557 in = str;
606 *out = '\0'; 558 *out = '\0';
607 out++; 559 out++;
608 new = parse_chan(line, in, device, opts, error_out); 560 new = parse_chan(line, in, device, opts, error_out);
609 if(new == NULL) 561 if (new == NULL)
610 return -1; 562 return -1;
611 563
612 new->input = 1; 564 new->input = 1;
613 list_add(&new->list, chans); 565 list_add(&new->list, chans);
614 566
615 new = parse_chan(line, out, device, opts, error_out); 567 new = parse_chan(line, out, device, opts, error_out);
616 if(new == NULL) 568 if (new == NULL)
617 return -1; 569 return -1;
618 570
619 list_add(&new->list, chans); 571 list_add(&new->list, chans);
@@ -621,7 +573,7 @@ int parse_chan_pair(char *str, struct line *line, int device,
621 } 573 }
622 else { 574 else {
623 new = parse_chan(line, str, device, opts, error_out); 575 new = parse_chan(line, str, device, opts, error_out);
624 if(new == NULL) 576 if (new == NULL)
625 return -1; 577 return -1;
626 578
627 list_add(&new->list, chans); 579 list_add(&new->list, chans);
@@ -636,9 +588,9 @@ int chan_out_fd(struct list_head *chans)
636 struct list_head *ele; 588 struct list_head *ele;
637 struct chan *chan; 589 struct chan *chan;
638 590
639 list_for_each(ele, chans){ 591 list_for_each(ele, chans) {
640 chan = list_entry(ele, struct chan, list); 592 chan = list_entry(ele, struct chan, list);
641 if(chan->primary && chan->output) 593 if (chan->primary && chan->output)
642 return chan->fd; 594 return chan->fd;
643 } 595 }
644 return -1; 596 return -1;
@@ -652,23 +604,25 @@ void chan_interrupt(struct list_head *chans, struct delayed_work *task,
652 int err; 604 int err;
653 char c; 605 char c;
654 606
655 list_for_each_safe(ele, next, chans){ 607 list_for_each_safe(ele, next, chans) {
656 chan = list_entry(ele, struct chan, list); 608 chan = list_entry(ele, struct chan, list);
657 if(!chan->input || (chan->ops->read == NULL)) continue; 609 if (!chan->input || (chan->ops->read == NULL))
610 continue;
658 do { 611 do {
659 if (tty && !tty_buffer_request_room(tty, 1)) { 612 if (tty && !tty_buffer_request_room(tty, 1)) {
660 schedule_delayed_work(task, 1); 613 schedule_delayed_work(task, 1);
661 goto out; 614 goto out;
662 } 615 }
663 err = chan->ops->read(chan->fd, &c, chan->data); 616 err = chan->ops->read(chan->fd, &c, chan->data);
664 if(err > 0) 617 if (err > 0)
665 tty_receive_char(tty, c); 618 tty_receive_char(tty, c);
666 } while(err > 0); 619 } while (err > 0);
667 620
668 if(err == 0) reactivate_fd(chan->fd, irq); 621 if (err == 0)
669 if(err == -EIO){ 622 reactivate_fd(chan->fd, irq);
670 if(chan->primary){ 623 if (err == -EIO) {
671 if(tty != NULL) 624 if (chan->primary) {
625 if (tty != NULL)
672 tty_hangup(tty); 626 tty_hangup(tty);
673 close_chan(chans, 1); 627 close_chan(chans, 1);
674 return; 628 return;
@@ -677,5 +631,6 @@ void chan_interrupt(struct list_head *chans, struct delayed_work *task,
677 } 631 }
678 } 632 }
679 out: 633 out:
680 if(tty) tty_flip_buffer_push(tty); 634 if (tty)
635 tty_flip_buffer_push(tty);
681} 636}
diff --git a/arch/um/drivers/chan_user.c b/arch/um/drivers/chan_user.c
index 4d438f36ea2e..b88e93b3a39f 100644
--- a/arch/um/drivers/chan_user.c
+++ b/arch/um/drivers/chan_user.c
@@ -1,51 +1,107 @@
1/* 1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <unistd.h>
7#include <stdlib.h> 6#include <stdlib.h>
7#include <unistd.h>
8#include <errno.h> 8#include <errno.h>
9#include <termios.h>
10#include <string.h>
11#include <signal.h>
12#include <sched.h> 9#include <sched.h>
13#include <sys/stat.h> 10#include <signal.h>
11#include <termios.h>
14#include <sys/ioctl.h> 12#include <sys/ioctl.h>
15#include <sys/socket.h>
16#include "kern_util.h"
17#include "chan_user.h" 13#include "chan_user.h"
18#include "user.h"
19#include "os.h" 14#include "os.h"
20#include "choose-mode.h" 15#include "um_malloc.h"
21#include "mode.h" 16#include "user.h"
17
18void generic_close(int fd, void *unused)
19{
20 close(fd);
21}
22
23int generic_read(int fd, char *c_out, void *unused)
24{
25 int n;
26
27 n = read(fd, c_out, sizeof(*c_out));
28 if (n > 0)
29 return n;
30 else if (errno == EAGAIN)
31 return 0;
32 else if (n == 0)
33 return -EIO;
34 return -errno;
35}
36
37/* XXX Trivial wrapper around write */
38
39int generic_write(int fd, const char *buf, int n, void *unused)
40{
41 int err;
42
43 err = write(fd, buf, n);
44 if (err > 0)
45 return err;
46 else if (errno == EAGAIN)
47 return 0;
48 else if (err == 0)
49 return -EIO;
50 return -errno;
51}
52
53int generic_window_size(int fd, void *unused, unsigned short *rows_out,
54 unsigned short *cols_out)
55{
56 struct winsize size;
57 int ret;
58
59 if (ioctl(fd, TIOCGWINSZ, &size) < 0)
60 return -errno;
61
62 ret = ((*rows_out != size.ws_row) || (*cols_out != size.ws_col));
63
64 *rows_out = size.ws_row;
65 *cols_out = size.ws_col;
66
67 return ret;
68}
69
70void generic_free(void *data)
71{
72 kfree(data);
73}
22 74
23int generic_console_write(int fd, const char *buf, int n) 75int generic_console_write(int fd, const char *buf, int n)
24{ 76{
25 struct termios save, new; 77 struct termios save, new;
26 int err; 78 int err;
27 79
28 if(isatty(fd)){ 80 if (isatty(fd)) {
29 CATCH_EINTR(err = tcgetattr(fd, &save)); 81 CATCH_EINTR(err = tcgetattr(fd, &save));
30 if (err) 82 if (err)
31 goto error; 83 goto error;
32 new = save; 84 new = save;
33 /* The terminal becomes a bit less raw, to handle \n also as 85 /*
86 * The terminal becomes a bit less raw, to handle \n also as
34 * "Carriage Return", not only as "New Line". Otherwise, the new 87 * "Carriage Return", not only as "New Line". Otherwise, the new
35 * line won't start at the first column.*/ 88 * line won't start at the first column.
89 */
36 new.c_oflag |= OPOST; 90 new.c_oflag |= OPOST;
37 CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &new)); 91 CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &new));
38 if (err) 92 if (err)
39 goto error; 93 goto error;
40 } 94 }
41 err = generic_write(fd, buf, n, NULL); 95 err = generic_write(fd, buf, n, NULL);
42 /* Restore raw mode, in any case; we *must* ignore any error apart 96 /*
43 * EINTR, except for debug.*/ 97 * Restore raw mode, in any case; we *must* ignore any error apart
44 if(isatty(fd)) 98 * EINTR, except for debug.
99 */
100 if (isatty(fd))
45 CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save)); 101 CATCH_EINTR(tcsetattr(fd, TCSAFLUSH, &save));
46 return(err); 102 return err;
47error: 103error:
48 return(-errno); 104 return -errno;
49} 105}
50 106
51/* 107/*
@@ -82,62 +138,73 @@ static int winch_thread(void *arg)
82 struct winch_data *data = arg; 138 struct winch_data *data = arg;
83 sigset_t sigs; 139 sigset_t sigs;
84 int pty_fd, pipe_fd; 140 int pty_fd, pipe_fd;
85 int count, err; 141 int count;
86 char c = 1; 142 char c = 1;
87 143
88 pty_fd = data->pty_fd; 144 pty_fd = data->pty_fd;
89 pipe_fd = data->pipe_fd; 145 pipe_fd = data->pipe_fd;
90 count = os_write_file(pipe_fd, &c, sizeof(c)); 146 count = write(pipe_fd, &c, sizeof(c));
91 if(count != sizeof(c)) 147 if (count != sizeof(c))
92 printk("winch_thread : failed to write synchronization " 148 printk(UM_KERN_ERR "winch_thread : failed to write "
93 "byte, err = %d\n", -count); 149 "synchronization byte, err = %d\n", -count);
94 150
95 /* We are not using SIG_IGN on purpose, so don't fix it as I thought to 151 /*
152 * We are not using SIG_IGN on purpose, so don't fix it as I thought to
96 * do! If using SIG_IGN, the sigsuspend() call below would not stop on 153 * do! If using SIG_IGN, the sigsuspend() call below would not stop on
97 * SIGWINCH. */ 154 * SIGWINCH.
155 */
98 156
99 signal(SIGWINCH, winch_handler); 157 signal(SIGWINCH, winch_handler);
100 sigfillset(&sigs); 158 sigfillset(&sigs);
101 /* Block all signals possible. */ 159 /* Block all signals possible. */
102 if(sigprocmask(SIG_SETMASK, &sigs, NULL) < 0){ 160 if (sigprocmask(SIG_SETMASK, &sigs, NULL) < 0) {
103 printk("winch_thread : sigprocmask failed, errno = %d\n", 161 printk(UM_KERN_ERR "winch_thread : sigprocmask failed, "
104 errno); 162 "errno = %d\n", errno);
105 exit(1); 163 exit(1);
106 } 164 }
107 /* In sigsuspend(), block anything else than SIGWINCH. */ 165 /* In sigsuspend(), block anything else than SIGWINCH. */
108 sigdelset(&sigs, SIGWINCH); 166 sigdelset(&sigs, SIGWINCH);
109 167
110 if(setsid() < 0){ 168 if (setsid() < 0) {
111 printk("winch_thread : setsid failed, errno = %d\n", errno); 169 printk(UM_KERN_ERR "winch_thread : setsid failed, errno = %d\n",
170 errno);
171 exit(1);
172 }
173
174 if (ioctl(pty_fd, TIOCSCTTY, 0) < 0) {
175 printk(UM_KERN_ERR "winch_thread : TIOCSCTTY failed on "
176 "fd %d err = %d\n", pty_fd, errno);
112 exit(1); 177 exit(1);
113 } 178 }
114 179
115 err = os_new_tty_pgrp(pty_fd, os_getpid()); 180 if (tcsetpgrp(pty_fd, os_getpid()) < 0) {
116 if(err < 0){ 181 printk(UM_KERN_ERR "winch_thread : tcsetpgrp failed on "
117 printk("winch_thread : new_tty_pgrp failed on fd %d, " 182 "fd %d err = %d\n", pty_fd, errno);
118 "err = %d\n", pty_fd, -err);
119 exit(1); 183 exit(1);
120 } 184 }
121 185
122 /* These are synchronization calls between various UML threads on the 186 /*
187 * These are synchronization calls between various UML threads on the
123 * host - since they are not different kernel threads, we cannot use 188 * host - since they are not different kernel threads, we cannot use
124 * kernel semaphores. We don't use SysV semaphores because they are 189 * kernel semaphores. We don't use SysV semaphores because they are
125 * persistent. */ 190 * persistent.
126 count = os_read_file(pipe_fd, &c, sizeof(c)); 191 */
127 if(count != sizeof(c)) 192 count = read(pipe_fd, &c, sizeof(c));
128 printk("winch_thread : failed to read synchronization byte, " 193 if (count != sizeof(c))
129 "err = %d\n", -count); 194 printk(UM_KERN_ERR "winch_thread : failed to read "
130 195 "synchronization byte, err = %d\n", errno);
131 while(1){ 196
132 /* This will be interrupted by SIGWINCH only, since 197 while(1) {
198 /*
199 * This will be interrupted by SIGWINCH only, since
133 * other signals are blocked. 200 * other signals are blocked.
134 */ 201 */
135 sigsuspend(&sigs); 202 sigsuspend(&sigs);
136 203
137 count = os_write_file(pipe_fd, &c, sizeof(c)); 204 count = write(pipe_fd, &c, sizeof(c));
138 if(count != sizeof(c)) 205 if (count != sizeof(c))
139 printk("winch_thread : write failed, err = %d\n", 206 printk(UM_KERN_ERR "winch_thread : write failed, "
140 -count); 207 "err = %d\n", errno);
141 } 208 }
142} 209}
143 210
@@ -149,44 +216,49 @@ static int winch_tramp(int fd, struct tty_struct *tty, int *fd_out,
149 char c; 216 char c;
150 217
151 err = os_pipe(fds, 1, 1); 218 err = os_pipe(fds, 1, 1);
152 if(err < 0){ 219 if (err < 0) {
153 printk("winch_tramp : os_pipe failed, err = %d\n", -err); 220 printk(UM_KERN_ERR "winch_tramp : os_pipe failed, err = %d\n",
221 -err);
154 goto out; 222 goto out;
155 } 223 }
156 224
157 data = ((struct winch_data) { .pty_fd = fd, 225 data = ((struct winch_data) { .pty_fd = fd,
158 .pipe_fd = fds[1] } ); 226 .pipe_fd = fds[1] } );
159 /* CLONE_FILES so this thread doesn't hold open files which are open 227 /*
228 * CLONE_FILES so this thread doesn't hold open files which are open
160 * now, but later closed in a different thread. This is a 229 * now, but later closed in a different thread. This is a
161 * problem with /dev/net/tun, which if held open by this 230 * problem with /dev/net/tun, which if held open by this
162 * thread, prevents the TUN/TAP device from being reused. 231 * thread, prevents the TUN/TAP device from being reused.
163 */ 232 */
164 err = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out); 233 err = run_helper_thread(winch_thread, &data, CLONE_FILES, stack_out);
165 if(err < 0){ 234 if (err < 0) {
166 printk("fork of winch_thread failed - errno = %d\n", -err); 235 printk(UM_KERN_ERR "fork of winch_thread failed - errno = %d\n",
236 -err);
167 goto out_close; 237 goto out_close;
168 } 238 }
169 239
170 *fd_out = fds[0]; 240 *fd_out = fds[0];
171 n = os_read_file(fds[0], &c, sizeof(c)); 241 n = read(fds[0], &c, sizeof(c));
172 if(n != sizeof(c)){ 242 if (n != sizeof(c)) {
173 printk("winch_tramp : failed to read synchronization byte\n"); 243 printk(UM_KERN_ERR "winch_tramp : failed to read "
174 printk("read failed, err = %d\n", -n); 244 "synchronization byte\n");
175 printk("fd %d will not support SIGWINCH\n", fd); 245 printk(UM_KERN_ERR "read failed, err = %d\n", errno);
176 err = -EINVAL; 246 printk(UM_KERN_ERR "fd %d will not support SIGWINCH\n", fd);
247 err = -EINVAL;
177 goto out_close; 248 goto out_close;
178 } 249 }
179 250
180 if (os_set_fd_block(*fd_out, 0)) { 251 if (os_set_fd_block(*fd_out, 0)) {
181 printk("winch_tramp: failed to set thread_fd non-blocking.\n"); 252 printk(UM_KERN_ERR "winch_tramp: failed to set thread_fd "
253 "non-blocking.\n");
182 goto out_close; 254 goto out_close;
183 } 255 }
184 256
185 return err; 257 return err;
186 258
187 out_close: 259 out_close:
188 os_close_file(fds[1]); 260 close(fds[1]);
189 os_close_file(fds[0]); 261 close(fds[0]);
190 out: 262 out:
191 return err; 263 return err;
192} 264}
@@ -197,21 +269,20 @@ void register_winch(int fd, struct tty_struct *tty)
197 int pid, thread, count, thread_fd = -1; 269 int pid, thread, count, thread_fd = -1;
198 char c = 1; 270 char c = 1;
199 271
200 if(!isatty(fd)) 272 if (!isatty(fd))
201 return; 273 return;
202 274
203 pid = tcgetpgrp(fd); 275 pid = tcgetpgrp(fd);
204 if (!CHOOSE_MODE_PROC(is_tracer_winch, is_skas_winch, pid, fd, tty) && 276 if (!is_skas_winch(pid, fd, tty) && (pid == -1)) {
205 (pid == -1)) {
206 thread = winch_tramp(fd, tty, &thread_fd, &stack); 277 thread = winch_tramp(fd, tty, &thread_fd, &stack);
207 if (thread < 0) 278 if (thread < 0)
208 return; 279 return;
209 280
210 register_winch_irq(thread_fd, fd, thread, tty, stack); 281 register_winch_irq(thread_fd, fd, thread, tty, stack);
211 282
212 count = os_write_file(thread_fd, &c, sizeof(c)); 283 count = write(thread_fd, &c, sizeof(c));
213 if(count != sizeof(c)) 284 if (count != sizeof(c))
214 printk("register_winch : failed to write " 285 printk(UM_KERN_ERR "register_winch : failed to write "
215 "synchronization byte, err = %d\n", -count); 286 "synchronization byte, err = %d\n", errno);
216 } 287 }
217} 288}
diff --git a/arch/um/drivers/cow_user.c b/arch/um/drivers/cow_user.c
index 0ec4052db9c5..93f227a25ba4 100644
--- a/arch/um/drivers/cow_user.c
+++ b/arch/um/drivers/cow_user.c
@@ -1,17 +1,18 @@
1#include <stddef.h> 1/*
2#include <string.h> 2 * Copyright (C) 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3#include <errno.h> 3 * Licensed under the GPL
4/* _XOPEN_SOURCE is needed for pread, but we define _GNU_SOURCE, which defines 4 */
5
6/*
7 * _XOPEN_SOURCE is needed for pread, but we define _GNU_SOURCE, which defines
5 * that. 8 * that.
6 */ 9 */
7#include <unistd.h> 10#include <unistd.h>
8#include <byteswap.h> 11#include <byteswap.h>
9#include <sys/time.h> 12#include <errno.h>
10#include <sys/param.h> 13#include <string.h>
11#include <sys/user.h> 14#include <arpa/inet.h>
12 15#include <asm/types.h>
13#include "os.h"
14
15#include "cow.h" 16#include "cow.h"
16#include "cow_sys.h" 17#include "cow_sys.h"
17 18
@@ -28,7 +29,8 @@ struct cow_header_v1 {
28 __s32 sectorsize; 29 __s32 sectorsize;
29} __attribute__((packed)); 30} __attribute__((packed));
30 31
31/* Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in 32/*
33 * Define PATH_LEN_V3 as the usual value of MAXPATHLEN, just hard-code it in
32 * case other systems have different values for MAXPATHLEN. 34 * case other systems have different values for MAXPATHLEN.
33 * 35 *
34 * The same must hold for V2 - we want file format compatibility, not anything 36 * The same must hold for V2 - we want file format compatibility, not anything
@@ -46,7 +48,8 @@ struct cow_header_v2 {
46 __s32 sectorsize; 48 __s32 sectorsize;
47} __attribute__((packed)); 49} __attribute__((packed));
48 50
49/* Changes from V2 - 51/*
52 * Changes from V2 -
50 * PATH_LEN_V3 as described above 53 * PATH_LEN_V3 as described above
51 * Explicitly specify field bit lengths for systems with different 54 * Explicitly specify field bit lengths for systems with different
52 * lengths for the usual C types. Not sure whether char or 55 * lengths for the usual C types. Not sure whether char or
@@ -70,7 +73,8 @@ struct cow_header_v2 {
70 * Fixed (finally!) the rounding bug 73 * Fixed (finally!) the rounding bug
71 */ 74 */
72 75
73/* Until Dec2005, __attribute__((packed)) was left out from the below 76/*
77 * Until Dec2005, __attribute__((packed)) was left out from the below
74 * definition, leading on 64-bit systems to 4 bytes of padding after mtime, to 78 * definition, leading on 64-bit systems to 4 bytes of padding after mtime, to
75 * align size to 8-byte alignment. This shifted all fields above (no padding 79 * align size to 8-byte alignment. This shifted all fields above (no padding
76 * was present on 32-bit, no other padding was added). 80 * was present on 32-bit, no other padding was added).
@@ -122,7 +126,7 @@ void cow_sizes(int version, __u64 size, int sectorsize, int align,
122 int bitmap_offset, unsigned long *bitmap_len_out, 126 int bitmap_offset, unsigned long *bitmap_len_out,
123 int *data_offset_out) 127 int *data_offset_out)
124{ 128{
125 if(version < 3){ 129 if (version < 3) {
126 *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize); 130 *bitmap_len_out = (size + sectorsize - 1) / (8 * sectorsize);
127 131
128 *data_offset_out = bitmap_offset + *bitmap_len_out; 132 *data_offset_out = bitmap_offset + *bitmap_len_out;
@@ -144,46 +148,46 @@ static int absolutize(char *to, int size, char *from)
144 char save_cwd[256], *slash; 148 char save_cwd[256], *slash;
145 int remaining; 149 int remaining;
146 150
147 if(getcwd(save_cwd, sizeof(save_cwd)) == NULL) { 151 if (getcwd(save_cwd, sizeof(save_cwd)) == NULL) {
148 cow_printf("absolutize : unable to get cwd - errno = %d\n", 152 cow_printf("absolutize : unable to get cwd - errno = %d\n",
149 errno); 153 errno);
150 return(-1); 154 return -1;
151 } 155 }
152 slash = strrchr(from, '/'); 156 slash = strrchr(from, '/');
153 if(slash != NULL){ 157 if (slash != NULL) {
154 *slash = '\0'; 158 *slash = '\0';
155 if(chdir(from)){ 159 if (chdir(from)) {
156 *slash = '/'; 160 *slash = '/';
157 cow_printf("absolutize : Can't cd to '%s' - " 161 cow_printf("absolutize : Can't cd to '%s' - "
158 "errno = %d\n", from, errno); 162 "errno = %d\n", from, errno);
159 return(-1); 163 return -1;
160 } 164 }
161 *slash = '/'; 165 *slash = '/';
162 if(getcwd(to, size) == NULL){ 166 if (getcwd(to, size) == NULL) {
163 cow_printf("absolutize : unable to get cwd of '%s' - " 167 cow_printf("absolutize : unable to get cwd of '%s' - "
164 "errno = %d\n", from, errno); 168 "errno = %d\n", from, errno);
165 return(-1); 169 return -1;
166 } 170 }
167 remaining = size - strlen(to); 171 remaining = size - strlen(to);
168 if(strlen(slash) + 1 > remaining){ 172 if (strlen(slash) + 1 > remaining) {
169 cow_printf("absolutize : unable to fit '%s' into %d " 173 cow_printf("absolutize : unable to fit '%s' into %d "
170 "chars\n", from, size); 174 "chars\n", from, size);
171 return(-1); 175 return -1;
172 } 176 }
173 strcat(to, slash); 177 strcat(to, slash);
174 } 178 }
175 else { 179 else {
176 if(strlen(save_cwd) + 1 + strlen(from) + 1 > size){ 180 if (strlen(save_cwd) + 1 + strlen(from) + 1 > size) {
177 cow_printf("absolutize : unable to fit '%s' into %d " 181 cow_printf("absolutize : unable to fit '%s' into %d "
178 "chars\n", from, size); 182 "chars\n", from, size);
179 return(-1); 183 return -1;
180 } 184 }
181 strcpy(to, save_cwd); 185 strcpy(to, save_cwd);
182 strcat(to, "/"); 186 strcat(to, "/");
183 strcat(to, from); 187 strcat(to, from);
184 } 188 }
185 chdir(save_cwd); 189 chdir(save_cwd);
186 return(0); 190 return 0;
187} 191}
188 192
189int write_cow_header(char *cow_file, int fd, char *backing_file, 193int write_cow_header(char *cow_file, int fd, char *backing_file,
@@ -194,22 +198,23 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
194 int err; 198 int err;
195 199
196 err = cow_seek_file(fd, 0); 200 err = cow_seek_file(fd, 0);
197 if(err < 0){ 201 if (err < 0) {
198 cow_printf("write_cow_header - lseek failed, err = %d\n", -err); 202 cow_printf("write_cow_header - lseek failed, err = %d\n", -err);
199 goto out; 203 goto out;
200 } 204 }
201 205
202 err = -ENOMEM; 206 err = -ENOMEM;
203 header = cow_malloc(sizeof(*header)); 207 header = cow_malloc(sizeof(*header));
204 if(header == NULL){ 208 if (header == NULL) {
205 cow_printf("write_cow_header - failed to allocate COW V3 header\n"); 209 cow_printf("write_cow_header - failed to allocate COW V3 "
210 "header\n");
206 goto out; 211 goto out;
207 } 212 }
208 header->magic = htonl(COW_MAGIC); 213 header->magic = htonl(COW_MAGIC);
209 header->version = htonl(COW_VERSION); 214 header->version = htonl(COW_VERSION);
210 215
211 err = -EINVAL; 216 err = -EINVAL;
212 if(strlen(backing_file) > sizeof(header->backing_file) - 1){ 217 if (strlen(backing_file) > sizeof(header->backing_file) - 1) {
213 /* Below, %zd is for a size_t value */ 218 /* Below, %zd is for a size_t value */
214 cow_printf("Backing file name \"%s\" is too long - names are " 219 cow_printf("Backing file name \"%s\" is too long - names are "
215 "limited to %zd characters\n", backing_file, 220 "limited to %zd characters\n", backing_file,
@@ -217,12 +222,12 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
217 goto out_free; 222 goto out_free;
218 } 223 }
219 224
220 if(absolutize(header->backing_file, sizeof(header->backing_file), 225 if (absolutize(header->backing_file, sizeof(header->backing_file),
221 backing_file)) 226 backing_file))
222 goto out_free; 227 goto out_free;
223 228
224 err = os_file_modtime(header->backing_file, &modtime); 229 err = os_file_modtime(header->backing_file, &modtime);
225 if(err < 0){ 230 if (err < 0) {
226 cow_printf("write_cow_header - backing file '%s' mtime " 231 cow_printf("write_cow_header - backing file '%s' mtime "
227 "request failed, err = %d\n", header->backing_file, 232 "request failed, err = %d\n", header->backing_file,
228 -err); 233 -err);
@@ -230,7 +235,7 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
230 } 235 }
231 236
232 err = cow_file_size(header->backing_file, size); 237 err = cow_file_size(header->backing_file, size);
233 if(err < 0){ 238 if (err < 0) {
234 cow_printf("write_cow_header - couldn't get size of " 239 cow_printf("write_cow_header - couldn't get size of "
235 "backing file '%s', err = %d\n", 240 "backing file '%s', err = %d\n",
236 header->backing_file, -err); 241 header->backing_file, -err);
@@ -244,7 +249,7 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
244 header->cow_format = COW_BITMAP; 249 header->cow_format = COW_BITMAP;
245 250
246 err = cow_write_file(fd, header, sizeof(*header)); 251 err = cow_write_file(fd, header, sizeof(*header));
247 if(err != sizeof(*header)){ 252 if (err != sizeof(*header)) {
248 cow_printf("write_cow_header - write of header to " 253 cow_printf("write_cow_header - write of header to "
249 "new COW file '%s' failed, err = %d\n", cow_file, 254 "new COW file '%s' failed, err = %d\n", cow_file,
250 -err); 255 -err);
@@ -254,14 +259,14 @@ int write_cow_header(char *cow_file, int fd, char *backing_file,
254 out_free: 259 out_free:
255 cow_free(header); 260 cow_free(header);
256 out: 261 out:
257 return(err); 262 return err;
258} 263}
259 264
260int file_reader(__u64 offset, char *buf, int len, void *arg) 265int file_reader(__u64 offset, char *buf, int len, void *arg)
261{ 266{
262 int fd = *((int *) arg); 267 int fd = *((int *) arg);
263 268
264 return(pread(fd, buf, len, offset)); 269 return pread(fd, buf, len, offset);
265} 270}
266 271
267/* XXX Need to sanity-check the values read from the header */ 272/* XXX Need to sanity-check the values read from the header */
@@ -278,31 +283,29 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
278 unsigned long version, magic; 283 unsigned long version, magic;
279 284
280 header = cow_malloc(sizeof(*header)); 285 header = cow_malloc(sizeof(*header));
281 if(header == NULL){ 286 if (header == NULL) {
282 cow_printf("read_cow_header - Failed to allocate header\n"); 287 cow_printf("read_cow_header - Failed to allocate header\n");
283 return(-ENOMEM); 288 return -ENOMEM;
284 } 289 }
285 err = -EINVAL; 290 err = -EINVAL;
286 n = (*reader)(0, (char *) header, sizeof(*header), arg); 291 n = (*reader)(0, (char *) header, sizeof(*header), arg);
287 if(n < offsetof(typeof(header->v1), backing_file)){ 292 if (n < offsetof(typeof(header->v1), backing_file)) {
288 cow_printf("read_cow_header - short header\n"); 293 cow_printf("read_cow_header - short header\n");
289 goto out; 294 goto out;
290 } 295 }
291 296
292 magic = header->v1.magic; 297 magic = header->v1.magic;
293 if(magic == COW_MAGIC) { 298 if (magic == COW_MAGIC)
294 version = header->v1.version; 299 version = header->v1.version;
295 } 300 else if (magic == ntohl(COW_MAGIC))
296 else if(magic == ntohl(COW_MAGIC)){
297 version = ntohl(header->v1.version); 301 version = ntohl(header->v1.version);
298 }
299 /* No error printed because the non-COW case comes through here */ 302 /* No error printed because the non-COW case comes through here */
300 else goto out; 303 else goto out;
301 304
302 *version_out = version; 305 *version_out = version;
303 306
304 if(version == 1){ 307 if (version == 1) {
305 if(n < sizeof(header->v1)){ 308 if (n < sizeof(header->v1)) {
306 cow_printf("read_cow_header - failed to read V1 " 309 cow_printf("read_cow_header - failed to read V1 "
307 "header\n"); 310 "header\n");
308 goto out; 311 goto out;
@@ -314,8 +317,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
314 *align_out = *sectorsize_out; 317 *align_out = *sectorsize_out;
315 file = header->v1.backing_file; 318 file = header->v1.backing_file;
316 } 319 }
317 else if(version == 2){ 320 else if (version == 2) {
318 if(n < sizeof(header->v2)){ 321 if (n < sizeof(header->v2)) {
319 cow_printf("read_cow_header - failed to read V2 " 322 cow_printf("read_cow_header - failed to read V2 "
320 "header\n"); 323 "header\n");
321 goto out; 324 goto out;
@@ -328,8 +331,8 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
328 file = header->v2.backing_file; 331 file = header->v2.backing_file;
329 } 332 }
330 /* This is very subtle - see above at union cow_header definition */ 333 /* This is very subtle - see above at union cow_header definition */
331 else if(version == 3 && (*((int*)header->v3.backing_file) != 0)){ 334 else if (version == 3 && (*((int*)header->v3.backing_file) != 0)) {
332 if(n < sizeof(header->v3)){ 335 if (n < sizeof(header->v3)) {
333 cow_printf("read_cow_header - failed to read V3 " 336 cow_printf("read_cow_header - failed to read V3 "
334 "header\n"); 337 "header\n");
335 goto out; 338 goto out;
@@ -345,17 +348,18 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
345 *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out); 348 *bitmap_offset_out = ROUND_UP(sizeof(header->v3), *align_out);
346 file = header->v3.backing_file; 349 file = header->v3.backing_file;
347 } 350 }
348 else if(version == 3){ 351 else if (version == 3) {
349 cow_printf("read_cow_header - broken V3 file with" 352 cow_printf("read_cow_header - broken V3 file with"
350 " 64-bit layout - recovering content.\n"); 353 " 64-bit layout - recovering content.\n");
351 354
352 if(n < sizeof(header->v3_b)){ 355 if (n < sizeof(header->v3_b)) {
353 cow_printf("read_cow_header - failed to read V3 " 356 cow_printf("read_cow_header - failed to read V3 "
354 "header\n"); 357 "header\n");
355 goto out; 358 goto out;
356 } 359 }
357 360
358 /* this was used until Dec2005 - 64bits are needed to represent 361 /*
362 * this was used until Dec2005 - 64bits are needed to represent
359 * 2038+. I.e. we can safely do this truncating cast. 363 * 2038+. I.e. we can safely do this truncating cast.
360 * 364 *
361 * Additionally, we must use ntohl() instead of ntohll(), since 365 * Additionally, we must use ntohl() instead of ntohll(), since
@@ -381,7 +385,7 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
381 } 385 }
382 err = -ENOMEM; 386 err = -ENOMEM;
383 *backing_file_out = cow_strdup(file); 387 *backing_file_out = cow_strdup(file);
384 if(*backing_file_out == NULL){ 388 if (*backing_file_out == NULL) {
385 cow_printf("read_cow_header - failed to allocate backing " 389 cow_printf("read_cow_header - failed to allocate backing "
386 "file\n"); 390 "file\n");
387 goto out; 391 goto out;
@@ -389,7 +393,7 @@ int read_cow_header(int (*reader)(__u64, char *, int, void *), void *arg,
389 err = 0; 393 err = 0;
390 out: 394 out:
391 cow_free(header); 395 cow_free(header);
392 return(err); 396 return err;
393} 397}
394 398
395int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize, 399int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
@@ -402,7 +406,7 @@ int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
402 406
403 err = write_cow_header(cow_file, fd, backing_file, sectorsize, 407 err = write_cow_header(cow_file, fd, backing_file, sectorsize,
404 alignment, &size); 408 alignment, &size);
405 if(err) 409 if (err)
406 goto out; 410 goto out;
407 411
408 *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment); 412 *bitmap_offset_out = ROUND_UP(sizeof(struct cow_header_v3), alignment);
@@ -411,17 +415,18 @@ int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
411 415
412 offset = *data_offset_out + size - sizeof(zero); 416 offset = *data_offset_out + size - sizeof(zero);
413 err = cow_seek_file(fd, offset); 417 err = cow_seek_file(fd, offset);
414 if(err < 0){ 418 if (err < 0) {
415 cow_printf("cow bitmap lseek failed : err = %d\n", -err); 419 cow_printf("cow bitmap lseek failed : err = %d\n", -err);
416 goto out; 420 goto out;
417 } 421 }
418 422
419 /* does not really matter how much we write it is just to set EOF 423 /*
424 * does not really matter how much we write it is just to set EOF
420 * this also sets the entire COW bitmap 425 * this also sets the entire COW bitmap
421 * to zero without having to allocate it 426 * to zero without having to allocate it
422 */ 427 */
423 err = cow_write_file(fd, &zero, sizeof(zero)); 428 err = cow_write_file(fd, &zero, sizeof(zero));
424 if(err != sizeof(zero)){ 429 if (err != sizeof(zero)) {
425 cow_printf("Write of bitmap to new COW file '%s' failed, " 430 cow_printf("Write of bitmap to new COW file '%s' failed, "
426 "err = %d\n", cow_file, -err); 431 "err = %d\n", cow_file, -err);
427 if (err >= 0) 432 if (err >= 0)
@@ -429,15 +434,7 @@ int init_cow_file(int fd, char *cow_file, char *backing_file, int sectorsize,
429 goto out; 434 goto out;
430 } 435 }
431 436
432 return(0); 437 return 0;
433
434 out: 438 out:
435 return(err); 439 return err;
436} 440}
437
438/*
439 * ---------------------------------------------------------------------------
440 * Local variables:
441 * c-file-style: "linux"
442 * End:
443 */
diff --git a/arch/um/drivers/daemon.h b/arch/um/drivers/daemon.h
index 3bc3cf6b94aa..6e0e891f8a00 100644
--- a/arch/um/drivers/daemon.h
+++ b/arch/um/drivers/daemon.h
@@ -1,8 +1,11 @@
1/* 1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#ifndef __DAEMON_H__
7#define __DAEMON_H__
8
6#include "net_user.h" 9#include "net_user.h"
7 10
8#define SWITCH_VERSION 3 11#define SWITCH_VERSION 3
@@ -20,16 +23,7 @@ struct daemon_data {
20 23
21extern const struct net_user_info daemon_user_info; 24extern const struct net_user_info daemon_user_info;
22 25
23extern int daemon_user_write(int fd, void *buf, int len, 26extern int daemon_user_write(int fd, void *buf, int len,
24 struct daemon_data *pri); 27 struct daemon_data *pri);
25 28
26/* 29#endif
27 * Overrides for Emacs so that we follow Linus's tabbing style.
28 * Emacs will notice this stuff at the end of the file and automatically
29 * adjust the settings for this buffer only. This must remain at the end
30 * of the file.
31 * ---------------------------------------------------------------------------
32 * Local variables:
33 * c-file-style: "linux"
34 * End:
35 */
diff --git a/arch/um/drivers/daemon_kern.c b/arch/um/drivers/daemon_kern.c
index adeece11e596..d53ff52bb404 100644
--- a/arch/um/drivers/daemon_kern.c
+++ b/arch/um/drivers/daemon_kern.c
@@ -1,16 +1,14 @@
1/* 1/*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
3 * James Leu (jleu@mindspring.net). 3 * James Leu (jleu@mindspring.net).
4 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Copyright (C) 2001 by various other people who didn't put their name here. 5 * Copyright (C) 2001 by various other people who didn't put their name here.
5 * Licensed under the GPL. 6 * Licensed under the GPL.
6 */ 7 */
7 8
8#include "linux/kernel.h"
9#include "linux/init.h" 9#include "linux/init.h"
10#include "linux/netdevice.h" 10#include <linux/netdevice.h>
11#include "linux/etherdevice.h"
12#include "net_kern.h" 11#include "net_kern.h"
13#include "net_user.h"
14#include "daemon.h" 12#include "daemon.h"
15 13
16struct daemon_init { 14struct daemon_init {
@@ -36,25 +34,21 @@ static void daemon_init(struct net_device *dev, void *data)
36 dpri->data_addr = NULL; 34 dpri->data_addr = NULL;
37 dpri->local_addr = NULL; 35 dpri->local_addr = NULL;
38 36
39 printk("daemon backend (uml_switch version %d) - %s:%s", 37 printk("daemon backend (uml_switch version %d) - %s:%s",
40 SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock); 38 SWITCH_VERSION, dpri->sock_type, dpri->ctl_sock);
41 printk("\n"); 39 printk("\n");
42} 40}
43 41
44static int daemon_read(int fd, struct sk_buff **skb, 42static int daemon_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
45 struct uml_net_private *lp)
46{ 43{
47 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 44 return net_recvfrom(fd, skb_mac_header(skb),
48 if(*skb == NULL) return(-ENOMEM); 45 skb->dev->mtu + ETH_HEADER_OTHER);
49 return(net_recvfrom(fd, skb_mac_header(*skb),
50 (*skb)->dev->mtu + ETH_HEADER_OTHER));
51} 46}
52 47
53static int daemon_write(int fd, struct sk_buff **skb, 48static int daemon_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
54 struct uml_net_private *lp)
55{ 49{
56 return(daemon_user_write(fd, (*skb)->data, (*skb)->len, 50 return daemon_user_write(fd, skb->data, skb->len,
57 (struct daemon_data *) &lp->user)); 51 (struct daemon_data *) &lp->user);
58} 52}
59 53
60static const struct net_kern_info daemon_kern_info = { 54static const struct net_kern_info daemon_kern_info = {
@@ -72,14 +66,14 @@ static int daemon_setup(char *str, char **mac_out, void *data)
72 *init = ((struct daemon_init) 66 *init = ((struct daemon_init)
73 { .sock_type = "unix", 67 { .sock_type = "unix",
74 .ctl_sock = "/tmp/uml.ctl" }); 68 .ctl_sock = "/tmp/uml.ctl" });
75 69
76 remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock, 70 remain = split_if_spec(str, mac_out, &init->sock_type, &init->ctl_sock,
77 NULL); 71 NULL);
78 if(remain != NULL) 72 if (remain != NULL)
79 printk(KERN_WARNING "daemon_setup : Ignoring data socket " 73 printk(KERN_WARNING "daemon_setup : Ignoring data socket "
80 "specification\n"); 74 "specification\n");
81 75
82 return(1); 76 return 1;
83} 77}
84 78
85static struct transport daemon_transport = { 79static struct transport daemon_transport = {
diff --git a/arch/um/drivers/daemon_user.c b/arch/um/drivers/daemon_user.c
index 8d2008f06682..f23c109a055c 100644
--- a/arch/um/drivers/daemon_user.c
+++ b/arch/um/drivers/daemon_user.c
@@ -1,24 +1,23 @@
1/* 1/*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
3 * James Leu (jleu@mindspring.net). 4 * James Leu (jleu@mindspring.net).
4 * Copyright (C) 2001 by various other people who didn't put their name here. 5 * Copyright (C) 2001 by various other people who didn't put their name here.
5 * Licensed under the GPL. 6 * Licensed under the GPL.
6 */ 7 */
7 8
8#include <errno.h>
9#include <unistd.h>
10#include <stdint.h> 9#include <stdint.h>
10#include <unistd.h>
11#include <errno.h>
12#include <sys/types.h>
11#include <sys/socket.h> 13#include <sys/socket.h>
12#include <sys/un.h>
13#include <sys/time.h> 14#include <sys/time.h>
14#include "net_user.h" 15#include <sys/un.h>
15#include "daemon.h" 16#include "daemon.h"
16#include "kern_util.h" 17#include "net_user.h"
17#include "user.h"
18#include "os.h" 18#include "os.h"
19#include "um_malloc.h" 19#include "um_malloc.h"
20 20#include "user.h"
21#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
22 21
23enum request_type { REQ_NEW_CONTROL }; 22enum request_type { REQ_NEW_CONTROL };
24 23
@@ -36,8 +35,9 @@ static struct sockaddr_un *new_addr(void *name, int len)
36 struct sockaddr_un *sun; 35 struct sockaddr_un *sun;
37 36
38 sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); 37 sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
39 if(sun == NULL){ 38 if (sun == NULL) {
40 printk("new_addr: allocation of sockaddr_un failed\n"); 39 printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
40 "failed\n");
41 return NULL; 41 return NULL;
42 } 42 }
43 sun->sun_family = AF_UNIX; 43 sun->sun_family = AF_UNIX;
@@ -54,38 +54,39 @@ static int connect_to_switch(struct daemon_data *pri)
54 int fd, n, err; 54 int fd, n, err;
55 55
56 pri->control = socket(AF_UNIX, SOCK_STREAM, 0); 56 pri->control = socket(AF_UNIX, SOCK_STREAM, 0);
57 if(pri->control < 0){ 57 if (pri->control < 0) {
58 err = -errno; 58 err = -errno;
59 printk("daemon_open : control socket failed, errno = %d\n", 59 printk(UM_KERN_ERR "daemon_open : control socket failed, "
60 -err); 60 "errno = %d\n", -err);
61 return err; 61 return err;
62 } 62 }
63 63
64 if(connect(pri->control, (struct sockaddr *) ctl_addr, 64 if (connect(pri->control, (struct sockaddr *) ctl_addr,
65 sizeof(*ctl_addr)) < 0){ 65 sizeof(*ctl_addr)) < 0) {
66 err = -errno; 66 err = -errno;
67 printk("daemon_open : control connect failed, errno = %d\n", 67 printk(UM_KERN_ERR "daemon_open : control connect failed, "
68 -err); 68 "errno = %d\n", -err);
69 goto out; 69 goto out;
70 } 70 }
71 71
72 fd = socket(AF_UNIX, SOCK_DGRAM, 0); 72 fd = socket(AF_UNIX, SOCK_DGRAM, 0);
73 if(fd < 0){ 73 if (fd < 0) {
74 err = -errno; 74 err = -errno;
75 printk("daemon_open : data socket failed, errno = %d\n", 75 printk(UM_KERN_ERR "daemon_open : data socket failed, "
76 -err); 76 "errno = %d\n", -err);
77 goto out; 77 goto out;
78 } 78 }
79 if(bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0){ 79 if (bind(fd, (struct sockaddr *) local_addr, sizeof(*local_addr)) < 0) {
80 err = -errno; 80 err = -errno;
81 printk("daemon_open : data bind failed, errno = %d\n", 81 printk(UM_KERN_ERR "daemon_open : data bind failed, "
82 -err); 82 "errno = %d\n", -err);
83 goto out_close; 83 goto out_close;
84 } 84 }
85 85
86 sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL); 86 sun = kmalloc(sizeof(struct sockaddr_un), UM_GFP_KERNEL);
87 if(sun == NULL){ 87 if (sun == NULL) {
88 printk("new_addr: allocation of sockaddr_un failed\n"); 88 printk(UM_KERN_ERR "new_addr: allocation of sockaddr_un "
89 "failed\n");
89 err = -ENOMEM; 90 err = -ENOMEM;
90 goto out_close; 91 goto out_close;
91 } 92 }
@@ -94,18 +95,18 @@ static int connect_to_switch(struct daemon_data *pri)
94 req.version = SWITCH_VERSION; 95 req.version = SWITCH_VERSION;
95 req.type = REQ_NEW_CONTROL; 96 req.type = REQ_NEW_CONTROL;
96 req.sock = *local_addr; 97 req.sock = *local_addr;
97 n = os_write_file(pri->control, &req, sizeof(req)); 98 n = write(pri->control, &req, sizeof(req));
98 if(n != sizeof(req)){ 99 if (n != sizeof(req)) {
99 printk("daemon_open : control setup request failed, err = %d\n", 100 printk(UM_KERN_ERR "daemon_open : control setup request "
100 -n); 101 "failed, err = %d\n", -errno);
101 err = -ENOTCONN; 102 err = -ENOTCONN;
102 goto out_free; 103 goto out_free;
103 } 104 }
104 105
105 n = os_read_file(pri->control, sun, sizeof(*sun)); 106 n = read(pri->control, sun, sizeof(*sun));
106 if(n != sizeof(*sun)){ 107 if (n != sizeof(*sun)) {
107 printk("daemon_open : read of data socket failed, err = %d\n", 108 printk(UM_KERN_ERR "daemon_open : read of data socket failed, "
108 -n); 109 "err = %d\n", -errno);
109 err = -ENOTCONN; 110 err = -ENOTCONN;
110 goto out_free; 111 goto out_free;
111 } 112 }
@@ -116,9 +117,9 @@ static int connect_to_switch(struct daemon_data *pri)
116 out_free: 117 out_free:
117 kfree(sun); 118 kfree(sun);
118 out_close: 119 out_close:
119 os_close_file(fd); 120 close(fd);
120 out: 121 out:
121 os_close_file(pri->control); 122 close(pri->control);
122 return err; 123 return err;
123} 124}
124 125
@@ -132,8 +133,8 @@ static int daemon_user_init(void *data, void *dev)
132 int usecs; 133 int usecs;
133 } name; 134 } name;
134 135
135 if(!strcmp(pri->sock_type, "unix")) 136 if (!strcmp(pri->sock_type, "unix"))
136 pri->ctl_addr = new_addr(pri->ctl_sock, 137 pri->ctl_addr = new_addr(pri->ctl_sock,
137 strlen(pri->ctl_sock) + 1); 138 strlen(pri->ctl_sock) + 1);
138 name.zero = 0; 139 name.zero = 0;
139 name.pid = os_getpid(); 140 name.pid = os_getpid();
@@ -142,7 +143,7 @@ static int daemon_user_init(void *data, void *dev)
142 pri->local_addr = new_addr(&name, sizeof(name)); 143 pri->local_addr = new_addr(&name, sizeof(name));
143 pri->dev = dev; 144 pri->dev = dev;
144 pri->fd = connect_to_switch(pri); 145 pri->fd = connect_to_switch(pri);
145 if(pri->fd < 0){ 146 if (pri->fd < 0) {
146 kfree(pri->local_addr); 147 kfree(pri->local_addr);
147 pri->local_addr = NULL; 148 pri->local_addr = NULL;
148 return pri->fd; 149 return pri->fd;
@@ -161,9 +162,9 @@ static void daemon_remove(void *data)
161{ 162{
162 struct daemon_data *pri = data; 163 struct daemon_data *pri = data;
163 164
164 os_close_file(pri->fd); 165 close(pri->fd);
165 pri->fd = -1; 166 pri->fd = -1;
166 os_close_file(pri->control); 167 close(pri->control);
167 pri->control = -1; 168 pri->control = -1;
168 169
169 kfree(pri->data_addr); 170 kfree(pri->data_addr);
@@ -181,18 +182,13 @@ int daemon_user_write(int fd, void *buf, int len, struct daemon_data *pri)
181 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); 182 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
182} 183}
183 184
184static int daemon_set_mtu(int mtu, void *data)
185{
186 return mtu;
187}
188
189const struct net_user_info daemon_user_info = { 185const struct net_user_info daemon_user_info = {
190 .init = daemon_user_init, 186 .init = daemon_user_init,
191 .open = daemon_open, 187 .open = daemon_open,
192 .close = NULL, 188 .close = NULL,
193 .remove = daemon_remove, 189 .remove = daemon_remove,
194 .set_mtu = daemon_set_mtu,
195 .add_address = NULL, 190 .add_address = NULL,
196 .delete_address = NULL, 191 .delete_address = NULL,
197 .max_packet = MAX_PACKET - ETH_HEADER_OTHER 192 .mtu = ETH_MAX_PACKET,
193 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
198}; 194};
diff --git a/arch/um/drivers/fd.c b/arch/um/drivers/fd.c
index 39c01ffd45c9..0a2bb5b64b82 100644
--- a/arch/um/drivers/fd.c
+++ b/arch/um/drivers/fd.c
@@ -1,17 +1,18 @@
1/* 1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h> 6#include <stdio.h>
7#include <stdlib.h> 7#include <stdlib.h>
8#include <unistd.h> 8#include <unistd.h>
9#include <termios.h>
10#include <errno.h> 9#include <errno.h>
11#include "user.h" 10#include <termios.h>
12#include "chan_user.h" 11#include "chan_user.h"
12#include "kern_constants.h"
13#include "os.h" 13#include "os.h"
14#include "um_malloc.h" 14#include "um_malloc.h"
15#include "user.h"
15 16
16struct fd_chan { 17struct fd_chan {
17 int fd; 18 int fd;
@@ -26,22 +27,26 @@ static void *fd_init(char *str, int device, const struct chan_opts *opts)
26 char *end; 27 char *end;
27 int n; 28 int n;
28 29
29 if(*str != ':'){ 30 if (*str != ':') {
30 printk("fd_init : channel type 'fd' must specify a file " 31 printk(UM_KERN_ERR "fd_init : channel type 'fd' must specify a "
31 "descriptor\n"); 32 "file descriptor\n");
32 return(NULL); 33 return NULL;
33 } 34 }
34 str++; 35 str++;
35 n = strtoul(str, &end, 0); 36 n = strtoul(str, &end, 0);
36 if((*end != '\0') || (end == str)){ 37 if ((*end != '\0') || (end == str)) {
37 printk("fd_init : couldn't parse file descriptor '%s'\n", str); 38 printk(UM_KERN_ERR "fd_init : couldn't parse file descriptor "
38 return(NULL); 39 "'%s'\n", str);
40 return NULL;
39 } 41 }
42
40 data = kmalloc(sizeof(*data), UM_GFP_KERNEL); 43 data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
41 if(data == NULL) return(NULL); 44 if (data == NULL)
45 return NULL;
46
42 *data = ((struct fd_chan) { .fd = n, 47 *data = ((struct fd_chan) { .fd = n,
43 .raw = opts->raw }); 48 .raw = opts->raw });
44 return(data); 49 return data;
45} 50}
46 51
47static int fd_open(int input, int output, int primary, void *d, char **dev_out) 52static int fd_open(int input, int output, int primary, void *d, char **dev_out)
@@ -49,18 +54,18 @@ static int fd_open(int input, int output, int primary, void *d, char **dev_out)
49 struct fd_chan *data = d; 54 struct fd_chan *data = d;
50 int err; 55 int err;
51 56
52 if(data->raw && isatty(data->fd)){ 57 if (data->raw && isatty(data->fd)) {
53 CATCH_EINTR(err = tcgetattr(data->fd, &data->tt)); 58 CATCH_EINTR(err = tcgetattr(data->fd, &data->tt));
54 if(err) 59 if (err)
55 return(err); 60 return err;
56 61
57 err = raw(data->fd); 62 err = raw(data->fd);
58 if(err) 63 if (err)
59 return(err); 64 return err;
60 } 65 }
61 sprintf(data->str, "%d", data->fd); 66 sprintf(data->str, "%d", data->fd);
62 *dev_out = data->str; 67 *dev_out = data->str;
63 return(data->fd); 68 return data->fd;
64} 69}
65 70
66static void fd_close(int fd, void *d) 71static void fd_close(int fd, void *d)
@@ -68,13 +73,14 @@ static void fd_close(int fd, void *d)
68 struct fd_chan *data = d; 73 struct fd_chan *data = d;
69 int err; 74 int err;
70 75
71 if(data->raw && isatty(fd)){ 76 if (!data->raw || !isatty(fd))
72 CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt)); 77 return;
73 if(err) 78
74 printk("Failed to restore terminal state - " 79 CATCH_EINTR(err = tcsetattr(fd, TCSAFLUSH, &data->tt));
75 "errno = %d\n", -err); 80 if (err)
76 data->raw = 0; 81 printk(UM_KERN_ERR "Failed to restore terminal state - "
77 } 82 "errno = %d\n", -err);
83 data->raw = 0;
78} 84}
79 85
80const struct chan_ops fd_ops = { 86const struct chan_ops fd_ops = {
@@ -89,14 +95,3 @@ const struct chan_ops fd_ops = {
89 .free = generic_free, 95 .free = generic_free,
90 .winch = 1, 96 .winch = 1,
91}; 97};
92
93/*
94 * Overrides for Emacs so that we follow Linus's tabbing style.
95 * Emacs will notice this stuff at the end of the file and automatically
96 * adjust the settings for this buffer only. This must remain at the end
97 * of the file.
98 * ---------------------------------------------------------------------------
99 * Local variables:
100 * c-file-style: "linux"
101 * End:
102 */
diff --git a/arch/um/drivers/harddog_kern.c b/arch/um/drivers/harddog_kern.c
index 55601687b3bc..a9ad4bd6d953 100644
--- a/arch/um/drivers/harddog_kern.c
+++ b/arch/um/drivers/harddog_kern.c
@@ -69,7 +69,7 @@ static int harddog_open(struct inode *inode, struct file *file)
69 spin_lock(&lock); 69 spin_lock(&lock);
70 if(timer_alive) 70 if(timer_alive)
71 goto err; 71 goto err;
72#ifdef CONFIG_HARDDOG_NOWAYOUT 72#ifdef CONFIG_WATCHDOG_NOWAYOUT
73 __module_get(THIS_MODULE); 73 __module_get(THIS_MODULE);
74#endif 74#endif
75 75
diff --git a/arch/um/drivers/harddog_user.c b/arch/um/drivers/harddog_user.c
index 1171790f742c..b56f8e0196a9 100644
--- a/arch/um/drivers/harddog_user.c
+++ b/arch/um/drivers/harddog_user.c
@@ -1,16 +1,13 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h> 6#include <stdio.h>
7#include <unistd.h> 7#include <unistd.h>
8#include <errno.h> 8#include <errno.h>
9#include "user.h"
10#include "mconsole.h"
11#include "os.h" 9#include "os.h"
12#include "choose-mode.h" 10#include "user.h"
13#include "mode.h"
14 11
15struct dog_data { 12struct dog_data {
16 int stdin; 13 int stdin;
@@ -25,10 +22,10 @@ static void pre_exec(void *d)
25 dup2(data->stdin, 0); 22 dup2(data->stdin, 0);
26 dup2(data->stdout, 1); 23 dup2(data->stdout, 1);
27 dup2(data->stdout, 2); 24 dup2(data->stdout, 2);
28 os_close_file(data->stdin); 25 close(data->stdin);
29 os_close_file(data->stdout); 26 close(data->stdout);
30 os_close_file(data->close_me[0]); 27 close(data->close_me[0]);
31 os_close_file(data->close_me[1]); 28 close(data->close_me[1]);
32} 29}
33 30
34int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock) 31int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
@@ -42,13 +39,13 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
42 char **args = NULL; 39 char **args = NULL;
43 40
44 err = os_pipe(in_fds, 1, 0); 41 err = os_pipe(in_fds, 1, 0);
45 if(err < 0){ 42 if (err < 0) {
46 printk("harddog_open - os_pipe failed, err = %d\n", -err); 43 printk("harddog_open - os_pipe failed, err = %d\n", -err);
47 goto out; 44 goto out;
48 } 45 }
49 46
50 err = os_pipe(out_fds, 1, 0); 47 err = os_pipe(out_fds, 1, 0);
51 if(err < 0){ 48 if (err < 0) {
52 printk("harddog_open - os_pipe failed, err = %d\n", -err); 49 printk("harddog_open - os_pipe failed, err = %d\n", -err);
53 goto out_close_in; 50 goto out_close_in;
54 } 51 }
@@ -58,37 +55,37 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
58 data.close_me[0] = out_fds[1]; 55 data.close_me[0] = out_fds[1];
59 data.close_me[1] = in_fds[0]; 56 data.close_me[1] = in_fds[0];
60 57
61 if(sock != NULL){ 58 if (sock != NULL) {
62 mconsole_args[2] = sock; 59 mconsole_args[2] = sock;
63 args = mconsole_args; 60 args = mconsole_args;
64 } 61 }
65 else { 62 else {
66 /* XXX The os_getpid() is not SMP correct */ 63 /* XXX The os_getpid() is not SMP correct */
67 sprintf(pid_buf, "%d", CHOOSE_MODE(tracing_pid, os_getpid())); 64 sprintf(pid_buf, "%d", os_getpid());
68 args = pid_args; 65 args = pid_args;
69 } 66 }
70 67
71 pid = run_helper(pre_exec, &data, args); 68 pid = run_helper(pre_exec, &data, args);
72 69
73 os_close_file(out_fds[0]); 70 close(out_fds[0]);
74 os_close_file(in_fds[1]); 71 close(in_fds[1]);
75 72
76 if(pid < 0){ 73 if (pid < 0) {
77 err = -pid; 74 err = -pid;
78 printk("harddog_open - run_helper failed, errno = %d\n", -err); 75 printk("harddog_open - run_helper failed, errno = %d\n", -err);
79 goto out_close_out; 76 goto out_close_out;
80 } 77 }
81 78
82 n = os_read_file(in_fds[0], &c, sizeof(c)); 79 n = read(in_fds[0], &c, sizeof(c));
83 if(n == 0){ 80 if (n == 0) {
84 printk("harddog_open - EOF on watchdog pipe\n"); 81 printk("harddog_open - EOF on watchdog pipe\n");
85 helper_wait(pid); 82 helper_wait(pid);
86 err = -EIO; 83 err = -EIO;
87 goto out_close_out; 84 goto out_close_out;
88 } 85 }
89 else if(n < 0){ 86 else if (n < 0) {
90 printk("harddog_open - read of watchdog pipe failed, " 87 printk("harddog_open - read of watchdog pipe failed, "
91 "err = %d\n", -n); 88 "err = %d\n", errno);
92 helper_wait(pid); 89 helper_wait(pid);
93 err = n; 90 err = n;
94 goto out_close_out; 91 goto out_close_out;
@@ -98,19 +95,19 @@ int start_watchdog(int *in_fd_ret, int *out_fd_ret, char *sock)
98 return 0; 95 return 0;
99 96
100 out_close_in: 97 out_close_in:
101 os_close_file(in_fds[0]); 98 close(in_fds[0]);
102 os_close_file(in_fds[1]); 99 close(in_fds[1]);
103 out_close_out: 100 out_close_out:
104 os_close_file(out_fds[0]); 101 close(out_fds[0]);
105 os_close_file(out_fds[1]); 102 close(out_fds[1]);
106 out: 103 out:
107 return err; 104 return err;
108} 105}
109 106
110void stop_watchdog(int in_fd, int out_fd) 107void stop_watchdog(int in_fd, int out_fd)
111{ 108{
112 os_close_file(in_fd); 109 close(in_fd);
113 os_close_file(out_fd); 110 close(out_fd);
114} 111}
115 112
116int ping_watchdog(int fd) 113int ping_watchdog(int fd)
@@ -118,10 +115,11 @@ int ping_watchdog(int fd)
118 int n; 115 int n;
119 char c = '\n'; 116 char c = '\n';
120 117
121 n = os_write_file(fd, &c, sizeof(c)); 118 n = write(fd, &c, sizeof(c));
122 if(n != sizeof(c)){ 119 if (n != sizeof(c)) {
123 printk("ping_watchdog - write failed, err = %d\n", -n); 120 printk("ping_watchdog - write failed, ret = %d, err = %d\n",
124 if(n < 0) 121 n, errno);
122 if (n < 0)
125 return n; 123 return n;
126 return -EIO; 124 return -EIO;
127 } 125 }
diff --git a/arch/um/drivers/hostaudio_kern.c b/arch/um/drivers/hostaudio_kern.c
index 10e08a8c17c3..ff1b22b69e9c 100644
--- a/arch/um/drivers/hostaudio_kern.c
+++ b/arch/um/drivers/hostaudio_kern.c
@@ -1,16 +1,14 @@
1/* 1/*
2 * Copyright (C) 2002 Steve Schmidtke 2 * Copyright (C) 2002 Steve Schmidtke
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/fs.h"
6#include "linux/module.h" 7#include "linux/module.h"
7#include "linux/init.h"
8#include "linux/slab.h" 8#include "linux/slab.h"
9#include "linux/fs.h"
10#include "linux/sound.h" 9#include "linux/sound.h"
11#include "linux/soundcard.h" 10#include "linux/soundcard.h"
12#include "asm/uaccess.h" 11#include "asm/uaccess.h"
13#include "kern_util.h"
14#include "init.h" 12#include "init.h"
15#include "os.h" 13#include "os.h"
16 14
@@ -25,7 +23,8 @@ struct hostmixer_state {
25#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp" 23#define HOSTAUDIO_DEV_DSP "/dev/sound/dsp"
26#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer" 24#define HOSTAUDIO_DEV_MIXER "/dev/sound/mixer"
27 25
28/* Changed either at boot time or module load time. At boot, this is 26/*
27 * Changed either at boot time or module load time. At boot, this is
29 * single-threaded; at module load, multiple modules would each have 28 * single-threaded; at module load, multiple modules would each have
30 * their own copy of these variables. 29 * their own copy of these variables.
31 */ 30 */
@@ -44,7 +43,7 @@ static char *mixer = HOSTAUDIO_DEV_MIXER;
44static int set_dsp(char *name, int *add) 43static int set_dsp(char *name, int *add)
45{ 44{
46 dsp = name; 45 dsp = name;
47 return(0); 46 return 0;
48} 47}
49 48
50__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP); 49__uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
@@ -52,7 +51,7 @@ __uml_setup("dsp=", set_dsp, "dsp=<dsp device>\n" DSP_HELP);
52static int set_mixer(char *name, int *add) 51static int set_mixer(char *name, int *add)
53{ 52{
54 mixer = name; 53 mixer = name;
55 return(0); 54 return 0;
56} 55}
57 56
58__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP); 57__uml_setup("mixer=", set_mixer, "mixer=<mixer device>\n" MIXER_HELP);
@@ -77,23 +76,23 @@ static ssize_t hostaudio_read(struct file *file, char __user *buffer,
77 int err; 76 int err;
78 77
79#ifdef DEBUG 78#ifdef DEBUG
80 printk("hostaudio: read called, count = %d\n", count); 79 printk(KERN_DEBUG "hostaudio: read called, count = %d\n", count);
81#endif 80#endif
82 81
83 kbuf = kmalloc(count, GFP_KERNEL); 82 kbuf = kmalloc(count, GFP_KERNEL);
84 if(kbuf == NULL) 83 if (kbuf == NULL)
85 return(-ENOMEM); 84 return -ENOMEM;
86 85
87 err = os_read_file(state->fd, kbuf, count); 86 err = os_read_file(state->fd, kbuf, count);
88 if(err < 0) 87 if (err < 0)
89 goto out; 88 goto out;
90 89
91 if(copy_to_user(buffer, kbuf, err)) 90 if (copy_to_user(buffer, kbuf, err))
92 err = -EFAULT; 91 err = -EFAULT;
93 92
94out: 93out:
95 kfree(kbuf); 94 kfree(kbuf);
96 return(err); 95 return err;
97} 96}
98 97
99static ssize_t hostaudio_write(struct file *file, const char __user *buffer, 98static ssize_t hostaudio_write(struct file *file, const char __user *buffer,
@@ -104,40 +103,40 @@ static ssize_t hostaudio_write(struct file *file, const char __user *buffer,
104 int err; 103 int err;
105 104
106#ifdef DEBUG 105#ifdef DEBUG
107 printk("hostaudio: write called, count = %d\n", count); 106 printk(KERN_DEBUG "hostaudio: write called, count = %d\n", count);
108#endif 107#endif
109 108
110 kbuf = kmalloc(count, GFP_KERNEL); 109 kbuf = kmalloc(count, GFP_KERNEL);
111 if(kbuf == NULL) 110 if (kbuf == NULL)
112 return(-ENOMEM); 111 return -ENOMEM;
113 112
114 err = -EFAULT; 113 err = -EFAULT;
115 if(copy_from_user(kbuf, buffer, count)) 114 if (copy_from_user(kbuf, buffer, count))
116 goto out; 115 goto out;
117 116
118 err = os_write_file(state->fd, kbuf, count); 117 err = os_write_file(state->fd, kbuf, count);
119 if(err < 0) 118 if (err < 0)
120 goto out; 119 goto out;
121 *ppos += err; 120 *ppos += err;
122 121
123 out: 122 out:
124 kfree(kbuf); 123 kfree(kbuf);
125 return(err); 124 return err;
126} 125}
127 126
128static unsigned int hostaudio_poll(struct file *file, 127static unsigned int hostaudio_poll(struct file *file,
129 struct poll_table_struct *wait) 128 struct poll_table_struct *wait)
130{ 129{
131 unsigned int mask = 0; 130 unsigned int mask = 0;
132 131
133#ifdef DEBUG 132#ifdef DEBUG
134 printk("hostaudio: poll called (unimplemented)\n"); 133 printk(KERN_DEBUG "hostaudio: poll called (unimplemented)\n");
135#endif 134#endif
136 135
137 return(mask); 136 return mask;
138} 137}
139 138
140static int hostaudio_ioctl(struct inode *inode, struct file *file, 139static int hostaudio_ioctl(struct inode *inode, struct file *file,
141 unsigned int cmd, unsigned long arg) 140 unsigned int cmd, unsigned long arg)
142{ 141{
143 struct hostaudio_state *state = file->private_data; 142 struct hostaudio_state *state = file->private_data;
@@ -145,7 +144,7 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
145 int err; 144 int err;
146 145
147#ifdef DEBUG 146#ifdef DEBUG
148 printk("hostaudio: ioctl called, cmd = %u\n", cmd); 147 printk(KERN_DEBUG "hostaudio: ioctl called, cmd = %u\n", cmd);
149#endif 148#endif
150 switch(cmd){ 149 switch(cmd){
151 case SNDCTL_DSP_SPEED: 150 case SNDCTL_DSP_SPEED:
@@ -154,8 +153,8 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
154 case SNDCTL_DSP_CHANNELS: 153 case SNDCTL_DSP_CHANNELS:
155 case SNDCTL_DSP_SUBDIVIDE: 154 case SNDCTL_DSP_SUBDIVIDE:
156 case SNDCTL_DSP_SETFRAGMENT: 155 case SNDCTL_DSP_SETFRAGMENT:
157 if(get_user(data, (int __user *) arg)) 156 if (get_user(data, (int __user *) arg))
158 return(-EFAULT); 157 return EFAULT;
159 break; 158 break;
160 default: 159 default:
161 break; 160 break;
@@ -170,14 +169,14 @@ static int hostaudio_ioctl(struct inode *inode, struct file *file,
170 case SNDCTL_DSP_CHANNELS: 169 case SNDCTL_DSP_CHANNELS:
171 case SNDCTL_DSP_SUBDIVIDE: 170 case SNDCTL_DSP_SUBDIVIDE:
172 case SNDCTL_DSP_SETFRAGMENT: 171 case SNDCTL_DSP_SETFRAGMENT:
173 if(put_user(data, (int __user *) arg)) 172 if (put_user(data, (int __user *) arg))
174 return(-EFAULT); 173 return -EFAULT;
175 break; 174 break;
176 default: 175 default:
177 break; 176 break;
178 } 177 }
179 178
180 return(err); 179 return err;
181} 180}
182 181
183static int hostaudio_open(struct inode *inode, struct file *file) 182static int hostaudio_open(struct inode *inode, struct file *file)
@@ -187,24 +186,26 @@ static int hostaudio_open(struct inode *inode, struct file *file)
187 int ret; 186 int ret;
188 187
189#ifdef DEBUG 188#ifdef DEBUG
190 printk("hostaudio: open called (host: %s)\n", dsp); 189 printk(KERN_DEBUG "hostaudio: open called (host: %s)\n", dsp);
191#endif 190#endif
192 191
193 state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL); 192 state = kmalloc(sizeof(struct hostaudio_state), GFP_KERNEL);
194 if(state == NULL) 193 if (state == NULL)
195 return(-ENOMEM); 194 return -ENOMEM;
196 195
197 if(file->f_mode & FMODE_READ) r = 1; 196 if (file->f_mode & FMODE_READ)
198 if(file->f_mode & FMODE_WRITE) w = 1; 197 r = 1;
198 if (file->f_mode & FMODE_WRITE)
199 w = 1;
199 200
200 ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0); 201 ret = os_open_file(dsp, of_set_rw(OPENFLAGS(), r, w), 0);
201 if(ret < 0){ 202 if (ret < 0) {
202 kfree(state); 203 kfree(state);
203 return(ret); 204 return ret;
204 } 205 }
205 state->fd = ret; 206 state->fd = ret;
206 file->private_data = state; 207 file->private_data = state;
207 return(0); 208 return 0;
208} 209}
209 210
210static int hostaudio_release(struct inode *inode, struct file *file) 211static int hostaudio_release(struct inode *inode, struct file *file)
@@ -212,26 +213,26 @@ static int hostaudio_release(struct inode *inode, struct file *file)
212 struct hostaudio_state *state = file->private_data; 213 struct hostaudio_state *state = file->private_data;
213 214
214#ifdef DEBUG 215#ifdef DEBUG
215 printk("hostaudio: release called\n"); 216 printk(KERN_DEBUG "hostaudio: release called\n");
216#endif 217#endif
217 os_close_file(state->fd); 218 os_close_file(state->fd);
218 kfree(state); 219 kfree(state);
219 220
220 return(0); 221 return 0;
221} 222}
222 223
223/* /dev/mixer file operations */ 224/* /dev/mixer file operations */
224 225
225static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file, 226static int hostmixer_ioctl_mixdev(struct inode *inode, struct file *file,
226 unsigned int cmd, unsigned long arg) 227 unsigned int cmd, unsigned long arg)
227{ 228{
228 struct hostmixer_state *state = file->private_data; 229 struct hostmixer_state *state = file->private_data;
229 230
230#ifdef DEBUG 231#ifdef DEBUG
231 printk("hostmixer: ioctl called\n"); 232 printk(KERN_DEBUG "hostmixer: ioctl called\n");
232#endif 233#endif
233 234
234 return(os_ioctl_generic(state->fd, cmd, arg)); 235 return os_ioctl_generic(state->fd, cmd, arg);
235} 236}
236 237
237static int hostmixer_open_mixdev(struct inode *inode, struct file *file) 238static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
@@ -241,26 +242,29 @@ static int hostmixer_open_mixdev(struct inode *inode, struct file *file)
241 int ret; 242 int ret;
242 243
243#ifdef DEBUG 244#ifdef DEBUG
244 printk("hostmixer: open called (host: %s)\n", mixer); 245 printk(KERN_DEBUG "hostmixer: open called (host: %s)\n", mixer);
245#endif 246#endif
246 247
247 state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL); 248 state = kmalloc(sizeof(struct hostmixer_state), GFP_KERNEL);
248 if(state == NULL) return(-ENOMEM); 249 if (state == NULL)
250 return -ENOMEM;
249 251
250 if(file->f_mode & FMODE_READ) r = 1; 252 if (file->f_mode & FMODE_READ)
251 if(file->f_mode & FMODE_WRITE) w = 1; 253 r = 1;
254 if (file->f_mode & FMODE_WRITE)
255 w = 1;
252 256
253 ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0); 257 ret = os_open_file(mixer, of_set_rw(OPENFLAGS(), r, w), 0);
254 258
255 if(ret < 0){ 259 if (ret < 0) {
256 printk("hostaudio_open_mixdev failed to open '%s', err = %d\n", 260 printk(KERN_ERR "hostaudio_open_mixdev failed to open '%s', "
257 dsp, -ret); 261 "err = %d\n", dsp, -ret);
258 kfree(state); 262 kfree(state);
259 return(ret); 263 return ret;
260 } 264 }
261 265
262 file->private_data = state; 266 file->private_data = state;
263 return(0); 267 return 0;
264} 268}
265 269
266static int hostmixer_release(struct inode *inode, struct file *file) 270static int hostmixer_release(struct inode *inode, struct file *file)
@@ -268,13 +272,13 @@ static int hostmixer_release(struct inode *inode, struct file *file)
268 struct hostmixer_state *state = file->private_data; 272 struct hostmixer_state *state = file->private_data;
269 273
270#ifdef DEBUG 274#ifdef DEBUG
271 printk("hostmixer: release called\n"); 275 printk(KERN_DEBUG "hostmixer: release called\n");
272#endif 276#endif
273 277
274 os_close_file(state->fd); 278 os_close_file(state->fd);
275 kfree(state); 279 kfree(state);
276 280
277 return(0); 281 return 0;
278} 282}
279 283
280/* kernel module operations */ 284/* kernel module operations */
@@ -314,13 +318,13 @@ static int __init hostaudio_init_module(void)
314 dsp, mixer); 318 dsp, mixer);
315 319
316 module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1); 320 module_data.dev_audio = register_sound_dsp(&hostaudio_fops, -1);
317 if(module_data.dev_audio < 0){ 321 if (module_data.dev_audio < 0) {
318 printk(KERN_ERR "hostaudio: couldn't register DSP device!\n"); 322 printk(KERN_ERR "hostaudio: couldn't register DSP device!\n");
319 return -ENODEV; 323 return -ENODEV;
320 } 324 }
321 325
322 module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1); 326 module_data.dev_mixer = register_sound_mixer(&hostmixer_fops, -1);
323 if(module_data.dev_mixer < 0){ 327 if (module_data.dev_mixer < 0) {
324 printk(KERN_ERR "hostmixer: couldn't register mixer " 328 printk(KERN_ERR "hostmixer: couldn't register mixer "
325 "device!\n"); 329 "device!\n");
326 unregister_sound_dsp(module_data.dev_audio); 330 unregister_sound_dsp(module_data.dev_audio);
diff --git a/arch/um/drivers/line.c b/arch/um/drivers/line.c
index 3e0b68e297f2..76fe0b0da996 100644
--- a/arch/um/drivers/line.c
+++ b/arch/um/drivers/line.c
@@ -1,22 +1,14 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/kernel.h" 6#include "linux/irqreturn.h"
7#include "linux/sched.h"
8#include "linux/slab.h"
9#include "linux/list.h"
10#include "linux/kd.h" 7#include "linux/kd.h"
11#include "linux/interrupt.h"
12#include "asm/uaccess.h"
13#include "chan_kern.h" 8#include "chan_kern.h"
9#include "irq_kern.h"
14#include "irq_user.h" 10#include "irq_user.h"
15#include "line.h"
16#include "kern.h"
17#include "kern_util.h"
18#include "os.h" 11#include "os.h"
19#include "irq_kern.h"
20 12
21#define LINE_BUFSIZE 4096 13#define LINE_BUFSIZE 4096
22 14
@@ -35,12 +27,13 @@ static void line_timer_cb(struct work_struct *work)
35{ 27{
36 struct line *line = container_of(work, struct line, task.work); 28 struct line *line = container_of(work, struct line, task.work);
37 29
38 if(!line->throttled) 30 if (!line->throttled)
39 chan_interrupt(&line->chan_list, &line->task, line->tty, 31 chan_interrupt(&line->chan_list, &line->task, line->tty,
40 line->driver->read_irq); 32 line->driver->read_irq);
41} 33}
42 34
43/* Returns the free space inside the ring buffer of this line. 35/*
36 * Returns the free space inside the ring buffer of this line.
44 * 37 *
45 * Should be called while holding line->lock (this does not modify datas). 38 * Should be called while holding line->lock (this does not modify datas).
46 */ 39 */
@@ -107,11 +100,12 @@ static int buffer_data(struct line *line, const char *buf, int len)
107{ 100{
108 int end, room; 101 int end, room;
109 102
110 if(line->buffer == NULL){ 103 if (line->buffer == NULL) {
111 line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC); 104 line->buffer = kmalloc(LINE_BUFSIZE, GFP_ATOMIC);
112 if (line->buffer == NULL) { 105 if (line->buffer == NULL) {
113 printk("buffer_data - atomic allocation failed\n"); 106 printk(KERN_ERR "buffer_data - atomic allocation "
114 return(0); 107 "failed\n");
108 return 0;
115 } 109 }
116 line->head = line->buffer; 110 line->head = line->buffer;
117 line->tail = line->buffer; 111 line->tail = line->buffer;
@@ -122,7 +116,7 @@ static int buffer_data(struct line *line, const char *buf, int len)
122 116
123 end = line->buffer + LINE_BUFSIZE - line->tail; 117 end = line->buffer + LINE_BUFSIZE - line->tail;
124 118
125 if (len < end){ 119 if (len < end) {
126 memcpy(line->tail, buf, len); 120 memcpy(line->tail, buf, len);
127 line->tail += len; 121 line->tail += len;
128 } 122 }
@@ -162,8 +156,10 @@ static int flush_buffer(struct line *line)
162 if (n < 0) 156 if (n < 0)
163 return n; 157 return n;
164 if (n == count) { 158 if (n == count) {
165 /* We have flushed from ->head to buffer end, now we 159 /*
166 * must flush only from the beginning to ->tail.*/ 160 * We have flushed from ->head to buffer end, now we
161 * must flush only from the beginning to ->tail.
162 */
167 line->head = line->buffer; 163 line->head = line->buffer;
168 } else { 164 } else {
169 line->head += n; 165 line->head += n;
@@ -175,7 +171,7 @@ static int flush_buffer(struct line *line)
175 n = write_chan(&line->chan_list, line->head, count, 171 n = write_chan(&line->chan_list, line->head, count,
176 line->driver->write_irq); 172 line->driver->write_irq);
177 173
178 if(n < 0) 174 if (n < 0)
179 return n; 175 return n;
180 176
181 line->head += n; 177 line->head += n;
@@ -189,19 +185,18 @@ void line_flush_buffer(struct tty_struct *tty)
189 int err; 185 int err;
190 186
191 /*XXX: copied from line_write, verify if it is correct!*/ 187 /*XXX: copied from line_write, verify if it is correct!*/
192 if(tty->stopped) 188 if (tty->stopped)
193 return; 189 return;
194 190
195 spin_lock_irqsave(&line->lock, flags); 191 spin_lock_irqsave(&line->lock, flags);
196 err = flush_buffer(line); 192 err = flush_buffer(line);
197 /*if (err == 1)
198 err = 0;*/
199 spin_unlock_irqrestore(&line->lock, flags); 193 spin_unlock_irqrestore(&line->lock, flags);
200 //return err;
201} 194}
202 195
203/* We map both ->flush_chars and ->put_char (which go in pair) onto ->flush_buffer 196/*
204 * and ->write. Hope it's not that bad.*/ 197 * We map both ->flush_chars and ->put_char (which go in pair) onto
198 * ->flush_buffer and ->write. Hope it's not that bad.
199 */
205void line_flush_chars(struct tty_struct *tty) 200void line_flush_chars(struct tty_struct *tty)
206{ 201{
207 line_flush_buffer(tty); 202 line_flush_buffer(tty);
@@ -216,18 +211,15 @@ int line_write(struct tty_struct *tty, const unsigned char *buf, int len)
216{ 211{
217 struct line *line = tty->driver_data; 212 struct line *line = tty->driver_data;
218 unsigned long flags; 213 unsigned long flags;
219 int n, err, ret = 0; 214 int n, ret = 0;
220 215
221 if(tty->stopped) 216 if (tty->stopped)
222 return 0; 217 return 0;
223 218
224 spin_lock_irqsave(&line->lock, flags); 219 spin_lock_irqsave(&line->lock, flags);
225 if (line->head != line->tail) { 220 if (line->head != line->tail)
226 ret = buffer_data(line, buf, len); 221 ret = buffer_data(line, buf, len);
227 err = flush_buffer(line); 222 else {
228 if (err <= 0 && (err != -EAGAIN || !ret))
229 ret = err;
230 } else {
231 n = write_chan(&line->chan_list, buf, len, 223 n = write_chan(&line->chan_list, buf, len,
232 line->driver->write_irq); 224 line->driver->write_irq);
233 if (n < 0) { 225 if (n < 0) {
@@ -257,17 +249,17 @@ static const struct {
257} tty_ioctls[] = { 249} tty_ioctls[] = {
258 /* don't print these, they flood the log ... */ 250 /* don't print these, they flood the log ... */
259 { TCGETS, NULL, "TCGETS" }, 251 { TCGETS, NULL, "TCGETS" },
260 { TCSETS, NULL, "TCSETS" }, 252 { TCSETS, NULL, "TCSETS" },
261 { TCSETSW, NULL, "TCSETSW" }, 253 { TCSETSW, NULL, "TCSETSW" },
262 { TCFLSH, NULL, "TCFLSH" }, 254 { TCFLSH, NULL, "TCFLSH" },
263 { TCSBRK, NULL, "TCSBRK" }, 255 { TCSBRK, NULL, "TCSBRK" },
264 256
265 /* general tty stuff */ 257 /* general tty stuff */
266 { TCSETSF, KERN_DEBUG, "TCSETSF" }, 258 { TCSETSF, KERN_DEBUG, "TCSETSF" },
267 { TCGETA, KERN_DEBUG, "TCGETA" }, 259 { TCGETA, KERN_DEBUG, "TCGETA" },
268 { TIOCMGET, KERN_DEBUG, "TIOCMGET" }, 260 { TIOCMGET, KERN_DEBUG, "TIOCMGET" },
269 { TCSBRKP, KERN_DEBUG, "TCSBRKP" }, 261 { TCSBRKP, KERN_DEBUG, "TCSBRKP" },
270 { TIOCMSET, KERN_DEBUG, "TIOCMSET" }, 262 { TIOCMSET, KERN_DEBUG, "TIOCMSET" },
271 263
272 /* linux-specific ones */ 264 /* linux-specific ones */
273 { TIOCLINUX, KERN_INFO, "TIOCLINUX" }, 265 { TIOCLINUX, KERN_INFO, "TIOCLINUX" },
@@ -324,12 +316,7 @@ int line_ioctl(struct tty_struct *tty, struct file * file,
324 for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++) 316 for (i = 0; i < ARRAY_SIZE(tty_ioctls); i++)
325 if (cmd == tty_ioctls[i].cmd) 317 if (cmd == tty_ioctls[i].cmd)
326 break; 318 break;
327 if (i < ARRAY_SIZE(tty_ioctls)) { 319 if (i == ARRAY_SIZE(tty_ioctls)) {
328 if (NULL != tty_ioctls[i].level)
329 printk("%s%s: %s: ioctl %s called\n",
330 tty_ioctls[i].level, __FUNCTION__,
331 tty->name, tty_ioctls[i].name);
332 } else {
333 printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n", 320 printk(KERN_ERR "%s: %s: unknown ioctl: 0x%x\n",
334 __FUNCTION__, tty->name, cmd); 321 __FUNCTION__, tty->name, cmd);
335 } 322 }
@@ -355,11 +342,12 @@ void line_unthrottle(struct tty_struct *tty)
355 chan_interrupt(&line->chan_list, &line->task, tty, 342 chan_interrupt(&line->chan_list, &line->task, tty,
356 line->driver->read_irq); 343 line->driver->read_irq);
357 344
358 /* Maybe there is enough stuff pending that calling the interrupt 345 /*
346 * Maybe there is enough stuff pending that calling the interrupt
359 * throttles us again. In this case, line->throttled will be 1 347 * throttles us again. In this case, line->throttled will be 1
360 * again and we shouldn't turn the interrupt back on. 348 * again and we shouldn't turn the interrupt back on.
361 */ 349 */
362 if(!line->throttled) 350 if (!line->throttled)
363 reactivate_chan(&line->chan_list, line->driver->read_irq); 351 reactivate_chan(&line->chan_list, line->driver->read_irq);
364} 352}
365 353
@@ -370,27 +358,30 @@ static irqreturn_t line_write_interrupt(int irq, void *data)
370 struct tty_struct *tty = line->tty; 358 struct tty_struct *tty = line->tty;
371 int err; 359 int err;
372 360
373 /* Interrupts are disabled here because we registered the interrupt with 361 /*
374 * IRQF_DISABLED (see line_setup_irq).*/ 362 * Interrupts are disabled here because we registered the interrupt with
363 * IRQF_DISABLED (see line_setup_irq).
364 */
375 365
376 spin_lock(&line->lock); 366 spin_lock(&line->lock);
377 err = flush_buffer(line); 367 err = flush_buffer(line);
378 if (err == 0) { 368 if (err == 0) {
379 return IRQ_NONE; 369 return IRQ_NONE;
380 } else if(err < 0) { 370 } else if (err < 0) {
381 line->head = line->buffer; 371 line->head = line->buffer;
382 line->tail = line->buffer; 372 line->tail = line->buffer;
383 } 373 }
384 spin_unlock(&line->lock); 374 spin_unlock(&line->lock);
385 375
386 if(tty == NULL) 376 if (tty == NULL)
387 return IRQ_NONE; 377 return IRQ_NONE;
388 378
389 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) && 379 if (test_bit(TTY_DO_WRITE_WAKEUP, &tty->flags) &&
390 (tty->ldisc.write_wakeup != NULL)) 380 (tty->ldisc.write_wakeup != NULL))
391 (tty->ldisc.write_wakeup)(tty); 381 (tty->ldisc.write_wakeup)(tty);
392 382
393 /* BLOCKING mode 383 /*
384 * BLOCKING mode
394 * In blocking mode, everything sleeps on tty->write_wait. 385 * In blocking mode, everything sleeps on tty->write_wait.
395 * Sleeping in the console driver would break non-blocking 386 * Sleeping in the console driver would break non-blocking
396 * writes. 387 * writes.
@@ -420,7 +411,8 @@ int line_setup_irq(int fd, int input, int output, struct line *line, void *data)
420 return err; 411 return err;
421} 412}
422 413
423/* Normally, a driver like this can rely mostly on the tty layer 414/*
415 * Normally, a driver like this can rely mostly on the tty layer
424 * locking, particularly when it comes to the driver structure. 416 * locking, particularly when it comes to the driver structure.
425 * However, in this case, mconsole requests can come in "from the 417 * However, in this case, mconsole requests can come in "from the
426 * side", and race with opens and closes. 418 * side", and race with opens and closes.
@@ -442,11 +434,11 @@ int line_open(struct line *lines, struct tty_struct *tty)
442 int err = -ENODEV; 434 int err = -ENODEV;
443 435
444 spin_lock(&line->count_lock); 436 spin_lock(&line->count_lock);
445 if(!line->valid) 437 if (!line->valid)
446 goto out_unlock; 438 goto out_unlock;
447 439
448 err = 0; 440 err = 0;
449 if(tty->count > 1) 441 if (tty->count > 1)
450 goto out_unlock; 442 goto out_unlock;
451 443
452 spin_unlock(&line->count_lock); 444 spin_unlock(&line->count_lock);
@@ -460,7 +452,7 @@ int line_open(struct line *lines, struct tty_struct *tty)
460 452
461 INIT_DELAYED_WORK(&line->task, line_timer_cb); 453 INIT_DELAYED_WORK(&line->task, line_timer_cb);
462 454
463 if(!line->sigio){ 455 if (!line->sigio) {
464 chan_enable_winch(&line->chan_list, tty); 456 chan_enable_winch(&line->chan_list, tty);
465 line->sigio = 1; 457 line->sigio = 1;
466 } 458 }
@@ -481,20 +473,21 @@ void line_close(struct tty_struct *tty, struct file * filp)
481{ 473{
482 struct line *line = tty->driver_data; 474 struct line *line = tty->driver_data;
483 475
484 /* If line_open fails (and tty->driver_data is never set), 476 /*
477 * If line_open fails (and tty->driver_data is never set),
485 * tty_open will call line_close. So just return in this case. 478 * tty_open will call line_close. So just return in this case.
486 */ 479 */
487 if(line == NULL) 480 if (line == NULL)
488 return; 481 return;
489 482
490 /* We ignore the error anyway! */ 483 /* We ignore the error anyway! */
491 flush_buffer(line); 484 flush_buffer(line);
492 485
493 spin_lock(&line->count_lock); 486 spin_lock(&line->count_lock);
494 if(!line->valid) 487 if (!line->valid)
495 goto out_unlock; 488 goto out_unlock;
496 489
497 if(tty->count > 1) 490 if (tty->count > 1)
498 goto out_unlock; 491 goto out_unlock;
499 492
500 spin_unlock(&line->count_lock); 493 spin_unlock(&line->count_lock);
@@ -502,10 +495,10 @@ void line_close(struct tty_struct *tty, struct file * filp)
502 line->tty = NULL; 495 line->tty = NULL;
503 tty->driver_data = NULL; 496 tty->driver_data = NULL;
504 497
505 if(line->sigio){ 498 if (line->sigio) {
506 unregister_winch(tty); 499 unregister_winch(tty);
507 line->sigio = 0; 500 line->sigio = 0;
508 } 501 }
509 502
510 return; 503 return;
511 504
@@ -529,12 +522,12 @@ static int setup_one_line(struct line *lines, int n, char *init, int init_prio,
529 522
530 spin_lock(&line->count_lock); 523 spin_lock(&line->count_lock);
531 524
532 if(line->tty != NULL){ 525 if (line->tty != NULL) {
533 *error_out = "Device is already open"; 526 *error_out = "Device is already open";
534 goto out; 527 goto out;
535 } 528 }
536 529
537 if (line->init_pri <= init_prio){ 530 if (line->init_pri <= init_prio) {
538 line->init_pri = init_prio; 531 line->init_pri = init_prio;
539 if (!strcmp(init, "none")) 532 if (!strcmp(init, "none"))
540 line->valid = 0; 533 line->valid = 0;
@@ -549,7 +542,8 @@ out:
549 return err; 542 return err;
550} 543}
551 544
552/* Common setup code for both startup command line and mconsole initialization. 545/*
546 * Common setup code for both startup command line and mconsole initialization.
553 * @lines contains the array (of size @num) to modify; 547 * @lines contains the array (of size @num) to modify;
554 * @init is the setup string; 548 * @init is the setup string;
555 * @error_out is an error string in the case of failure; 549 * @error_out is an error string in the case of failure;
@@ -561,14 +555,16 @@ int line_setup(struct line *lines, unsigned int num, char *init,
561 int i, n, err; 555 int i, n, err;
562 char *end; 556 char *end;
563 557
564 if(*init == '=') { 558 if (*init == '=') {
565 /* We said con=/ssl= instead of con#=, so we are configuring all 559 /*
566 * consoles at once.*/ 560 * We said con=/ssl= instead of con#=, so we are configuring all
561 * consoles at once.
562 */
567 n = -1; 563 n = -1;
568 } 564 }
569 else { 565 else {
570 n = simple_strtoul(init, &end, 0); 566 n = simple_strtoul(init, &end, 0);
571 if(*end != '='){ 567 if (*end != '=') {
572 *error_out = "Couldn't parse device number"; 568 *error_out = "Couldn't parse device number";
573 return -EINVAL; 569 return -EINVAL;
574 } 570 }
@@ -580,16 +576,16 @@ int line_setup(struct line *lines, unsigned int num, char *init,
580 *error_out = "Device number out of range"; 576 *error_out = "Device number out of range";
581 return -EINVAL; 577 return -EINVAL;
582 } 578 }
583 else if (n >= 0){ 579 else if (n >= 0) {
584 err = setup_one_line(lines, n, init, INIT_ONE, error_out); 580 err = setup_one_line(lines, n, init, INIT_ONE, error_out);
585 if(err) 581 if (err)
586 return err; 582 return err;
587 } 583 }
588 else { 584 else {
589 for(i = 0; i < num; i++){ 585 for(i = 0; i < num; i++) {
590 err = setup_one_line(lines, i, init, INIT_ALL, 586 err = setup_one_line(lines, i, init, INIT_ALL,
591 error_out); 587 error_out);
592 if(err) 588 if (err)
593 return err; 589 return err;
594 } 590 }
595 } 591 }
@@ -603,18 +599,18 @@ int line_config(struct line *lines, unsigned int num, char *str,
603 char *new; 599 char *new;
604 int n; 600 int n;
605 601
606 if(*str == '='){ 602 if (*str == '=') {
607 *error_out = "Can't configure all devices from mconsole"; 603 *error_out = "Can't configure all devices from mconsole";
608 return -EINVAL; 604 return -EINVAL;
609 } 605 }
610 606
611 new = kstrdup(str, GFP_KERNEL); 607 new = kstrdup(str, GFP_KERNEL);
612 if(new == NULL){ 608 if (new == NULL) {
613 *error_out = "Failed to allocate memory"; 609 *error_out = "Failed to allocate memory";
614 return -ENOMEM; 610 return -ENOMEM;
615 } 611 }
616 n = line_setup(lines, num, new, error_out); 612 n = line_setup(lines, num, new, error_out);
617 if(n < 0) 613 if (n < 0)
618 return n; 614 return n;
619 615
620 line = &lines[n]; 616 line = &lines[n];
@@ -629,12 +625,12 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
629 int dev, n = 0; 625 int dev, n = 0;
630 626
631 dev = simple_strtoul(name, &end, 0); 627 dev = simple_strtoul(name, &end, 0);
632 if((*end != '\0') || (end == name)){ 628 if ((*end != '\0') || (end == name)) {
633 *error_out = "line_get_config failed to parse device number"; 629 *error_out = "line_get_config failed to parse device number";
634 return 0; 630 return 0;
635 } 631 }
636 632
637 if((dev < 0) || (dev >= num)){ 633 if ((dev < 0) || (dev >= num)) {
638 *error_out = "device number out of range"; 634 *error_out = "device number out of range";
639 return 0; 635 return 0;
640 } 636 }
@@ -642,9 +638,9 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
642 line = &lines[dev]; 638 line = &lines[dev];
643 639
644 spin_lock(&line->count_lock); 640 spin_lock(&line->count_lock);
645 if(!line->valid) 641 if (!line->valid)
646 CONFIG_CHUNK(str, size, n, "none", 1); 642 CONFIG_CHUNK(str, size, n, "none", 1);
647 else if(line->tty == NULL) 643 else if (line->tty == NULL)
648 CONFIG_CHUNK(str, size, n, line->init_str, 1); 644 CONFIG_CHUNK(str, size, n, line->init_str, 1);
649 else n = chan_config_string(&line->chan_list, str, size, error_out); 645 else n = chan_config_string(&line->chan_list, str, size, error_out);
650 spin_unlock(&line->count_lock); 646 spin_unlock(&line->count_lock);
@@ -655,16 +651,16 @@ int line_get_config(char *name, struct line *lines, unsigned int num, char *str,
655int line_id(char **str, int *start_out, int *end_out) 651int line_id(char **str, int *start_out, int *end_out)
656{ 652{
657 char *end; 653 char *end;
658 int n; 654 int n;
659 655
660 n = simple_strtoul(*str, &end, 0); 656 n = simple_strtoul(*str, &end, 0);
661 if((*end != '\0') || (end == *str)) 657 if ((*end != '\0') || (end == *str))
662 return -1; 658 return -1;
663 659
664 *str = end; 660 *str = end;
665 *start_out = n; 661 *start_out = n;
666 *end_out = n; 662 *end_out = n;
667 return n; 663 return n;
668} 664}
669 665
670int line_remove(struct line *lines, unsigned int num, int n, char **error_out) 666int line_remove(struct line *lines, unsigned int num, int n, char **error_out)
@@ -674,7 +670,7 @@ int line_remove(struct line *lines, unsigned int num, int n, char **error_out)
674 670
675 sprintf(config, "%d=none", n); 671 sprintf(config, "%d=none", n);
676 err = line_setup(lines, num, config, error_out); 672 err = line_setup(lines, num, config, error_out);
677 if(err >= 0) 673 if (err >= 0)
678 err = 0; 674 err = 0;
679 return err; 675 return err;
680} 676}
@@ -700,14 +696,14 @@ struct tty_driver *register_lines(struct line_driver *line_driver,
700 tty_set_operations(driver, ops); 696 tty_set_operations(driver, ops);
701 697
702 if (tty_register_driver(driver)) { 698 if (tty_register_driver(driver)) {
703 printk("%s: can't register %s driver\n", 699 printk(KERN_ERR "register_lines : can't register %s driver\n",
704 __FUNCTION__,line_driver->name); 700 line_driver->name);
705 put_tty_driver(driver); 701 put_tty_driver(driver);
706 return NULL; 702 return NULL;
707 } 703 }
708 704
709 for(i = 0; i < nlines; i++){ 705 for(i = 0; i < nlines; i++) {
710 if(!lines[i].valid) 706 if (!lines[i].valid)
711 tty_unregister_device(driver, i); 707 tty_unregister_device(driver, i);
712 } 708 }
713 709
@@ -724,20 +720,20 @@ void lines_init(struct line *lines, int nlines, struct chan_opts *opts)
724 char *error; 720 char *error;
725 int i; 721 int i;
726 722
727 for(i = 0; i < nlines; i++){ 723 for(i = 0; i < nlines; i++) {
728 line = &lines[i]; 724 line = &lines[i];
729 INIT_LIST_HEAD(&line->chan_list); 725 INIT_LIST_HEAD(&line->chan_list);
730 726
731 if(line->init_str == NULL) 727 if (line->init_str == NULL)
732 continue; 728 continue;
733 729
734 line->init_str = kstrdup(line->init_str, GFP_KERNEL); 730 line->init_str = kstrdup(line->init_str, GFP_KERNEL);
735 if(line->init_str == NULL) 731 if (line->init_str == NULL)
736 printk("lines_init - kstrdup returned NULL\n"); 732 printk(KERN_ERR "lines_init - kstrdup returned NULL\n");
737 733
738 if(parse_chan_pair(line->init_str, line, i, opts, &error)){ 734 if (parse_chan_pair(line->init_str, line, i, opts, &error)) {
739 printk("parse_chan_pair failed for device %d : %s\n", 735 printk(KERN_ERR "parse_chan_pair failed for "
740 i, error); 736 "device %d : %s\n", i, error);
741 line->valid = 0; 737 line->valid = 0;
742 } 738 }
743 } 739 }
@@ -775,14 +771,14 @@ static irqreturn_t winch_interrupt(int irq, void *data)
775 int err; 771 int err;
776 char c; 772 char c;
777 773
778 if(winch->fd != -1){ 774 if (winch->fd != -1) {
779 err = generic_read(winch->fd, &c, NULL); 775 err = generic_read(winch->fd, &c, NULL);
780 if(err < 0){ 776 if (err < 0) {
781 if(err != -EAGAIN){ 777 if (err != -EAGAIN) {
782 printk("winch_interrupt : read failed, " 778 printk(KERN_ERR "winch_interrupt : "
783 "errno = %d\n", -err); 779 "read failed, errno = %d\n", -err);
784 printk("fd %d is losing SIGWINCH support\n", 780 printk(KERN_ERR "fd %d is losing SIGWINCH "
785 winch->tty_fd); 781 "support\n", winch->tty_fd);
786 free_winch(winch, 0); 782 free_winch(winch, 0);
787 return IRQ_HANDLED; 783 return IRQ_HANDLED;
788 } 784 }
@@ -797,7 +793,7 @@ static irqreturn_t winch_interrupt(int irq, void *data)
797 kill_pgrp(tty->pgrp, SIGWINCH, 1); 793 kill_pgrp(tty->pgrp, SIGWINCH, 1);
798 } 794 }
799 out: 795 out:
800 if(winch->fd != -1) 796 if (winch->fd != -1)
801 reactivate_fd(winch->fd, WINCH_IRQ); 797 reactivate_fd(winch->fd, WINCH_IRQ);
802 return IRQ_HANDLED; 798 return IRQ_HANDLED;
803} 799}
@@ -809,7 +805,7 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
809 805
810 winch = kmalloc(sizeof(*winch), GFP_KERNEL); 806 winch = kmalloc(sizeof(*winch), GFP_KERNEL);
811 if (winch == NULL) { 807 if (winch == NULL) {
812 printk("register_winch_irq - kmalloc failed\n"); 808 printk(KERN_ERR "register_winch_irq - kmalloc failed\n");
813 goto cleanup; 809 goto cleanup;
814 } 810 }
815 811
@@ -823,7 +819,8 @@ void register_winch_irq(int fd, int tty_fd, int pid, struct tty_struct *tty,
823 if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt, 819 if (um_request_irq(WINCH_IRQ, fd, IRQ_READ, winch_interrupt,
824 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, 820 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
825 "winch", winch) < 0) { 821 "winch", winch) < 0) {
826 printk("register_winch_irq - failed to register IRQ\n"); 822 printk(KERN_ERR "register_winch_irq - failed to register "
823 "IRQ\n");
827 goto out_free; 824 goto out_free;
828 } 825 }
829 826
@@ -849,13 +846,13 @@ static void unregister_winch(struct tty_struct *tty)
849 846
850 spin_lock(&winch_handler_lock); 847 spin_lock(&winch_handler_lock);
851 848
852 list_for_each(ele, &winch_handlers){ 849 list_for_each(ele, &winch_handlers) {
853 winch = list_entry(ele, struct winch, list); 850 winch = list_entry(ele, struct winch, list);
854 if(winch->tty == tty){ 851 if (winch->tty == tty) {
855 free_winch(winch, 1); 852 free_winch(winch, 1);
856 break; 853 break;
857 } 854 }
858 } 855 }
859 spin_unlock(&winch_handler_lock); 856 spin_unlock(&winch_handler_lock);
860} 857}
861 858
@@ -866,7 +863,7 @@ static void winch_cleanup(void)
866 863
867 spin_lock(&winch_handler_lock); 864 spin_lock(&winch_handler_lock);
868 865
869 list_for_each_safe(ele, next, &winch_handlers){ 866 list_for_each_safe(ele, next, &winch_handlers) {
870 winch = list_entry(ele, struct winch, list); 867 winch = list_entry(ele, struct winch, list);
871 free_winch(winch, 1); 868 free_winch(winch, 1);
872 } 869 }
@@ -881,13 +878,13 @@ char *add_xterm_umid(char *base)
881 int len; 878 int len;
882 879
883 umid = get_umid(); 880 umid = get_umid();
884 if(*umid == '\0') 881 if (*umid == '\0')
885 return base; 882 return base;
886 883
887 len = strlen(base) + strlen(" ()") + strlen(umid) + 1; 884 len = strlen(base) + strlen(" ()") + strlen(umid) + 1;
888 title = kmalloc(len, GFP_KERNEL); 885 title = kmalloc(len, GFP_KERNEL);
889 if(title == NULL){ 886 if (title == NULL) {
890 printk("Failed to allocate buffer for xterm title\n"); 887 printk(KERN_ERR "Failed to allocate buffer for xterm title\n");
891 return base; 888 return base;
892 } 889 }
893 890
diff --git a/arch/um/drivers/mcast.h b/arch/um/drivers/mcast.h
index bc56af9d3e53..6fa282e896be 100644
--- a/arch/um/drivers/mcast.h
+++ b/arch/um/drivers/mcast.h
@@ -1,8 +1,11 @@
1/* 1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#ifndef __DRIVERS_MCAST_H
7#define __DRIVERS_MCAST_H
8
6#include "net_user.h" 9#include "net_user.h"
7 10
8struct mcast_data { 11struct mcast_data {
@@ -18,13 +21,4 @@ extern const struct net_user_info mcast_user_info;
18extern int mcast_user_write(int fd, void *buf, int len, 21extern int mcast_user_write(int fd, void *buf, int len,
19 struct mcast_data *pri); 22 struct mcast_data *pri);
20 23
21/* 24#endif
22 * Overrides for Emacs so that we follow Linus's tabbing style.
23 * Emacs will notice this stuff at the end of the file and automatically
24 * adjust the settings for this buffer only. This must remain at the end
25 * of the file.
26 * ---------------------------------------------------------------------------
27 * Local variables:
28 * c-file-style: "linux"
29 * End:
30 */
diff --git a/arch/um/drivers/mcast_kern.c b/arch/um/drivers/mcast_kern.c
index e6b8e0dd72a8..822092f149be 100644
--- a/arch/um/drivers/mcast_kern.c
+++ b/arch/um/drivers/mcast_kern.c
@@ -1,24 +1,20 @@
1/* 1/*
2 * user-mode-linux networking multicast transport 2 * user-mode-linux networking multicast transport
3 * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org> 3 * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * 5 *
5 * based on the existing uml-networking code, which is 6 * based on the existing uml-networking code, which is
6 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 7 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
7 * James Leu (jleu@mindspring.net). 8 * James Leu (jleu@mindspring.net).
8 * Copyright (C) 2001 by various other people who didn't put their name here. 9 * Copyright (C) 2001 by various other people who didn't put their name here.
9 * 10 *
10 * Licensed under the GPL. 11 * Licensed under the GPL.
11 */ 12 */
12 13
13#include "linux/kernel.h"
14#include "linux/init.h" 14#include "linux/init.h"
15#include "linux/netdevice.h" 15#include <linux/netdevice.h>
16#include "linux/etherdevice.h"
17#include "linux/in.h"
18#include "linux/inet.h"
19#include "net_kern.h"
20#include "net_user.h"
21#include "mcast.h" 16#include "mcast.h"
17#include "net_kern.h"
22 18
23struct mcast_init { 19struct mcast_init {
24 char *addr; 20 char *addr;
@@ -39,26 +35,20 @@ static void mcast_init(struct net_device *dev, void *data)
39 dpri->ttl = init->ttl; 35 dpri->ttl = init->ttl;
40 dpri->dev = dev; 36 dpri->dev = dev;
41 37
42 printk("mcast backend "); 38 printk("mcast backend multicast address: %s:%u, TTL:%u\n",
43 printk("multicast address: %s:%u, TTL:%u ",
44 dpri->addr, dpri->port, dpri->ttl); 39 dpri->addr, dpri->port, dpri->ttl);
45
46 printk("\n");
47} 40}
48 41
49static int mcast_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) 42static int mcast_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
50{ 43{
51 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 44 return net_recvfrom(fd, skb_mac_header(skb),
52 if(*skb == NULL) return(-ENOMEM); 45 skb->dev->mtu + ETH_HEADER_OTHER);
53 return(net_recvfrom(fd, skb_mac_header(*skb),
54 (*skb)->dev->mtu + ETH_HEADER_OTHER));
55} 46}
56 47
57static int mcast_write(int fd, struct sk_buff **skb, 48static int mcast_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
58 struct uml_net_private *lp)
59{ 49{
60 return mcast_user_write(fd, (*skb)->data, (*skb)->len, 50 return mcast_user_write(fd, skb->data, skb->len,
61 (struct mcast_data *) &lp->user); 51 (struct mcast_data *) &lp->user);
62} 52}
63 53
64static const struct net_kern_info mcast_kern_info = { 54static const struct net_kern_info mcast_kern_info = {
@@ -81,34 +71,34 @@ int mcast_setup(char *str, char **mac_out, void *data)
81 71
82 remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str, 72 remain = split_if_spec(str, mac_out, &init->addr, &port_str, &ttl_str,
83 NULL); 73 NULL);
84 if(remain != NULL){ 74 if (remain != NULL) {
85 printk(KERN_ERR "mcast_setup - Extra garbage on " 75 printk(KERN_ERR "mcast_setup - Extra garbage on "
86 "specification : '%s'\n", remain); 76 "specification : '%s'\n", remain);
87 return(0); 77 return 0;
88 } 78 }
89 79
90 if(port_str != NULL){ 80 if (port_str != NULL) {
91 init->port = simple_strtoul(port_str, &last, 10); 81 init->port = simple_strtoul(port_str, &last, 10);
92 if((*last != '\0') || (last == port_str)){ 82 if ((*last != '\0') || (last == port_str)) {
93 printk(KERN_ERR "mcast_setup - Bad port : '%s'\n", 83 printk(KERN_ERR "mcast_setup - Bad port : '%s'\n",
94 port_str); 84 port_str);
95 return(0); 85 return 0;
96 } 86 }
97 } 87 }
98 88
99 if(ttl_str != NULL){ 89 if (ttl_str != NULL) {
100 init->ttl = simple_strtoul(ttl_str, &last, 10); 90 init->ttl = simple_strtoul(ttl_str, &last, 10);
101 if((*last != '\0') || (last == ttl_str)){ 91 if ((*last != '\0') || (last == ttl_str)) {
102 printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n", 92 printk(KERN_ERR "mcast_setup - Bad ttl : '%s'\n",
103 ttl_str); 93 ttl_str);
104 return(0); 94 return 0;
105 } 95 }
106 } 96 }
107 97
108 printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr, 98 printk(KERN_INFO "Configured mcast device: %s:%u-%u\n", init->addr,
109 init->port, init->ttl); 99 init->port, init->ttl);
110 100
111 return(1); 101 return 1;
112} 102}
113 103
114static struct transport mcast_transport = { 104static struct transport mcast_transport = {
diff --git a/arch/um/drivers/mcast_user.c b/arch/um/drivers/mcast_user.c
index 236a3dfc297d..5f647d7a7292 100644
--- a/arch/um/drivers/mcast_user.c
+++ b/arch/um/drivers/mcast_user.c
@@ -1,9 +1,10 @@
1/* 1/*
2 * user-mode-linux networking multicast transport 2 * user-mode-linux networking multicast transport
3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org> 4 * Copyright (C) 2001 by Harald Welte <laforge@gnumonks.org>
4 * 5 *
5 * based on the existing uml-networking code, which is 6 * based on the existing uml-networking code, which is
6 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 7 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
7 * James Leu (jleu@mindspring.net). 8 * James Leu (jleu@mindspring.net).
8 * Copyright (C) 2001 by various other people who didn't put their name here. 9 * Copyright (C) 2001 by various other people who didn't put their name here.
9 * 10 *
@@ -11,28 +12,22 @@
11 * 12 *
12 */ 13 */
13 14
14#include <errno.h>
15#include <unistd.h> 15#include <unistd.h>
16#include <sys/socket.h> 16#include <errno.h>
17#include <sys/un.h>
18#include <sys/time.h>
19#include <netinet/in.h> 17#include <netinet/in.h>
20#include "net_user.h"
21#include "mcast.h" 18#include "mcast.h"
22#include "kern_util.h" 19#include "net_user.h"
23#include "user.h"
24#include "os.h"
25#include "um_malloc.h" 20#include "um_malloc.h"
26 21#include "user.h"
27#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER)
28 22
29static struct sockaddr_in *new_addr(char *addr, unsigned short port) 23static struct sockaddr_in *new_addr(char *addr, unsigned short port)
30{ 24{
31 struct sockaddr_in *sin; 25 struct sockaddr_in *sin;
32 26
33 sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL); 27 sin = kmalloc(sizeof(struct sockaddr_in), UM_GFP_KERNEL);
34 if(sin == NULL){ 28 if (sin == NULL) {
35 printk("new_addr: allocation of sockaddr_in failed\n"); 29 printk(UM_KERN_ERR "new_addr: allocation of sockaddr_in "
30 "failed\n");
36 return NULL; 31 return NULL;
37 } 32 }
38 sin->sin_family = AF_INET; 33 sin->sin_family = AF_INET;
@@ -71,17 +66,17 @@ static int mcast_open(void *data)
71 66
72 fd = socket(AF_INET, SOCK_DGRAM, 0); 67 fd = socket(AF_INET, SOCK_DGRAM, 0);
73 68
74 if (fd < 0){ 69 if (fd < 0) {
75 err = -errno; 70 err = -errno;
76 printk("mcast_open : data socket failed, errno = %d\n", 71 printk(UM_KERN_ERR "mcast_open : data socket failed, "
77 errno); 72 "errno = %d\n", errno);
78 goto out; 73 goto out;
79 } 74 }
80 75
81 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) { 76 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &yes, sizeof(yes)) < 0) {
82 err = -errno; 77 err = -errno;
83 printk("mcast_open: SO_REUSEADDR failed, errno = %d\n", 78 printk(UM_KERN_ERR "mcast_open: SO_REUSEADDR failed, "
84 errno); 79 "errno = %d\n", errno);
85 goto out_close; 80 goto out_close;
86 } 81 }
87 82
@@ -89,45 +84,46 @@ static int mcast_open(void *data)
89 if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl, 84 if (setsockopt(fd, SOL_IP, IP_MULTICAST_TTL, &pri->ttl,
90 sizeof(pri->ttl)) < 0) { 85 sizeof(pri->ttl)) < 0) {
91 err = -errno; 86 err = -errno;
92 printk("mcast_open: IP_MULTICAST_TTL failed, error = %d\n", 87 printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_TTL failed, "
93 errno); 88 "error = %d\n", errno);
94 goto out_close; 89 goto out_close;
95 } 90 }
96 91
97 /* set LOOP, so data does get fed back to local sockets */ 92 /* set LOOP, so data does get fed back to local sockets */
98 if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) { 93 if (setsockopt(fd, SOL_IP, IP_MULTICAST_LOOP, &yes, sizeof(yes)) < 0) {
99 err = -errno; 94 err = -errno;
100 printk("mcast_open: IP_MULTICAST_LOOP failed, error = %d\n", 95 printk(UM_KERN_ERR "mcast_open: IP_MULTICAST_LOOP failed, "
101 errno); 96 "error = %d\n", errno);
102 goto out_close; 97 goto out_close;
103 } 98 }
104 99
105 /* bind socket to mcast address */ 100 /* bind socket to mcast address */
106 if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) { 101 if (bind(fd, (struct sockaddr *) sin, sizeof(*sin)) < 0) {
107 err = -errno; 102 err = -errno;
108 printk("mcast_open : data bind failed, errno = %d\n", errno); 103 printk(UM_KERN_ERR "mcast_open : data bind failed, "
104 "errno = %d\n", errno);
109 goto out_close; 105 goto out_close;
110 } 106 }
111 107
112 /* subscribe to the multicast group */ 108 /* subscribe to the multicast group */
113 mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr; 109 mreq.imr_multiaddr.s_addr = sin->sin_addr.s_addr;
114 mreq.imr_interface.s_addr = 0; 110 mreq.imr_interface.s_addr = 0;
115 if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP, 111 if (setsockopt(fd, SOL_IP, IP_ADD_MEMBERSHIP,
116 &mreq, sizeof(mreq)) < 0) { 112 &mreq, sizeof(mreq)) < 0) {
117 err = -errno; 113 err = -errno;
118 printk("mcast_open: IP_ADD_MEMBERSHIP failed, error = %d\n", 114 printk(UM_KERN_ERR "mcast_open: IP_ADD_MEMBERSHIP failed, "
119 errno); 115 "error = %d\n", errno);
120 printk("There appears not to be a multicast-capable network " 116 printk(UM_KERN_ERR "There appears not to be a multicast-"
121 "interface on the host.\n"); 117 "capable network interface on the host.\n");
122 printk("eth0 should be configured in order to use the " 118 printk(UM_KERN_ERR "eth0 should be configured in order to use "
123 "multicast transport.\n"); 119 "the multicast transport.\n");
124 goto out_close; 120 goto out_close;
125 } 121 }
126 122
127 return fd; 123 return fd;
128 124
129 out_close: 125 out_close:
130 os_close_file(fd); 126 close(fd);
131 out: 127 out:
132 return err; 128 return err;
133} 129}
@@ -142,11 +138,11 @@ static void mcast_close(int fd, void *data)
142 mreq.imr_interface.s_addr = 0; 138 mreq.imr_interface.s_addr = 0;
143 if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP, 139 if (setsockopt(fd, SOL_IP, IP_DROP_MEMBERSHIP,
144 &mreq, sizeof(mreq)) < 0) { 140 &mreq, sizeof(mreq)) < 0) {
145 printk("mcast_open: IP_DROP_MEMBERSHIP failed, error = %d\n", 141 printk(UM_KERN_ERR "mcast_open: IP_DROP_MEMBERSHIP failed, "
146 errno); 142 "error = %d\n", errno);
147 } 143 }
148 144
149 os_close_file(fd); 145 close(fd);
150} 146}
151 147
152int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri) 148int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
@@ -156,18 +152,13 @@ int mcast_user_write(int fd, void *buf, int len, struct mcast_data *pri)
156 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr)); 152 return net_sendto(fd, buf, len, data_addr, sizeof(*data_addr));
157} 153}
158 154
159static int mcast_set_mtu(int mtu, void *data)
160{
161 return mtu;
162}
163
164const struct net_user_info mcast_user_info = { 155const struct net_user_info mcast_user_info = {
165 .init = mcast_user_init, 156 .init = mcast_user_init,
166 .open = mcast_open, 157 .open = mcast_open,
167 .close = mcast_close, 158 .close = mcast_close,
168 .remove = mcast_remove, 159 .remove = mcast_remove,
169 .set_mtu = mcast_set_mtu,
170 .add_address = NULL, 160 .add_address = NULL,
171 .delete_address = NULL, 161 .delete_address = NULL,
172 .max_packet = MAX_PACKET - ETH_HEADER_OTHER 162 .mtu = ETH_MAX_PACKET,
163 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
173}; 164};
diff --git a/arch/um/drivers/mconsole_kern.c b/arch/um/drivers/mconsole_kern.c
index d87090507401..0f3c7d14a6e3 100644
--- a/arch/um/drivers/mconsole_kern.c
+++ b/arch/um/drivers/mconsole_kern.c
@@ -1,44 +1,35 @@
1/* 1/*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) 2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
3 * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) 3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7#include "linux/kernel.h" 7#include "linux/console.h"
8#include "linux/slab.h"
9#include "linux/init.h"
10#include "linux/notifier.h"
11#include "linux/reboot.h"
12#include "linux/utsname.h"
13#include "linux/ctype.h" 8#include "linux/ctype.h"
14#include "linux/interrupt.h" 9#include "linux/interrupt.h"
15#include "linux/sysrq.h" 10#include "linux/list.h"
16#include "linux/workqueue.h" 11#include "linux/mm.h"
17#include "linux/module.h" 12#include "linux/module.h"
18#include "linux/file.h" 13#include "linux/notifier.h"
19#include "linux/fs.h" 14#include "linux/reboot.h"
20#include "linux/namei.h"
21#include "linux/proc_fs.h" 15#include "linux/proc_fs.h"
16#include "linux/slab.h"
22#include "linux/syscalls.h" 17#include "linux/syscalls.h"
23#include "linux/list.h" 18#include "linux/utsname.h"
24#include "linux/mm.h" 19#include "linux/workqueue.h"
25#include "linux/console.h"
26#include "asm/irq.h"
27#include "asm/uaccess.h" 20#include "asm/uaccess.h"
21#include "init.h"
22#include "irq_kern.h"
23#include "irq_user.h"
28#include "kern_util.h" 24#include "kern_util.h"
29#include "kern.h"
30#include "mconsole.h" 25#include "mconsole.h"
31#include "mconsole_kern.h" 26#include "mconsole_kern.h"
32#include "irq_user.h"
33#include "init.h"
34#include "os.h" 27#include "os.h"
35#include "irq_kern.h"
36#include "choose-mode.h"
37 28
38static int do_unlink_socket(struct notifier_block *notifier, 29static int do_unlink_socket(struct notifier_block *notifier,
39 unsigned long what, void *data) 30 unsigned long what, void *data)
40{ 31{
41 return(mconsole_unlink_socket()); 32 return mconsole_unlink_socket();
42} 33}
43 34
44 35
@@ -59,10 +50,9 @@ static void mc_work_proc(struct work_struct *unused)
59 struct mconsole_entry *req; 50 struct mconsole_entry *req;
60 unsigned long flags; 51 unsigned long flags;
61 52
62 while(!list_empty(&mc_requests)){ 53 while (!list_empty(&mc_requests)) {
63 local_irq_save(flags); 54 local_irq_save(flags);
64 req = list_entry(mc_requests.next, struct mconsole_entry, 55 req = list_entry(mc_requests.next, struct mconsole_entry, list);
65 list);
66 list_del(&req->list); 56 list_del(&req->list);
67 local_irq_restore(flags); 57 local_irq_restore(flags);
68 req->request.cmd->handler(&req->request); 58 req->request.cmd->handler(&req->request);
@@ -80,12 +70,12 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id)
80 static struct mc_request req; /* that's OK */ 70 static struct mc_request req; /* that's OK */
81 71
82 fd = (long) dev_id; 72 fd = (long) dev_id;
83 while (mconsole_get_request(fd, &req)){ 73 while (mconsole_get_request(fd, &req)) {
84 if(req.cmd->context == MCONSOLE_INTR) 74 if (req.cmd->context == MCONSOLE_INTR)
85 (*req.cmd->handler)(&req); 75 (*req.cmd->handler)(&req);
86 else { 76 else {
87 new = kmalloc(sizeof(*new), GFP_NOWAIT); 77 new = kmalloc(sizeof(*new), GFP_NOWAIT);
88 if(new == NULL) 78 if (new == NULL)
89 mconsole_reply(&req, "Out of memory", 1, 0); 79 mconsole_reply(&req, "Out of memory", 1, 0);
90 else { 80 else {
91 new->request = req; 81 new->request = req;
@@ -94,10 +84,10 @@ static irqreturn_t mconsole_interrupt(int irq, void *dev_id)
94 } 84 }
95 } 85 }
96 } 86 }
97 if(!list_empty(&mc_requests)) 87 if (!list_empty(&mc_requests))
98 schedule_work(&mconsole_work); 88 schedule_work(&mconsole_work);
99 reactivate_fd(fd, MCONSOLE_IRQ); 89 reactivate_fd(fd, MCONSOLE_IRQ);
100 return(IRQ_HANDLED); 90 return IRQ_HANDLED;
101} 91}
102 92
103void mconsole_version(struct mc_request *req) 93void mconsole_version(struct mc_request *req)
@@ -105,8 +95,8 @@ void mconsole_version(struct mc_request *req)
105 char version[256]; 95 char version[256];
106 96
107 sprintf(version, "%s %s %s %s %s", utsname()->sysname, 97 sprintf(version, "%s %s %s %s %s", utsname()->sysname,
108 utsname()->nodename, utsname()->release, 98 utsname()->nodename, utsname()->release, utsname()->version,
109 utsname()->version, utsname()->machine); 99 utsname()->machine);
110 mconsole_reply(req, version, 0, 0); 100 mconsole_reply(req, version, 0, 0);
111} 101}
112 102
@@ -118,7 +108,7 @@ void mconsole_log(struct mc_request *req)
118 ptr += strlen("log "); 108 ptr += strlen("log ");
119 109
120 len = req->len - (ptr - req->request.data); 110 len = req->len - (ptr - req->request.data);
121 printk("%.*s", len, ptr); 111 printk(KERN_WARNING "%.*s", len, ptr);
122 mconsole_reply(req, "", 0, 0); 112 mconsole_reply(req, "", 0, 0);
123} 113}
124 114
@@ -137,17 +127,17 @@ void mconsole_proc(struct mc_request *req)
137 char *ptr = req->request.data, *buf; 127 char *ptr = req->request.data, *buf;
138 128
139 ptr += strlen("proc"); 129 ptr += strlen("proc");
140 while(isspace(*ptr)) ptr++; 130 while (isspace(*ptr)) ptr++;
141 131
142 proc = get_fs_type("proc"); 132 proc = get_fs_type("proc");
143 if(proc == NULL){ 133 if (proc == NULL) {
144 mconsole_reply(req, "procfs not registered", 1, 0); 134 mconsole_reply(req, "procfs not registered", 1, 0);
145 goto out; 135 goto out;
146 } 136 }
147 137
148 super = (*proc->get_sb)(proc, 0, NULL, NULL); 138 super = (*proc->get_sb)(proc, 0, NULL, NULL);
149 put_filesystem(proc); 139 put_filesystem(proc);
150 if(super == NULL){ 140 if (super == NULL) {
151 mconsole_reply(req, "Failed to get procfs superblock", 1, 0); 141 mconsole_reply(req, "Failed to get procfs superblock", 1, 0);
152 goto out; 142 goto out;
153 } 143 }
@@ -162,29 +152,29 @@ void mconsole_proc(struct mc_request *req)
162 * if commenting out these two calls + the below read cycle. To 152 * if commenting out these two calls + the below read cycle. To
163 * make UML crash again, it was enough to readd either one.*/ 153 * make UML crash again, it was enough to readd either one.*/
164 err = link_path_walk(ptr, &nd); 154 err = link_path_walk(ptr, &nd);
165 if(err){ 155 if (err) {
166 mconsole_reply(req, "Failed to look up file", 1, 0); 156 mconsole_reply(req, "Failed to look up file", 1, 0);
167 goto out_kill; 157 goto out_kill;
168 } 158 }
169 159
170 file = dentry_open(nd.dentry, nd.mnt, O_RDONLY); 160 file = dentry_open(nd.dentry, nd.mnt, O_RDONLY);
171 if(IS_ERR(file)){ 161 if (IS_ERR(file)) {
172 mconsole_reply(req, "Failed to open file", 1, 0); 162 mconsole_reply(req, "Failed to open file", 1, 0);
173 goto out_kill; 163 goto out_kill;
174 } 164 }
175 /*END*/ 165 /*END*/
176 166
177 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 167 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
178 if(buf == NULL){ 168 if (buf == NULL) {
179 mconsole_reply(req, "Failed to allocate buffer", 1, 0); 169 mconsole_reply(req, "Failed to allocate buffer", 1, 0);
180 goto out_fput; 170 goto out_fput;
181 } 171 }
182 172
183 if((file->f_op != NULL) && (file->f_op->read != NULL)){ 173 if ((file->f_op != NULL) && (file->f_op->read != NULL)) {
184 do { 174 do {
185 n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1, 175 n = (*file->f_op->read)(file, buf, PAGE_SIZE - 1,
186 &file->f_pos); 176 &file->f_pos);
187 if(n >= 0){ 177 if (n >= 0) {
188 buf[n] = '\0'; 178 buf[n] = '\0';
189 mconsole_reply(req, buf, 0, (n > 0)); 179 mconsole_reply(req, buf, 0, (n > 0));
190 } 180 }
@@ -193,7 +183,7 @@ void mconsole_proc(struct mc_request *req)
193 1, 0); 183 1, 0);
194 goto out_free; 184 goto out_free;
195 } 185 }
196 } while(n > 0); 186 } while (n > 0);
197 } 187 }
198 else mconsole_reply(req, "", 0, 0); 188 else mconsole_reply(req, "", 0, 0);
199 189
@@ -217,18 +207,19 @@ void mconsole_proc(struct mc_request *req)
217 char *ptr = req->request.data; 207 char *ptr = req->request.data;
218 208
219 ptr += strlen("proc"); 209 ptr += strlen("proc");
220 while(isspace(*ptr)) ptr++; 210 while (isspace(*ptr))
211 ptr++;
221 snprintf(path, sizeof(path), "/proc/%s", ptr); 212 snprintf(path, sizeof(path), "/proc/%s", ptr);
222 213
223 fd = sys_open(path, 0, 0); 214 fd = sys_open(path, 0, 0);
224 if (fd < 0) { 215 if (fd < 0) {
225 mconsole_reply(req, "Failed to open file", 1, 0); 216 mconsole_reply(req, "Failed to open file", 1, 0);
226 printk("open %s: %d\n",path,fd); 217 printk(KERN_ERR "open %s: %d\n",path,fd);
227 goto out; 218 goto out;
228 } 219 }
229 220
230 buf = kmalloc(PAGE_SIZE, GFP_KERNEL); 221 buf = kmalloc(PAGE_SIZE, GFP_KERNEL);
231 if(buf == NULL){ 222 if (buf == NULL) {
232 mconsole_reply(req, "Failed to allocate buffer", 1, 0); 223 mconsole_reply(req, "Failed to allocate buffer", 1, 0);
233 goto out_close; 224 goto out_close;
234 } 225 }
@@ -239,7 +230,7 @@ void mconsole_proc(struct mc_request *req)
239 mconsole_reply(req, "Read of file failed", 1, 0); 230 mconsole_reply(req, "Read of file failed", 1, 0);
240 goto out_free; 231 goto out_free;
241 } 232 }
242 /*Begin the file content on his own line.*/ 233 /* Begin the file content on his own line. */
243 if (first_chunk) { 234 if (first_chunk) {
244 mconsole_reply(req, "\n", 0, 1); 235 mconsole_reply(req, "\n", 0, 1);
245 first_chunk = 0; 236 first_chunk = 0;
@@ -351,12 +342,12 @@ static struct mc_device *mconsole_find_dev(char *name)
351 struct list_head *ele; 342 struct list_head *ele;
352 struct mc_device *dev; 343 struct mc_device *dev;
353 344
354 list_for_each(ele, &mconsole_devices){ 345 list_for_each(ele, &mconsole_devices) {
355 dev = list_entry(ele, struct mc_device, list); 346 dev = list_entry(ele, struct mc_device, list);
356 if(!strncmp(name, dev->name, strlen(dev->name))) 347 if (!strncmp(name, dev->name, strlen(dev->name)))
357 return(dev); 348 return dev;
358 } 349 }
359 return(NULL); 350 return NULL;
360} 351}
361 352
362#define UNPLUGGED_PER_PAGE \ 353#define UNPLUGGED_PER_PAGE \
@@ -378,15 +369,15 @@ static int mem_config(char *str, char **error_out)
378 int err = -EINVAL, i, add; 369 int err = -EINVAL, i, add;
379 char *ret; 370 char *ret;
380 371
381 if(str[0] != '='){ 372 if (str[0] != '=') {
382 *error_out = "Expected '=' after 'mem'"; 373 *error_out = "Expected '=' after 'mem'";
383 goto out; 374 goto out;
384 } 375 }
385 376
386 str++; 377 str++;
387 if(str[0] == '-') 378 if (str[0] == '-')
388 add = 0; 379 add = 0;
389 else if(str[0] == '+'){ 380 else if (str[0] == '+') {
390 add = 1; 381 add = 1;
391 } 382 }
392 else { 383 else {
@@ -396,7 +387,7 @@ static int mem_config(char *str, char **error_out)
396 387
397 str++; 388 str++;
398 diff = memparse(str, &ret); 389 diff = memparse(str, &ret);
399 if(*ret != '\0'){ 390 if (*ret != '\0') {
400 *error_out = "Failed to parse memory increment"; 391 *error_out = "Failed to parse memory increment";
401 goto out; 392 goto out;
402 } 393 }
@@ -404,17 +395,17 @@ static int mem_config(char *str, char **error_out)
404 diff /= PAGE_SIZE; 395 diff /= PAGE_SIZE;
405 396
406 down(&plug_mem_mutex); 397 down(&plug_mem_mutex);
407 for(i = 0; i < diff; i++){ 398 for (i = 0; i < diff; i++) {
408 struct unplugged_pages *unplugged; 399 struct unplugged_pages *unplugged;
409 void *addr; 400 void *addr;
410 401
411 if(add){ 402 if (add) {
412 if(list_empty(&unplugged_pages)) 403 if (list_empty(&unplugged_pages))
413 break; 404 break;
414 405
415 unplugged = list_entry(unplugged_pages.next, 406 unplugged = list_entry(unplugged_pages.next,
416 struct unplugged_pages, list); 407 struct unplugged_pages, list);
417 if(unplug_index > 0) 408 if (unplug_index > 0)
418 addr = unplugged->pages[--unplug_index]; 409 addr = unplugged->pages[--unplug_index];
419 else { 410 else {
420 list_del(&unplugged->list); 411 list_del(&unplugged->list);
@@ -429,11 +420,11 @@ static int mem_config(char *str, char **error_out)
429 struct page *page; 420 struct page *page;
430 421
431 page = alloc_page(GFP_ATOMIC); 422 page = alloc_page(GFP_ATOMIC);
432 if(page == NULL) 423 if (page == NULL)
433 break; 424 break;
434 425
435 unplugged = page_address(page); 426 unplugged = page_address(page);
436 if(unplug_index == UNPLUGGED_PER_PAGE){ 427 if (unplug_index == UNPLUGGED_PER_PAGE) {
437 list_add(&unplugged->list, &unplugged_pages); 428 list_add(&unplugged->list, &unplugged_pages);
438 unplug_index = 0; 429 unplug_index = 0;
439 } 430 }
@@ -445,9 +436,9 @@ static int mem_config(char *str, char **error_out)
445 struct unplugged_pages, 436 struct unplugged_pages,
446 list); 437 list);
447 err = os_drop_memory(addr, PAGE_SIZE); 438 err = os_drop_memory(addr, PAGE_SIZE);
448 if(err){ 439 if (err) {
449 printk("Failed to release memory - " 440 printk(KERN_ERR "Failed to release "
450 "errno = %d\n", err); 441 "memory - errno = %d\n", err);
451 *error_out = "Failed to release memory"; 442 *error_out = "Failed to release memory";
452 goto out_unlock; 443 goto out_unlock;
453 } 444 }
@@ -501,10 +492,10 @@ static struct mc_device mem_mc = {
501 492
502static int __init mem_mc_init(void) 493static int __init mem_mc_init(void)
503{ 494{
504 if(can_drop_memory()) 495 if (can_drop_memory())
505 mconsole_register_dev(&mem_mc); 496 mconsole_register_dev(&mem_mc);
506 else printk("Can't release memory to the host - memory hotplug won't " 497 else printk(KERN_ERR "Can't release memory to the host - memory "
507 "be supported\n"); 498 "hotplug won't be supported\n");
508 return 0; 499 return 0;
509} 500}
510 501
@@ -519,7 +510,7 @@ static void mconsole_get_config(int (*get_config)(char *, char *, int,
519 char default_buf[CONFIG_BUF_SIZE], *error, *buf; 510 char default_buf[CONFIG_BUF_SIZE], *error, *buf;
520 int n, size; 511 int n, size;
521 512
522 if(get_config == NULL){ 513 if (get_config == NULL) {
523 mconsole_reply(req, "No get_config routine defined", 1, 0); 514 mconsole_reply(req, "No get_config routine defined", 1, 0);
524 return; 515 return;
525 } 516 }
@@ -528,30 +519,30 @@ static void mconsole_get_config(int (*get_config)(char *, char *, int,
528 size = ARRAY_SIZE(default_buf); 519 size = ARRAY_SIZE(default_buf);
529 buf = default_buf; 520 buf = default_buf;
530 521
531 while(1){ 522 while (1) {
532 n = (*get_config)(name, buf, size, &error); 523 n = (*get_config)(name, buf, size, &error);
533 if(error != NULL){ 524 if (error != NULL) {
534 mconsole_reply(req, error, 1, 0); 525 mconsole_reply(req, error, 1, 0);
535 goto out; 526 goto out;
536 } 527 }
537 528
538 if(n <= size){ 529 if (n <= size) {
539 mconsole_reply(req, buf, 0, 0); 530 mconsole_reply(req, buf, 0, 0);
540 goto out; 531 goto out;
541 } 532 }
542 533
543 if(buf != default_buf) 534 if (buf != default_buf)
544 kfree(buf); 535 kfree(buf);
545 536
546 size = n; 537 size = n;
547 buf = kmalloc(size, GFP_KERNEL); 538 buf = kmalloc(size, GFP_KERNEL);
548 if(buf == NULL){ 539 if (buf == NULL) {
549 mconsole_reply(req, "Failed to allocate buffer", 1, 0); 540 mconsole_reply(req, "Failed to allocate buffer", 1, 0);
550 return; 541 return;
551 } 542 }
552 } 543 }
553 out: 544 out:
554 if(buf != default_buf) 545 if (buf != default_buf)
555 kfree(buf); 546 kfree(buf);
556} 547}
557 548
@@ -562,19 +553,20 @@ void mconsole_config(struct mc_request *req)
562 int err; 553 int err;
563 554
564 ptr += strlen("config"); 555 ptr += strlen("config");
565 while(isspace(*ptr)) ptr++; 556 while (isspace(*ptr))
557 ptr++;
566 dev = mconsole_find_dev(ptr); 558 dev = mconsole_find_dev(ptr);
567 if(dev == NULL){ 559 if (dev == NULL) {
568 mconsole_reply(req, "Bad configuration option", 1, 0); 560 mconsole_reply(req, "Bad configuration option", 1, 0);
569 return; 561 return;
570 } 562 }
571 563
572 name = &ptr[strlen(dev->name)]; 564 name = &ptr[strlen(dev->name)];
573 ptr = name; 565 ptr = name;
574 while((*ptr != '=') && (*ptr != '\0')) 566 while ((*ptr != '=') && (*ptr != '\0'))
575 ptr++; 567 ptr++;
576 568
577 if(*ptr == '='){ 569 if (*ptr == '=') {
578 err = (*dev->config)(name, &error_string); 570 err = (*dev->config)(name, &error_string);
579 mconsole_reply(req, error_string, err, 0); 571 mconsole_reply(req, error_string, err, 0);
580 } 572 }
@@ -589,9 +581,9 @@ void mconsole_remove(struct mc_request *req)
589 int err, start, end, n; 581 int err, start, end, n;
590 582
591 ptr += strlen("remove"); 583 ptr += strlen("remove");
592 while(isspace(*ptr)) ptr++; 584 while (isspace(*ptr)) ptr++;
593 dev = mconsole_find_dev(ptr); 585 dev = mconsole_find_dev(ptr);
594 if(dev == NULL){ 586 if (dev == NULL) {
595 mconsole_reply(req, "Bad remove option", 1, 0); 587 mconsole_reply(req, "Bad remove option", 1, 0);
596 return; 588 return;
597 } 589 }
@@ -600,11 +592,11 @@ void mconsole_remove(struct mc_request *req)
600 592
601 err = 1; 593 err = 1;
602 n = (*dev->id)(&ptr, &start, &end); 594 n = (*dev->id)(&ptr, &start, &end);
603 if(n < 0){ 595 if (n < 0) {
604 err_msg = "Couldn't parse device number"; 596 err_msg = "Couldn't parse device number";
605 goto out; 597 goto out;
606 } 598 }
607 else if((n < start) || (n > end)){ 599 else if ((n < start) || (n > end)) {
608 sprintf(error, "Invalid device number - must be between " 600 sprintf(error, "Invalid device number - must be between "
609 "%d and %d", start, end); 601 "%d and %d", start, end);
610 err_msg = error; 602 err_msg = error;
@@ -613,16 +605,16 @@ void mconsole_remove(struct mc_request *req)
613 605
614 err_msg = NULL; 606 err_msg = NULL;
615 err = (*dev->remove)(n, &err_msg); 607 err = (*dev->remove)(n, &err_msg);
616 switch(err){ 608 switch(err) {
617 case 0: 609 case 0:
618 err_msg = ""; 610 err_msg = "";
619 break; 611 break;
620 case -ENODEV: 612 case -ENODEV:
621 if(err_msg == NULL) 613 if (err_msg == NULL)
622 err_msg = "Device doesn't exist"; 614 err_msg = "Device doesn't exist";
623 break; 615 break;
624 case -EBUSY: 616 case -EBUSY:
625 if(err_msg == NULL) 617 if (err_msg == NULL)
626 err_msg = "Device is currently open"; 618 err_msg = "Device is currently open";
627 break; 619 break;
628 default: 620 default:
@@ -640,35 +632,28 @@ struct mconsole_output {
640static DEFINE_SPINLOCK(client_lock); 632static DEFINE_SPINLOCK(client_lock);
641static LIST_HEAD(clients); 633static LIST_HEAD(clients);
642static char console_buf[MCONSOLE_MAX_DATA]; 634static char console_buf[MCONSOLE_MAX_DATA];
643static int console_index = 0;
644 635
645static void console_write(struct console *console, const char *string, 636static void console_write(struct console *console, const char *string,
646 unsigned len) 637 unsigned int len)
647{ 638{
648 struct list_head *ele; 639 struct list_head *ele;
649 int n; 640 int n;
650 641
651 if(list_empty(&clients)) 642 if (list_empty(&clients))
652 return; 643 return;
653 644
654 while(1){ 645 while (len > 0) {
655 n = min((size_t) len, ARRAY_SIZE(console_buf) - console_index); 646 n = min((size_t) len, ARRAY_SIZE(console_buf));
656 strncpy(&console_buf[console_index], string, n); 647 strncpy(console_buf, string, n);
657 console_index += n;
658 string += n; 648 string += n;
659 len -= n; 649 len -= n;
660 if(len == 0)
661 return;
662 650
663 list_for_each(ele, &clients){ 651 list_for_each(ele, &clients) {
664 struct mconsole_output *entry; 652 struct mconsole_output *entry;
665 653
666 entry = list_entry(ele, struct mconsole_output, list); 654 entry = list_entry(ele, struct mconsole_output, list);
667 mconsole_reply_len(entry->req, console_buf, 655 mconsole_reply_len(entry->req, console_buf, n, 0, 1);
668 console_index, 0, 1);
669 } 656 }
670
671 console_index = 0;
672 } 657 }
673} 658}
674 659
@@ -698,8 +683,7 @@ static void with_console(struct mc_request *req, void (*proc)(void *),
698 683
699 (*proc)(arg); 684 (*proc)(arg);
700 685
701 mconsole_reply_len(req, console_buf, console_index, 0, 0); 686 mconsole_reply_len(req, "", 0, 0, 0);
702 console_index = 0;
703 687
704 spin_lock_irqsave(&client_lock, flags); 688 spin_lock_irqsave(&client_lock, flags);
705 list_del(&entry.list); 689 list_del(&entry.list);
@@ -707,6 +691,9 @@ static void with_console(struct mc_request *req, void (*proc)(void *),
707} 691}
708 692
709#ifdef CONFIG_MAGIC_SYSRQ 693#ifdef CONFIG_MAGIC_SYSRQ
694
695#include <linux/sysrq.h>
696
710static void sysrq_proc(void *arg) 697static void sysrq_proc(void *arg)
711{ 698{
712 char *op = arg; 699 char *op = arg;
@@ -718,12 +705,13 @@ void mconsole_sysrq(struct mc_request *req)
718 char *ptr = req->request.data; 705 char *ptr = req->request.data;
719 706
720 ptr += strlen("sysrq"); 707 ptr += strlen("sysrq");
721 while(isspace(*ptr)) ptr++; 708 while (isspace(*ptr)) ptr++;
722 709
723 /* With 'b', the system will shut down without a chance to reply, 710 /*
711 * With 'b', the system will shut down without a chance to reply,
724 * so in this case, we reply first. 712 * so in this case, we reply first.
725 */ 713 */
726 if(*ptr == 'b') 714 if (*ptr == 'b')
727 mconsole_reply(req, "", 0, 0); 715 mconsole_reply(req, "", 0, 0);
728 716
729 with_console(req, sysrq_proc, ptr); 717 with_console(req, sysrq_proc, ptr);
@@ -735,8 +723,6 @@ void mconsole_sysrq(struct mc_request *req)
735} 723}
736#endif 724#endif
737 725
738#ifdef CONFIG_MODE_SKAS
739
740static void stack_proc(void *arg) 726static void stack_proc(void *arg)
741{ 727{
742 struct task_struct *from = current, *to = arg; 728 struct task_struct *from = current, *to = arg;
@@ -745,29 +731,34 @@ static void stack_proc(void *arg)
745 switch_to(from, to, from); 731 switch_to(from, to, from);
746} 732}
747 733
748/* Mconsole stack trace 734/*
735 * Mconsole stack trace
749 * Added by Allan Graves, Jeff Dike 736 * Added by Allan Graves, Jeff Dike
750 * Dumps a stacks registers to the linux console. 737 * Dumps a stacks registers to the linux console.
751 * Usage stack <pid>. 738 * Usage stack <pid>.
752 */ 739 */
753static void do_stack_trace(struct mc_request *req) 740void mconsole_stack(struct mc_request *req)
754{ 741{
755 char *ptr = req->request.data; 742 char *ptr = req->request.data;
756 int pid_requested= -1; 743 int pid_requested= -1;
757 struct task_struct *from = NULL; 744 struct task_struct *from = NULL;
758 struct task_struct *to = NULL; 745 struct task_struct *to = NULL;
759 746
760 /* Would be nice: 747 /*
748 * Would be nice:
761 * 1) Send showregs output to mconsole. 749 * 1) Send showregs output to mconsole.
762 * 2) Add a way to stack dump all pids. 750 * 2) Add a way to stack dump all pids.
763 */ 751 */
764 752
765 ptr += strlen("stack"); 753 ptr += strlen("stack");
766 while(isspace(*ptr)) ptr++; 754 while (isspace(*ptr))
755 ptr++;
767 756
768 /* Should really check for multiple pids or reject bad args here */ 757 /*
758 * Should really check for multiple pids or reject bad args here
759 */
769 /* What do the arguments in mconsole_reply mean? */ 760 /* What do the arguments in mconsole_reply mean? */
770 if(sscanf(ptr, "%d", &pid_requested) == 0){ 761 if (sscanf(ptr, "%d", &pid_requested) == 0) {
771 mconsole_reply(req, "Please specify a pid", 1, 0); 762 mconsole_reply(req, "Please specify a pid", 1, 0);
772 return; 763 return;
773 } 764 }
@@ -775,25 +766,15 @@ static void do_stack_trace(struct mc_request *req)
775 from = current; 766 from = current;
776 767
777 to = find_task_by_pid(pid_requested); 768 to = find_task_by_pid(pid_requested);
778 if((to == NULL) || (pid_requested == 0)) { 769 if ((to == NULL) || (pid_requested == 0)) {
779 mconsole_reply(req, "Couldn't find that pid", 1, 0); 770 mconsole_reply(req, "Couldn't find that pid", 1, 0);
780 return; 771 return;
781 } 772 }
782 with_console(req, stack_proc, to); 773 with_console(req, stack_proc, to);
783} 774}
784#endif /* CONFIG_MODE_SKAS */
785 775
786void mconsole_stack(struct mc_request *req) 776/*
787{ 777 * Changed by mconsole_setup, which is __setup, and called before SMP is
788 /* This command doesn't work in TT mode, so let's check and then
789 * get out of here
790 */
791 CHOOSE_MODE(mconsole_reply(req, "Sorry, this doesn't work in TT mode",
792 1, 0),
793 do_stack_trace(req));
794}
795
796/* Changed by mconsole_setup, which is __setup, and called before SMP is
797 * active. 778 * active.
798 */ 779 */
799static char *notify_socket = NULL; 780static char *notify_socket = NULL;
@@ -805,13 +786,14 @@ static int __init mconsole_init(void)
805 int err; 786 int err;
806 char file[256]; 787 char file[256];
807 788
808 if(umid_file_name("mconsole", file, sizeof(file))) return(-1); 789 if (umid_file_name("mconsole", file, sizeof(file)))
790 return -1;
809 snprintf(mconsole_socket_name, sizeof(file), "%s", file); 791 snprintf(mconsole_socket_name, sizeof(file), "%s", file);
810 792
811 sock = os_create_unix_socket(file, sizeof(file), 1); 793 sock = os_create_unix_socket(file, sizeof(file), 1);
812 if (sock < 0){ 794 if (sock < 0) {
813 printk("Failed to initialize management console\n"); 795 printk(KERN_ERR "Failed to initialize management console\n");
814 return(1); 796 return 1;
815 } 797 }
816 798
817 register_reboot_notifier(&reboot_notifier); 799 register_reboot_notifier(&reboot_notifier);
@@ -819,14 +801,14 @@ static int __init mconsole_init(void)
819 err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt, 801 err = um_request_irq(MCONSOLE_IRQ, sock, IRQ_READ, mconsole_interrupt,
820 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, 802 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
821 "mconsole", (void *)sock); 803 "mconsole", (void *)sock);
822 if (err){ 804 if (err) {
823 printk("Failed to get IRQ for management console\n"); 805 printk(KERN_ERR "Failed to get IRQ for management console\n");
824 return(1); 806 return 1;
825 } 807 }
826 808
827 if(notify_socket != NULL){ 809 if (notify_socket != NULL) {
828 notify_socket = kstrdup(notify_socket, GFP_KERNEL); 810 notify_socket = kstrdup(notify_socket, GFP_KERNEL);
829 if(notify_socket != NULL) 811 if (notify_socket != NULL)
830 mconsole_notify(notify_socket, MCONSOLE_SOCKET, 812 mconsole_notify(notify_socket, MCONSOLE_SOCKET,
831 mconsole_socket_name, 813 mconsole_socket_name,
832 strlen(mconsole_socket_name) + 1); 814 strlen(mconsole_socket_name) + 1);
@@ -834,9 +816,9 @@ static int __init mconsole_init(void)
834 "string\n"); 816 "string\n");
835 } 817 }
836 818
837 printk("mconsole (version %d) initialized on %s\n", 819 printk(KERN_INFO "mconsole (version %d) initialized on %s\n",
838 MCONSOLE_VERSION, mconsole_socket_name); 820 MCONSOLE_VERSION, mconsole_socket_name);
839 return(0); 821 return 0;
840} 822}
841 823
842__initcall(mconsole_init); 824__initcall(mconsole_init);
@@ -847,10 +829,10 @@ static int write_proc_mconsole(struct file *file, const char __user *buffer,
847 char *buf; 829 char *buf;
848 830
849 buf = kmalloc(count + 1, GFP_KERNEL); 831 buf = kmalloc(count + 1, GFP_KERNEL);
850 if(buf == NULL) 832 if (buf == NULL)
851 return(-ENOMEM); 833 return -ENOMEM;
852 834
853 if(copy_from_user(buf, buffer, count)){ 835 if (copy_from_user(buf, buffer, count)) {
854 count = -EFAULT; 836 count = -EFAULT;
855 goto out; 837 goto out;
856 } 838 }
@@ -860,24 +842,26 @@ static int write_proc_mconsole(struct file *file, const char __user *buffer,
860 mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count); 842 mconsole_notify(notify_socket, MCONSOLE_USER_NOTIFY, buf, count);
861 out: 843 out:
862 kfree(buf); 844 kfree(buf);
863 return(count); 845 return count;
864} 846}
865 847
866static int create_proc_mconsole(void) 848static int create_proc_mconsole(void)
867{ 849{
868 struct proc_dir_entry *ent; 850 struct proc_dir_entry *ent;
869 851
870 if(notify_socket == NULL) return(0); 852 if (notify_socket == NULL)
853 return 0;
871 854
872 ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL); 855 ent = create_proc_entry("mconsole", S_IFREG | 0200, NULL);
873 if(ent == NULL){ 856 if (ent == NULL) {
874 printk(KERN_INFO "create_proc_mconsole : create_proc_entry failed\n"); 857 printk(KERN_INFO "create_proc_mconsole : create_proc_entry "
875 return(0); 858 "failed\n");
859 return 0;
876 } 860 }
877 861
878 ent->read_proc = NULL; 862 ent->read_proc = NULL;
879 ent->write_proc = write_proc_mconsole; 863 ent->write_proc = write_proc_mconsole;
880 return(0); 864 return 0;
881} 865}
882 866
883static DEFINE_SPINLOCK(notify_spinlock); 867static DEFINE_SPINLOCK(notify_spinlock);
@@ -894,19 +878,19 @@ void unlock_notify(void)
894 878
895__initcall(create_proc_mconsole); 879__initcall(create_proc_mconsole);
896 880
897#define NOTIFY "=notify:" 881#define NOTIFY "notify:"
898 882
899static int mconsole_setup(char *str) 883static int mconsole_setup(char *str)
900{ 884{
901 if(!strncmp(str, NOTIFY, strlen(NOTIFY))){ 885 if (!strncmp(str, NOTIFY, strlen(NOTIFY))) {
902 str += strlen(NOTIFY); 886 str += strlen(NOTIFY);
903 notify_socket = str; 887 notify_socket = str;
904 } 888 }
905 else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str); 889 else printk(KERN_ERR "mconsole_setup : Unknown option - '%s'\n", str);
906 return(1); 890 return 1;
907} 891}
908 892
909__setup("mconsole", mconsole_setup); 893__setup("mconsole=", mconsole_setup);
910 894
911__uml_help(mconsole_setup, 895__uml_help(mconsole_setup,
912"mconsole=notify:<socket>\n" 896"mconsole=notify:<socket>\n"
@@ -921,11 +905,12 @@ static int notify_panic(struct notifier_block *self, unsigned long unused1,
921{ 905{
922 char *message = ptr; 906 char *message = ptr;
923 907
924 if(notify_socket == NULL) return(0); 908 if (notify_socket == NULL)
909 return 0;
925 910
926 mconsole_notify(notify_socket, MCONSOLE_PANIC, message, 911 mconsole_notify(notify_socket, MCONSOLE_PANIC, message,
927 strlen(message) + 1); 912 strlen(message) + 1);
928 return(0); 913 return 0;
929} 914}
930 915
931static struct notifier_block panic_exit_notifier = { 916static struct notifier_block panic_exit_notifier = {
@@ -938,14 +923,14 @@ static int add_notifier(void)
938{ 923{
939 atomic_notifier_chain_register(&panic_notifier_list, 924 atomic_notifier_chain_register(&panic_notifier_list,
940 &panic_exit_notifier); 925 &panic_exit_notifier);
941 return(0); 926 return 0;
942} 927}
943 928
944__initcall(add_notifier); 929__initcall(add_notifier);
945 930
946char *mconsole_notify_socket(void) 931char *mconsole_notify_socket(void)
947{ 932{
948 return(notify_socket); 933 return notify_socket;
949} 934}
950 935
951EXPORT_SYMBOL(mconsole_notify_socket); 936EXPORT_SYMBOL(mconsole_notify_socket);
diff --git a/arch/um/drivers/mconsole_user.c b/arch/um/drivers/mconsole_user.c
index f31e71546e52..430c024a19b0 100644
--- a/arch/um/drivers/mconsole_user.c
+++ b/arch/um/drivers/mconsole_user.c
@@ -1,25 +1,22 @@
1/* 1/*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) 2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
3 * Copyright (C) 2001 - 2003 Jeff Dike (jdike@addtoit.com) 3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7#include <stdio.h>
8#include <stdlib.h>
9#include <errno.h> 7#include <errno.h>
10#include <signal.h> 8#include <string.h>
9#include <unistd.h>
11#include <sys/socket.h> 10#include <sys/socket.h>
12#include <sys/types.h>
13#include <sys/uio.h> 11#include <sys/uio.h>
14#include <sys/un.h> 12#include <sys/un.h>
15#include <unistd.h> 13#include "kern_constants.h"
16#include "user.h"
17#include "sysdep/ptrace.h"
18#include "mconsole.h" 14#include "mconsole.h"
19#include "os.h" 15#include "user.h"
20 16
21static struct mconsole_command commands[] = { 17static struct mconsole_command commands[] = {
22 /* With uts namespaces, uts information becomes process-specific, so 18 /*
19 * With uts namespaces, uts information becomes process-specific, so
23 * we need a process context. If we try handling this in interrupt 20 * we need a process context. If we try handling this in interrupt
24 * context, we may hit an exiting process without a valid uts 21 * context, we may hit an exiting process without a valid uts
25 * namespace. 22 * namespace.
@@ -36,7 +33,7 @@ static struct mconsole_command commands[] = {
36 { "go", mconsole_go, MCONSOLE_INTR }, 33 { "go", mconsole_go, MCONSOLE_INTR },
37 { "log", mconsole_log, MCONSOLE_INTR }, 34 { "log", mconsole_log, MCONSOLE_INTR },
38 { "proc", mconsole_proc, MCONSOLE_PROC }, 35 { "proc", mconsole_proc, MCONSOLE_PROC },
39 { "stack", mconsole_stack, MCONSOLE_INTR }, 36 { "stack", mconsole_stack, MCONSOLE_INTR },
40}; 37};
41 38
42/* Initialized in mconsole_init, which is an initcall */ 39/* Initialized in mconsole_init, which is an initcall */
@@ -44,21 +41,21 @@ char mconsole_socket_name[256];
44 41
45int mconsole_reply_v0(struct mc_request *req, char *reply) 42int mconsole_reply_v0(struct mc_request *req, char *reply)
46{ 43{
47 struct iovec iov; 44 struct iovec iov;
48 struct msghdr msg; 45 struct msghdr msg;
49 46
50 iov.iov_base = reply; 47 iov.iov_base = reply;
51 iov.iov_len = strlen(reply); 48 iov.iov_len = strlen(reply);
52 49
53 msg.msg_name = &(req->origin); 50 msg.msg_name = &(req->origin);
54 msg.msg_namelen = req->originlen; 51 msg.msg_namelen = req->originlen;
55 msg.msg_iov = &iov; 52 msg.msg_iov = &iov;
56 msg.msg_iovlen = 1; 53 msg.msg_iovlen = 1;
57 msg.msg_control = NULL; 54 msg.msg_control = NULL;
58 msg.msg_controllen = 0; 55 msg.msg_controllen = 0;
59 msg.msg_flags = 0; 56 msg.msg_flags = 0;
60 57
61 return sendmsg(req->originating_fd, &msg, 0); 58 return sendmsg(req->originating_fd, &msg, 0);
62} 59}
63 60
64static struct mconsole_command *mconsole_parse(struct mc_request *req) 61static struct mconsole_command *mconsole_parse(struct mc_request *req)
@@ -66,10 +63,10 @@ static struct mconsole_command *mconsole_parse(struct mc_request *req)
66 struct mconsole_command *cmd; 63 struct mconsole_command *cmd;
67 int i; 64 int i;
68 65
69 for(i = 0; i < ARRAY_SIZE(commands); i++){ 66 for (i = 0; i < ARRAY_SIZE(commands); i++) {
70 cmd = &commands[i]; 67 cmd = &commands[i];
71 if(!strncmp(req->request.data, cmd->command, 68 if (!strncmp(req->request.data, cmd->command,
72 strlen(cmd->command))){ 69 strlen(cmd->command))) {
73 return cmd; 70 return cmd;
74 } 71 }
75 } 72 }
@@ -94,9 +91,9 @@ int mconsole_get_request(int fd, struct mc_request *req)
94 91
95 req->originating_fd = fd; 92 req->originating_fd = fd;
96 93
97 if(req->request.magic != MCONSOLE_MAGIC){ 94 if (req->request.magic != MCONSOLE_MAGIC) {
98 /* Unversioned request */ 95 /* Unversioned request */
99 len = MIN(sizeof(req->request.data) - 1, 96 len = MIN(sizeof(req->request.data) - 1,
100 strlen((char *) &req->request)); 97 strlen((char *) &req->request));
101 memmove(req->request.data, &req->request, len); 98 memmove(req->request.data, &req->request, len);
102 req->request.data[len] = '\0'; 99 req->request.data[len] = '\0';
@@ -107,32 +104,33 @@ int mconsole_get_request(int fd, struct mc_request *req)
107 104
108 mconsole_reply_v0(req, "ERR Version 0 mconsole clients are " 105 mconsole_reply_v0(req, "ERR Version 0 mconsole clients are "
109 "not supported by this driver"); 106 "not supported by this driver");
110 return(0); 107 return 0;
111 } 108 }
112 109
113 if(req->request.len >= MCONSOLE_MAX_DATA){ 110 if (req->request.len >= MCONSOLE_MAX_DATA) {
114 mconsole_reply(req, "Request too large", 1, 0); 111 mconsole_reply(req, "Request too large", 1, 0);
115 return(0); 112 return 0;
116 } 113 }
117 if(req->request.version != MCONSOLE_VERSION){ 114 if (req->request.version != MCONSOLE_VERSION) {
118 mconsole_reply(req, "This driver only supports version " 115 mconsole_reply(req, "This driver only supports version "
119 STRING(MCONSOLE_VERSION) " clients", 1, 0); 116 STRING(MCONSOLE_VERSION) " clients", 1, 0);
120 } 117 }
121 118
122 req->request.data[req->request.len] = '\0'; 119 req->request.data[req->request.len] = '\0';
123 req->cmd = mconsole_parse(req); 120 req->cmd = mconsole_parse(req);
124 if(req->cmd == NULL){ 121 if (req->cmd == NULL) {
125 mconsole_reply(req, "Unknown command", 1, 0); 122 mconsole_reply(req, "Unknown command", 1, 0);
126 return(0); 123 return 0;
127 } 124 }
128 125
129 return(1); 126 return 1;
130} 127}
131 128
132int mconsole_reply_len(struct mc_request *req, const char *str, int total, 129int mconsole_reply_len(struct mc_request *req, const char *str, int total,
133 int err, int more) 130 int err, int more)
134{ 131{
135 /* XXX This is a stack consumption problem. It'd be nice to 132 /*
133 * XXX This is a stack consumption problem. It'd be nice to
136 * make it global and serialize access to it, but there are a 134 * make it global and serialize access to it, but there are a
137 * ton of callers to this function. 135 * ton of callers to this function.
138 */ 136 */
@@ -147,7 +145,7 @@ int mconsole_reply_len(struct mc_request *req, const char *str, int total,
147 145
148 len = MIN(total, MCONSOLE_MAX_DATA - 1); 146 len = MIN(total, MCONSOLE_MAX_DATA - 1);
149 147
150 if(len == total) reply.more = more; 148 if (len == total) reply.more = more;
151 else reply.more = 1; 149 else reply.more = 1;
152 150
153 memcpy(reply.data, str, len); 151 memcpy(reply.data, str, len);
@@ -161,9 +159,10 @@ int mconsole_reply_len(struct mc_request *req, const char *str, int total,
161 n = sendto(req->originating_fd, &reply, len, 0, 159 n = sendto(req->originating_fd, &reply, len, 0,
162 (struct sockaddr *) req->origin, req->originlen); 160 (struct sockaddr *) req->origin, req->originlen);
163 161
164 if(n < 0) return(-errno); 162 if (n < 0)
165 } while(total > 0); 163 return -errno;
166 return(0); 164 } while (total > 0);
165 return 0;
167} 166}
168 167
169int mconsole_reply(struct mc_request *req, const char *str, int err, int more) 168int mconsole_reply(struct mc_request *req, const char *str, int err, int more)
@@ -187,18 +186,18 @@ int mconsole_notify(char *sock_name, int type, const void *data, int len)
187 int n, err = 0; 186 int n, err = 0;
188 187
189 lock_notify(); 188 lock_notify();
190 if(notify_sock < 0){ 189 if (notify_sock < 0) {
191 notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0); 190 notify_sock = socket(PF_UNIX, SOCK_DGRAM, 0);
192 if(notify_sock < 0){ 191 if (notify_sock < 0) {
193 err = -errno; 192 err = -errno;
194 printk("mconsole_notify - socket failed, errno = %d\n", 193 printk(UM_KERN_ERR "mconsole_notify - socket failed, "
195 err); 194 "errno = %d\n", errno);
196 } 195 }
197 } 196 }
198 unlock_notify(); 197 unlock_notify();
199 198
200 if(err) 199 if (err)
201 return(err); 200 return err;
202 201
203 target.sun_family = AF_UNIX; 202 target.sun_family = AF_UNIX;
204 strcpy(target.sun_path, sock_name); 203 strcpy(target.sun_path, sock_name);
@@ -212,22 +211,12 @@ int mconsole_notify(char *sock_name, int type, const void *data, int len)
212 211
213 err = 0; 212 err = 0;
214 len = sizeof(packet) + packet.len - sizeof(packet.data); 213 len = sizeof(packet) + packet.len - sizeof(packet.data);
215 n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target, 214 n = sendto(notify_sock, &packet, len, 0, (struct sockaddr *) &target,
216 sizeof(target)); 215 sizeof(target));
217 if(n < 0){ 216 if (n < 0) {
218 err = -errno; 217 err = -errno;
219 printk("mconsole_notify - sendto failed, errno = %d\n", errno); 218 printk(UM_KERN_ERR "mconsole_notify - sendto failed, "
219 "errno = %d\n", errno);
220 } 220 }
221 return(err); 221 return err;
222} 222}
223
224/*
225 * Overrides for Emacs so that we follow Linus's tabbing style.
226 * Emacs will notice this stuff at the end of the file and automatically
227 * adjust the settings for this buffer only. This must remain at the end
228 * of the file.
229 * ---------------------------------------------------------------------------
230 * Local variables:
231 * c-file-style: "linux"
232 * End:
233 */
diff --git a/arch/um/drivers/mmapper_kern.c b/arch/um/drivers/mmapper_kern.c
index 867666a02339..67b2f55a602f 100644
--- a/arch/um/drivers/mmapper_kern.c
+++ b/arch/um/drivers/mmapper_kern.c
@@ -9,27 +9,29 @@
9 * 9 *
10 */ 10 */
11 11
12#include <linux/init.h> 12#include <linux/stddef.h>
13#include <linux/module.h> 13#include <linux/types.h>
14#include <linux/mm.h>
15#include <linux/fs.h> 14#include <linux/fs.h>
15#include <linux/init.h>
16#include <linux/miscdevice.h> 16#include <linux/miscdevice.h>
17#include <linux/module.h>
18#include <linux/mm.h>
17#include <asm/uaccess.h> 19#include <asm/uaccess.h>
18#include "mem_user.h" 20#include "mem_user.h"
19 21
20/* These are set in mmapper_init, which is called at boot time */ 22/* These are set in mmapper_init, which is called at boot time */
21static unsigned long mmapper_size; 23static unsigned long mmapper_size;
22static unsigned long p_buf = 0; 24static unsigned long p_buf;
23static char *v_buf = NULL; 25static char *v_buf;
24 26
25static ssize_t 27static ssize_t mmapper_read(struct file *file, char __user *buf, size_t count,
26mmapper_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 28 loff_t *ppos)
27{ 29{
28 return simple_read_from_buffer(buf, count, ppos, v_buf, mmapper_size); 30 return simple_read_from_buffer(buf, count, ppos, v_buf, mmapper_size);
29} 31}
30 32
31static ssize_t 33static ssize_t mmapper_write(struct file *file, const char __user *buf,
32mmapper_write(struct file *file, const char __user *buf, size_t count, loff_t *ppos) 34 size_t count, loff_t *ppos)
33{ 35{
34 if (*ppos > mmapper_size) 36 if (*ppos > mmapper_size)
35 return -EINVAL; 37 return -EINVAL;
@@ -39,48 +41,46 @@ mmapper_write(struct file *file, const char __user *buf, size_t count, loff_t *p
39 41
40 if (copy_from_user(&v_buf[*ppos], buf, count)) 42 if (copy_from_user(&v_buf[*ppos], buf, count))
41 return -EFAULT; 43 return -EFAULT;
42 44
43 return count; 45 return count;
44} 46}
45 47
46static int 48static int mmapper_ioctl(struct inode *inode, struct file *file,
47mmapper_ioctl(struct inode *inode, struct file *file, unsigned int cmd, 49 unsigned int cmd, unsigned long arg)
48 unsigned long arg)
49{ 50{
50 return(-ENOIOCTLCMD); 51 return -ENOIOCTLCMD;
51} 52}
52 53
53static int 54static int mmapper_mmap(struct file *file, struct vm_area_struct *vma)
54mmapper_mmap(struct file *file, struct vm_area_struct * vma)
55{ 55{
56 int ret = -EINVAL; 56 int ret = -EINVAL;
57 int size; 57 int size;
58 58
59 if (vma->vm_pgoff != 0) 59 if (vma->vm_pgoff != 0)
60 goto out; 60 goto out;
61 61
62 size = vma->vm_end - vma->vm_start; 62 size = vma->vm_end - vma->vm_start;
63 if(size > mmapper_size) return(-EFAULT); 63 if (size > mmapper_size)
64 return -EFAULT;
64 65
65 /* XXX A comment above remap_pfn_range says it should only be 66 /*
67 * XXX A comment above remap_pfn_range says it should only be
66 * called when the mm semaphore is held 68 * called when the mm semaphore is held
67 */ 69 */
68 if (remap_pfn_range(vma, vma->vm_start, p_buf >> PAGE_SHIFT, size, 70 if (remap_pfn_range(vma, vma->vm_start, p_buf >> PAGE_SHIFT, size,
69 vma->vm_page_prot)) 71 vma->vm_page_prot))
70 goto out; 72 goto out;
71 ret = 0; 73 ret = 0;
72out: 74out:
73 return ret; 75 return ret;
74} 76}
75 77
76static int 78static int mmapper_open(struct inode *inode, struct file *file)
77mmapper_open(struct inode *inode, struct file *file)
78{ 79{
79 return 0; 80 return 0;
80} 81}
81 82
82static int 83static int mmapper_release(struct inode *inode, struct file *file)
83mmapper_release(struct inode *inode, struct file *file)
84{ 84{
85 return 0; 85 return 0;
86} 86}
@@ -95,7 +95,9 @@ static const struct file_operations mmapper_fops = {
95 .release = mmapper_release, 95 .release = mmapper_release,
96}; 96};
97 97
98/* No locking needed - only used (and modified) by below initcall and exitcall. */ 98/*
99 * No locking needed - only used (and modified) by below initcall and exitcall.
100 */
99static struct miscdevice mmapper_dev = { 101static struct miscdevice mmapper_dev = {
100 .minor = MISC_DYNAMIC_MINOR, 102 .minor = MISC_DYNAMIC_MINOR,
101 .name = "mmapper", 103 .name = "mmapper",
@@ -109,13 +111,13 @@ static int __init mmapper_init(void)
109 printk(KERN_INFO "Mapper v0.1\n"); 111 printk(KERN_INFO "Mapper v0.1\n");
110 112
111 v_buf = (char *) find_iomem("mmapper", &mmapper_size); 113 v_buf = (char *) find_iomem("mmapper", &mmapper_size);
112 if(mmapper_size == 0){ 114 if (mmapper_size == 0) {
113 printk(KERN_ERR "mmapper_init - find_iomem failed\n"); 115 printk(KERN_ERR "mmapper_init - find_iomem failed\n");
114 goto out; 116 goto out;
115 } 117 }
116 118
117 err = misc_register(&mmapper_dev); 119 err = misc_register(&mmapper_dev);
118 if(err){ 120 if (err) {
119 printk(KERN_ERR "mmapper - misc_register failed, err = %d\n", 121 printk(KERN_ERR "mmapper - misc_register failed, err = %d\n",
120 err); 122 err);
121 goto out; 123 goto out;
@@ -136,9 +138,3 @@ module_exit(mmapper_exit);
136 138
137MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>"); 139MODULE_AUTHOR("Greg Lonnon <glonnon@ridgerun.com>");
138MODULE_DESCRIPTION("DSPLinux simulator mmapper driver"); 140MODULE_DESCRIPTION("DSPLinux simulator mmapper driver");
139/*
140 * ---------------------------------------------------------------------------
141 * Local variables:
142 * c-file-style: "linux"
143 * End:
144 */
diff --git a/arch/um/drivers/net_kern.c b/arch/um/drivers/net_kern.c
index d35d0c1ee7f4..8c01fa81a1ae 100644
--- a/arch/um/drivers/net_kern.c
+++ b/arch/um/drivers/net_kern.c
@@ -1,33 +1,28 @@
1/* 1/*
2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 3 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
3 * James Leu (jleu@mindspring.net). 4 * James Leu (jleu@mindspring.net).
4 * Copyright (C) 2001 by various other people who didn't put their name here. 5 * Copyright (C) 2001 by various other people who didn't put their name here.
5 * Licensed under the GPL. 6 * Licensed under the GPL.
6 */ 7 */
7 8
8#include "linux/kernel.h" 9#include <linux/bootmem.h>
9#include "linux/netdevice.h" 10#include <linux/etherdevice.h>
10#include "linux/rtnetlink.h" 11#include <linux/ethtool.h>
11#include "linux/skbuff.h" 12#include <linux/inetdevice.h>
12#include "linux/socket.h" 13#include <linux/init.h>
13#include "linux/spinlock.h" 14#include <linux/list.h>
14#include "linux/module.h" 15#include <linux/netdevice.h>
15#include "linux/init.h" 16#include <linux/platform_device.h>
16#include "linux/etherdevice.h" 17#include <linux/rtnetlink.h>
17#include "linux/list.h" 18#include <linux/skbuff.h>
18#include "linux/inetdevice.h" 19#include <linux/spinlock.h>
19#include "linux/ctype.h"
20#include "linux/bootmem.h"
21#include "linux/ethtool.h"
22#include "linux/platform_device.h"
23#include "asm/uaccess.h"
24#include "kern_util.h"
25#include "net_kern.h"
26#include "net_user.h"
27#include "mconsole_kern.h"
28#include "init.h" 20#include "init.h"
29#include "irq_user.h"
30#include "irq_kern.h" 21#include "irq_kern.h"
22#include "irq_user.h"
23#include "mconsole_kern.h"
24#include "net_kern.h"
25#include "net_user.h"
31 26
32static inline void set_ether_mac(struct net_device *dev, unsigned char *addr) 27static inline void set_ether_mac(struct net_device *dev, unsigned char *addr)
33{ 28{
@@ -39,6 +34,46 @@ static inline void set_ether_mac(struct net_device *dev, unsigned char *addr)
39static DEFINE_SPINLOCK(opened_lock); 34static DEFINE_SPINLOCK(opened_lock);
40static LIST_HEAD(opened); 35static LIST_HEAD(opened);
41 36
37/*
38 * The drop_skb is used when we can't allocate an skb. The
39 * packet is read into drop_skb in order to get the data off the
40 * connection to the host.
41 * It is reallocated whenever a maximum packet size is seen which is
42 * larger than any seen before. update_drop_skb is called from
43 * eth_configure when a new interface is added.
44 */
45static DEFINE_SPINLOCK(drop_lock);
46static struct sk_buff *drop_skb;
47static int drop_max;
48
49static int update_drop_skb(int max)
50{
51 struct sk_buff *new;
52 unsigned long flags;
53 int err = 0;
54
55 spin_lock_irqsave(&drop_lock, flags);
56
57 if (max <= drop_max)
58 goto out;
59
60 err = -ENOMEM;
61 new = dev_alloc_skb(max);
62 if (new == NULL)
63 goto out;
64
65 skb_put(new, max);
66
67 kfree_skb(drop_skb);
68 drop_skb = new;
69 drop_max = max;
70 err = 0;
71out:
72 spin_unlock_irqrestore(&drop_lock, flags);
73
74 return err;
75}
76
42static int uml_net_rx(struct net_device *dev) 77static int uml_net_rx(struct net_device *dev)
43{ 78{
44 struct uml_net_private *lp = dev->priv; 79 struct uml_net_private *lp = dev->priv;
@@ -46,16 +81,19 @@ static int uml_net_rx(struct net_device *dev)
46 struct sk_buff *skb; 81 struct sk_buff *skb;
47 82
48 /* If we can't allocate memory, try again next round. */ 83 /* If we can't allocate memory, try again next round. */
49 skb = dev_alloc_skb(dev->mtu); 84 skb = dev_alloc_skb(lp->max_packet);
50 if (skb == NULL) { 85 if (skb == NULL) {
86 drop_skb->dev = dev;
87 /* Read a packet into drop_skb and don't do anything with it. */
88 (*lp->read)(lp->fd, drop_skb, lp);
51 lp->stats.rx_dropped++; 89 lp->stats.rx_dropped++;
52 return 0; 90 return 0;
53 } 91 }
54 92
55 skb->dev = dev; 93 skb->dev = dev;
56 skb_put(skb, dev->mtu); 94 skb_put(skb, lp->max_packet);
57 skb_reset_mac_header(skb); 95 skb_reset_mac_header(skb);
58 pkt_len = (*lp->read)(lp->fd, &skb, lp); 96 pkt_len = (*lp->read)(lp->fd, skb, lp);
59 97
60 if (pkt_len > 0) { 98 if (pkt_len > 0) {
61 skb_trim(skb, pkt_len); 99 skb_trim(skb, pkt_len);
@@ -84,12 +122,12 @@ irqreturn_t uml_net_interrupt(int irq, void *dev_id)
84 struct uml_net_private *lp = dev->priv; 122 struct uml_net_private *lp = dev->priv;
85 int err; 123 int err;
86 124
87 if(!netif_running(dev)) 125 if (!netif_running(dev))
88 return(IRQ_NONE); 126 return IRQ_NONE;
89 127
90 spin_lock(&lp->lock); 128 spin_lock(&lp->lock);
91 while((err = uml_net_rx(dev)) > 0) ; 129 while ((err = uml_net_rx(dev)) > 0) ;
92 if(err < 0) { 130 if (err < 0) {
93 printk(KERN_ERR 131 printk(KERN_ERR
94 "Device '%s' read returned %d, shutting it down\n", 132 "Device '%s' read returned %d, shutting it down\n",
95 dev->name, err); 133 dev->name, err);
@@ -115,20 +153,20 @@ static int uml_net_open(struct net_device *dev)
115 struct uml_net_private *lp = dev->priv; 153 struct uml_net_private *lp = dev->priv;
116 int err; 154 int err;
117 155
118 if(lp->fd >= 0){ 156 if (lp->fd >= 0) {
119 err = -ENXIO; 157 err = -ENXIO;
120 goto out; 158 goto out;
121 } 159 }
122 160
123 lp->fd = (*lp->open)(&lp->user); 161 lp->fd = (*lp->open)(&lp->user);
124 if(lp->fd < 0){ 162 if (lp->fd < 0) {
125 err = lp->fd; 163 err = lp->fd;
126 goto out; 164 goto out;
127 } 165 }
128 166
129 err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt, 167 err = um_request_irq(dev->irq, lp->fd, IRQ_READ, uml_net_interrupt,
130 IRQF_DISABLED | IRQF_SHARED, dev->name, dev); 168 IRQF_DISABLED | IRQF_SHARED, dev->name, dev);
131 if(err != 0){ 169 if (err != 0) {
132 printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err); 170 printk(KERN_ERR "uml_net_open: failed to get irq(%d)\n", err);
133 err = -ENETUNREACH; 171 err = -ENETUNREACH;
134 goto out_close; 172 goto out_close;
@@ -141,7 +179,7 @@ static int uml_net_open(struct net_device *dev)
141 * is full when we get here. In this case, new data is never queued, 179 * is full when we get here. In this case, new data is never queued,
142 * SIGIOs never arrive, and the net never works. 180 * SIGIOs never arrive, and the net never works.
143 */ 181 */
144 while((err = uml_net_rx(dev)) > 0) ; 182 while ((err = uml_net_rx(dev)) > 0) ;
145 183
146 spin_lock(&opened_lock); 184 spin_lock(&opened_lock);
147 list_add(&lp->list, &opened); 185 list_add(&lp->list, &opened);
@@ -149,7 +187,7 @@ static int uml_net_open(struct net_device *dev)
149 187
150 return 0; 188 return 0;
151out_close: 189out_close:
152 if(lp->close != NULL) (*lp->close)(lp->fd, &lp->user); 190 if (lp->close != NULL) (*lp->close)(lp->fd, &lp->user);
153 lp->fd = -1; 191 lp->fd = -1;
154out: 192out:
155 return err; 193 return err;
@@ -162,7 +200,7 @@ static int uml_net_close(struct net_device *dev)
162 netif_stop_queue(dev); 200 netif_stop_queue(dev);
163 201
164 free_irq(dev->irq, dev); 202 free_irq(dev->irq, dev);
165 if(lp->close != NULL) 203 if (lp->close != NULL)
166 (*lp->close)(lp->fd, &lp->user); 204 (*lp->close)(lp->fd, &lp->user);
167 lp->fd = -1; 205 lp->fd = -1;
168 206
@@ -183,9 +221,9 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
183 221
184 spin_lock_irqsave(&lp->lock, flags); 222 spin_lock_irqsave(&lp->lock, flags);
185 223
186 len = (*lp->write)(lp->fd, &skb, lp); 224 len = (*lp->write)(lp->fd, skb, lp);
187 225
188 if(len == skb->len) { 226 if (len == skb->len) {
189 lp->stats.tx_packets++; 227 lp->stats.tx_packets++;
190 lp->stats.tx_bytes += skb->len; 228 lp->stats.tx_bytes += skb->len;
191 dev->trans_start = jiffies; 229 dev->trans_start = jiffies;
@@ -194,7 +232,7 @@ static int uml_net_start_xmit(struct sk_buff *skb, struct net_device *dev)
194 /* this is normally done in the interrupt when tx finishes */ 232 /* this is normally done in the interrupt when tx finishes */
195 netif_wake_queue(dev); 233 netif_wake_queue(dev);
196 } 234 }
197 else if(len == 0){ 235 else if (len == 0) {
198 netif_start_queue(dev); 236 netif_start_queue(dev);
199 lp->stats.tx_dropped++; 237 lp->stats.tx_dropped++;
200 } 238 }
@@ -218,8 +256,10 @@ static struct net_device_stats *uml_net_get_stats(struct net_device *dev)
218 256
219static void uml_net_set_multicast_list(struct net_device *dev) 257static void uml_net_set_multicast_list(struct net_device *dev)
220{ 258{
221 if (dev->flags & IFF_PROMISC) return; 259 if (dev->flags & IFF_PROMISC)
222 else if (dev->mc_count) dev->flags |= IFF_ALLMULTI; 260 return;
261 else if (dev->mc_count)
262 dev->flags |= IFF_ALLMULTI;
223 else dev->flags &= ~IFF_ALLMULTI; 263 else dev->flags &= ~IFF_ALLMULTI;
224} 264}
225 265
@@ -243,22 +283,9 @@ static int uml_net_set_mac(struct net_device *dev, void *addr)
243 283
244static int uml_net_change_mtu(struct net_device *dev, int new_mtu) 284static int uml_net_change_mtu(struct net_device *dev, int new_mtu)
245{ 285{
246 struct uml_net_private *lp = dev->priv;
247 int err = 0;
248
249 spin_lock_irq(&lp->lock);
250
251 new_mtu = (*lp->set_mtu)(new_mtu, &lp->user);
252 if(new_mtu < 0){
253 err = new_mtu;
254 goto out;
255 }
256
257 dev->mtu = new_mtu; 286 dev->mtu = new_mtu;
258 287
259 out: 288 return 0;
260 spin_unlock_irq(&lp->lock);
261 return err;
262} 289}
263 290
264static void uml_net_get_drvinfo(struct net_device *dev, 291static void uml_net_get_drvinfo(struct net_device *dev,
@@ -288,13 +315,13 @@ static void setup_etheraddr(char *str, unsigned char *addr, char *name)
288 char *end; 315 char *end;
289 int i; 316 int i;
290 317
291 if(str == NULL) 318 if (str == NULL)
292 goto random; 319 goto random;
293 320
294 for(i=0;i<6;i++){ 321 for (i = 0;i < 6; i++) {
295 addr[i] = simple_strtoul(str, &end, 16); 322 addr[i] = simple_strtoul(str, &end, 16);
296 if((end == str) || 323 if ((end == str) ||
297 ((*end != ':') && (*end != ',') && (*end != '\0'))){ 324 ((*end != ':') && (*end != ',') && (*end != '\0'))) {
298 printk(KERN_ERR 325 printk(KERN_ERR
299 "setup_etheraddr: failed to parse '%s' " 326 "setup_etheraddr: failed to parse '%s' "
300 "as an ethernet address\n", str); 327 "as an ethernet address\n", str);
@@ -349,7 +376,7 @@ static void net_device_release(struct device *dev)
349 struct net_device *netdev = device->dev; 376 struct net_device *netdev = device->dev;
350 struct uml_net_private *lp = netdev->priv; 377 struct uml_net_private *lp = netdev->priv;
351 378
352 if(lp->remove != NULL) 379 if (lp->remove != NULL)
353 (*lp->remove)(&lp->user); 380 (*lp->remove)(&lp->user);
354 list_del(&device->list); 381 list_del(&device->list);
355 kfree(device); 382 kfree(device);
@@ -413,7 +440,7 @@ static void eth_configure(int n, void *init, char *mac,
413 device->pdev.name = DRIVER_NAME; 440 device->pdev.name = DRIVER_NAME;
414 device->pdev.dev.release = net_device_release; 441 device->pdev.dev.release = net_device_release;
415 device->pdev.dev.driver_data = device; 442 device->pdev.dev.driver_data = device;
416 if(platform_device_register(&device->pdev)) 443 if (platform_device_register(&device->pdev))
417 goto out_free_netdev; 444 goto out_free_netdev;
418 SET_NETDEV_DEV(dev,&device->pdev.dev); 445 SET_NETDEV_DEV(dev,&device->pdev.dev);
419 446
@@ -430,6 +457,7 @@ static void eth_configure(int n, void *init, char *mac,
430 .dev = dev, 457 .dev = dev,
431 .fd = -1, 458 .fd = -1,
432 .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0}, 459 .mac = { 0xfe, 0xfd, 0x0, 0x0, 0x0, 0x0},
460 .max_packet = transport->user->max_packet,
433 .protocol = transport->kern->protocol, 461 .protocol = transport->kern->protocol,
434 .open = transport->user->open, 462 .open = transport->user->open,
435 .close = transport->user->close, 463 .close = transport->user->close,
@@ -437,8 +465,7 @@ static void eth_configure(int n, void *init, char *mac,
437 .read = transport->kern->read, 465 .read = transport->kern->read,
438 .write = transport->kern->write, 466 .write = transport->kern->write,
439 .add_address = transport->user->add_address, 467 .add_address = transport->user->add_address,
440 .delete_address = transport->user->delete_address, 468 .delete_address = transport->user->delete_address });
441 .set_mtu = transport->user->set_mtu });
442 469
443 init_timer(&lp->tl); 470 init_timer(&lp->tl);
444 spin_lock_init(&lp->lock); 471 spin_lock_init(&lp->lock);
@@ -450,7 +477,7 @@ static void eth_configure(int n, void *init, char *mac,
450 goto out_unregister; 477 goto out_unregister;
451 478
452 set_ether_mac(dev, device->mac); 479 set_ether_mac(dev, device->mac);
453 dev->mtu = transport->user->max_packet; 480 dev->mtu = transport->user->mtu;
454 dev->open = uml_net_open; 481 dev->open = uml_net_open;
455 dev->hard_start_xmit = uml_net_start_xmit; 482 dev->hard_start_xmit = uml_net_start_xmit;
456 dev->stop = uml_net_close; 483 dev->stop = uml_net_close;
@@ -463,6 +490,10 @@ static void eth_configure(int n, void *init, char *mac,
463 dev->watchdog_timeo = (HZ >> 1); 490 dev->watchdog_timeo = (HZ >> 1);
464 dev->irq = UM_ETH_IRQ; 491 dev->irq = UM_ETH_IRQ;
465 492
493 err = update_drop_skb(lp->max_packet);
494 if (err)
495 goto out_undo_user_init;
496
466 rtnl_lock(); 497 rtnl_lock();
467 err = register_netdevice(dev); 498 err = register_netdevice(dev);
468 rtnl_unlock(); 499 rtnl_unlock();
@@ -493,9 +524,9 @@ static struct uml_net *find_device(int n)
493 struct list_head *ele; 524 struct list_head *ele;
494 525
495 spin_lock(&devices_lock); 526 spin_lock(&devices_lock);
496 list_for_each(ele, &devices){ 527 list_for_each(ele, &devices) {
497 device = list_entry(ele, struct uml_net, list); 528 device = list_entry(ele, struct uml_net, list);
498 if(device->index == n) 529 if (device->index == n)
499 goto out; 530 goto out;
500 } 531 }
501 device = NULL; 532 device = NULL;
@@ -511,19 +542,19 @@ static int eth_parse(char *str, int *index_out, char **str_out,
511 int n, err = -EINVAL;; 542 int n, err = -EINVAL;;
512 543
513 n = simple_strtoul(str, &end, 0); 544 n = simple_strtoul(str, &end, 0);
514 if(end == str){ 545 if (end == str) {
515 *error_out = "Bad device number"; 546 *error_out = "Bad device number";
516 return err; 547 return err;
517 } 548 }
518 549
519 str = end; 550 str = end;
520 if(*str != '='){ 551 if (*str != '=') {
521 *error_out = "Expected '=' after device number"; 552 *error_out = "Expected '=' after device number";
522 return err; 553 return err;
523 } 554 }
524 555
525 str++; 556 str++;
526 if(find_device(n)){ 557 if (find_device(n)) {
527 *error_out = "Device already configured"; 558 *error_out = "Device already configured";
528 return err; 559 return err;
529 } 560 }
@@ -551,20 +582,20 @@ static int check_transport(struct transport *transport, char *eth, int n,
551 int len; 582 int len;
552 583
553 len = strlen(transport->name); 584 len = strlen(transport->name);
554 if(strncmp(eth, transport->name, len)) 585 if (strncmp(eth, transport->name, len))
555 return 0; 586 return 0;
556 587
557 eth += len; 588 eth += len;
558 if(*eth == ',') 589 if (*eth == ',')
559 eth++; 590 eth++;
560 else if(*eth != '\0') 591 else if (*eth != '\0')
561 return 0; 592 return 0;
562 593
563 *init_out = kmalloc(transport->setup_size, GFP_KERNEL); 594 *init_out = kmalloc(transport->setup_size, GFP_KERNEL);
564 if(*init_out == NULL) 595 if (*init_out == NULL)
565 return 1; 596 return 1;
566 597
567 if(!transport->setup(eth, mac_out, *init_out)){ 598 if (!transport->setup(eth, mac_out, *init_out)) {
568 kfree(*init_out); 599 kfree(*init_out);
569 *init_out = NULL; 600 *init_out = NULL;
570 } 601 }
@@ -584,13 +615,13 @@ void register_transport(struct transport *new)
584 list_add(&new->list, &transports); 615 list_add(&new->list, &transports);
585 spin_unlock(&transports_lock); 616 spin_unlock(&transports_lock);
586 617
587 list_for_each_safe(ele, next, &eth_cmd_line){ 618 list_for_each_safe(ele, next, &eth_cmd_line) {
588 eth = list_entry(ele, struct eth_init, list); 619 eth = list_entry(ele, struct eth_init, list);
589 match = check_transport(new, eth->init, eth->index, &init, 620 match = check_transport(new, eth->init, eth->index, &init,
590 &mac); 621 &mac);
591 if(!match) 622 if (!match)
592 continue; 623 continue;
593 else if(init != NULL){ 624 else if (init != NULL) {
594 eth_configure(eth->index, init, mac, new); 625 eth_configure(eth->index, init, mac, new);
595 kfree(init); 626 kfree(init);
596 } 627 }
@@ -607,11 +638,11 @@ static int eth_setup_common(char *str, int index)
607 int found = 0; 638 int found = 0;
608 639
609 spin_lock(&transports_lock); 640 spin_lock(&transports_lock);
610 list_for_each(ele, &transports){ 641 list_for_each(ele, &transports) {
611 transport = list_entry(ele, struct transport, list); 642 transport = list_entry(ele, struct transport, list);
612 if(!check_transport(transport, str, index, &init, &mac)) 643 if (!check_transport(transport, str, index, &init, &mac))
613 continue; 644 continue;
614 if(init != NULL){ 645 if (init != NULL) {
615 eth_configure(index, init, mac, transport); 646 eth_configure(index, init, mac, transport);
616 kfree(init); 647 kfree(init);
617 } 648 }
@@ -630,15 +661,15 @@ static int __init eth_setup(char *str)
630 int n, err; 661 int n, err;
631 662
632 err = eth_parse(str, &n, &str, &error); 663 err = eth_parse(str, &n, &str, &error);
633 if(err){ 664 if (err) {
634 printk(KERN_ERR "eth_setup - Couldn't parse '%s' : %s\n", 665 printk(KERN_ERR "eth_setup - Couldn't parse '%s' : %s\n",
635 str, error); 666 str, error);
636 return 1; 667 return 1;
637 } 668 }
638 669
639 new = alloc_bootmem(sizeof(*new)); 670 new = alloc_bootmem(sizeof(*new));
640 if (new == NULL){ 671 if (new == NULL) {
641 printk("eth_init : alloc_bootmem failed\n"); 672 printk(KERN_ERR "eth_init : alloc_bootmem failed\n");
642 return 1; 673 return 1;
643 } 674 }
644 675
@@ -661,36 +692,36 @@ static int net_config(char *str, char **error_out)
661 int n, err; 692 int n, err;
662 693
663 err = eth_parse(str, &n, &str, error_out); 694 err = eth_parse(str, &n, &str, error_out);
664 if(err) 695 if (err)
665 return err; 696 return err;
666 697
667 /* This string is broken up and the pieces used by the underlying 698 /* This string is broken up and the pieces used by the underlying
668 * driver. So, it is freed only if eth_setup_common fails. 699 * driver. So, it is freed only if eth_setup_common fails.
669 */ 700 */
670 str = kstrdup(str, GFP_KERNEL); 701 str = kstrdup(str, GFP_KERNEL);
671 if(str == NULL){ 702 if (str == NULL) {
672 *error_out = "net_config failed to strdup string"; 703 *error_out = "net_config failed to strdup string";
673 return -ENOMEM; 704 return -ENOMEM;
674 } 705 }
675 err = !eth_setup_common(str, n); 706 err = !eth_setup_common(str, n);
676 if(err) 707 if (err)
677 kfree(str); 708 kfree(str);
678 return(err); 709 return err;
679} 710}
680 711
681static int net_id(char **str, int *start_out, int *end_out) 712static int net_id(char **str, int *start_out, int *end_out)
682{ 713{
683 char *end; 714 char *end;
684 int n; 715 int n;
685 716
686 n = simple_strtoul(*str, &end, 0); 717 n = simple_strtoul(*str, &end, 0);
687 if((*end != '\0') || (end == *str)) 718 if ((*end != '\0') || (end == *str))
688 return -1; 719 return -1;
689 720
690 *start_out = n; 721 *start_out = n;
691 *end_out = n; 722 *end_out = n;
692 *str = end; 723 *str = end;
693 return n; 724 return n;
694} 725}
695 726
696static int net_remove(int n, char **error_out) 727static int net_remove(int n, char **error_out)
@@ -700,12 +731,12 @@ static int net_remove(int n, char **error_out)
700 struct uml_net_private *lp; 731 struct uml_net_private *lp;
701 732
702 device = find_device(n); 733 device = find_device(n);
703 if(device == NULL) 734 if (device == NULL)
704 return -ENODEV; 735 return -ENODEV;
705 736
706 dev = device->dev; 737 dev = device->dev;
707 lp = dev->priv; 738 lp = dev->priv;
708 if(lp->fd > 0) 739 if (lp->fd > 0)
709 return -EBUSY; 740 return -EBUSY;
710 unregister_netdev(dev); 741 unregister_netdev(dev);
711 platform_device_unregister(&device->pdev); 742 platform_device_unregister(&device->pdev);
@@ -731,13 +762,13 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
731 void (*proc)(unsigned char *, unsigned char *, void *); 762 void (*proc)(unsigned char *, unsigned char *, void *);
732 unsigned char addr_buf[4], netmask_buf[4]; 763 unsigned char addr_buf[4], netmask_buf[4];
733 764
734 if(dev->open != uml_net_open) 765 if (dev->open != uml_net_open)
735 return NOTIFY_DONE; 766 return NOTIFY_DONE;
736 767
737 lp = dev->priv; 768 lp = dev->priv;
738 769
739 proc = NULL; 770 proc = NULL;
740 switch (event){ 771 switch (event) {
741 case NETDEV_UP: 772 case NETDEV_UP:
742 proc = lp->add_address; 773 proc = lp->add_address;
743 break; 774 break;
@@ -745,7 +776,7 @@ static int uml_inetaddr_event(struct notifier_block *this, unsigned long event,
745 proc = lp->delete_address; 776 proc = lp->delete_address;
746 break; 777 break;
747 } 778 }
748 if(proc != NULL){ 779 if (proc != NULL) {
749 memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf)); 780 memcpy(addr_buf, &ifa->ifa_address, sizeof(addr_buf));
750 memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf)); 781 memcpy(netmask_buf, &ifa->ifa_mask, sizeof(netmask_buf));
751 (*proc)(addr_buf, netmask_buf, &lp->user); 782 (*proc)(addr_buf, netmask_buf, &lp->user);
@@ -773,13 +804,13 @@ static int uml_net_init(void)
773 * addresses which have already been set up get handled properly. 804 * addresses which have already been set up get handled properly.
774 */ 805 */
775 spin_lock(&opened_lock); 806 spin_lock(&opened_lock);
776 list_for_each(ele, &opened){ 807 list_for_each(ele, &opened) {
777 lp = list_entry(ele, struct uml_net_private, list); 808 lp = list_entry(ele, struct uml_net_private, list);
778 ip = lp->dev->ip_ptr; 809 ip = lp->dev->ip_ptr;
779 if(ip == NULL) 810 if (ip == NULL)
780 continue; 811 continue;
781 in = ip->ifa_list; 812 in = ip->ifa_list;
782 while(in != NULL){ 813 while (in != NULL) {
783 uml_inetaddr_event(NULL, NETDEV_UP, in); 814 uml_inetaddr_event(NULL, NETDEV_UP, in);
784 in = in->ifa_next; 815 in = in->ifa_next;
785 } 816 }
@@ -797,12 +828,12 @@ static void close_devices(void)
797 struct uml_net_private *lp; 828 struct uml_net_private *lp;
798 829
799 spin_lock(&opened_lock); 830 spin_lock(&opened_lock);
800 list_for_each(ele, &opened){ 831 list_for_each(ele, &opened) {
801 lp = list_entry(ele, struct uml_net_private, list); 832 lp = list_entry(ele, struct uml_net_private, list);
802 free_irq(lp->dev->irq, lp->dev); 833 free_irq(lp->dev->irq, lp->dev);
803 if((lp->close != NULL) && (lp->fd >= 0)) 834 if ((lp->close != NULL) && (lp->fd >= 0))
804 (*lp->close)(lp->fd, &lp->user); 835 (*lp->close)(lp->fd, &lp->user);
805 if(lp->remove != NULL) 836 if (lp->remove != NULL)
806 (*lp->remove)(&lp->user); 837 (*lp->remove)(&lp->user);
807 } 838 }
808 spin_unlock(&opened_lock); 839 spin_unlock(&opened_lock);
@@ -810,19 +841,6 @@ static void close_devices(void)
810 841
811__uml_exitcall(close_devices); 842__uml_exitcall(close_devices);
812 843
813struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra)
814{
815 if((skb != NULL) && (skb_tailroom(skb) < extra)){
816 struct sk_buff *skb2;
817
818 skb2 = skb_copy_expand(skb, 0, extra, GFP_ATOMIC);
819 dev_kfree_skb(skb);
820 skb = skb2;
821 }
822 if(skb != NULL) skb_put(skb, extra);
823 return(skb);
824}
825
826void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *, 844void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
827 void *), 845 void *),
828 void *arg) 846 void *arg)
@@ -832,9 +850,9 @@ void iter_addresses(void *d, void (*cb)(unsigned char *, unsigned char *,
832 struct in_ifaddr *in; 850 struct in_ifaddr *in;
833 unsigned char address[4], netmask[4]; 851 unsigned char address[4], netmask[4];
834 852
835 if(ip == NULL) return; 853 if (ip == NULL) return;
836 in = ip->ifa_list; 854 in = ip->ifa_list;
837 while(in != NULL){ 855 while (in != NULL) {
838 memcpy(address, &in->ifa_address, sizeof(address)); 856 memcpy(address, &in->ifa_address, sizeof(address));
839 memcpy(netmask, &in->ifa_mask, sizeof(netmask)); 857 memcpy(netmask, &in->ifa_mask, sizeof(netmask));
840 (*cb)(address, netmask, arg); 858 (*cb)(address, netmask, arg);
@@ -849,15 +867,15 @@ int dev_netmask(void *d, void *m)
849 struct in_ifaddr *in; 867 struct in_ifaddr *in;
850 __be32 *mask_out = m; 868 __be32 *mask_out = m;
851 869
852 if(ip == NULL) 870 if (ip == NULL)
853 return(1); 871 return 1;
854 872
855 in = ip->ifa_list; 873 in = ip->ifa_list;
856 if(in == NULL) 874 if (in == NULL)
857 return(1); 875 return 1;
858 876
859 *mask_out = in->ifa_mask; 877 *mask_out = in->ifa_mask;
860 return(0); 878 return 0;
861} 879}
862 880
863void *get_output_buffer(int *len_out) 881void *get_output_buffer(int *len_out)
@@ -865,7 +883,7 @@ void *get_output_buffer(int *len_out)
865 void *ret; 883 void *ret;
866 884
867 ret = (void *) __get_free_pages(GFP_KERNEL, 0); 885 ret = (void *) __get_free_pages(GFP_KERNEL, 0);
868 if(ret) *len_out = PAGE_SIZE; 886 if (ret) *len_out = PAGE_SIZE;
869 else *len_out = 0; 887 else *len_out = 0;
870 return ret; 888 return ret;
871} 889}
@@ -881,16 +899,16 @@ int tap_setup_common(char *str, char *type, char **dev_name, char **mac_out,
881 char *remain; 899 char *remain;
882 900
883 remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL); 901 remain = split_if_spec(str, dev_name, mac_out, gate_addr, NULL);
884 if(remain != NULL){ 902 if (remain != NULL) {
885 printk("tap_setup_common - Extra garbage on specification : " 903 printk(KERN_ERR "tap_setup_common - Extra garbage on "
886 "'%s'\n", remain); 904 "specification : '%s'\n", remain);
887 return(1); 905 return 1;
888 } 906 }
889 907
890 return(0); 908 return 0;
891} 909}
892 910
893unsigned short eth_protocol(struct sk_buff *skb) 911unsigned short eth_protocol(struct sk_buff *skb)
894{ 912{
895 return(eth_type_trans(skb, skb->dev)); 913 return eth_type_trans(skb, skb->dev);
896} 914}
diff --git a/arch/um/drivers/net_user.c b/arch/um/drivers/net_user.c
index da946e3e1bf2..90d7f2e8ead8 100644
--- a/arch/um/drivers/net_user.c
+++ b/arch/um/drivers/net_user.c
@@ -1,34 +1,32 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stddef.h>
7#include <stdarg.h>
8#include <unistd.h>
9#include <stdio.h> 6#include <stdio.h>
7#include <unistd.h>
8#include <stdarg.h>
10#include <errno.h> 9#include <errno.h>
11#include <stdlib.h> 10#include <stddef.h>
12#include <string.h> 11#include <string.h>
13#include <sys/socket.h> 12#include <sys/socket.h>
14#include <sys/wait.h> 13#include <sys/wait.h>
15#include <sys/time.h>
16#include "user.h"
17#include "kern_util.h"
18#include "net_user.h" 14#include "net_user.h"
15#include "kern_constants.h"
19#include "os.h" 16#include "os.h"
20#include "um_malloc.h" 17#include "um_malloc.h"
21#include "kern_constants.h" 18#include "user.h"
22 19
23int tap_open_common(void *dev, char *gate_addr) 20int tap_open_common(void *dev, char *gate_addr)
24{ 21{
25 int tap_addr[4]; 22 int tap_addr[4];
26 23
27 if(gate_addr == NULL) 24 if (gate_addr == NULL)
28 return 0; 25 return 0;
29 if(sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 26 if (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
30 &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4){ 27 &tap_addr[1], &tap_addr[2], &tap_addr[3]) != 4) {
31 printk("Invalid tap IP address - '%s'\n", gate_addr); 28 printk(UM_KERN_ERR "Invalid tap IP address - '%s'\n",
29 gate_addr);
32 return -EINVAL; 30 return -EINVAL;
33 } 31 }
34 return 0; 32 return 0;
@@ -38,15 +36,15 @@ void tap_check_ips(char *gate_addr, unsigned char *eth_addr)
38{ 36{
39 int tap_addr[4]; 37 int tap_addr[4];
40 38
41 if((gate_addr != NULL) && 39 if ((gate_addr != NULL) &&
42 (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0], 40 (sscanf(gate_addr, "%d.%d.%d.%d", &tap_addr[0],
43 &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) && 41 &tap_addr[1], &tap_addr[2], &tap_addr[3]) == 4) &&
44 (eth_addr[0] == tap_addr[0]) && 42 (eth_addr[0] == tap_addr[0]) &&
45 (eth_addr[1] == tap_addr[1]) && 43 (eth_addr[1] == tap_addr[1]) &&
46 (eth_addr[2] == tap_addr[2]) && 44 (eth_addr[2] == tap_addr[2]) &&
47 (eth_addr[3] == tap_addr[3])){ 45 (eth_addr[3] == tap_addr[3])) {
48 printk("The tap IP address and the UML eth IP address" 46 printk(UM_KERN_ERR "The tap IP address and the UML eth IP "
49 " must be different\n"); 47 "address must be different\n");
50 } 48 }
51} 49}
52 50
@@ -57,24 +55,28 @@ void read_output(int fd, char *output, int len)
57 char c; 55 char c;
58 char *str; 56 char *str;
59 57
60 if(output == NULL){ 58 if (output == NULL) {
61 output = &c; 59 output = &c;
62 len = sizeof(c); 60 len = sizeof(c);
63 } 61 }
64 62
65 *output = '\0'; 63 *output = '\0';
66 ret = os_read_file(fd, &remain, sizeof(remain)); 64 ret = read(fd, &remain, sizeof(remain));
67 65
68 if (ret != sizeof(remain)) { 66 if (ret != sizeof(remain)) {
67 if (ret < 0)
68 ret = -errno;
69 expected = sizeof(remain); 69 expected = sizeof(remain);
70 str = "length"; 70 str = "length";
71 goto err; 71 goto err;
72 } 72 }
73 73
74 while(remain != 0){ 74 while (remain != 0) {
75 expected = (remain < len) ? remain : len; 75 expected = (remain < len) ? remain : len;
76 ret = os_read_file(fd, output, expected); 76 ret = read(fd, output, expected);
77 if (ret != expected) { 77 if (ret != expected) {
78 if (ret < 0)
79 ret = -errno;
78 str = "data"; 80 str = "data";
79 goto err; 81 goto err;
80 } 82 }
@@ -85,20 +87,22 @@ void read_output(int fd, char *output, int len)
85 87
86err: 88err:
87 if (ret < 0) 89 if (ret < 0)
88 printk("read_output - read of %s failed, errno = %d\n", str, -ret); 90 printk(UM_KERN_ERR "read_output - read of %s failed, "
91 "errno = %d\n", str, -ret);
89 else 92 else
90 printk("read_output - read of %s failed, read only %d of %d bytes\n", str, ret, expected); 93 printk(UM_KERN_ERR "read_output - read of %s failed, read only "
94 "%d of %d bytes\n", str, ret, expected);
91} 95}
92 96
93int net_read(int fd, void *buf, int len) 97int net_read(int fd, void *buf, int len)
94{ 98{
95 int n; 99 int n;
96 100
97 n = os_read_file(fd, buf, len); 101 n = read(fd, buf, len);
98 102
99 if(n == -EAGAIN) 103 if ((n < 0) && (errno == EAGAIN))
100 return 0; 104 return 0;
101 else if(n == 0) 105 else if (n == 0)
102 return -ENOTCONN; 106 return -ENOTCONN;
103 return n; 107 return n;
104} 108}
@@ -108,12 +112,12 @@ int net_recvfrom(int fd, void *buf, int len)
108 int n; 112 int n;
109 113
110 CATCH_EINTR(n = recvfrom(fd, buf, len, 0, NULL, NULL)); 114 CATCH_EINTR(n = recvfrom(fd, buf, len, 0, NULL, NULL));
111 if(n < 0){ 115 if (n < 0) {
112 if(errno == EAGAIN) 116 if (errno == EAGAIN)
113 return 0; 117 return 0;
114 return -errno; 118 return -errno;
115 } 119 }
116 else if(n == 0) 120 else if (n == 0)
117 return -ENOTCONN; 121 return -ENOTCONN;
118 return n; 122 return n;
119} 123}
@@ -122,11 +126,11 @@ int net_write(int fd, void *buf, int len)
122{ 126{
123 int n; 127 int n;
124 128
125 n = os_write_file(fd, buf, len); 129 n = write(fd, buf, len);
126 130
127 if(n == -EAGAIN) 131 if ((n < 0) && (errno == EAGAIN))
128 return 0; 132 return 0;
129 else if(n == 0) 133 else if (n == 0)
130 return -ENOTCONN; 134 return -ENOTCONN;
131 return n; 135 return n;
132} 136}
@@ -136,12 +140,12 @@ int net_send(int fd, void *buf, int len)
136 int n; 140 int n;
137 141
138 CATCH_EINTR(n = send(fd, buf, len, 0)); 142 CATCH_EINTR(n = send(fd, buf, len, 0));
139 if(n < 0){ 143 if (n < 0) {
140 if(errno == EAGAIN) 144 if (errno == EAGAIN)
141 return 0; 145 return 0;
142 return -errno; 146 return -errno;
143 } 147 }
144 else if(n == 0) 148 else if (n == 0)
145 return -ENOTCONN; 149 return -ENOTCONN;
146 return n; 150 return n;
147} 151}
@@ -152,12 +156,12 @@ int net_sendto(int fd, void *buf, int len, void *to, int sock_len)
152 156
153 CATCH_EINTR(n = sendto(fd, buf, len, 0, (struct sockaddr *) to, 157 CATCH_EINTR(n = sendto(fd, buf, len, 0, (struct sockaddr *) to,
154 sock_len)); 158 sock_len));
155 if(n < 0){ 159 if (n < 0) {
156 if(errno == EAGAIN) 160 if (errno == EAGAIN)
157 return 0; 161 return 0;
158 return -errno; 162 return -errno;
159 } 163 }
160 else if(n == 0) 164 else if (n == 0)
161 return -ENOTCONN; 165 return -ENOTCONN;
162 return n; 166 return n;
163} 167}
@@ -171,7 +175,7 @@ static void change_pre_exec(void *arg)
171{ 175{
172 struct change_pre_exec_data *data = arg; 176 struct change_pre_exec_data *data = arg;
173 177
174 os_close_file(data->close_me); 178 close(data->close_me);
175 dup2(data->stdout, 1); 179 dup2(data->stdout, 1);
176} 180}
177 181
@@ -181,8 +185,9 @@ static int change_tramp(char **argv, char *output, int output_len)
181 struct change_pre_exec_data pe_data; 185 struct change_pre_exec_data pe_data;
182 186
183 err = os_pipe(fds, 1, 0); 187 err = os_pipe(fds, 1, 0);
184 if(err < 0){ 188 if (err < 0) {
185 printk("change_tramp - pipe failed, err = %d\n", -err); 189 printk(UM_KERN_ERR "change_tramp - pipe failed, err = %d\n",
190 -err);
186 return err; 191 return err;
187 } 192 }
188 pe_data.close_me = fds[0]; 193 pe_data.close_me = fds[0];
@@ -192,8 +197,8 @@ static int change_tramp(char **argv, char *output, int output_len)
192 if (pid > 0) /* Avoid hang as we won't get data in failure case. */ 197 if (pid > 0) /* Avoid hang as we won't get data in failure case. */
193 read_output(fds[0], output, output_len); 198 read_output(fds[0], output, output_len);
194 199
195 os_close_file(fds[0]); 200 close(fds[0]);
196 os_close_file(fds[1]); 201 close(fds[1]);
197 202
198 if (pid > 0) 203 if (pid > 0)
199 CATCH_EINTR(err = waitpid(pid, NULL, 0)); 204 CATCH_EINTR(err = waitpid(pid, NULL, 0));
@@ -206,25 +211,26 @@ static void change(char *dev, char *what, unsigned char *addr,
206 char addr_buf[sizeof("255.255.255.255\0")]; 211 char addr_buf[sizeof("255.255.255.255\0")];
207 char netmask_buf[sizeof("255.255.255.255\0")]; 212 char netmask_buf[sizeof("255.255.255.255\0")];
208 char version[sizeof("nnnnn\0")]; 213 char version[sizeof("nnnnn\0")];
209 char *argv[] = { "uml_net", version, what, dev, addr_buf, 214 char *argv[] = { "uml_net", version, what, dev, addr_buf,
210 netmask_buf, NULL }; 215 netmask_buf, NULL };
211 char *output; 216 char *output;
212 int output_len, pid; 217 int output_len, pid;
213 218
214 sprintf(version, "%d", UML_NET_VERSION); 219 sprintf(version, "%d", UML_NET_VERSION);
215 sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]); 220 sprintf(addr_buf, "%d.%d.%d.%d", addr[0], addr[1], addr[2], addr[3]);
216 sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1], 221 sprintf(netmask_buf, "%d.%d.%d.%d", netmask[0], netmask[1],
217 netmask[2], netmask[3]); 222 netmask[2], netmask[3]);
218 223
219 output_len = UM_KERN_PAGE_SIZE; 224 output_len = UM_KERN_PAGE_SIZE;
220 output = kmalloc(output_len, UM_GFP_KERNEL); 225 output = kmalloc(output_len, UM_GFP_KERNEL);
221 if(output == NULL) 226 if (output == NULL)
222 printk("change : failed to allocate output buffer\n"); 227 printk(UM_KERN_ERR "change : failed to allocate output "
228 "buffer\n");
223 229
224 pid = change_tramp(argv, output, output_len); 230 pid = change_tramp(argv, output, output_len);
225 if(pid < 0) return; 231 if (pid < 0) return;
226 232
227 if(output != NULL){ 233 if (output != NULL) {
228 printk("%s", output); 234 printk("%s", output);
229 kfree(output); 235 kfree(output);
230 } 236 }
@@ -246,13 +252,13 @@ char *split_if_spec(char *str, ...)
246 va_list ap; 252 va_list ap;
247 253
248 va_start(ap, str); 254 va_start(ap, str);
249 while((arg = va_arg(ap, char **)) != NULL){ 255 while ((arg = va_arg(ap, char **)) != NULL) {
250 if(*str == '\0') 256 if (*str == '\0')
251 return NULL; 257 return NULL;
252 end = strchr(str, ','); 258 end = strchr(str, ',');
253 if(end != str) 259 if (end != str)
254 *arg = str; 260 *arg = str;
255 if(end == NULL) 261 if (end == NULL)
256 return NULL; 262 return NULL;
257 *end++ = '\0'; 263 *end++ = '\0';
258 str = end; 264 str = end;
diff --git a/arch/um/drivers/null.c b/arch/um/drivers/null.c
index 9016c68beee8..21ad3d7932b3 100644
--- a/arch/um/drivers/null.c
+++ b/arch/um/drivers/null.c
@@ -1,10 +1,11 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdlib.h> 6#include <stddef.h>
7#include <errno.h> 7#include <errno.h>
8#include <fcntl.h>
8#include "chan_user.h" 9#include "chan_user.h"
9#include "os.h" 10#include "os.h"
10 11
@@ -13,19 +14,23 @@ static int null_chan;
13 14
14static void *null_init(char *str, int device, const struct chan_opts *opts) 15static void *null_init(char *str, int device, const struct chan_opts *opts)
15{ 16{
16 return(&null_chan); 17 return &null_chan;
17} 18}
18 19
19static int null_open(int input, int output, int primary, void *d, 20static int null_open(int input, int output, int primary, void *d,
20 char **dev_out) 21 char **dev_out)
21{ 22{
23 int fd;
24
22 *dev_out = NULL; 25 *dev_out = NULL;
23 return(os_open_file(DEV_NULL, of_rdwr(OPENFLAGS()), 0)); 26
27 fd = open(DEV_NULL, O_RDWR);
28 return (fd < 0) ? -errno : fd;
24} 29}
25 30
26static int null_read(int fd, char *c_out, void *unused) 31static int null_read(int fd, char *c_out, void *unused)
27{ 32{
28 return(-ENODEV); 33 return -ENODEV;
29} 34}
30 35
31static void null_free(void *data) 36static void null_free(void *data)
@@ -44,14 +49,3 @@ const struct chan_ops null_ops = {
44 .free = null_free, 49 .free = null_free,
45 .winch = 0, 50 .winch = 0,
46}; 51};
47
48/*
49 * Overrides for Emacs so that we follow Linus's tabbing style.
50 * Emacs will notice this stuff at the end of the file and automatically
51 * adjust the settings for this buffer only. This must remain at the end
52 * of the file.
53 * ---------------------------------------------------------------------------
54 * Local variables:
55 * c-file-style: "linux"
56 * End:
57 */
diff --git a/arch/um/drivers/pcap_kern.c b/arch/um/drivers/pcap_kern.c
index c329931673d6..3a750dd39be1 100644
--- a/arch/um/drivers/pcap_kern.c
+++ b/arch/um/drivers/pcap_kern.c
@@ -1,13 +1,11 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike <jdike@karaya.com> 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL. 3 * Licensed under the GPL.
4 */ 4 */
5 5
6#include "linux/init.h" 6#include "linux/init.h"
7#include "linux/netdevice.h" 7#include <linux/netdevice.h>
8#include "linux/etherdevice.h"
9#include "net_kern.h" 8#include "net_kern.h"
10#include "net_user.h"
11#include "pcap_user.h" 9#include "pcap_user.h"
12 10
13struct pcap_init { 11struct pcap_init {
@@ -33,19 +31,14 @@ void pcap_init(struct net_device *dev, void *data)
33 printk("pcap backend, host interface %s\n", ppri->host_if); 31 printk("pcap backend, host interface %s\n", ppri->host_if);
34} 32}
35 33
36static int pcap_read(int fd, struct sk_buff **skb, 34static int pcap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
37 struct uml_net_private *lp)
38{ 35{
39 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 36 return pcap_user_read(fd, skb_mac_header(skb),
40 if(*skb == NULL) 37 skb->dev->mtu + ETH_HEADER_OTHER,
41 return -ENOMEM;
42
43 return pcap_user_read(fd, skb_mac_header(*skb),
44 (*skb)->dev->mtu + ETH_HEADER_OTHER,
45 (struct pcap_data *) &lp->user); 38 (struct pcap_data *) &lp->user);
46} 39}
47 40
48static int pcap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) 41static int pcap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
49{ 42{
50 return -EPERM; 43 return -EPERM;
51} 44}
@@ -71,28 +64,29 @@ int pcap_setup(char *str, char **mac_out, void *data)
71 64
72 remain = split_if_spec(str, &host_if, &init->filter, 65 remain = split_if_spec(str, &host_if, &init->filter,
73 &options[0], &options[1], mac_out, NULL); 66 &options[0], &options[1], mac_out, NULL);
74 if(remain != NULL){ 67 if (remain != NULL) {
75 printk(KERN_ERR "pcap_setup - Extra garbage on " 68 printk(KERN_ERR "pcap_setup - Extra garbage on "
76 "specification : '%s'\n", remain); 69 "specification : '%s'\n", remain);
77 return 0; 70 return 0;
78 } 71 }
79 72
80 if(host_if != NULL) 73 if (host_if != NULL)
81 init->host_if = host_if; 74 init->host_if = host_if;
82 75
83 for(i = 0; i < ARRAY_SIZE(options); i++){ 76 for (i = 0; i < ARRAY_SIZE(options); i++) {
84 if(options[i] == NULL) 77 if (options[i] == NULL)
85 continue; 78 continue;
86 if(!strcmp(options[i], "promisc")) 79 if (!strcmp(options[i], "promisc"))
87 init->promisc = 1; 80 init->promisc = 1;
88 else if(!strcmp(options[i], "nopromisc")) 81 else if (!strcmp(options[i], "nopromisc"))
89 init->promisc = 0; 82 init->promisc = 0;
90 else if(!strcmp(options[i], "optimize")) 83 else if (!strcmp(options[i], "optimize"))
91 init->optimize = 1; 84 init->optimize = 1;
92 else if(!strcmp(options[i], "nooptimize")) 85 else if (!strcmp(options[i], "nooptimize"))
93 init->optimize = 0; 86 init->optimize = 0;
94 else { 87 else {
95 printk("pcap_setup : bad option - '%s'\n", options[i]); 88 printk(KERN_ERR "pcap_setup : bad option - '%s'\n",
89 options[i]);
96 return 0; 90 return 0;
97 } 91 }
98 } 92 }
diff --git a/arch/um/drivers/pcap_user.c b/arch/um/drivers/pcap_user.c
index 1316456e2a28..e9809356c530 100644
--- a/arch/um/drivers/pcap_user.c
+++ b/arch/um/drivers/pcap_user.c
@@ -1,21 +1,17 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike <jdike@karaya.com> 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL. 3 * Licensed under the GPL.
4 */ 4 */
5 5
6#include <unistd.h>
7#include <stdlib.h>
8#include <string.h>
9#include <errno.h> 6#include <errno.h>
10#include <pcap.h> 7#include <pcap.h>
8#include <string.h>
11#include <asm/types.h> 9#include <asm/types.h>
12#include "net_user.h" 10#include "net_user.h"
13#include "pcap_user.h" 11#include "pcap_user.h"
14#include "user.h"
15#include "um_malloc.h"
16#include "kern_constants.h" 12#include "kern_constants.h"
17 13#include "um_malloc.h"
18#define MAX_PACKET (ETH_MAX_PACKET + ETH_HEADER_OTHER) 14#include "user.h"
19 15
20#define PCAP_FD(p) (*(int *)(p)) 16#define PCAP_FD(p) (*(int *)(p))
21 17
@@ -25,8 +21,9 @@ static int pcap_user_init(void *data, void *dev)
25 pcap_t *p; 21 pcap_t *p;
26 char errors[PCAP_ERRBUF_SIZE]; 22 char errors[PCAP_ERRBUF_SIZE];
27 23
28 p = pcap_open_live(pri->host_if, MAX_PACKET, pri->promisc, 0, errors); 24 p = pcap_open_live(pri->host_if, ETH_MAX_PACKET + ETH_HEADER_OTHER,
29 if(p == NULL){ 25 pri->promisc, 0, errors);
26 if (p == NULL) {
30 printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - " 27 printk(UM_KERN_ERR "pcap_user_init : pcap_open_live failed - "
31 "'%s'\n", errors); 28 "'%s'\n", errors);
32 return -EINVAL; 29 return -EINVAL;
@@ -43,50 +40,55 @@ static int pcap_open(void *data)
43 __u32 netmask; 40 __u32 netmask;
44 int err; 41 int err;
45 42
46 if(pri->pcap == NULL) 43 if (pri->pcap == NULL)
47 return -ENODEV; 44 return -ENODEV;
48 45
49 if(pri->filter != NULL){ 46 if (pri->filter != NULL) {
50 err = dev_netmask(pri->dev, &netmask); 47 err = dev_netmask(pri->dev, &netmask);
51 if(err < 0){ 48 if (err < 0) {
52 printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n"); 49 printk(UM_KERN_ERR "pcap_open : dev_netmask failed\n");
53 return -EIO; 50 return -EIO;
54 } 51 }
55 52
56 pri->compiled = kmalloc(sizeof(struct bpf_program), UM_GFP_KERNEL); 53 pri->compiled = kmalloc(sizeof(struct bpf_program),
57 if(pri->compiled == NULL){ 54 UM_GFP_KERNEL);
55 if (pri->compiled == NULL) {
58 printk(UM_KERN_ERR "pcap_open : kmalloc failed\n"); 56 printk(UM_KERN_ERR "pcap_open : kmalloc failed\n");
59 return -ENOMEM; 57 return -ENOMEM;
60 } 58 }
61 59
62 err = pcap_compile(pri->pcap, 60 err = pcap_compile(pri->pcap,
63 (struct bpf_program *) pri->compiled, 61 (struct bpf_program *) pri->compiled,
64 pri->filter, pri->optimize, netmask); 62 pri->filter, pri->optimize, netmask);
65 if(err < 0){ 63 if (err < 0) {
66 printk(UM_KERN_ERR "pcap_open : pcap_compile failed - " 64 printk(UM_KERN_ERR "pcap_open : pcap_compile failed - "
67 "'%s'\n", pcap_geterr(pri->pcap)); 65 "'%s'\n", pcap_geterr(pri->pcap));
68 return -EIO; 66 goto out;
69 } 67 }
70 68
71 err = pcap_setfilter(pri->pcap, pri->compiled); 69 err = pcap_setfilter(pri->pcap, pri->compiled);
72 if(err < 0){ 70 if (err < 0) {
73 printk(UM_KERN_ERR "pcap_open : pcap_setfilter " 71 printk(UM_KERN_ERR "pcap_open : pcap_setfilter "
74 "failed - '%s'\n", pcap_geterr(pri->pcap)); 72 "failed - '%s'\n", pcap_geterr(pri->pcap));
75 return -EIO; 73 goto out;
76 } 74 }
77 } 75 }
78 76
79 return PCAP_FD(pri->pcap); 77 return PCAP_FD(pri->pcap);
78
79 out:
80 kfree(pri->compiled);
81 return -EIO;
80} 82}
81 83
82static void pcap_remove(void *data) 84static void pcap_remove(void *data)
83{ 85{
84 struct pcap_data *pri = data; 86 struct pcap_data *pri = data;
85 87
86 if(pri->compiled != NULL) 88 if (pri->compiled != NULL)
87 pcap_freecode(pri->compiled); 89 pcap_freecode(pri->compiled);
88 90
89 if(pri->pcap != NULL) 91 if (pri->pcap != NULL)
90 pcap_close(pri->pcap); 92 pcap_close(pri->pcap);
91} 93}
92 94
@@ -95,7 +97,7 @@ struct pcap_handler_data {
95 int len; 97 int len;
96}; 98};
97 99
98static void handler(u_char *data, const struct pcap_pkthdr *header, 100static void handler(u_char *data, const struct pcap_pkthdr *header,
99 const u_char *packet) 101 const u_char *packet)
100{ 102{
101 int len; 103 int len;
@@ -115,12 +117,12 @@ int pcap_user_read(int fd, void *buffer, int len, struct pcap_data *pri)
115 int n; 117 int n;
116 118
117 n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata); 119 n = pcap_dispatch(pri->pcap, 1, handler, (u_char *) &hdata);
118 if(n < 0){ 120 if (n < 0) {
119 printk(UM_KERN_ERR "pcap_dispatch failed - %s\n", 121 printk(UM_KERN_ERR "pcap_dispatch failed - %s\n",
120 pcap_geterr(pri->pcap)); 122 pcap_geterr(pri->pcap));
121 return -EIO; 123 return -EIO;
122 } 124 }
123 else if(n == 0) 125 else if (n == 0)
124 return 0; 126 return 0;
125 return hdata.len; 127 return hdata.len;
126} 128}
@@ -130,8 +132,8 @@ const struct net_user_info pcap_user_info = {
130 .open = pcap_open, 132 .open = pcap_open,
131 .close = NULL, 133 .close = NULL,
132 .remove = pcap_remove, 134 .remove = pcap_remove,
133 .set_mtu = NULL,
134 .add_address = NULL, 135 .add_address = NULL,
135 .delete_address = NULL, 136 .delete_address = NULL,
136 .max_packet = MAX_PACKET - ETH_HEADER_OTHER 137 .mtu = ETH_MAX_PACKET,
138 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
137}; 139};
diff --git a/arch/um/drivers/port_kern.c b/arch/um/drivers/port_kern.c
index 1c8efd95c421..330543b3129b 100644
--- a/arch/um/drivers/port_kern.c
+++ b/arch/um/drivers/port_kern.c
@@ -1,24 +1,16 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/list.h" 6#include "linux/completion.h"
7#include "linux/sched.h"
8#include "linux/slab.h"
9#include "linux/interrupt.h" 7#include "linux/interrupt.h"
10#include "linux/spinlock.h" 8#include "linux/list.h"
11#include "linux/errno.h"
12#include "asm/atomic.h" 9#include "asm/atomic.h"
13#include "asm/semaphore.h"
14#include "asm/errno.h"
15#include "kern_util.h"
16#include "kern.h"
17#include "irq_user.h"
18#include "irq_kern.h"
19#include "port.h"
20#include "init.h" 10#include "init.h"
11#include "irq_kern.h"
21#include "os.h" 12#include "os.h"
13#include "port.h"
22 14
23struct port_list { 15struct port_list {
24 struct list_head list; 16 struct list_head list;
@@ -53,8 +45,8 @@ static irqreturn_t pipe_interrupt(int irq, void *data)
53 int fd; 45 int fd;
54 46
55 fd = os_rcv_fd(conn->socket[0], &conn->helper_pid); 47 fd = os_rcv_fd(conn->socket[0], &conn->helper_pid);
56 if(fd < 0){ 48 if (fd < 0) {
57 if(fd == -EAGAIN) 49 if (fd == -EAGAIN)
58 return IRQ_NONE; 50 return IRQ_NONE;
59 51
60 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n", 52 printk(KERN_ERR "pipe_interrupt : os_rcv_fd returned %d\n",
@@ -81,18 +73,18 @@ static irqreturn_t pipe_interrupt(int irq, void *data)
81static int port_accept(struct port_list *port) 73static int port_accept(struct port_list *port)
82{ 74{
83 struct connection *conn; 75 struct connection *conn;
84 int fd, socket[2], pid, ret = 0; 76 int fd, socket[2], pid;
85 77
86 fd = port_connection(port->fd, socket, &pid); 78 fd = port_connection(port->fd, socket, &pid);
87 if(fd < 0){ 79 if (fd < 0) {
88 if(fd != -EAGAIN) 80 if (fd != -EAGAIN)
89 printk(KERN_ERR "port_accept : port_connection " 81 printk(KERN_ERR "port_accept : port_connection "
90 "returned %d\n", -fd); 82 "returned %d\n", -fd);
91 goto out; 83 goto out;
92 } 84 }
93 85
94 conn = kmalloc(sizeof(*conn), GFP_ATOMIC); 86 conn = kmalloc(sizeof(*conn), GFP_ATOMIC);
95 if(conn == NULL){ 87 if (conn == NULL) {
96 printk(KERN_ERR "port_accept : failed to allocate " 88 printk(KERN_ERR "port_accept : failed to allocate "
97 "connection\n"); 89 "connection\n");
98 goto out_close; 90 goto out_close;
@@ -104,17 +96,17 @@ static int port_accept(struct port_list *port)
104 .telnetd_pid = pid, 96 .telnetd_pid = pid,
105 .port = port }); 97 .port = port });
106 98
107 if(um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt, 99 if (um_request_irq(TELNETD_IRQ, socket[0], IRQ_READ, pipe_interrupt,
108 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, 100 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
109 "telnetd", conn)){ 101 "telnetd", conn)) {
110 printk(KERN_ERR "port_accept : failed to get IRQ for " 102 printk(KERN_ERR "port_accept : failed to get IRQ for "
111 "telnetd\n"); 103 "telnetd\n");
112 goto out_free; 104 goto out_free;
113 } 105 }
114 106
115 if(atomic_read(&port->wait_count) == 0){ 107 if (atomic_read(&port->wait_count) == 0) {
116 os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG)); 108 os_write_file(fd, NO_WAITER_MSG, sizeof(NO_WAITER_MSG));
117 printk("No one waiting for port\n"); 109 printk(KERN_ERR "No one waiting for port\n");
118 } 110 }
119 list_add(&conn->list, &port->pending); 111 list_add(&conn->list, &port->pending);
120 return 1; 112 return 1;
@@ -123,28 +115,29 @@ static int port_accept(struct port_list *port)
123 kfree(conn); 115 kfree(conn);
124 out_close: 116 out_close:
125 os_close_file(fd); 117 os_close_file(fd);
126 if(pid != -1) 118 os_kill_process(pid, 1);
127 os_kill_process(pid, 1);
128 out: 119 out:
129 return ret; 120 return 0;
130} 121}
131 122
132static DECLARE_MUTEX(ports_sem); 123static DECLARE_MUTEX(ports_sem);
133static LIST_HEAD(ports); 124static LIST_HEAD(ports);
134 125
135void port_work_proc(struct work_struct *unused) 126static void port_work_proc(struct work_struct *unused)
136{ 127{
137 struct port_list *port; 128 struct port_list *port;
138 struct list_head *ele; 129 struct list_head *ele;
139 unsigned long flags; 130 unsigned long flags;
140 131
141 local_irq_save(flags); 132 local_irq_save(flags);
142 list_for_each(ele, &ports){ 133 list_for_each(ele, &ports) {
143 port = list_entry(ele, struct port_list, list); 134 port = list_entry(ele, struct port_list, list);
144 if(!port->has_connection) 135 if (!port->has_connection)
145 continue; 136 continue;
137
146 reactivate_fd(port->fd, ACCEPT_IRQ); 138 reactivate_fd(port->fd, ACCEPT_IRQ);
147 while(port_accept(port)) ; 139 while (port_accept(port))
140 ;
148 port->has_connection = 0; 141 port->has_connection = 0;
149 } 142 }
150 local_irq_restore(flags); 143 local_irq_restore(flags);
@@ -169,25 +162,27 @@ void *port_data(int port_num)
169 int fd; 162 int fd;
170 163
171 down(&ports_sem); 164 down(&ports_sem);
172 list_for_each(ele, &ports){ 165 list_for_each(ele, &ports) {
173 port = list_entry(ele, struct port_list, list); 166 port = list_entry(ele, struct port_list, list);
174 if(port->port == port_num) goto found; 167 if (port->port == port_num)
168 goto found;
175 } 169 }
176 port = kmalloc(sizeof(struct port_list), GFP_KERNEL); 170 port = kmalloc(sizeof(struct port_list), GFP_KERNEL);
177 if(port == NULL){ 171 if (port == NULL) {
178 printk(KERN_ERR "Allocation of port list failed\n"); 172 printk(KERN_ERR "Allocation of port list failed\n");
179 goto out; 173 goto out;
180 } 174 }
181 175
182 fd = port_listen_fd(port_num); 176 fd = port_listen_fd(port_num);
183 if(fd < 0){ 177 if (fd < 0) {
184 printk(KERN_ERR "binding to port %d failed, errno = %d\n", 178 printk(KERN_ERR "binding to port %d failed, errno = %d\n",
185 port_num, -fd); 179 port_num, -fd);
186 goto out_free; 180 goto out_free;
187 } 181 }
188 if(um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt, 182
183 if (um_request_irq(ACCEPT_IRQ, fd, IRQ_READ, port_interrupt,
189 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM, 184 IRQF_DISABLED | IRQF_SHARED | IRQF_SAMPLE_RANDOM,
190 "port", port)){ 185 "port", port)) {
191 printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num); 186 printk(KERN_ERR "Failed to get IRQ for port %d\n", port_num);
192 goto out_close; 187 goto out_close;
193 } 188 }
@@ -206,7 +201,7 @@ void *port_data(int port_num)
206 201
207 found: 202 found:
208 dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL); 203 dev = kmalloc(sizeof(struct port_dev), GFP_KERNEL);
209 if(dev == NULL){ 204 if (dev == NULL) {
210 printk(KERN_ERR "Allocation of port device entry failed\n"); 205 printk(KERN_ERR "Allocation of port device entry failed\n");
211 goto out; 206 goto out;
212 } 207 }
@@ -216,10 +211,10 @@ void *port_data(int port_num)
216 .telnetd_pid = -1 }); 211 .telnetd_pid = -1 });
217 goto out; 212 goto out;
218 213
219 out_free:
220 kfree(port);
221 out_close: 214 out_close:
222 os_close_file(fd); 215 os_close_file(fd);
216 out_free:
217 kfree(port);
223 out: 218 out:
224 up(&ports_sem); 219 up(&ports_sem);
225 return dev; 220 return dev;
@@ -233,9 +228,9 @@ int port_wait(void *data)
233 int fd; 228 int fd;
234 229
235 atomic_inc(&port->wait_count); 230 atomic_inc(&port->wait_count);
236 while(1){ 231 while (1) {
237 fd = -ERESTARTSYS; 232 fd = -ERESTARTSYS;
238 if(wait_for_completion_interruptible(&port->done)) 233 if (wait_for_completion_interruptible(&port->done))
239 goto out; 234 goto out;
240 235
241 spin_lock(&port->lock); 236 spin_lock(&port->lock);
@@ -258,7 +253,8 @@ int port_wait(void *data)
258 */ 253 */
259 free_irq(TELNETD_IRQ, conn); 254 free_irq(TELNETD_IRQ, conn);
260 255
261 if(conn->fd >= 0) break; 256 if (conn->fd >= 0)
257 break;
262 os_close_file(conn->fd); 258 os_close_file(conn->fd);
263 kfree(conn); 259 kfree(conn);
264 } 260 }
@@ -276,9 +272,9 @@ void port_remove_dev(void *d)
276{ 272{
277 struct port_dev *dev = d; 273 struct port_dev *dev = d;
278 274
279 if(dev->helper_pid != -1) 275 if (dev->helper_pid != -1)
280 os_kill_process(dev->helper_pid, 0); 276 os_kill_process(dev->helper_pid, 0);
281 if(dev->telnetd_pid != -1) 277 if (dev->telnetd_pid != -1)
282 os_kill_process(dev->telnetd_pid, 1); 278 os_kill_process(dev->telnetd_pid, 1);
283 dev->helper_pid = -1; 279 dev->helper_pid = -1;
284 dev->telnetd_pid = -1; 280 dev->telnetd_pid = -1;
@@ -297,7 +293,7 @@ static void free_port(void)
297 struct list_head *ele; 293 struct list_head *ele;
298 struct port_list *port; 294 struct port_list *port;
299 295
300 list_for_each(ele, &ports){ 296 list_for_each(ele, &ports) {
301 port = list_entry(ele, struct port_list, list); 297 port = list_entry(ele, struct port_list, list);
302 free_irq_by_fd(port->fd); 298 free_irq_by_fd(port->fd);
303 os_close_file(port->fd); 299 os_close_file(port->fd);
diff --git a/arch/um/drivers/port_user.c b/arch/um/drivers/port_user.c
index c799b00012c7..addd75902656 100644
--- a/arch/um/drivers/port_user.c
+++ b/arch/um/drivers/port_user.c
@@ -1,24 +1,20 @@
1/* 1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h> 6#include <stdio.h>
7#include <stddef.h>
8#include <stdlib.h> 7#include <stdlib.h>
9#include <string.h>
10#include <errno.h> 8#include <errno.h>
11#include <unistd.h>
12#include <termios.h> 9#include <termios.h>
13#include <sys/socket.h> 10#include <unistd.h>
14#include <sys/un.h>
15#include <netinet/in.h> 11#include <netinet/in.h>
16#include "kern_util.h"
17#include "user.h"
18#include "chan_user.h" 12#include "chan_user.h"
19#include "port.h" 13#include "kern_constants.h"
20#include "os.h" 14#include "os.h"
15#include "port.h"
21#include "um_malloc.h" 16#include "um_malloc.h"
17#include "user.h"
22 18
23struct port_chan { 19struct port_chan {
24 int raw; 20 int raw;
@@ -34,24 +30,25 @@ static void *port_init(char *str, int device, const struct chan_opts *opts)
34 char *end; 30 char *end;
35 int port; 31 int port;
36 32
37 if(*str != ':'){ 33 if (*str != ':') {
38 printk("port_init : channel type 'port' must specify a " 34 printk(UM_KERN_ERR "port_init : channel type 'port' must "
39 "port number\n"); 35 "specify a port number\n");
40 return NULL; 36 return NULL;
41 } 37 }
42 str++; 38 str++;
43 port = strtoul(str, &end, 0); 39 port = strtoul(str, &end, 0);
44 if((*end != '\0') || (end == str)){ 40 if ((*end != '\0') || (end == str)) {
45 printk("port_init : couldn't parse port '%s'\n", str); 41 printk(UM_KERN_ERR "port_init : couldn't parse port '%s'\n",
42 str);
46 return NULL; 43 return NULL;
47 } 44 }
48 45
49 kern_data = port_data(port); 46 kern_data = port_data(port);
50 if(kern_data == NULL) 47 if (kern_data == NULL)
51 return NULL; 48 return NULL;
52 49
53 data = kmalloc(sizeof(*data), UM_GFP_KERNEL); 50 data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
54 if(data == NULL) 51 if (data == NULL)
55 goto err; 52 goto err;
56 53
57 *data = ((struct port_chan) { .raw = opts->raw, 54 *data = ((struct port_chan) { .raw = opts->raw,
@@ -79,13 +76,13 @@ static int port_open(int input, int output, int primary, void *d,
79 int fd, err; 76 int fd, err;
80 77
81 fd = port_wait(data->kernel_data); 78 fd = port_wait(data->kernel_data);
82 if((fd >= 0) && data->raw){ 79 if ((fd >= 0) && data->raw) {
83 CATCH_EINTR(err = tcgetattr(fd, &data->tt)); 80 CATCH_EINTR(err = tcgetattr(fd, &data->tt));
84 if(err) 81 if (err)
85 return err; 82 return err;
86 83
87 err = raw(fd); 84 err = raw(fd);
88 if(err) 85 if (err)
89 return err; 86 return err;
90 } 87 }
91 *dev_out = data->dev; 88 *dev_out = data->dev;
@@ -119,11 +116,11 @@ int port_listen_fd(int port)
119 int fd, err, arg; 116 int fd, err, arg;
120 117
121 fd = socket(PF_INET, SOCK_STREAM, 0); 118 fd = socket(PF_INET, SOCK_STREAM, 0);
122 if(fd == -1) 119 if (fd == -1)
123 return -errno; 120 return -errno;
124 121
125 arg = 1; 122 arg = 1;
126 if(setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0){ 123 if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &arg, sizeof(arg)) < 0) {
127 err = -errno; 124 err = -errno;
128 goto out; 125 goto out;
129 } 126 }
@@ -131,23 +128,23 @@ int port_listen_fd(int port)
131 addr.sin_family = AF_INET; 128 addr.sin_family = AF_INET;
132 addr.sin_port = htons(port); 129 addr.sin_port = htons(port);
133 addr.sin_addr.s_addr = htonl(INADDR_ANY); 130 addr.sin_addr.s_addr = htonl(INADDR_ANY);
134 if(bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0){ 131 if (bind(fd, (struct sockaddr *) &addr, sizeof(addr)) < 0) {
135 err = -errno; 132 err = -errno;
136 goto out; 133 goto out;
137 } 134 }
138 135
139 if(listen(fd, 1) < 0){ 136 if (listen(fd, 1) < 0) {
140 err = -errno; 137 err = -errno;
141 goto out; 138 goto out;
142 } 139 }
143 140
144 err = os_set_fd_block(fd, 0); 141 err = os_set_fd_block(fd, 0);
145 if(err < 0) 142 if (err < 0)
146 goto out; 143 goto out;
147 144
148 return fd; 145 return fd;
149 out: 146 out:
150 os_close_file(fd); 147 close(fd);
151 return err; 148 return err;
152} 149}
153 150
@@ -163,10 +160,10 @@ void port_pre_exec(void *arg)
163 dup2(data->sock_fd, 0); 160 dup2(data->sock_fd, 0);
164 dup2(data->sock_fd, 1); 161 dup2(data->sock_fd, 1);
165 dup2(data->sock_fd, 2); 162 dup2(data->sock_fd, 2);
166 os_close_file(data->sock_fd); 163 close(data->sock_fd);
167 dup2(data->pipe_fd, 3); 164 dup2(data->pipe_fd, 3);
168 os_shutdown_socket(3, 1, 0); 165 shutdown(3, SHUT_RD);
169 os_close_file(data->pipe_fd); 166 close(data->pipe_fd);
170} 167}
171 168
172int port_connection(int fd, int *socket, int *pid_out) 169int port_connection(int fd, int *socket, int *pid_out)
@@ -176,12 +173,12 @@ int port_connection(int fd, int *socket, int *pid_out)
176 "/usr/lib/uml/port-helper", NULL }; 173 "/usr/lib/uml/port-helper", NULL };
177 struct port_pre_exec_data data; 174 struct port_pre_exec_data data;
178 175
179 new = os_accept_connection(fd); 176 new = accept(fd, NULL, 0);
180 if(new < 0) 177 if (new < 0)
181 return new; 178 return -errno;
182 179
183 err = os_pipe(socket, 0, 0); 180 err = os_pipe(socket, 0, 0);
184 if(err < 0) 181 if (err < 0)
185 goto out_close; 182 goto out_close;
186 183
187 data = ((struct port_pre_exec_data) 184 data = ((struct port_pre_exec_data)
@@ -189,18 +186,18 @@ int port_connection(int fd, int *socket, int *pid_out)
189 .pipe_fd = socket[1] }); 186 .pipe_fd = socket[1] });
190 187
191 err = run_helper(port_pre_exec, &data, argv); 188 err = run_helper(port_pre_exec, &data, argv);
192 if(err < 0) 189 if (err < 0)
193 goto out_shutdown; 190 goto out_shutdown;
194 191
195 *pid_out = err; 192 *pid_out = err;
196 return new; 193 return new;
197 194
198 out_shutdown: 195 out_shutdown:
199 os_shutdown_socket(socket[0], 1, 1); 196 shutdown(socket[0], SHUT_RDWR);
200 os_close_file(socket[0]); 197 close(socket[0]);
201 os_shutdown_socket(socket[1], 1, 1); 198 shutdown(socket[1], SHUT_RDWR);
202 os_close_file(socket[1]); 199 close(socket[1]);
203 out_close: 200 out_close:
204 os_close_file(new); 201 close(new);
205 return err; 202 return err;
206} 203}
diff --git a/arch/um/drivers/pty.c b/arch/um/drivers/pty.c
index 1e3fd619a837..49c79dda6046 100644
--- a/arch/um/drivers/pty.c
+++ b/arch/um/drivers/pty.c
@@ -1,4 +1,4 @@
1/* 1/*
2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
@@ -6,16 +6,16 @@
6#include <stdio.h> 6#include <stdio.h>
7#include <stdlib.h> 7#include <stdlib.h>
8#include <unistd.h> 8#include <unistd.h>
9#include <string.h>
10#include <fcntl.h>
11#include <errno.h> 9#include <errno.h>
10#include <fcntl.h>
11#include <string.h>
12#include <termios.h> 12#include <termios.h>
13#include <sys/stat.h> 13#include <sys/stat.h>
14#include "chan_user.h" 14#include "chan_user.h"
15#include "os.h"
16#include "user.h"
17#include "kern_constants.h" 15#include "kern_constants.h"
16#include "os.h"
18#include "um_malloc.h" 17#include "um_malloc.h"
18#include "user.h"
19 19
20struct pty_chan { 20struct pty_chan {
21 void (*announce)(char *dev_name, int dev); 21 void (*announce)(char *dev_name, int dev);
@@ -33,7 +33,7 @@ static void *pty_chan_init(char *str, int device, const struct chan_opts *opts)
33 if (data == NULL) 33 if (data == NULL)
34 return NULL; 34 return NULL;
35 35
36 *data = ((struct pty_chan) { .announce = opts->announce, 36 *data = ((struct pty_chan) { .announce = opts->announce,
37 .dev = device, 37 .dev = device,
38 .raw = opts->raw }); 38 .raw = opts->raw });
39 return data; 39 return data;
@@ -56,11 +56,11 @@ static int pts_open(int input, int output, int primary, void *d,
56 if (data->raw) { 56 if (data->raw) {
57 CATCH_EINTR(err = tcgetattr(fd, &data->tt)); 57 CATCH_EINTR(err = tcgetattr(fd, &data->tt));
58 if (err) 58 if (err)
59 return err; 59 goto out_close;
60 60
61 err = raw(fd); 61 err = raw(fd);
62 if (err) 62 if (err)
63 return err; 63 goto out_close;
64 } 64 }
65 65
66 dev = ptsname(fd); 66 dev = ptsname(fd);
@@ -71,6 +71,10 @@ static int pts_open(int input, int output, int primary, void *d,
71 (*data->announce)(dev, data->dev); 71 (*data->announce)(dev, data->dev);
72 72
73 return fd; 73 return fd;
74
75out_close:
76 close(fd);
77 return err;
74} 78}
75 79
76static int getmaster(char *line) 80static int getmaster(char *line)
@@ -97,7 +101,7 @@ static int getmaster(char *line)
97 *tp = 't'; 101 *tp = 't';
98 err = access(line, R_OK | W_OK); 102 err = access(line, R_OK | W_OK);
99 *tp = 'p'; 103 *tp = 'p';
100 if(!err) 104 if (!err)
101 return master; 105 return master;
102 close(master); 106 close(master);
103 } 107 }
@@ -119,12 +123,14 @@ static int pty_open(int input, int output, int primary, void *d,
119 if (fd < 0) 123 if (fd < 0)
120 return fd; 124 return fd;
121 125
122 if(data->raw){ 126 if (data->raw) {
123 err = raw(fd); 127 err = raw(fd);
124 if (err) 128 if (err) {
129 close(fd);
125 return err; 130 return err;
131 }
126 } 132 }
127 133
128 if (data->announce) 134 if (data->announce)
129 (*data->announce)(dev, data->dev); 135 (*data->announce)(dev, data->dev);
130 136
diff --git a/arch/um/drivers/slip_kern.c b/arch/um/drivers/slip_kern.c
index 125c44f77638..ae67e7158e71 100644
--- a/arch/um/drivers/slip_kern.c
+++ b/arch/um/drivers/slip_kern.c
@@ -1,11 +1,12 @@
1#include "linux/kernel.h" 1/*
2#include "linux/stddef.h" 2 * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3#include "linux/init.h" 3 * Licensed under the GPL.
4#include "linux/netdevice.h" 4 */
5#include "linux/if_arp.h" 5
6#include <linux/if_arp.h>
7#include <linux/init.h>
8#include <linux/netdevice.h>
6#include "net_kern.h" 9#include "net_kern.h"
7#include "net_user.h"
8#include "kern.h"
9#include "slip.h" 10#include "slip.h"
10 11
11struct slip_init { 12struct slip_init {
@@ -43,21 +44,19 @@ void slip_init(struct net_device *dev, void *data)
43 44
44static unsigned short slip_protocol(struct sk_buff *skbuff) 45static unsigned short slip_protocol(struct sk_buff *skbuff)
45{ 46{
46 return(htons(ETH_P_IP)); 47 return htons(ETH_P_IP);
47} 48}
48 49
49static int slip_read(int fd, struct sk_buff **skb, 50static int slip_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
50 struct uml_net_private *lp)
51{ 51{
52 return(slip_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu, 52 return slip_user_read(fd, skb_mac_header(skb), skb->dev->mtu,
53 (struct slip_data *) &lp->user)); 53 (struct slip_data *) &lp->user);
54} 54}
55 55
56static int slip_write(int fd, struct sk_buff **skb, 56static int slip_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
57 struct uml_net_private *lp)
58{ 57{
59 return(slip_user_write(fd, (*skb)->data, (*skb)->len, 58 return slip_user_write(fd, skb->data, skb->len,
60 (struct slip_data *) &lp->user)); 59 (struct slip_data *) &lp->user);
61} 60}
62 61
63const struct net_kern_info slip_kern_info = { 62const struct net_kern_info slip_kern_info = {
@@ -71,12 +70,11 @@ static int slip_setup(char *str, char **mac_out, void *data)
71{ 70{
72 struct slip_init *init = data; 71 struct slip_init *init = data;
73 72
74 *init = ((struct slip_init) 73 *init = ((struct slip_init) { .gate_addr = NULL });
75 { .gate_addr = NULL });
76 74
77 if(str[0] != '\0') 75 if (str[0] != '\0')
78 init->gate_addr = str; 76 init->gate_addr = str;
79 return(1); 77 return 1;
80} 78}
81 79
82static struct transport slip_transport = { 80static struct transport slip_transport = {
diff --git a/arch/um/drivers/slip_user.c b/arch/um/drivers/slip_user.c
index c0b73c28cff0..5f06204d6871 100644
--- a/arch/um/drivers/slip_user.c
+++ b/arch/um/drivers/slip_user.c
@@ -1,21 +1,22 @@
1/*
2 * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL.
4 */
5
1#include <stdio.h> 6#include <stdio.h>
2#include <stdlib.h> 7#include <stdlib.h>
3#include <unistd.h> 8#include <unistd.h>
4#include <stddef.h>
5#include <sched.h>
6#include <string.h>
7#include <errno.h> 9#include <errno.h>
10#include <fcntl.h>
11#include <string.h>
8#include <sys/termios.h> 12#include <sys/termios.h>
9#include <sys/wait.h> 13#include <sys/wait.h>
10#include <sys/signal.h> 14#include "kern_constants.h"
11#include "kern_util.h"
12#include "user.h"
13#include "net_user.h" 15#include "net_user.h"
14#include "slip.h"
15#include "slip_common.h"
16#include "os.h" 16#include "os.h"
17#include "slip.h"
17#include "um_malloc.h" 18#include "um_malloc.h"
18#include "kern_constants.h" 19#include "user.h"
19 20
20static int slip_user_init(void *data, void *dev) 21static int slip_user_init(void *data, void *dev)
21{ 22{
@@ -31,8 +32,9 @@ static int set_up_tty(int fd)
31 struct termios tios; 32 struct termios tios;
32 33
33 if (tcgetattr(fd, &tios) < 0) { 34 if (tcgetattr(fd, &tios) < 0) {
34 printk("could not get initial terminal attributes\n"); 35 printk(UM_KERN_ERR "could not get initial terminal "
35 return(-1); 36 "attributes\n");
37 return -1;
36 } 38 }
37 39
38 tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL; 40 tios.c_cflag = CS8 | CREAD | HUPCL | CLOCAL;
@@ -48,10 +50,10 @@ static int set_up_tty(int fd)
48 cfsetispeed(&tios, B38400); 50 cfsetispeed(&tios, B38400);
49 51
50 if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) { 52 if (tcsetattr(fd, TCSAFLUSH, &tios) < 0) {
51 printk("failed to set terminal attributes\n"); 53 printk(UM_KERN_ERR "failed to set terminal attributes\n");
52 return(-1); 54 return -1;
53 } 55 }
54 return(0); 56 return 0;
55} 57}
56 58
57struct slip_pre_exec_data { 59struct slip_pre_exec_data {
@@ -64,9 +66,11 @@ static void slip_pre_exec(void *arg)
64{ 66{
65 struct slip_pre_exec_data *data = arg; 67 struct slip_pre_exec_data *data = arg;
66 68
67 if(data->stdin >= 0) dup2(data->stdin, 0); 69 if (data->stdin >= 0)
70 dup2(data->stdin, 0);
68 dup2(data->stdout, 1); 71 dup2(data->stdout, 1);
69 if(data->close_me >= 0) os_close_file(data->close_me); 72 if (data->close_me >= 0)
73 close(data->close_me);
70} 74}
71 75
72static int slip_tramp(char **argv, int fd) 76static int slip_tramp(char **argv, int fd)
@@ -76,8 +80,9 @@ static int slip_tramp(char **argv, int fd)
76 int status, pid, fds[2], err, output_len; 80 int status, pid, fds[2], err, output_len;
77 81
78 err = os_pipe(fds, 1, 0); 82 err = os_pipe(fds, 1, 0);
79 if(err < 0){ 83 if (err < 0) {
80 printk("slip_tramp : pipe failed, err = %d\n", -err); 84 printk(UM_KERN_ERR "slip_tramp : pipe failed, err = %d\n",
85 -err);
81 goto out; 86 goto out;
82 } 87 }
83 88
@@ -86,41 +91,42 @@ static int slip_tramp(char **argv, int fd)
86 pe_data.stdout = fds[1]; 91 pe_data.stdout = fds[1];
87 pe_data.close_me = fds[0]; 92 pe_data.close_me = fds[0];
88 err = run_helper(slip_pre_exec, &pe_data, argv); 93 err = run_helper(slip_pre_exec, &pe_data, argv);
89 if(err < 0) 94 if (err < 0)
90 goto out_close; 95 goto out_close;
91 pid = err; 96 pid = err;
92 97
93 output_len = UM_KERN_PAGE_SIZE; 98 output_len = UM_KERN_PAGE_SIZE;
94 output = kmalloc(output_len, UM_GFP_KERNEL); 99 output = kmalloc(output_len, UM_GFP_KERNEL);
95 if(output == NULL){ 100 if (output == NULL) {
96 printk("slip_tramp : failed to allocate output buffer\n"); 101 printk(UM_KERN_ERR "slip_tramp : failed to allocate output "
102 "buffer\n");
97 os_kill_process(pid, 1); 103 os_kill_process(pid, 1);
98 err = -ENOMEM; 104 err = -ENOMEM;
99 goto out_free; 105 goto out_free;
100 } 106 }
101 107
102 os_close_file(fds[1]); 108 close(fds[1]);
103 read_output(fds[0], output, output_len); 109 read_output(fds[0], output, output_len);
104 printk("%s", output); 110 printk("%s", output);
105 111
106 CATCH_EINTR(err = waitpid(pid, &status, 0)); 112 CATCH_EINTR(err = waitpid(pid, &status, 0));
107 if(err < 0) 113 if (err < 0)
108 err = errno; 114 err = errno;
109 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 0)){ 115 else if (!WIFEXITED(status) || (WEXITSTATUS(status) != 0)) {
110 printk("'%s' didn't exit with status 0\n", argv[0]); 116 printk(UM_KERN_ERR "'%s' didn't exit with status 0\n", argv[0]);
111 err = -EINVAL; 117 err = -EINVAL;
112 } 118 }
113 else err = 0; 119 else err = 0;
114 120
115 os_close_file(fds[0]); 121 close(fds[0]);
116 122
117out_free: 123out_free:
118 kfree(output); 124 kfree(output);
119 return err; 125 return err;
120 126
121out_close: 127out_close:
122 os_close_file(fds[0]); 128 close(fds[0]);
123 os_close_file(fds[1]); 129 close(fds[1]);
124out: 130out:
125 return err; 131 return err;
126} 132}
@@ -130,60 +136,64 @@ static int slip_open(void *data)
130 struct slip_data *pri = data; 136 struct slip_data *pri = data;
131 char version_buf[sizeof("nnnnn\0")]; 137 char version_buf[sizeof("nnnnn\0")];
132 char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; 138 char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
133 char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf, 139 char *argv[] = { "uml_net", version_buf, "slip", "up", gate_buf,
134 NULL }; 140 NULL };
135 int sfd, mfd, err; 141 int sfd, mfd, err;
136 142
137 err = get_pty(); 143 err = get_pty();
138 if(err < 0){ 144 if (err < 0) {
139 printk("slip-open : Failed to open pty, err = %d\n", -err); 145 printk(UM_KERN_ERR "slip-open : Failed to open pty, err = %d\n",
146 -err);
140 goto out; 147 goto out;
141 } 148 }
142 mfd = err; 149 mfd = err;
143 150
144 err = os_open_file(ptsname(mfd), of_rdwr(OPENFLAGS()), 0); 151 err = open(ptsname(mfd), O_RDWR, 0);
145 if(err < 0){ 152 if (err < 0) {
146 printk("Couldn't open tty for slip line, err = %d\n", -err); 153 printk(UM_KERN_ERR "Couldn't open tty for slip line, "
154 "err = %d\n", -err);
147 goto out_close; 155 goto out_close;
148 } 156 }
149 sfd = err; 157 sfd = err;
150 158
151 if(set_up_tty(sfd)) 159 if (set_up_tty(sfd))
152 goto out_close2; 160 goto out_close2;
153 161
154 pri->slave = sfd; 162 pri->slave = sfd;
155 pri->slip.pos = 0; 163 pri->slip.pos = 0;
156 pri->slip.esc = 0; 164 pri->slip.esc = 0;
157 if(pri->gate_addr != NULL){ 165 if (pri->gate_addr != NULL) {
158 sprintf(version_buf, "%d", UML_NET_VERSION); 166 sprintf(version_buf, "%d", UML_NET_VERSION);
159 strcpy(gate_buf, pri->gate_addr); 167 strcpy(gate_buf, pri->gate_addr);
160 168
161 err = slip_tramp(argv, sfd); 169 err = slip_tramp(argv, sfd);
162 170
163 if(err < 0){ 171 if (err < 0) {
164 printk("slip_tramp failed - err = %d\n", -err); 172 printk(UM_KERN_ERR "slip_tramp failed - err = %d\n",
173 -err);
165 goto out_close2; 174 goto out_close2;
166 } 175 }
167 err = os_get_ifname(pri->slave, pri->name); 176 err = os_get_ifname(pri->slave, pri->name);
168 if(err < 0){ 177 if (err < 0) {
169 printk("get_ifname failed, err = %d\n", -err); 178 printk(UM_KERN_ERR "get_ifname failed, err = %d\n",
179 -err);
170 goto out_close2; 180 goto out_close2;
171 } 181 }
172 iter_addresses(pri->dev, open_addr, pri->name); 182 iter_addresses(pri->dev, open_addr, pri->name);
173 } 183 }
174 else { 184 else {
175 err = os_set_slip(sfd); 185 err = os_set_slip(sfd);
176 if(err < 0){ 186 if (err < 0) {
177 printk("Failed to set slip discipline encapsulation - " 187 printk(UM_KERN_ERR "Failed to set slip discipline "
178 "err = %d\n", -err); 188 "encapsulation - err = %d\n", -err);
179 goto out_close2; 189 goto out_close2;
180 } 190 }
181 } 191 }
182 return(mfd); 192 return mfd;
183out_close2: 193out_close2:
184 os_close_file(sfd); 194 close(sfd);
185out_close: 195out_close:
186 os_close_file(mfd); 196 close(mfd);
187out: 197out:
188 return err; 198 return err;
189} 199}
@@ -192,21 +202,21 @@ static void slip_close(int fd, void *data)
192{ 202{
193 struct slip_data *pri = data; 203 struct slip_data *pri = data;
194 char version_buf[sizeof("nnnnn\0")]; 204 char version_buf[sizeof("nnnnn\0")];
195 char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name, 205 char *argv[] = { "uml_net", version_buf, "slip", "down", pri->name,
196 NULL }; 206 NULL };
197 int err; 207 int err;
198 208
199 if(pri->gate_addr != NULL) 209 if (pri->gate_addr != NULL)
200 iter_addresses(pri->dev, close_addr, pri->name); 210 iter_addresses(pri->dev, close_addr, pri->name);
201 211
202 sprintf(version_buf, "%d", UML_NET_VERSION); 212 sprintf(version_buf, "%d", UML_NET_VERSION);
203 213
204 err = slip_tramp(argv, pri->slave); 214 err = slip_tramp(argv, pri->slave);
205 215
206 if(err != 0) 216 if (err != 0)
207 printk("slip_tramp failed - errno = %d\n", -err); 217 printk(UM_KERN_ERR "slip_tramp failed - errno = %d\n", -err);
208 os_close_file(fd); 218 close(fd);
209 os_close_file(pri->slave); 219 close(pri->slave);
210 pri->slave = -1; 220 pri->slave = -1;
211} 221}
212 222
@@ -220,17 +230,13 @@ int slip_user_write(int fd, void *buf, int len, struct slip_data *pri)
220 return slip_proto_write(fd, buf, len, &pri->slip); 230 return slip_proto_write(fd, buf, len, &pri->slip);
221} 231}
222 232
223static int slip_set_mtu(int mtu, void *data)
224{
225 return(mtu);
226}
227
228static void slip_add_addr(unsigned char *addr, unsigned char *netmask, 233static void slip_add_addr(unsigned char *addr, unsigned char *netmask,
229 void *data) 234 void *data)
230{ 235{
231 struct slip_data *pri = data; 236 struct slip_data *pri = data;
232 237
233 if(pri->slave < 0) return; 238 if (pri->slave < 0)
239 return;
234 open_addr(addr, netmask, pri->name); 240 open_addr(addr, netmask, pri->name);
235} 241}
236 242
@@ -239,7 +245,8 @@ static void slip_del_addr(unsigned char *addr, unsigned char *netmask,
239{ 245{
240 struct slip_data *pri = data; 246 struct slip_data *pri = data;
241 247
242 if(pri->slave < 0) return; 248 if (pri->slave < 0)
249 return;
243 close_addr(addr, netmask, pri->name); 250 close_addr(addr, netmask, pri->name);
244} 251}
245 252
@@ -248,8 +255,8 @@ const struct net_user_info slip_user_info = {
248 .open = slip_open, 255 .open = slip_open,
249 .close = slip_close, 256 .close = slip_close,
250 .remove = NULL, 257 .remove = NULL,
251 .set_mtu = slip_set_mtu,
252 .add_address = slip_add_addr, 258 .add_address = slip_add_addr,
253 .delete_address = slip_del_addr, 259 .delete_address = slip_del_addr,
254 .max_packet = BUF_SIZE 260 .mtu = BUF_SIZE,
261 .max_packet = BUF_SIZE,
255}; 262};
diff --git a/arch/um/drivers/slirp_kern.c b/arch/um/drivers/slirp_kern.c
index 0a0324a6d290..240ee650865d 100644
--- a/arch/um/drivers/slirp_kern.c
+++ b/arch/um/drivers/slirp_kern.c
@@ -1,11 +1,14 @@
1#include "linux/kernel.h" 1/*
2#include "linux/stddef.h" 2 * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL.
4 */
5
6#include <linux/if_arp.h>
3#include "linux/init.h" 7#include "linux/init.h"
4#include "linux/netdevice.h" 8#include <linux/netdevice.h>
5#include "linux/if_arp.h" 9#include <linux/string.h>
6#include "net_kern.h" 10#include "net_kern.h"
7#include "net_user.h" 11#include "net_user.h"
8#include "kern.h"
9#include "slirp.h" 12#include "slirp.h"
10 13
11struct slirp_init { 14struct slirp_init {
@@ -39,29 +42,26 @@ void slirp_init(struct net_device *dev, void *data)
39 dev->tx_queue_len = 256; 42 dev->tx_queue_len = 256;
40 dev->flags = IFF_NOARP; 43 dev->flags = IFF_NOARP;
41 printk("SLIRP backend - command line:"); 44 printk("SLIRP backend - command line:");
42 for(i=0;spri->argw.argv[i]!=NULL;i++) { 45 for (i = 0; spri->argw.argv[i] != NULL; i++)
43 printk(" '%s'",spri->argw.argv[i]); 46 printk(" '%s'",spri->argw.argv[i]);
44 }
45 printk("\n"); 47 printk("\n");
46} 48}
47 49
48static unsigned short slirp_protocol(struct sk_buff *skbuff) 50static unsigned short slirp_protocol(struct sk_buff *skbuff)
49{ 51{
50 return(htons(ETH_P_IP)); 52 return htons(ETH_P_IP);
51} 53}
52 54
53static int slirp_read(int fd, struct sk_buff **skb, 55static int slirp_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
54 struct uml_net_private *lp)
55{ 56{
56 return(slirp_user_read(fd, skb_mac_header(*skb), (*skb)->dev->mtu, 57 return slirp_user_read(fd, skb_mac_header(skb), skb->dev->mtu,
57 (struct slirp_data *) &lp->user)); 58 (struct slirp_data *) &lp->user);
58} 59}
59 60
60static int slirp_write(int fd, struct sk_buff **skb, 61static int slirp_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
61 struct uml_net_private *lp)
62{ 62{
63 return(slirp_user_write(fd, (*skb)->data, (*skb)->len, 63 return slirp_user_write(fd, skb->data, skb->len,
64 (struct slirp_data *) &lp->user)); 64 (struct slirp_data *) &lp->user);
65} 65}
66 66
67const struct net_kern_info slirp_kern_info = { 67const struct net_kern_info slirp_kern_info = {
@@ -76,31 +76,32 @@ static int slirp_setup(char *str, char **mac_out, void *data)
76 struct slirp_init *init = data; 76 struct slirp_init *init = data;
77 int i=0; 77 int i=0;
78 78
79 *init = ((struct slirp_init) 79 *init = ((struct slirp_init) { .argw = { { "slirp", NULL } } });
80 { .argw = { { "slirp", NULL } } });
81 80
82 str = split_if_spec(str, mac_out, NULL); 81 str = split_if_spec(str, mac_out, NULL);
83 82
84 if(str == NULL) { /* no command line given after MAC addr */ 83 if (str == NULL) /* no command line given after MAC addr */
85 return(1); 84 return 1;
86 }
87 85
88 do { 86 do {
89 if(i>=SLIRP_MAX_ARGS-1) { 87 if (i >= SLIRP_MAX_ARGS - 1) {
90 printk("slirp_setup: truncating slirp arguments\n"); 88 printk(KERN_WARNING "slirp_setup: truncating slirp "
89 "arguments\n");
91 break; 90 break;
92 } 91 }
93 init->argw.argv[i++] = str; 92 init->argw.argv[i++] = str;
94 while(*str && *str!=',') { 93 while(*str && *str!=',') {
95 if(*str=='_') *str=' '; 94 if (*str == '_')
95 *str=' ';
96 str++; 96 str++;
97 } 97 }
98 if(*str!=',') 98 if (*str != ',')
99 break; 99 break;
100 *str++='\0'; 100 *str++ = '\0';
101 } while(1); 101 } while (1);
102 init->argw.argv[i]=NULL; 102
103 return(1); 103 init->argw.argv[i] = NULL;
104 return 1;
104} 105}
105 106
106static struct transport slirp_transport = { 107static struct transport slirp_transport = {
diff --git a/arch/um/drivers/slirp_user.c b/arch/um/drivers/slirp_user.c
index 0e462f64f227..1865089ff41a 100644
--- a/arch/um/drivers/slirp_user.c
+++ b/arch/um/drivers/slirp_user.c
@@ -1,18 +1,17 @@
1#include <stdio.h> 1/*
2#include <stdlib.h> 2 * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL.
4 */
5
3#include <unistd.h> 6#include <unistd.h>
4#include <stddef.h>
5#include <sched.h>
6#include <string.h>
7#include <errno.h> 7#include <errno.h>
8#include <string.h>
8#include <sys/wait.h> 9#include <sys/wait.h>
9#include <sys/signal.h> 10#include "kern_constants.h"
10#include "kern_util.h"
11#include "user.h"
12#include "net_user.h" 11#include "net_user.h"
13#include "slirp.h"
14#include "slip_common.h"
15#include "os.h" 12#include "os.h"
13#include "slirp.h"
14#include "user.h"
16 15
17static int slirp_user_init(void *data, void *dev) 16static int slirp_user_init(void *data, void *dev)
18{ 17{
@@ -31,8 +30,10 @@ static void slirp_pre_exec(void *arg)
31{ 30{
32 struct slirp_pre_exec_data *data = arg; 31 struct slirp_pre_exec_data *data = arg;
33 32
34 if(data->stdin != -1) dup2(data->stdin, 0); 33 if (data->stdin != -1)
35 if(data->stdout != -1) dup2(data->stdout, 1); 34 dup2(data->stdin, 0);
35 if (data->stdout != -1)
36 dup2(data->stdout, 1);
36} 37}
37 38
38static int slirp_tramp(char **argv, int fd) 39static int slirp_tramp(char **argv, int fd)
@@ -44,7 +45,7 @@ static int slirp_tramp(char **argv, int fd)
44 pe_data.stdout = fd; 45 pe_data.stdout = fd;
45 pid = run_helper(slirp_pre_exec, &pe_data, argv); 46 pid = run_helper(slirp_pre_exec, &pe_data, argv);
46 47
47 return(pid); 48 return pid;
48} 49}
49 50
50static int slirp_open(void *data) 51static int slirp_open(void *data)
@@ -53,12 +54,12 @@ static int slirp_open(void *data)
53 int fds[2], pid, err; 54 int fds[2], pid, err;
54 55
55 err = os_pipe(fds, 1, 1); 56 err = os_pipe(fds, 1, 1);
56 if(err) 57 if (err)
57 return(err); 58 return err;
58 59
59 err = slirp_tramp(pri->argw.argv, fds[1]); 60 err = slirp_tramp(pri->argw.argv, fds[1]);
60 if(err < 0){ 61 if (err < 0) {
61 printk("slirp_tramp failed - errno = %d\n", -err); 62 printk(UM_KERN_ERR "slirp_tramp failed - errno = %d\n", -err);
62 goto out; 63 goto out;
63 } 64 }
64 pid = err; 65 pid = err;
@@ -68,10 +69,10 @@ static int slirp_open(void *data)
68 pri->slip.esc = 0; 69 pri->slip.esc = 0;
69 pri->pid = err; 70 pri->pid = err;
70 71
71 return(fds[0]); 72 return fds[0];
72out: 73out:
73 os_close_file(fds[0]); 74 close(fds[0]);
74 os_close_file(fds[1]); 75 close(fds[1]);
75 return err; 76 return err;
76} 77}
77 78
@@ -80,31 +81,33 @@ static void slirp_close(int fd, void *data)
80 struct slirp_data *pri = data; 81 struct slirp_data *pri = data;
81 int status,err; 82 int status,err;
82 83
83 os_close_file(fd); 84 close(fd);
84 os_close_file(pri->slave); 85 close(pri->slave);
85 86
86 pri->slave = -1; 87 pri->slave = -1;
87 88
88 if(pri->pid<1) { 89 if (pri->pid<1) {
89 printk("slirp_close: no child process to shut down\n"); 90 printk(UM_KERN_ERR "slirp_close: no child process to shut "
91 "down\n");
90 return; 92 return;
91 } 93 }
92 94
93#if 0 95#if 0
94 if(kill(pri->pid, SIGHUP)<0) { 96 if (kill(pri->pid, SIGHUP)<0) {
95 printk("slirp_close: sending hangup to %d failed (%d)\n", 97 printk(UM_KERN_ERR "slirp_close: sending hangup to %d failed "
96 pri->pid, errno); 98 "(%d)\n", pri->pid, errno);
97 } 99 }
98#endif 100#endif
99 101
100 CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG)); 102 CATCH_EINTR(err = waitpid(pri->pid, &status, WNOHANG));
101 if(err < 0) { 103 if (err < 0) {
102 printk("slirp_close: waitpid returned %d\n", errno); 104 printk(UM_KERN_ERR "slirp_close: waitpid returned %d\n", errno);
103 return; 105 return;
104 } 106 }
105 107
106 if(err == 0) { 108 if (err == 0) {
107 printk("slirp_close: process %d has not exited\n", pri->pid); 109 printk(UM_KERN_ERR "slirp_close: process %d has not exited\n",
110 pri->pid);
108 return; 111 return;
109 } 112 }
110 113
@@ -121,18 +124,13 @@ int slirp_user_write(int fd, void *buf, int len, struct slirp_data *pri)
121 return slip_proto_write(fd, buf, len, &pri->slip); 124 return slip_proto_write(fd, buf, len, &pri->slip);
122} 125}
123 126
124static int slirp_set_mtu(int mtu, void *data)
125{
126 return(mtu);
127}
128
129const struct net_user_info slirp_user_info = { 127const struct net_user_info slirp_user_info = {
130 .init = slirp_user_init, 128 .init = slirp_user_init,
131 .open = slirp_open, 129 .open = slirp_open,
132 .close = slirp_close, 130 .close = slirp_close,
133 .remove = NULL, 131 .remove = NULL,
134 .set_mtu = slirp_set_mtu,
135 .add_address = NULL, 132 .add_address = NULL,
136 .delete_address = NULL, 133 .delete_address = NULL,
137 .max_packet = BUF_SIZE 134 .mtu = BUF_SIZE,
135 .max_packet = BUF_SIZE,
138}; 136};
diff --git a/arch/um/drivers/tty.c b/arch/um/drivers/tty.c
index a9f87e19c5bf..c930fedc5172 100644
--- a/arch/um/drivers/tty.c
+++ b/arch/um/drivers/tty.c
@@ -1,16 +1,16 @@
1/* 1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h>
7#include <termios.h>
8#include <errno.h> 6#include <errno.h>
9#include <unistd.h> 7#include <fcntl.h>
8#include <termios.h>
10#include "chan_user.h" 9#include "chan_user.h"
11#include "user.h" 10#include "kern_constants.h"
12#include "os.h" 11#include "os.h"
13#include "um_malloc.h" 12#include "um_malloc.h"
13#include "user.h"
14 14
15struct tty_chan { 15struct tty_chan {
16 char *dev; 16 char *dev;
@@ -22,15 +22,15 @@ static void *tty_chan_init(char *str, int device, const struct chan_opts *opts)
22{ 22{
23 struct tty_chan *data; 23 struct tty_chan *data;
24 24
25 if(*str != ':'){ 25 if (*str != ':') {
26 printk("tty_init : channel type 'tty' must specify " 26 printk(UM_KERN_ERR "tty_init : channel type 'tty' must specify "
27 "a device\n"); 27 "a device\n");
28 return NULL; 28 return NULL;
29 } 29 }
30 str++; 30 str++;
31 31
32 data = kmalloc(sizeof(*data), UM_GFP_KERNEL); 32 data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
33 if(data == NULL) 33 if (data == NULL)
34 return NULL; 34 return NULL;
35 *data = ((struct tty_chan) { .dev = str, 35 *data = ((struct tty_chan) { .dev = str,
36 .raw = opts->raw }); 36 .raw = opts->raw });
@@ -42,19 +42,26 @@ static int tty_open(int input, int output, int primary, void *d,
42 char **dev_out) 42 char **dev_out)
43{ 43{
44 struct tty_chan *data = d; 44 struct tty_chan *data = d;
45 int fd, err; 45 int fd, err, mode = 0;
46
47 if (input && output)
48 mode = O_RDWR;
49 else if (input)
50 mode = O_RDONLY;
51 else if (output)
52 mode = O_WRONLY;
46 53
47 fd = os_open_file(data->dev, of_set_rw(OPENFLAGS(), input, output), 0); 54 fd = open(data->dev, mode);
48 if(fd < 0) 55 if (fd < 0)
49 return fd; 56 return -errno;
50 57
51 if(data->raw){ 58 if (data->raw) {
52 CATCH_EINTR(err = tcgetattr(fd, &data->tt)); 59 CATCH_EINTR(err = tcgetattr(fd, &data->tt));
53 if(err) 60 if (err)
54 return err; 61 return err;
55 62
56 err = raw(fd); 63 err = raw(fd);
57 if(err) 64 if (err)
58 return err; 65 return err;
59 } 66 }
60 67
diff --git a/arch/um/drivers/ubd_kern.c b/arch/um/drivers/ubd_kern.c
index 0eabe73c964d..25b248a02507 100644
--- a/arch/um/drivers/ubd_kern.c
+++ b/arch/um/drivers/ubd_kern.c
@@ -615,7 +615,7 @@ static int ubd_open_dev(struct ubd *ubd_dev)
615 blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long)); 615 blk_queue_max_sectors(ubd_dev->queue, 8 * sizeof(long));
616 616
617 err = -ENOMEM; 617 err = -ENOMEM;
618 ubd_dev->cow.bitmap = (void *) vmalloc(ubd_dev->cow.bitmap_len); 618 ubd_dev->cow.bitmap = vmalloc(ubd_dev->cow.bitmap_len);
619 if(ubd_dev->cow.bitmap == NULL){ 619 if(ubd_dev->cow.bitmap == NULL){
620 printk(KERN_ERR "Failed to vmalloc COW bitmap\n"); 620 printk(KERN_ERR "Failed to vmalloc COW bitmap\n");
621 goto error; 621 goto error;
diff --git a/arch/um/drivers/vde.h b/arch/um/drivers/vde.h
new file mode 100644
index 000000000000..fc3a05902ba1
--- /dev/null
+++ b/arch/um/drivers/vde.h
@@ -0,0 +1,32 @@
1/*
2 * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org).
3 * Licensed under the GPL.
4 */
5
6#ifndef __UM_VDE_H__
7#define __UM_VDE_H__
8
9struct vde_data {
10 char *vde_switch;
11 char *descr;
12 void *args;
13 void *conn;
14 void *dev;
15};
16
17struct vde_init {
18 char *vde_switch;
19 char *descr;
20 int port;
21 char *group;
22 int mode;
23};
24
25extern const struct net_user_info vde_user_info;
26
27extern void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init);
28
29extern int vde_user_read(void *conn, void *buf, int len);
30extern int vde_user_write(void *conn, void *buf, int len);
31
32#endif
diff --git a/arch/um/drivers/vde_kern.c b/arch/um/drivers/vde_kern.c
new file mode 100644
index 000000000000..add7e722defb
--- /dev/null
+++ b/arch/um/drivers/vde_kern.c
@@ -0,0 +1,129 @@
1/*
2 * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org).
3 * Licensed under the GPL.
4 *
5 * Transport usage:
6 * ethN=vde,<vde_switch>,<mac addr>,<port>,<group>,<mode>,<description>
7 *
8 */
9
10#include "linux/init.h"
11#include <linux/netdevice.h>
12#include "net_kern.h"
13#include "net_user.h"
14#include "vde.h"
15
16static void vde_init(struct net_device *dev, void *data)
17{
18 struct vde_init *init = data;
19 struct uml_net_private *pri;
20 struct vde_data *vpri;
21
22 pri = dev->priv;
23 vpri = (struct vde_data *) pri->user;
24
25 vpri->vde_switch = init->vde_switch;
26 vpri->descr = init->descr ? init->descr : "UML vde_transport";
27 vpri->args = NULL;
28 vpri->conn = NULL;
29 vpri->dev = dev;
30
31 printk("vde backend - %s, ", vpri->vde_switch ?
32 vpri->vde_switch : "(default socket)");
33
34 vde_init_libstuff(vpri, init);
35
36 printk("\n");
37}
38
39static int vde_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
40{
41 struct vde_data *pri = (struct vde_data *) &lp->user;
42
43 if (pri->conn != NULL)
44 return vde_user_read(pri->conn, skb_mac_header(skb),
45 skb->dev->mtu + ETH_HEADER_OTHER);
46
47 printk(KERN_ERR "vde_read - we have no VDECONN to read from");
48 return -EBADF;
49}
50
51static int vde_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
52{
53 struct vde_data *pri = (struct vde_data *) &lp->user;
54
55 if (pri->conn != NULL)
56 return vde_user_write((void *)pri->conn, skb->data,
57 skb->len);
58
59 printk(KERN_ERR "vde_write - we have no VDECONN to write to");
60 return -EBADF;
61}
62
63static const struct net_kern_info vde_kern_info = {
64 .init = vde_init,
65 .protocol = eth_protocol,
66 .read = vde_read,
67 .write = vde_write,
68};
69
70static int vde_setup(char *str, char **mac_out, void *data)
71{
72 struct vde_init *init = data;
73 char *remain, *port_str = NULL, *mode_str = NULL, *last;
74
75 *init = ((struct vde_init)
76 { .vde_switch = NULL,
77 .descr = NULL,
78 .port = 0,
79 .group = NULL,
80 .mode = 0 });
81
82 remain = split_if_spec(str, &init->vde_switch, mac_out, &port_str,
83 &init->group, &mode_str, &init->descr, NULL);
84
85 if (remain != NULL)
86 printk(KERN_WARNING "vde_setup - Ignoring extra data :"
87 "'%s'\n", remain);
88
89 if (port_str != NULL) {
90 init->port = simple_strtoul(port_str, &last, 10);
91 if ((*last != '\0') || (last == port_str)) {
92 printk(KERN_ERR "vde_setup - Bad port : '%s'\n",
93 port_str);
94 return 0;
95 }
96 }
97
98 if (mode_str != NULL) {
99 init->mode = simple_strtoul(mode_str, &last, 8);
100 if ((*last != '\0') || (last == mode_str)) {
101 printk(KERN_ERR "vde_setup - Bad mode : '%s'\n",
102 mode_str);
103 return 0;
104 }
105 }
106
107 printk(KERN_INFO "Configured vde device: %s\n", init->vde_switch ?
108 init->vde_switch : "(default socket)");
109
110 return 1;
111}
112
113static struct transport vde_transport = {
114 .list = LIST_HEAD_INIT(vde_transport.list),
115 .name = "vde",
116 .setup = vde_setup,
117 .user = &vde_user_info,
118 .kern = &vde_kern_info,
119 .private_size = sizeof(struct vde_data),
120 .setup_size = sizeof(struct vde_init),
121};
122
123static int register_vde(void)
124{
125 register_transport(&vde_transport);
126 return 0;
127}
128
129late_initcall(register_vde);
diff --git a/arch/um/drivers/vde_user.c b/arch/um/drivers/vde_user.c
new file mode 100644
index 000000000000..d9941fe5f931
--- /dev/null
+++ b/arch/um/drivers/vde_user.c
@@ -0,0 +1,127 @@
1/*
2 * Copyright (C) 2007 Luca Bigliardi (shammash@artha.org).
3 * Licensed under the GPL.
4 */
5
6#include <stddef.h>
7#include <errno.h>
8#include <libvdeplug.h>
9#include "kern_constants.h"
10#include "net_user.h"
11#include "um_malloc.h"
12#include "user.h"
13#include "vde.h"
14
15static int vde_user_init(void *data, void *dev)
16{
17 struct vde_data *pri = data;
18 VDECONN *conn = NULL;
19 int err = -EINVAL;
20
21 pri->dev = dev;
22
23 conn = vde_open(pri->vde_switch, pri->descr, pri->args);
24
25 if (conn == NULL) {
26 err = -errno;
27 printk(UM_KERN_ERR "vde_user_init: vde_open failed, "
28 "errno = %d\n", errno);
29 return err;
30 }
31
32 printk(UM_KERN_INFO "vde backend - connection opened\n");
33
34 pri->conn = conn;
35
36 return 0;
37}
38
39static int vde_user_open(void *data)
40{
41 struct vde_data *pri = data;
42
43 if (pri->conn != NULL)
44 return vde_datafd(pri->conn);
45
46 printk(UM_KERN_WARNING "vde_open - we have no VDECONN to open");
47 return -EINVAL;
48}
49
50static void vde_remove(void *data)
51{
52 struct vde_data *pri = data;
53
54 if (pri->conn != NULL) {
55 printk(UM_KERN_INFO "vde backend - closing connection\n");
56 vde_close(pri->conn);
57 pri->conn = NULL;
58 kfree(pri->args);
59 pri->args = NULL;
60 return;
61 }
62
63 printk(UM_KERN_WARNING "vde_remove - we have no VDECONN to remove");
64}
65
66const struct net_user_info vde_user_info = {
67 .init = vde_user_init,
68 .open = vde_user_open,
69 .close = NULL,
70 .remove = vde_remove,
71 .add_address = NULL,
72 .delete_address = NULL,
73 .mtu = ETH_MAX_PACKET,
74 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
75};
76
77void vde_init_libstuff(struct vde_data *vpri, struct vde_init *init)
78{
79 struct vde_open_args *args;
80
81 vpri->args = kmalloc(sizeof(struct vde_open_args), UM_GFP_KERNEL);
82 if (vpri->args == NULL) {
83 printk(UM_KERN_ERR "vde_init_libstuff - vde_open_args"
84 "allocation failed");
85 return;
86 }
87
88 args = vpri->args;
89
90 args->port = init->port;
91 args->group = init->group;
92 args->mode = init->mode ? init->mode : 0700;
93
94 args->port ? printk(UM_KERN_INFO "port %d", args->port) :
95 printk(UM_KERN_INFO "undefined port");
96}
97
98int vde_user_read(void *conn, void *buf, int len)
99{
100 VDECONN *vconn = conn;
101 int rv;
102
103 if (vconn == NULL)
104 return 0;
105
106 rv = vde_recv(vconn, buf, len, 0);
107 if (rv < 0) {
108 if (errno == EAGAIN)
109 return 0;
110 return -errno;
111 }
112 else if (rv == 0)
113 return -ENOTCONN;
114
115 return rv;
116}
117
118int vde_user_write(void *conn, void *buf, int len)
119{
120 VDECONN *vconn = conn;
121
122 if (vconn == NULL)
123 return 0;
124
125 return vde_send(vconn, buf, len, 0);
126}
127
diff --git a/arch/um/drivers/xterm.c b/arch/um/drivers/xterm.c
index fd817e541543..8a1c18a9b240 100644
--- a/arch/um/drivers/xterm.c
+++ b/arch/um/drivers/xterm.c
@@ -1,20 +1,21 @@
1/* 1/*
2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdlib.h> 6#include <stddef.h>
7#include <stdio.h> 7#include <stdio.h>
8#include <stdlib.h>
8#include <unistd.h> 9#include <unistd.h>
9#include <string.h>
10#include <errno.h> 10#include <errno.h>
11#include <string.h>
11#include <termios.h> 12#include <termios.h>
12#include "chan_user.h" 13#include "chan_user.h"
14#include "kern_constants.h"
13#include "os.h" 15#include "os.h"
14#include "init.h" 16#include "um_malloc.h"
15#include "user.h" 17#include "user.h"
16#include "xterm.h" 18#include "xterm.h"
17#include "kern_constants.h"
18 19
19struct xterm_chan { 20struct xterm_chan {
20 int pid; 21 int pid;
@@ -29,7 +30,7 @@ static void *xterm_init(char *str, int device, const struct chan_opts *opts)
29{ 30{
30 struct xterm_chan *data; 31 struct xterm_chan *data;
31 32
32 data = malloc(sizeof(*data)); 33 data = kmalloc(sizeof(*data), UM_GFP_KERNEL);
33 if (data == NULL) 34 if (data == NULL)
34 return NULL; 35 return NULL;
35 *data = ((struct xterm_chan) { .pid = -1, 36 *data = ((struct xterm_chan) { .pid = -1,
@@ -95,8 +96,10 @@ static int xterm_open(int input, int output, int primary, void *d,
95 if (access(argv[4], X_OK) < 0) 96 if (access(argv[4], X_OK) < 0)
96 argv[4] = "port-helper"; 97 argv[4] = "port-helper";
97 98
98 /* Check that DISPLAY is set, this doesn't guarantee the xterm 99 /*
99 * will work but w/o it we can be pretty sure it won't. */ 100 * Check that DISPLAY is set, this doesn't guarantee the xterm
101 * will work but w/o it we can be pretty sure it won't.
102 */
100 if (getenv("DISPLAY") == NULL) { 103 if (getenv("DISPLAY") == NULL) {
101 printk(UM_KERN_ERR "xterm_open: $DISPLAY not set.\n"); 104 printk(UM_KERN_ERR "xterm_open: $DISPLAY not set.\n");
102 return -ENODEV; 105 return -ENODEV;
@@ -195,7 +198,7 @@ static int xterm_open(int input, int output, int primary, void *d,
195static void xterm_close(int fd, void *d) 198static void xterm_close(int fd, void *d)
196{ 199{
197 struct xterm_chan *data = d; 200 struct xterm_chan *data = d;
198 201
199 if (data->pid != -1) 202 if (data->pid != -1)
200 os_kill_process(data->pid, 1); 203 os_kill_process(data->pid, 1);
201 data->pid = -1; 204 data->pid = -1;
@@ -207,11 +210,6 @@ static void xterm_close(int fd, void *d)
207 os_close_file(fd); 210 os_close_file(fd);
208} 211}
209 212
210static void xterm_free(void *d)
211{
212 free(d);
213}
214
215const struct chan_ops xterm_ops = { 213const struct chan_ops xterm_ops = {
216 .type = "xterm", 214 .type = "xterm",
217 .init = xterm_init, 215 .init = xterm_init,
@@ -221,6 +219,6 @@ const struct chan_ops xterm_ops = {
221 .write = generic_write, 219 .write = generic_write,
222 .console_write = generic_console_write, 220 .console_write = generic_console_write,
223 .window_size = generic_window_size, 221 .window_size = generic_window_size,
224 .free = xterm_free, 222 .free = generic_free,
225 .winch = 1, 223 .winch = 1,
226}; 224};
diff --git a/arch/um/include/arch.h b/arch/um/include/arch.h
index 10ad52daa8c5..49c601ff2bac 100644
--- a/arch/um/include/arch.h
+++ b/arch/um/include/arch.h
@@ -9,7 +9,7 @@
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10 10
11extern void arch_check_bugs(void); 11extern void arch_check_bugs(void);
12extern int arch_fixup(unsigned long address, union uml_pt_regs *regs); 12extern int arch_fixup(unsigned long address, struct uml_pt_regs *regs);
13extern int arch_handle_signal(int sig, union uml_pt_regs *regs); 13extern int arch_handle_signal(int sig, struct uml_pt_regs *regs);
14 14
15#endif 15#endif
diff --git a/arch/um/include/as-layout.h b/arch/um/include/as-layout.h
index fccf187bf4e1..a5cdf953e04a 100644
--- a/arch/um/include/as-layout.h
+++ b/arch/um/include/as-layout.h
@@ -6,6 +6,28 @@
6#ifndef __START_H__ 6#ifndef __START_H__
7#define __START_H__ 7#define __START_H__
8 8
9#include "uml-config.h"
10#include "kern_constants.h"
11
12/*
13 * Assembly doesn't want any casting, but C does, so define these
14 * without casts here, and define new symbols with casts inside the C
15 * section.
16 */
17#define ASM_STUB_CODE (UML_CONFIG_TOP_ADDR - 2 * UM_KERN_PAGE_SIZE)
18#define ASM_STUB_DATA (UML_CONFIG_TOP_ADDR - UM_KERN_PAGE_SIZE)
19#define ASM_STUB_START ASM_STUB_CODE
20
21/*
22 * This file is included by the assembly stubs, which just want the
23 * definitions above.
24 */
25#ifndef __ASSEMBLY__
26
27#define STUB_CODE ((unsigned long) ASM_STUB_CODE)
28#define STUB_DATA ((unsigned long) ASM_STUB_DATA)
29#define STUB_START ((unsigned long) ASM_STUB_START)
30
9#include "sysdep/ptrace.h" 31#include "sysdep/ptrace.h"
10 32
11struct cpu_task { 33struct cpu_task {
@@ -28,8 +50,9 @@ extern unsigned long _unprotected_end;
28extern unsigned long brk_start; 50extern unsigned long brk_start;
29 51
30extern int linux_main(int argc, char **argv); 52extern int linux_main(int argc, char **argv);
31extern void set_cmdline(char *cmd);
32 53
33extern void (*sig_info[])(int, union uml_pt_regs *); 54extern void (*sig_info[])(int, struct uml_pt_regs *);
55
56#endif
34 57
35#endif 58#endif
diff --git a/arch/um/include/choose-mode.h b/arch/um/include/choose-mode.h
deleted file mode 100644
index b87b36a87d91..000000000000
--- a/arch/um/include/choose-mode.h
+++ /dev/null
@@ -1,38 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __CHOOSE_MODE_H__
7#define __CHOOSE_MODE_H__
8
9#include "uml-config.h"
10
11#if defined(UML_CONFIG_MODE_TT) && defined(UML_CONFIG_MODE_SKAS)
12#define CHOOSE_MODE(tt, skas) (mode_tt ? (tt) : (skas))
13
14extern int mode_tt;
15static inline void *__choose_mode(void *tt, void *skas) {
16 return mode_tt ? tt : skas;
17}
18
19#define __CHOOSE_MODE(tt, skas) (*( (typeof(tt) *) __choose_mode(&(tt), &(skas))))
20
21#elif defined(UML_CONFIG_MODE_SKAS)
22#define CHOOSE_MODE(tt, skas) (skas)
23
24#elif defined(UML_CONFIG_MODE_TT)
25#define CHOOSE_MODE(tt, skas) (tt)
26
27#else
28#error CONFIG_MODE_SKAS and CONFIG_MODE_TT are both disabled
29#endif
30
31#define CHOOSE_MODE_PROC(tt, skas, args...) \
32 CHOOSE_MODE(tt(args), skas(args))
33
34#ifndef __CHOOSE_MODE
35#define __CHOOSE_MODE(tt, skas) CHOOSE_MODE(tt, skas)
36#endif
37
38#endif
diff --git a/arch/um/include/common-offsets.h b/arch/um/include/common-offsets.h
index 6eee343e53eb..0edab695ed4e 100644
--- a/arch/um/include/common-offsets.h
+++ b/arch/um/include/common-offsets.h
@@ -1,15 +1,13 @@
1/* for use by sys-$SUBARCH/kernel-offsets.c */ 1/* for use by sys-$SUBARCH/kernel-offsets.c */
2 2
3DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE); 3DEFINE(KERNEL_MADV_REMOVE, MADV_REMOVE);
4#ifdef CONFIG_MODE_TT
5OFFSET(HOST_TASK_EXTERN_PID, task_struct, thread.mode.tt.extern_pid);
6#endif
7 4
8OFFSET(HOST_TASK_REGS, task_struct, thread.regs); 5OFFSET(HOST_TASK_REGS, task_struct, thread.regs);
9OFFSET(HOST_TASK_PID, task_struct, pid); 6OFFSET(HOST_TASK_PID, task_struct, pid);
10 7
11DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE); 8DEFINE(UM_KERN_PAGE_SIZE, PAGE_SIZE);
12DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK); 9DEFINE(UM_KERN_PAGE_MASK, PAGE_MASK);
10DEFINE(UM_KERN_PAGE_SHIFT, PAGE_SHIFT);
13DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC); 11DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
14 12
15DEFINE_STR(UM_KERN_EMERG, KERN_EMERG); 13DEFINE_STR(UM_KERN_EMERG, KERN_EMERG);
@@ -34,3 +32,9 @@ DEFINE(UM_GFP_ATOMIC, GFP_ATOMIC);
34DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx)); 32DEFINE(crypto_tfm_ctx_offset, offsetof(struct crypto_tfm, __crt_ctx));
35 33
36DEFINE(UM_THREAD_SIZE, THREAD_SIZE); 34DEFINE(UM_THREAD_SIZE, THREAD_SIZE);
35
36DEFINE(UM_HZ, HZ);
37
38DEFINE(UM_USEC_PER_SEC, USEC_PER_SEC);
39DEFINE(UM_NSEC_PER_SEC, NSEC_PER_SEC);
40DEFINE(UM_NSEC_PER_USEC, NSEC_PER_USEC);
diff --git a/arch/um/include/irq_user.h b/arch/um/include/irq_user.h
index 15d311b9be9e..884a9c17eea0 100644
--- a/arch/um/include/irq_user.h
+++ b/arch/um/include/irq_user.h
@@ -1,12 +1,12 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#ifndef __IRQ_USER_H__ 6#ifndef __IRQ_USER_H__
7#define __IRQ_USER_H__ 7#define __IRQ_USER_H__
8 8
9#include "uml-config.h" 9#include "sysdep/ptrace.h"
10 10
11struct irq_fd { 11struct irq_fd {
12 struct irq_fd *next; 12 struct irq_fd *next;
@@ -21,7 +21,7 @@ struct irq_fd {
21 21
22enum { IRQ_READ, IRQ_WRITE }; 22enum { IRQ_READ, IRQ_WRITE };
23 23
24extern void sigio_handler(int sig, union uml_pt_regs *regs); 24extern void sigio_handler(int sig, struct uml_pt_regs *regs);
25extern int activate_fd(int irq, int fd, int type, void *dev_id); 25extern int activate_fd(int irq, int fd, int type, void *dev_id);
26extern void free_irq_by_irq_and_dev(unsigned int irq, void *dev_id); 26extern void free_irq_by_irq_and_dev(unsigned int irq, void *dev_id);
27extern void free_irq_by_fd(int fd); 27extern void free_irq_by_fd(int fd);
@@ -30,8 +30,4 @@ extern void deactivate_fd(int fd, int irqnum);
30extern int deactivate_all_fds(void); 30extern int deactivate_all_fds(void);
31extern int activate_ipi(int fd, int pid); 31extern int activate_ipi(int fd, int pid);
32 32
33#ifdef CONFIG_MODE_TT
34extern void forward_interrupts(int pid);
35#endif
36
37#endif 33#endif
diff --git a/arch/um/include/kern_util.h b/arch/um/include/kern_util.h
index 6c2be26f1d7d..74ce8e5370a6 100644
--- a/arch/um/include/kern_util.h
+++ b/arch/um/include/kern_util.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -8,9 +8,8 @@
8 8
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10#include "sysdep/faultinfo.h" 10#include "sysdep/faultinfo.h"
11#include "uml-config.h"
12 11
13typedef void (*kern_hndl)(int, union uml_pt_regs *); 12typedef void (*kern_hndl)(int, struct uml_pt_regs *);
14 13
15struct kern_handlers { 14struct kern_handlers {
16 kern_hndl relay_signal; 15 kern_hndl relay_signal;
@@ -34,9 +33,6 @@ extern int nsyscalls;
34 UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1) 33 UML_ROUND_DOWN(((unsigned long) addr) + PAGE_SIZE - 1)
35 34
36extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg); 35extern int kernel_fork(unsigned long flags, int (*fn)(void *), void * arg);
37#ifdef UML_CONFIG_MODE_TT
38extern unsigned long stack_sp(unsigned long page);
39#endif
40extern int kernel_thread_proc(void *data); 36extern int kernel_thread_proc(void *data);
41extern void syscall_segv(int sig); 37extern void syscall_segv(int sig);
42extern int current_pid(void); 38extern int current_pid(void);
@@ -44,7 +40,7 @@ extern unsigned long alloc_stack(int order, int atomic);
44extern int do_signal(void); 40extern int do_signal(void);
45extern int is_stack_fault(unsigned long sp); 41extern int is_stack_fault(unsigned long sp);
46extern unsigned long segv(struct faultinfo fi, unsigned long ip, 42extern unsigned long segv(struct faultinfo fi, unsigned long ip,
47 int is_user, union uml_pt_regs *regs); 43 int is_user, struct uml_pt_regs *regs);
48extern int handle_page_fault(unsigned long address, unsigned long ip, 44extern int handle_page_fault(unsigned long address, unsigned long ip,
49 int is_write, int is_user, int *code_out); 45 int is_write, int is_user, int *code_out);
50extern void syscall_ready(void); 46extern void syscall_ready(void);
@@ -57,7 +53,7 @@ extern int need_finish_fork(void);
57extern void free_stack(unsigned long stack, int order); 53extern void free_stack(unsigned long stack, int order);
58extern void add_input_request(int op, void (*proc)(int), void *arg); 54extern void add_input_request(int op, void (*proc)(int), void *arg);
59extern char *current_cmd(void); 55extern char *current_cmd(void);
60extern void timer_handler(int sig, union uml_pt_regs *regs); 56extern void timer_handler(int sig, struct uml_pt_regs *regs);
61extern int set_signals(int enable); 57extern int set_signals(int enable);
62extern int pid_to_processor_id(int pid); 58extern int pid_to_processor_id(int pid);
63extern void deliver_signals(void *t); 59extern void deliver_signals(void *t);
@@ -67,9 +63,8 @@ extern void finish_fork(void);
67extern void paging_init(void); 63extern void paging_init(void);
68extern void init_flush_vm(void); 64extern void init_flush_vm(void);
69extern void *syscall_sp(void *t); 65extern void *syscall_sp(void *t);
70extern void syscall_trace(union uml_pt_regs *regs, int entryexit); 66extern void syscall_trace(struct uml_pt_regs *regs, int entryexit);
71extern int hz(void); 67extern unsigned int do_IRQ(int irq, struct uml_pt_regs *regs);
72extern unsigned int do_IRQ(int irq, union uml_pt_regs *regs);
73extern void interrupt_end(void); 68extern void interrupt_end(void);
74extern void initial_thread_cb(void (*proc)(void *), void *arg); 69extern void initial_thread_cb(void (*proc)(void *), void *arg);
75extern int debugger_signal(int status, int pid); 70extern int debugger_signal(int status, int pid);
@@ -79,10 +74,9 @@ extern int init_ptrace_proxy(int idle_pid, int startup, int stop);
79extern int init_parent_proxy(int pid); 74extern int init_parent_proxy(int pid);
80extern int singlestepping(void *t); 75extern int singlestepping(void *t);
81extern void check_stack_overflow(void *ptr); 76extern void check_stack_overflow(void *ptr);
82extern void relay_signal(int sig, union uml_pt_regs *regs); 77extern void relay_signal(int sig, struct uml_pt_regs *regs);
83extern int user_context(unsigned long sp); 78extern int user_context(unsigned long sp);
84extern void timer_irq(union uml_pt_regs *regs); 79extern void timer_irq(struct uml_pt_regs *regs);
85extern void unprotect_stack(unsigned long stack);
86extern void do_uml_exitcalls(void); 80extern void do_uml_exitcalls(void);
87extern int attach_debugger(int idle_pid, int pid, int stop); 81extern int attach_debugger(int idle_pid, int pid, int stop);
88extern int config_gdb(char *str); 82extern int config_gdb(char *str);
@@ -113,11 +107,9 @@ extern void time_init_kern(void);
113 107
114/* Are we disallowed to sleep? Used to choose between GFP_KERNEL and GFP_ATOMIC. */ 108/* Are we disallowed to sleep? Used to choose between GFP_KERNEL and GFP_ATOMIC. */
115extern int __cant_sleep(void); 109extern int __cant_sleep(void);
116extern void sigio_handler(int sig, union uml_pt_regs *regs); 110extern void sigio_handler(int sig, struct uml_pt_regs *regs);
117 111extern void copy_sc(struct uml_pt_regs *regs, void *from);
118extern void copy_sc(union uml_pt_regs *regs, void *from);
119
120extern unsigned long to_irq_stack(unsigned long *mask_out); 112extern unsigned long to_irq_stack(unsigned long *mask_out);
121unsigned long from_irq_stack(int nested); 113unsigned long from_irq_stack(int nested);
122 114extern int start_uml(void);
123#endif 115#endif
diff --git a/arch/um/include/mconsole.h b/arch/um/include/mconsole.h
index b282839c1625..c139ae1d6826 100644
--- a/arch/um/include/mconsole.h
+++ b/arch/um/include/mconsole.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) 2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org)
3 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 3 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
@@ -63,7 +63,7 @@ struct mc_request
63 63
64 struct mconsole_request request; 64 struct mconsole_request request;
65 struct mconsole_command *cmd; 65 struct mconsole_command *cmd;
66 union uml_pt_regs regs; 66 struct uml_pt_regs regs;
67}; 67};
68 68
69extern char mconsole_socket_name[]; 69extern char mconsole_socket_name[];
@@ -96,14 +96,3 @@ extern void lock_notify(void);
96extern void unlock_notify(void); 96extern void unlock_notify(void);
97 97
98#endif 98#endif
99
100/*
101 * Overrides for Emacs so that we follow Linus's tabbing style.
102 * Emacs will notice this stuff at the end of the file and automatically
103 * adjust the settings for this buffer only. This must remain at the end
104 * of the file.
105 * ---------------------------------------------------------------------------
106 * Local variables:
107 * c-file-style: "linux"
108 * End:
109 */
diff --git a/arch/um/include/mem.h b/arch/um/include/mem.h
index e8ff0d8fa610..5cd40e99e8d5 100644
--- a/arch/um/include/mem.h
+++ b/arch/um/include/mem.h
@@ -1,18 +1,12 @@
1/* 1/*
2 * Copyright (C) 2002, 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#ifndef __MEM_H__ 6#ifndef __MEM_H__
7#define __MEM_H__ 7#define __MEM_H__
8 8
9#include "linux/types.h" 9extern int phys_mapping(unsigned long phys, unsigned long long *offset_out);
10
11extern int phys_mapping(unsigned long phys, __u64 *offset_out);
12extern int physmem_subst_mapping(void *virt, int fd, __u64 offset, int w);
13extern int is_remapped(void *virt);
14extern int physmem_remove_mapping(void *virt);
15extern void physmem_forget_descriptor(int fd);
16 10
17extern unsigned long uml_physmem; 11extern unsigned long uml_physmem;
18static inline unsigned long to_phys(void *virt) 12static inline unsigned long to_phys(void *virt)
@@ -26,14 +20,3 @@ static inline void *to_virt(unsigned long phys)
26} 20}
27 21
28#endif 22#endif
29
30/*
31 * Overrides for Emacs so that we follow Linus's tabbing style.
32 * Emacs will notice this stuff at the end of the file and automatically
33 * adjust the settings for this buffer only. This must remain at the end
34 * of the file.
35 * ---------------------------------------------------------------------------
36 * Local variables:
37 * c-file-style: "linux"
38 * End:
39 */
diff --git a/arch/um/include/mode.h b/arch/um/include/mode.h
deleted file mode 100644
index 786cf563eb05..000000000000
--- a/arch/um/include/mode.h
+++ /dev/null
@@ -1,30 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MODE_H__
7#define __MODE_H__
8
9#include "uml-config.h"
10
11#ifdef UML_CONFIG_MODE_TT
12#include "mode-tt.h"
13#endif
14
15#ifdef UML_CONFIG_MODE_SKAS
16#include "mode-skas.h"
17#endif
18
19#endif
20
21/*
22 * Overrides for Emacs so that we follow Linus's tabbing style.
23 * Emacs will notice this stuff at the end of the file and automatically
24 * adjust the settings for this buffer only. This must remain at the end
25 * of the file.
26 * ---------------------------------------------------------------------------
27 * Local variables:
28 * c-file-style: "linux"
29 * End:
30 */
diff --git a/arch/um/include/mode_kern.h b/arch/um/include/mode_kern.h
deleted file mode 100644
index 88e5e77bf517..000000000000
--- a/arch/um/include/mode_kern.h
+++ /dev/null
@@ -1,17 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MODE_KERN_H__
7#define __MODE_KERN_H__
8
9#ifdef CONFIG_MODE_TT
10#include "mode_kern_tt.h"
11#endif
12
13#ifdef CONFIG_MODE_SKAS
14#include "mode_kern_skas.h"
15#endif
16
17#endif
diff --git a/arch/um/include/net_kern.h b/arch/um/include/net_kern.h
index 9237056b9103..d843c7924a7c 100644
--- a/arch/um/include/net_kern.h
+++ b/arch/um/include/net_kern.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -30,24 +30,24 @@ struct uml_net_private {
30 struct work_struct work; 30 struct work_struct work;
31 int fd; 31 int fd;
32 unsigned char mac[ETH_ALEN]; 32 unsigned char mac[ETH_ALEN];
33 int max_packet;
33 unsigned short (*protocol)(struct sk_buff *); 34 unsigned short (*protocol)(struct sk_buff *);
34 int (*open)(void *); 35 int (*open)(void *);
35 void (*close)(int, void *); 36 void (*close)(int, void *);
36 void (*remove)(void *); 37 void (*remove)(void *);
37 int (*read)(int, struct sk_buff **skb, struct uml_net_private *); 38 int (*read)(int, struct sk_buff *skb, struct uml_net_private *);
38 int (*write)(int, struct sk_buff **skb, struct uml_net_private *); 39 int (*write)(int, struct sk_buff *skb, struct uml_net_private *);
39 40
40 void (*add_address)(unsigned char *, unsigned char *, void *); 41 void (*add_address)(unsigned char *, unsigned char *, void *);
41 void (*delete_address)(unsigned char *, unsigned char *, void *); 42 void (*delete_address)(unsigned char *, unsigned char *, void *);
42 int (*set_mtu)(int mtu, void *);
43 char user[0]; 43 char user[0];
44}; 44};
45 45
46struct net_kern_info { 46struct net_kern_info {
47 void (*init)(struct net_device *, void *); 47 void (*init)(struct net_device *, void *);
48 unsigned short (*protocol)(struct sk_buff *); 48 unsigned short (*protocol)(struct sk_buff *);
49 int (*read)(int, struct sk_buff **skb, struct uml_net_private *); 49 int (*read)(int, struct sk_buff *skb, struct uml_net_private *);
50 int (*write)(int, struct sk_buff **skb, struct uml_net_private *); 50 int (*write)(int, struct sk_buff *skb, struct uml_net_private *);
51}; 51};
52 52
53struct transport { 53struct transport {
@@ -62,7 +62,6 @@ struct transport {
62 62
63extern struct net_device *ether_init(int); 63extern struct net_device *ether_init(int);
64extern unsigned short ether_protocol(struct sk_buff *); 64extern unsigned short ether_protocol(struct sk_buff *);
65extern struct sk_buff *ether_adjust_skb(struct sk_buff *skb, int extra);
66extern int tap_setup_common(char *str, char *type, char **dev_name, 65extern int tap_setup_common(char *str, char *type, char **dev_name,
67 char **mac_out, char **gate_addr); 66 char **mac_out, char **gate_addr);
68extern void register_transport(struct transport *new); 67extern void register_transport(struct transport *new);
diff --git a/arch/um/include/net_user.h b/arch/um/include/net_user.h
index cfe7c50634b9..63bee158cd8e 100644
--- a/arch/um/include/net_user.h
+++ b/arch/um/include/net_user.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -18,10 +18,10 @@ struct net_user_info {
18 int (*open)(void *); 18 int (*open)(void *);
19 void (*close)(int, void *); 19 void (*close)(int, void *);
20 void (*remove)(void *); 20 void (*remove)(void *);
21 int (*set_mtu)(int mtu, void *);
22 void (*add_address)(unsigned char *, unsigned char *, void *); 21 void (*add_address)(unsigned char *, unsigned char *, void *);
23 void (*delete_address)(unsigned char *, unsigned char *, void *); 22 void (*delete_address)(unsigned char *, unsigned char *, void *);
24 int max_packet; 23 int max_packet;
24 int mtu;
25}; 25};
26 26
27extern void ether_user_init(void *data, void *dev); 27extern void ether_user_init(void *data, void *dev);
diff --git a/arch/um/include/os.h b/arch/um/include/os.h
index 930b261ea483..fbf0a87c6eaa 100644
--- a/arch/um/include/os.h
+++ b/arch/um/include/os.h
@@ -1,20 +1,18 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#ifndef __OS_H__ 6#ifndef __OS_H__
7#define __OS_H__ 7#define __OS_H__
8 8
9#include "uml-config.h" 9#include <stdarg.h>
10#include "asm/types.h"
11#include "../os/include/file.h"
12#include "sysdep/ptrace.h"
13#include "kern_util.h"
14#include "skas/mm_id.h"
15#include "irq_user.h" 10#include "irq_user.h"
11#include "kern_util.h"
12#include "longjmp.h"
13#include "mm_id.h"
16#include "sysdep/tls.h" 14#include "sysdep/tls.h"
17#include "sysdep/archsetjmp.h" 15#include "../os/include/file.h"
18 16
19#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR)) 17#define CATCH_EINTR(expr) while ((errno = 0, ((expr) < 0)) && (errno == EINTR))
20 18
@@ -130,18 +128,15 @@ static inline struct openflags of_cloexec(struct openflags flags)
130extern int os_stat_file(const char *file_name, struct uml_stat *buf); 128extern int os_stat_file(const char *file_name, struct uml_stat *buf);
131extern int os_stat_fd(const int fd, struct uml_stat *buf); 129extern int os_stat_fd(const int fd, struct uml_stat *buf);
132extern int os_access(const char *file, int mode); 130extern int os_access(const char *file, int mode);
133extern void os_print_error(int error, const char* str);
134extern int os_get_exec_close(int fd, int *close_on_exec); 131extern int os_get_exec_close(int fd, int *close_on_exec);
135extern int os_set_exec_close(int fd, int close_on_exec); 132extern int os_set_exec_close(int fd);
136extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg); 133extern int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg);
137extern int os_window_size(int fd, int *rows, int *cols);
138extern int os_new_tty_pgrp(int fd, int pid);
139extern int os_get_ifname(int fd, char *namebuf); 134extern int os_get_ifname(int fd, char *namebuf);
140extern int os_set_slip(int fd); 135extern int os_set_slip(int fd);
141extern int os_set_owner(int fd, int pid); 136extern int os_set_owner(int fd, int pid);
142extern int os_mode_fd(int fd, int mode); 137extern int os_mode_fd(int fd, int mode);
143 138
144extern int os_seek_file(int fd, __u64 offset); 139extern int os_seek_file(int fd, unsigned long long offset);
145extern int os_open_file(char *file, struct openflags flags, int mode); 140extern int os_open_file(char *file, struct openflags flags, int mode);
146extern int os_read_file(int fd, void *buf, int len); 141extern int os_read_file(int fd, void *buf, int len);
147extern int os_write_file(int fd, const void *buf, int count); 142extern int os_write_file(int fd, const void *buf, int count);
@@ -179,11 +174,7 @@ extern void check_host_supports_tls(int *supports_tls, int *tls_min);
179 174
180/* Make sure they are clear when running in TT mode. Required by 175/* Make sure they are clear when running in TT mode. Required by
181 * SEGV_MAYBE_FIXABLE */ 176 * SEGV_MAYBE_FIXABLE */
182#ifdef UML_CONFIG_MODE_SKAS
183#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0) 177#define clear_can_do_skas() do { ptrace_faultinfo = proc_mm = 0; } while (0)
184#else
185#define clear_can_do_skas() do {} while (0)
186#endif
187 178
188/* mem.c */ 179/* mem.c */
189extern int create_mem_file(unsigned long long len); 180extern int create_mem_file(unsigned long long len);
@@ -194,20 +185,13 @@ extern int os_process_parent(int pid);
194extern void os_stop_process(int pid); 185extern void os_stop_process(int pid);
195extern void os_kill_process(int pid, int reap_child); 186extern void os_kill_process(int pid, int reap_child);
196extern void os_kill_ptraced_process(int pid, int reap_child); 187extern void os_kill_ptraced_process(int pid, int reap_child);
197#ifdef UML_CONFIG_MODE_TT
198extern void os_usr1_process(int pid);
199#endif
200extern long os_ptrace_ldt(long pid, long addr, long data); 188extern long os_ptrace_ldt(long pid, long addr, long data);
201 189
202extern int os_getpid(void); 190extern int os_getpid(void);
203extern int os_getpgrp(void); 191extern int os_getpgrp(void);
204 192
205#ifdef UML_CONFIG_MODE_TT
206extern void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int));
207extern void stop(void);
208#endif
209extern void init_new_thread_signals(void); 193extern void init_new_thread_signals(void);
210extern int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr); 194extern int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr);
211 195
212extern int os_map_memory(void *virt, int fd, unsigned long long off, 196extern int os_map_memory(void *virt, int fd, unsigned long long off,
213 unsigned long len, int r, int w, int x); 197 unsigned long len, int r, int w, int x);
@@ -218,21 +202,9 @@ extern int os_drop_memory(void *addr, int length);
218extern int can_drop_memory(void); 202extern int can_drop_memory(void);
219extern void os_flush_stdout(void); 203extern void os_flush_stdout(void);
220 204
221/* tt.c
222 * for tt mode only (will be deleted in future...)
223 */
224extern void forward_ipi(int fd, int pid);
225extern void kill_child_dead(int pid);
226extern int wait_for_stop(int pid, int sig, int cont_type, void *relay);
227extern int protect_memory(unsigned long addr, unsigned long len,
228 int r, int w, int x, int must_succeed);
229extern void forward_pending_sigio(int target);
230extern int start_fork_tramp(void *arg, unsigned long temp_stack,
231 int clone_flags, int (*tramp)(void *));
232
233/* uaccess.c */ 205/* uaccess.c */
234extern unsigned long __do_user_copy(void *to, const void *from, int n, 206extern unsigned long __do_user_copy(void *to, const void *from, int n,
235 void **fault_addr, void **fault_catcher, 207 void **fault_addr, jmp_buf **fault_catcher,
236 void (*op)(void *to, const void *from, 208 void (*op)(void *to, const void *from,
237 int n), int *faulted_out); 209 int n), int *faulted_out);
238 210
@@ -255,6 +227,7 @@ extern int set_umid(char *name);
255extern char *get_umid(void); 227extern char *get_umid(void);
256 228
257/* signal.c */ 229/* signal.c */
230extern void timer_init(void);
258extern void set_sigstack(void *sig_stack, int size); 231extern void set_sigstack(void *sig_stack, int size);
259extern void remove_sigstack(void); 232extern void remove_sigstack(void);
260extern void set_handler(int sig, void (*handler)(int), int flags, ...); 233extern void set_handler(int sig, void (*handler)(int), int flags, ...);
@@ -266,7 +239,6 @@ extern int set_signals(int enable);
266 239
267/* trap.c */ 240/* trap.c */
268extern void os_fill_handlinfo(struct kern_handlers h); 241extern void os_fill_handlinfo(struct kern_handlers h);
269extern void do_longjmp(void *p, int val);
270 242
271/* util.c */ 243/* util.c */
272extern void stack_protections(unsigned long address); 244extern void stack_protections(unsigned long address);
@@ -277,17 +249,12 @@ extern int setjmp_wrapper(void (*proc)(void *, void *), ...);
277extern void os_dump_core(void); 249extern void os_dump_core(void);
278 250
279/* time.c */ 251/* time.c */
280#define BILLION (1000 * 1000 * 1000) 252extern void idle_sleep(unsigned long long nsecs);
281 253extern int set_interval(void);
282extern void switch_timers(int to_real); 254extern int timer_one_shot(int ticks);
283extern void idle_sleep(int secs); 255extern long long disable_timer(void);
284extern int set_interval(int is_virtual);
285#ifdef CONFIG_MODE_TT
286extern void enable_timer(void);
287#endif
288extern void disable_timer(void);
289extern void uml_idle_timer(void); 256extern void uml_idle_timer(void);
290extern unsigned long long os_nsecs(void); 257extern long long os_nsecs(void);
291 258
292/* skas/mem.c */ 259/* skas/mem.c */
293extern long run_syscall_stub(struct mm_id * mm_idp, 260extern long run_syscall_stub(struct mm_id * mm_idp,
@@ -308,7 +275,9 @@ extern int protect(struct mm_id * mm_idp, unsigned long addr,
308extern int is_skas_winch(int pid, int fd, void *data); 275extern int is_skas_winch(int pid, int fd, void *data);
309extern int start_userspace(unsigned long stub_stack); 276extern int start_userspace(unsigned long stub_stack);
310extern int copy_context_skas0(unsigned long stack, int pid); 277extern int copy_context_skas0(unsigned long stack, int pid);
311extern void userspace(union uml_pt_regs *regs); 278extern void save_registers(int pid, struct uml_pt_regs *regs);
279extern void restore_registers(int pid, struct uml_pt_regs *regs);
280extern void userspace(struct uml_pt_regs *regs);
312extern void map_stub_pages(int fd, unsigned long code, 281extern void map_stub_pages(int fd, unsigned long code,
313 unsigned long data, unsigned long stack); 282 unsigned long data, unsigned long stack);
314extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void)); 283extern void new_thread(void *stack, jmp_buf *buf, void (*handler)(void));
diff --git a/arch/um/include/registers.h b/arch/um/include/registers.h
index f845b3629a6d..0e27406a43a4 100644
--- a/arch/um/include/registers.h
+++ b/arch/um/include/registers.h
@@ -9,13 +9,15 @@
9#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
10#include "sysdep/archsetjmp.h" 10#include "sysdep/archsetjmp.h"
11 11
12extern void init_thread_registers(union uml_pt_regs *to); 12extern void init_thread_registers(struct uml_pt_regs *to);
13extern int save_fp_registers(int pid, unsigned long *fp_regs); 13extern int save_fp_registers(int pid, unsigned long *fp_regs);
14extern int restore_fp_registers(int pid, unsigned long *fp_regs); 14extern int restore_fp_registers(int pid, unsigned long *fp_regs);
15extern void save_registers(int pid, union uml_pt_regs *regs); 15extern int save_fpx_registers(int pid, unsigned long *fp_regs);
16extern void restore_registers(int pid, union uml_pt_regs *regs); 16extern int restore_fpx_registers(int pid, unsigned long *fp_regs);
17extern void save_registers(int pid, struct uml_pt_regs *regs);
18extern void restore_registers(int pid, struct uml_pt_regs *regs);
17extern void init_registers(int pid); 19extern void init_registers(int pid);
18extern void get_safe_registers(unsigned long * regs, unsigned long * fp_regs); 20extern void get_safe_registers(unsigned long *regs);
19extern unsigned long get_thread_reg(int reg, jmp_buf *buf); 21extern unsigned long get_thread_reg(int reg, jmp_buf *buf);
20 22
21#endif 23#endif
diff --git a/arch/um/include/skas/mmu-skas.h b/arch/um/include/skas/mmu-skas.h
deleted file mode 100644
index b26986c0c3d2..000000000000
--- a/arch/um/include/skas/mmu-skas.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SKAS_MMU_H
7#define __SKAS_MMU_H
8
9#include "mm_id.h"
10#include "asm/ldt.h"
11
12struct mmu_context_skas {
13 struct mm_id id;
14 unsigned long last_page_table;
15#ifdef CONFIG_3_LEVEL_PGTABLES
16 unsigned long last_pmd;
17#endif
18 uml_ldt_t ldt;
19};
20
21extern void switch_mm_skas(struct mm_id * mm_idp);
22
23#endif
diff --git a/arch/um/include/skas/mode-skas.h b/arch/um/include/skas/mode-skas.h
index 8bc6916bbbb1..e065feb000df 100644
--- a/arch/um/include/skas/mode-skas.h
+++ b/arch/um/include/skas/mode-skas.h
@@ -1,18 +1,11 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{linux.intel,addtoit}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#ifndef __MODE_SKAS_H__ 6#ifndef __MODE_SKAS_H__
7#define __MODE_SKAS_H__ 7#define __MODE_SKAS_H__
8 8
9#include <sysdep/ptrace.h>
10
11extern unsigned long exec_regs[];
12extern unsigned long exec_fp_regs[];
13extern unsigned long exec_fpx_regs[];
14extern int have_fpx_regs;
15
16extern void kill_off_processes_skas(void); 9extern void kill_off_processes_skas(void);
17 10
18#endif 11#endif
diff --git a/arch/um/include/skas/mode_kern_skas.h b/arch/um/include/skas/mode_kern_skas.h
deleted file mode 100644
index 8ee6285dfacc..000000000000
--- a/arch/um/include/skas/mode_kern_skas.h
+++ /dev/null
@@ -1,41 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SKAS_MODE_KERN_H__
7#define __SKAS_MODE_KERN_H__
8
9#include "linux/sched.h"
10#include "asm/page.h"
11#include "asm/ptrace.h"
12
13extern void flush_thread_skas(void);
14extern void switch_to_skas(void *prev, void *next);
15extern void start_thread_skas(struct pt_regs *regs, unsigned long eip,
16 unsigned long esp);
17extern int copy_thread_skas(int nr, unsigned long clone_flags,
18 unsigned long sp, unsigned long stack_top,
19 struct task_struct *p, struct pt_regs *regs);
20extern void release_thread_skas(struct task_struct *task);
21extern void init_idle_skas(void);
22extern void flush_tlb_kernel_range_skas(unsigned long start,
23 unsigned long end);
24extern void flush_tlb_kernel_vm_skas(void);
25extern void __flush_tlb_one_skas(unsigned long addr);
26extern void flush_tlb_range_skas(struct vm_area_struct *vma,
27 unsigned long start, unsigned long end);
28extern void flush_tlb_mm_skas(struct mm_struct *mm);
29extern void force_flush_all_skas(void);
30extern long execute_syscall_skas(void *r);
31extern void before_mem_skas(unsigned long unused);
32extern unsigned long set_task_sizes_skas(unsigned long *task_size_out);
33extern int start_uml_skas(void);
34extern int external_pid_skas(struct task_struct *task);
35extern int thread_pid_skas(struct task_struct *task);
36extern void flush_tlb_page_skas(struct vm_area_struct *vma,
37 unsigned long address);
38
39#define kmem_end_skas (host_task_size - 1024 * 1024)
40
41#endif
diff --git a/arch/um/include/skas/skas.h b/arch/um/include/skas/skas.h
index e88926b16072..b073f8a86bd3 100644
--- a/arch/um/include/skas/skas.h
+++ b/arch/um/include/skas/skas.h
@@ -1,12 +1,11 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#ifndef __SKAS_H 6#ifndef __SKAS_H
7#define __SKAS_H 7#define __SKAS_H
8 8
9#include "mm_id.h"
10#include "sysdep/ptrace.h" 9#include "sysdep/ptrace.h"
11 10
12extern int userspace_pid[]; 11extern int userspace_pid[];
@@ -15,7 +14,7 @@ extern int skas_needs_stub;
15 14
16extern int user_thread(unsigned long stack, int flags); 15extern int user_thread(unsigned long stack, int flags);
17extern void new_thread_handler(void); 16extern void new_thread_handler(void);
18extern void handle_syscall(union uml_pt_regs *regs); 17extern void handle_syscall(struct uml_pt_regs *regs);
19extern int new_mm(unsigned long stack); 18extern int new_mm(unsigned long stack);
20extern void get_skas_faultinfo(int pid, struct faultinfo * fi); 19extern void get_skas_faultinfo(int pid, struct faultinfo * fi);
21extern long execute_syscall_skas(void *r); 20extern long execute_syscall_skas(void *r);
diff --git a/arch/um/include/skas/uaccess-skas.h b/arch/um/include/skas/uaccess-skas.h
deleted file mode 100644
index 224a75f4c025..000000000000
--- a/arch/um/include/skas/uaccess-skas.h
+++ /dev/null
@@ -1,21 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __SKAS_UACCESS_H
7#define __SKAS_UACCESS_H
8
9#include "asm/errno.h"
10
11/* No SKAS-specific checking. */
12#define access_ok_skas(type, addr, size) 0
13
14extern int copy_from_user_skas(void *to, const void __user *from, int n);
15extern int copy_to_user_skas(void __user *to, const void *from, int n);
16extern int strncpy_from_user_skas(char *dst, const char __user *src, int count);
17extern int __clear_user_skas(void __user *mem, int len);
18extern int clear_user_skas(void __user *mem, int len);
19extern int strnlen_user_skas(const void __user *str, int len);
20
21#endif
diff --git a/arch/um/include/sysdep-i386/kernel-offsets.h b/arch/um/include/sysdep-i386/kernel-offsets.h
index 97ec9d894d75..5868526b5eef 100644
--- a/arch/um/include/sysdep-i386/kernel-offsets.h
+++ b/arch/um/include/sysdep-i386/kernel-offsets.h
@@ -17,6 +17,5 @@
17 17
18void foo(void) 18void foo(void)
19{ 19{
20 OFFSET(HOST_TASK_DEBUGREGS, task_struct, thread.arch.debugregs);
21#include <common-offsets.h> 20#include <common-offsets.h>
22} 21}
diff --git a/arch/um/include/sysdep-i386/ptrace.h b/arch/um/include/sysdep-i386/ptrace.h
index 52b398bcafcf..11c08969d134 100644
--- a/arch/um/include/sysdep-i386/ptrace.h
+++ b/arch/um/include/sysdep-i386/ptrace.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -9,17 +9,11 @@
9#include "uml-config.h" 9#include "uml-config.h"
10#include "user_constants.h" 10#include "user_constants.h"
11#include "sysdep/faultinfo.h" 11#include "sysdep/faultinfo.h"
12#include "choose-mode.h"
13 12
14#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long)) 13#define MAX_REG_NR (UM_FRAME_SIZE / sizeof(unsigned long))
15#define MAX_REG_OFFSET (UM_FRAME_SIZE) 14#define MAX_REG_OFFSET (UM_FRAME_SIZE)
16 15
17#ifdef UML_CONFIG_PT_PROXY
18extern void update_debugregs(int seq);
19#else
20static inline void update_debugregs(int seq) {} 16static inline void update_debugregs(int seq) {}
21#endif
22
23 17
24/* syscall emulation path in ptrace */ 18/* syscall emulation path in ptrace */
25 19
@@ -31,12 +25,6 @@ void set_using_sysemu(int value);
31int get_using_sysemu(void); 25int get_using_sysemu(void);
32extern int sysemu_supported; 26extern int sysemu_supported;
33 27
34#ifdef UML_CONFIG_MODE_TT
35#include "sysdep/sc.h"
36#endif
37
38#ifdef UML_CONFIG_MODE_SKAS
39
40#include "skas_ptregs.h" 28#include "skas_ptregs.h"
41 29
42#define REGS_IP(r) ((r)[HOST_IP]) 30#define REGS_IP(r) ((r)[HOST_IP])
@@ -60,70 +48,36 @@ extern int sysemu_supported;
60 48
61#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r)) 49#define REGS_RESTART_SYSCALL(r) IP_RESTART_SYSCALL(REGS_IP(r))
62 50
63#endif
64#ifndef PTRACE_SYSEMU_SINGLESTEP 51#ifndef PTRACE_SYSEMU_SINGLESTEP
65#define PTRACE_SYSEMU_SINGLESTEP 32 52#define PTRACE_SYSEMU_SINGLESTEP 32
66#endif 53#endif
67 54
68union uml_pt_regs { 55struct uml_pt_regs {
69#ifdef UML_CONFIG_MODE_TT 56 unsigned long gp[MAX_REG_NR];
70 struct tt_regs { 57 struct faultinfo faultinfo;
71 long syscall; 58 long syscall;
72 void *sc; 59 int is_user;
73 struct faultinfo faultinfo;
74 } tt;
75#endif
76#ifdef UML_CONFIG_MODE_SKAS
77 struct skas_regs {
78 unsigned long regs[MAX_REG_NR];
79 unsigned long fp[HOST_FP_SIZE];
80 unsigned long xfp[HOST_XFP_SIZE];
81 struct faultinfo faultinfo;
82 long syscall;
83 int is_user;
84 } skas;
85#endif
86}; 60};
87 61
88#define EMPTY_UML_PT_REGS { } 62#define EMPTY_UML_PT_REGS { }
89 63
90extern int mode_tt; 64#define UPT_IP(r) REGS_IP((r)->gp)
91 65#define UPT_SP(r) REGS_SP((r)->gp)
92#define UPT_SC(r) ((r)->tt.sc) 66#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp)
93#define UPT_IP(r) \ 67#define UPT_EAX(r) REGS_EAX((r)->gp)
94 __CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs)) 68#define UPT_EBX(r) REGS_EBX((r)->gp)
95#define UPT_SP(r) \ 69#define UPT_ECX(r) REGS_ECX((r)->gp)
96 __CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs)) 70#define UPT_EDX(r) REGS_EDX((r)->gp)
97#define UPT_EFLAGS(r) \ 71#define UPT_ESI(r) REGS_ESI((r)->gp)
98 __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs)) 72#define UPT_EDI(r) REGS_EDI((r)->gp)
99#define UPT_EAX(r) \ 73#define UPT_EBP(r) REGS_EBP((r)->gp)
100 __CHOOSE_MODE(SC_EAX(UPT_SC(r)), REGS_EAX((r)->skas.regs)) 74#define UPT_ORIG_EAX(r) ((r)->syscall)
101#define UPT_EBX(r) \ 75#define UPT_CS(r) REGS_CS((r)->gp)
102 __CHOOSE_MODE(SC_EBX(UPT_SC(r)), REGS_EBX((r)->skas.regs)) 76#define UPT_SS(r) REGS_SS((r)->gp)
103#define UPT_ECX(r) \ 77#define UPT_DS(r) REGS_DS((r)->gp)
104 __CHOOSE_MODE(SC_ECX(UPT_SC(r)), REGS_ECX((r)->skas.regs)) 78#define UPT_ES(r) REGS_ES((r)->gp)
105#define UPT_EDX(r) \ 79#define UPT_FS(r) REGS_FS((r)->gp)
106 __CHOOSE_MODE(SC_EDX(UPT_SC(r)), REGS_EDX((r)->skas.regs)) 80#define UPT_GS(r) REGS_GS((r)->gp)
107#define UPT_ESI(r) \
108 __CHOOSE_MODE(SC_ESI(UPT_SC(r)), REGS_ESI((r)->skas.regs))
109#define UPT_EDI(r) \
110 __CHOOSE_MODE(SC_EDI(UPT_SC(r)), REGS_EDI((r)->skas.regs))
111#define UPT_EBP(r) \
112 __CHOOSE_MODE(SC_EBP(UPT_SC(r)), REGS_EBP((r)->skas.regs))
113#define UPT_ORIG_EAX(r) \
114 __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
115#define UPT_CS(r) \
116 __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs))
117#define UPT_SS(r) \
118 __CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs))
119#define UPT_DS(r) \
120 __CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs))
121#define UPT_ES(r) \
122 __CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs))
123#define UPT_FS(r) \
124 __CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs))
125#define UPT_GS(r) \
126 __CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs))
127 81
128#define UPT_SYSCALL_ARG1(r) UPT_EBX(r) 82#define UPT_SYSCALL_ARG1(r) UPT_EBX(r)
129#define UPT_SYSCALL_ARG2(r) UPT_ECX(r) 83#define UPT_SYSCALL_ARG2(r) UPT_ECX(r)
@@ -134,20 +88,19 @@ extern int mode_tt;
134 88
135extern int user_context(unsigned long sp); 89extern int user_context(unsigned long sp);
136 90
137#define UPT_IS_USER(r) \ 91#define UPT_IS_USER(r) ((r)->is_user)
138 CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
139 92
140struct syscall_args { 93struct syscall_args {
141 unsigned long args[6]; 94 unsigned long args[6];
142}; 95};
143 96
144#define SYSCALL_ARGS(r) ((struct syscall_args) \ 97#define SYSCALL_ARGS(r) ((struct syscall_args) \
145 { .args = { UPT_SYSCALL_ARG1(r), \ 98 { .args = { UPT_SYSCALL_ARG1(r), \
146 UPT_SYSCALL_ARG2(r), \ 99 UPT_SYSCALL_ARG2(r), \
147 UPT_SYSCALL_ARG3(r), \ 100 UPT_SYSCALL_ARG3(r), \
148 UPT_SYSCALL_ARG4(r), \ 101 UPT_SYSCALL_ARG4(r), \
149 UPT_SYSCALL_ARG5(r), \ 102 UPT_SYSCALL_ARG5(r), \
150 UPT_SYSCALL_ARG6(r) } } ) 103 UPT_SYSCALL_ARG6(r) } } )
151 104
152#define UPT_REG(regs, reg) \ 105#define UPT_REG(regs, reg) \
153 ({ unsigned long val; \ 106 ({ unsigned long val; \
@@ -175,7 +128,6 @@ struct syscall_args {
175 } \ 128 } \
176 val; \ 129 val; \
177 }) 130 })
178
179 131
180#define UPT_SET(regs, reg, val) \ 132#define UPT_SET(regs, reg, val) \
181 do { \ 133 do { \
@@ -204,29 +156,16 @@ struct syscall_args {
204 } while (0) 156 } while (0)
205 157
206#define UPT_SET_SYSCALL_RETURN(r, res) \ 158#define UPT_SET_SYSCALL_RETURN(r, res) \
207 CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \ 159 REGS_SET_SYSCALL_RETURN((r)->regs, (res))
208 REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res)))
209 160
210#define UPT_RESTART_SYSCALL(r) \ 161#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp)
211 CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
212 REGS_RESTART_SYSCALL((r)->skas.regs))
213 162
214#define UPT_ORIG_SYSCALL(r) UPT_EAX(r) 163#define UPT_ORIG_SYSCALL(r) UPT_EAX(r)
215#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r) 164#define UPT_SYSCALL_NR(r) UPT_ORIG_EAX(r)
216#define UPT_SYSCALL_RET(r) UPT_EAX(r) 165#define UPT_SYSCALL_RET(r) UPT_EAX(r)
217 166
218#define UPT_FAULTINFO(r) \ 167#define UPT_FAULTINFO(r) (&(r)->faultinfo)
219 CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo))
220 168
221#endif 169extern void arch_init_registers(int pid);
222 170
223/* 171#endif
224 * Overrides for Emacs so that we follow Linus's tabbing style.
225 * Emacs will notice this stuff at the end of the file and automatically
226 * adjust the settings for this buffer only. This must remain at the end
227 * of the file.
228 * ---------------------------------------------------------------------------
229 * Local variables:
230 * c-file-style: "linux"
231 * End:
232 */
diff --git a/arch/um/include/sysdep-i386/sigcontext.h b/arch/um/include/sysdep-i386/sigcontext.h
index 23fd2644d7ed..67e77122aa45 100644
--- a/arch/um/include/sysdep-i386/sigcontext.h
+++ b/arch/um/include/sysdep-i386/sigcontext.h
@@ -1,19 +1,15 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#ifndef __SYS_SIGCONTEXT_I386_H 6#ifndef __SYS_SIGCONTEXT_I386_H
7#define __SYS_SIGCONTEXT_I386_H 7#define __SYS_SIGCONTEXT_I386_H
8 8
9#include "uml-config.h" 9#include "sysdep/sc.h"
10#include <sysdep/sc.h>
11 10
12#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) 11#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
13 12
14#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc))
15#define SC_SET_SYSCALL_RETURN(sc, result) SC_EAX(sc) = (result)
16
17#define GET_FAULTINFO_FROM_SC(fi,sc) \ 13#define GET_FAULTINFO_FROM_SC(fi,sc) \
18 { \ 14 { \
19 (fi).cr2 = SC_CR2(sc); \ 15 (fi).cr2 = SC_CR2(sc); \
@@ -21,32 +17,10 @@
21 (fi).trap_no = SC_TRAPNO(sc); \ 17 (fi).trap_no = SC_TRAPNO(sc); \
22 } 18 }
23 19
24/* ptrace expects that, at the start of a system call, %eax contains
25 * -ENOSYS, so this makes it so.
26 */
27#define SC_START_SYSCALL(sc) do SC_EAX(sc) = -ENOSYS; while(0)
28
29/* This is Page Fault */ 20/* This is Page Fault */
30#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) 21#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
31 22
32/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */ 23/* SKAS3 has no trap_no on i386, but get_skas_faultinfo() sets it to 0. */
33#ifdef UML_CONFIG_MODE_SKAS
34#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo) 24#define SEGV_MAYBE_FIXABLE(fi) ((fi)->trap_no == 0 && ptrace_faultinfo)
35#else
36#define SEGV_MAYBE_FIXABLE(fi) 0
37#endif
38
39extern unsigned long *sc_sigmask(void *sc_ptr);
40extern int sc_get_fpregs(unsigned long buf, void *sc_ptr);
41 25
42#endif 26#endif
43/*
44 * Overrides for Emacs so that we follow Linus's tabbing style.
45 * Emacs will notice this stuff at the end of the file and automatically
46 * adjust the settings for this buffer only. This must remain at the end
47 * of the file.
48 * ---------------------------------------------------------------------------
49 * Local variables:
50 * c-file-style: "linux"
51 * End:
52 */
diff --git a/arch/um/include/sysdep-i386/stub.h b/arch/um/include/sysdep-i386/stub.h
index 4fffae75ba53..8c097b87fca7 100644
--- a/arch/um/include/sysdep-i386/stub.h
+++ b/arch/um/include/sysdep-i386/stub.h
@@ -9,7 +9,7 @@
9#include <sys/mman.h> 9#include <sys/mman.h>
10#include <asm/ptrace.h> 10#include <asm/ptrace.h>
11#include <asm/unistd.h> 11#include <asm/unistd.h>
12#include <asm/page.h> 12#include "as-layout.h"
13#include "stub-data.h" 13#include "stub-data.h"
14#include "kern_constants.h" 14#include "kern_constants.h"
15#include "uml-config.h" 15#include "uml-config.h"
@@ -19,7 +19,7 @@ extern void stub_clone_handler(void);
19 19
20#define STUB_SYSCALL_RET EAX 20#define STUB_SYSCALL_RET EAX
21#define STUB_MMAP_NR __NR_mmap2 21#define STUB_MMAP_NR __NR_mmap2
22#define MMAP_OFFSET(o) ((o) >> PAGE_SHIFT) 22#define MMAP_OFFSET(o) ((o) >> UM_KERN_PAGE_SHIFT)
23 23
24static inline long stub_syscall0(long syscall) 24static inline long stub_syscall0(long syscall)
25{ 25{
@@ -90,12 +90,12 @@ static inline void remap_stack(int fd, unsigned long offset)
90{ 90{
91 __asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;" 91 __asm__ volatile ("movl %%eax,%%ebp ; movl %0,%%eax ; int $0x80 ;"
92 "movl %7, %%ebx ; movl %%eax, (%%ebx)" 92 "movl %7, %%ebx ; movl %%eax, (%%ebx)"
93 : : "g" (STUB_MMAP_NR), "b" (UML_CONFIG_STUB_DATA), 93 : : "g" (STUB_MMAP_NR), "b" (STUB_DATA),
94 "c" (UM_KERN_PAGE_SIZE), 94 "c" (UM_KERN_PAGE_SIZE),
95 "d" (PROT_READ | PROT_WRITE), 95 "d" (PROT_READ | PROT_WRITE),
96 "S" (MAP_FIXED | MAP_SHARED), "D" (fd), 96 "S" (MAP_FIXED | MAP_SHARED), "D" (fd),
97 "a" (offset), 97 "a" (offset),
98 "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) 98 "i" (&((struct stub_data *) STUB_DATA)->err)
99 : "memory"); 99 : "memory");
100} 100}
101 101
diff --git a/arch/um/include/sysdep-i386/thread.h b/arch/um/include/sysdep-i386/thread.h
deleted file mode 100644
index 243fed44d780..000000000000
--- a/arch/um/include/sysdep-i386/thread.h
+++ /dev/null
@@ -1,11 +0,0 @@
1#ifndef __UM_THREAD_H
2#define __UM_THREAD_H
3
4#include <kern_constants.h>
5
6#define TASK_DEBUGREGS(task) ((unsigned long *) &(((char *) (task))[HOST_TASK_DEBUGREGS]))
7#ifdef UML_CONFIG_MODE_TT
8#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
9#endif
10
11#endif
diff --git a/arch/um/include/sysdep-x86_64/ptrace.h b/arch/um/include/sysdep-x86_64/ptrace.h
index 62403bd99661..9ea44d111f33 100644
--- a/arch/um/include/sysdep-x86_64/ptrace.h
+++ b/arch/um/include/sysdep-x86_64/ptrace.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright 2003 PathScale, Inc. 2 * Copyright 2003 PathScale, Inc.
3 * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * 4 *
4 * Licensed under the GPL 5 * Licensed under the GPL
5 */ 6 */
@@ -14,11 +15,6 @@
14#define MAX_REG_OFFSET (UM_FRAME_SIZE) 15#define MAX_REG_OFFSET (UM_FRAME_SIZE)
15#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long)) 16#define MAX_REG_NR ((MAX_REG_OFFSET) / sizeof(unsigned long))
16 17
17#ifdef UML_CONFIG_MODE_TT
18#include "sysdep/sc.h"
19#endif
20
21#ifdef UML_CONFIG_MODE_SKAS
22#include "skas_ptregs.h" 18#include "skas_ptregs.h"
23 19
24#define REGS_IP(r) ((r)[HOST_IP]) 20#define REGS_IP(r) ((r)[HOST_IP])
@@ -88,78 +84,51 @@
88 84
89#define REGS_ERR(r) ((r)->fault_type) 85#define REGS_ERR(r) ((r)->fault_type)
90 86
91#endif 87struct uml_pt_regs {
92 88 unsigned long gp[MAX_REG_NR];
93#include "choose-mode.h" 89 struct faultinfo faultinfo;
94 90 long syscall;
95/* XXX */ 91 int is_user;
96union uml_pt_regs {
97#ifdef UML_CONFIG_MODE_TT
98 struct tt_regs {
99 long syscall;
100 unsigned long orig_rax;
101 void *sc;
102 struct faultinfo faultinfo;
103 } tt;
104#endif
105#ifdef UML_CONFIG_MODE_SKAS
106 struct skas_regs {
107 unsigned long regs[MAX_REG_NR];
108 unsigned long fp[HOST_FP_SIZE];
109 struct faultinfo faultinfo;
110 long syscall;
111 int is_user;
112 } skas;
113#endif
114}; 92};
115 93
116#define EMPTY_UML_PT_REGS { } 94#define EMPTY_UML_PT_REGS { }
117 95
118/* XXX */ 96#define UPT_RBX(r) REGS_RBX((r)->gp)
119extern int mode_tt; 97#define UPT_RCX(r) REGS_RCX((r)->gp)
120 98#define UPT_RDX(r) REGS_RDX((r)->gp)
121#define UPT_RBX(r) __CHOOSE_MODE(SC_RBX(UPT_SC(r)), REGS_RBX((r)->skas.regs)) 99#define UPT_RSI(r) REGS_RSI((r)->gp)
122#define UPT_RCX(r) __CHOOSE_MODE(SC_RCX(UPT_SC(r)), REGS_RCX((r)->skas.regs)) 100#define UPT_RDI(r) REGS_RDI((r)->gp)
123#define UPT_RDX(r) __CHOOSE_MODE(SC_RDX(UPT_SC(r)), REGS_RDX((r)->skas.regs)) 101#define UPT_RBP(r) REGS_RBP((r)->gp)
124#define UPT_RSI(r) __CHOOSE_MODE(SC_RSI(UPT_SC(r)), REGS_RSI((r)->skas.regs)) 102#define UPT_RAX(r) REGS_RAX((r)->gp)
125#define UPT_RDI(r) __CHOOSE_MODE(SC_RDI(UPT_SC(r)), REGS_RDI((r)->skas.regs)) 103#define UPT_R8(r) REGS_R8((r)->gp)
126#define UPT_RBP(r) __CHOOSE_MODE(SC_RBP(UPT_SC(r)), REGS_RBP((r)->skas.regs)) 104#define UPT_R9(r) REGS_R9((r)->gp)
127#define UPT_RAX(r) __CHOOSE_MODE(SC_RAX(UPT_SC(r)), REGS_RAX((r)->skas.regs)) 105#define UPT_R10(r) REGS_R10((r)->gp)
128#define UPT_R8(r) __CHOOSE_MODE(SC_R8(UPT_SC(r)), REGS_R8((r)->skas.regs)) 106#define UPT_R11(r) REGS_R11((r)->gp)
129#define UPT_R9(r) __CHOOSE_MODE(SC_R9(UPT_SC(r)), REGS_R9((r)->skas.regs)) 107#define UPT_R12(r) REGS_R12((r)->gp)
130#define UPT_R10(r) __CHOOSE_MODE(SC_R10(UPT_SC(r)), REGS_R10((r)->skas.regs)) 108#define UPT_R13(r) REGS_R13((r)->gp)
131#define UPT_R11(r) __CHOOSE_MODE(SC_R11(UPT_SC(r)), REGS_R11((r)->skas.regs)) 109#define UPT_R14(r) REGS_R14((r)->gp)
132#define UPT_R12(r) __CHOOSE_MODE(SC_R12(UPT_SC(r)), REGS_R12((r)->skas.regs)) 110#define UPT_R15(r) REGS_R15((r)->gp)
133#define UPT_R13(r) __CHOOSE_MODE(SC_R13(UPT_SC(r)), REGS_R13((r)->skas.regs)) 111#define UPT_CS(r) REGS_CS((r)->gp)
134#define UPT_R14(r) __CHOOSE_MODE(SC_R14(UPT_SC(r)), REGS_R14((r)->skas.regs)) 112#define UPT_FS_BASE(r) REGS_FS_BASE((r)->gp)
135#define UPT_R15(r) __CHOOSE_MODE(SC_R15(UPT_SC(r)), REGS_R15((r)->skas.regs)) 113#define UPT_FS(r) REGS_FS((r)->gp)
136#define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) 114#define UPT_GS_BASE(r) REGS_GS_BASE((r)->gp)
137#define UPT_FS_BASE(r) \ 115#define UPT_GS(r) REGS_GS((r)->gp)
138 __CHOOSE_MODE(SC_FS_BASE(UPT_SC(r)), REGS_FS_BASE((r)->skas.regs)) 116#define UPT_DS(r) REGS_DS((r)->gp)
139#define UPT_FS(r) __CHOOSE_MODE(SC_FS(UPT_SC(r)), REGS_FS((r)->skas.regs)) 117#define UPT_ES(r) REGS_ES((r)->gp)
140#define UPT_GS_BASE(r) \ 118#define UPT_CS(r) REGS_CS((r)->gp)
141 __CHOOSE_MODE(SC_GS_BASE(UPT_SC(r)), REGS_GS_BASE((r)->skas.regs)) 119#define UPT_SS(r) REGS_SS((r)->gp)
142#define UPT_GS(r) __CHOOSE_MODE(SC_GS(UPT_SC(r)), REGS_GS((r)->skas.regs)) 120#define UPT_ORIG_RAX(r) REGS_ORIG_RAX((r)->gp)
143#define UPT_DS(r) __CHOOSE_MODE(SC_DS(UPT_SC(r)), REGS_DS((r)->skas.regs)) 121
144#define UPT_ES(r) __CHOOSE_MODE(SC_ES(UPT_SC(r)), REGS_ES((r)->skas.regs)) 122#define UPT_IP(r) REGS_IP((r)->gp)
145#define UPT_CS(r) __CHOOSE_MODE(SC_CS(UPT_SC(r)), REGS_CS((r)->skas.regs)) 123#define UPT_SP(r) REGS_SP((r)->gp)
146#define UPT_SS(r) __CHOOSE_MODE(SC_SS(UPT_SC(r)), REGS_SS((r)->skas.regs)) 124
147#define UPT_ORIG_RAX(r) \ 125#define UPT_EFLAGS(r) REGS_EFLAGS((r)->gp)
148 __CHOOSE_MODE((r)->tt.orig_rax, REGS_ORIG_RAX((r)->skas.regs)) 126#define UPT_SYSCALL_NR(r) ((r)->syscall)
149
150#define UPT_IP(r) __CHOOSE_MODE(SC_IP(UPT_SC(r)), REGS_IP((r)->skas.regs))
151#define UPT_SP(r) __CHOOSE_MODE(SC_SP(UPT_SC(r)), REGS_SP((r)->skas.regs))
152
153#define UPT_EFLAGS(r) \
154 __CHOOSE_MODE(SC_EFLAGS(UPT_SC(r)), REGS_EFLAGS((r)->skas.regs))
155#define UPT_SC(r) ((r)->tt.sc)
156#define UPT_SYSCALL_NR(r) __CHOOSE_MODE((r)->tt.syscall, (r)->skas.syscall)
157#define UPT_SYSCALL_RET(r) UPT_RAX(r) 127#define UPT_SYSCALL_RET(r) UPT_RAX(r)
158 128
159extern int user_context(unsigned long sp); 129extern int user_context(unsigned long sp);
160 130
161#define UPT_IS_USER(r) \ 131#define UPT_IS_USER(r) ((r)->is_user)
162 CHOOSE_MODE(user_context(UPT_SP(r)), (r)->skas.is_user)
163 132
164#define UPT_SYSCALL_ARG1(r) UPT_RDI(r) 133#define UPT_SYSCALL_ARG1(r) UPT_RDI(r)
165#define UPT_SYSCALL_ARG2(r) UPT_RSI(r) 134#define UPT_SYSCALL_ARG2(r) UPT_RSI(r)
@@ -173,101 +142,99 @@ struct syscall_args {
173}; 142};
174 143
175#define SYSCALL_ARGS(r) ((struct syscall_args) \ 144#define SYSCALL_ARGS(r) ((struct syscall_args) \
176 { .args = { UPT_SYSCALL_ARG1(r), \ 145 { .args = { UPT_SYSCALL_ARG1(r), \
177 UPT_SYSCALL_ARG2(r), \ 146 UPT_SYSCALL_ARG2(r), \
178 UPT_SYSCALL_ARG3(r), \ 147 UPT_SYSCALL_ARG3(r), \
179 UPT_SYSCALL_ARG4(r), \ 148 UPT_SYSCALL_ARG4(r), \
180 UPT_SYSCALL_ARG5(r), \ 149 UPT_SYSCALL_ARG5(r), \
181 UPT_SYSCALL_ARG6(r) } } ) 150 UPT_SYSCALL_ARG6(r) } } )
182 151
183#define UPT_REG(regs, reg) \ 152#define UPT_REG(regs, reg) \
184 ({ unsigned long val; \ 153 ({ unsigned long val; \
185 switch(reg){ \ 154 switch(reg){ \
186 case R8: val = UPT_R8(regs); break; \ 155 case R8: val = UPT_R8(regs); break; \
187 case R9: val = UPT_R9(regs); break; \ 156 case R9: val = UPT_R9(regs); break; \
188 case R10: val = UPT_R10(regs); break; \ 157 case R10: val = UPT_R10(regs); break; \
189 case R11: val = UPT_R11(regs); break; \ 158 case R11: val = UPT_R11(regs); break; \
190 case R12: val = UPT_R12(regs); break; \ 159 case R12: val = UPT_R12(regs); break; \
191 case R13: val = UPT_R13(regs); break; \ 160 case R13: val = UPT_R13(regs); break; \
192 case R14: val = UPT_R14(regs); break; \ 161 case R14: val = UPT_R14(regs); break; \
193 case R15: val = UPT_R15(regs); break; \ 162 case R15: val = UPT_R15(regs); break; \
194 case RIP: val = UPT_IP(regs); break; \ 163 case RIP: val = UPT_IP(regs); break; \
195 case RSP: val = UPT_SP(regs); break; \ 164 case RSP: val = UPT_SP(regs); break; \
196 case RAX: val = UPT_RAX(regs); break; \ 165 case RAX: val = UPT_RAX(regs); break; \
197 case RBX: val = UPT_RBX(regs); break; \ 166 case RBX: val = UPT_RBX(regs); break; \
198 case RCX: val = UPT_RCX(regs); break; \ 167 case RCX: val = UPT_RCX(regs); break; \
199 case RDX: val = UPT_RDX(regs); break; \ 168 case RDX: val = UPT_RDX(regs); break; \
200 case RSI: val = UPT_RSI(regs); break; \ 169 case RSI: val = UPT_RSI(regs); break; \
201 case RDI: val = UPT_RDI(regs); break; \ 170 case RDI: val = UPT_RDI(regs); break; \
202 case RBP: val = UPT_RBP(regs); break; \ 171 case RBP: val = UPT_RBP(regs); break; \
203 case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \ 172 case ORIG_RAX: val = UPT_ORIG_RAX(regs); break; \
204 case CS: val = UPT_CS(regs); break; \ 173 case CS: val = UPT_CS(regs); break; \
205 case SS: val = UPT_SS(regs); break; \ 174 case SS: val = UPT_SS(regs); break; \
206 case FS_BASE: val = UPT_FS_BASE(regs); break; \ 175 case FS_BASE: val = UPT_FS_BASE(regs); break; \
207 case GS_BASE: val = UPT_GS_BASE(regs); break; \ 176 case GS_BASE: val = UPT_GS_BASE(regs); break; \
208 case DS: val = UPT_DS(regs); break; \ 177 case DS: val = UPT_DS(regs); break; \
209 case ES: val = UPT_ES(regs); break; \ 178 case ES: val = UPT_ES(regs); break; \
210 case FS : val = UPT_FS (regs); break; \ 179 case FS : val = UPT_FS (regs); break; \
211 case GS: val = UPT_GS(regs); break; \ 180 case GS: val = UPT_GS(regs); break; \
212 case EFLAGS: val = UPT_EFLAGS(regs); break; \ 181 case EFLAGS: val = UPT_EFLAGS(regs); break; \
213 default : \ 182 default : \
214 panic("Bad register in UPT_REG : %d\n", reg); \ 183 panic("Bad register in UPT_REG : %d\n", reg); \
215 val = -1; \ 184 val = -1; \
216 } \ 185 } \
217 val; \ 186 val; \
218 }) 187 })
219 188
220 189
221#define UPT_SET(regs, reg, val) \ 190#define UPT_SET(regs, reg, val) \
222 ({ unsigned long __upt_val = val; \ 191 ({ unsigned long __upt_val = val; \
223 switch(reg){ \ 192 switch(reg){ \
224 case R8: UPT_R8(regs) = __upt_val; break; \ 193 case R8: UPT_R8(regs) = __upt_val; break; \
225 case R9: UPT_R9(regs) = __upt_val; break; \ 194 case R9: UPT_R9(regs) = __upt_val; break; \
226 case R10: UPT_R10(regs) = __upt_val; break; \ 195 case R10: UPT_R10(regs) = __upt_val; break; \
227 case R11: UPT_R11(regs) = __upt_val; break; \ 196 case R11: UPT_R11(regs) = __upt_val; break; \
228 case R12: UPT_R12(regs) = __upt_val; break; \ 197 case R12: UPT_R12(regs) = __upt_val; break; \
229 case R13: UPT_R13(regs) = __upt_val; break; \ 198 case R13: UPT_R13(regs) = __upt_val; break; \
230 case R14: UPT_R14(regs) = __upt_val; break; \ 199 case R14: UPT_R14(regs) = __upt_val; break; \
231 case R15: UPT_R15(regs) = __upt_val; break; \ 200 case R15: UPT_R15(regs) = __upt_val; break; \
232 case RIP: UPT_IP(regs) = __upt_val; break; \ 201 case RIP: UPT_IP(regs) = __upt_val; break; \
233 case RSP: UPT_SP(regs) = __upt_val; break; \ 202 case RSP: UPT_SP(regs) = __upt_val; break; \
234 case RAX: UPT_RAX(regs) = __upt_val; break; \ 203 case RAX: UPT_RAX(regs) = __upt_val; break; \
235 case RBX: UPT_RBX(regs) = __upt_val; break; \ 204 case RBX: UPT_RBX(regs) = __upt_val; break; \
236 case RCX: UPT_RCX(regs) = __upt_val; break; \ 205 case RCX: UPT_RCX(regs) = __upt_val; break; \
237 case RDX: UPT_RDX(regs) = __upt_val; break; \ 206 case RDX: UPT_RDX(regs) = __upt_val; break; \
238 case RSI: UPT_RSI(regs) = __upt_val; break; \ 207 case RSI: UPT_RSI(regs) = __upt_val; break; \
239 case RDI: UPT_RDI(regs) = __upt_val; break; \ 208 case RDI: UPT_RDI(regs) = __upt_val; break; \
240 case RBP: UPT_RBP(regs) = __upt_val; break; \ 209 case RBP: UPT_RBP(regs) = __upt_val; break; \
241 case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \ 210 case ORIG_RAX: UPT_ORIG_RAX(regs) = __upt_val; break; \
242 case CS: UPT_CS(regs) = __upt_val; break; \ 211 case CS: UPT_CS(regs) = __upt_val; break; \
243 case SS: UPT_SS(regs) = __upt_val; break; \ 212 case SS: UPT_SS(regs) = __upt_val; break; \
244 case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \ 213 case FS_BASE: UPT_FS_BASE(regs) = __upt_val; break; \
245 case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \ 214 case GS_BASE: UPT_GS_BASE(regs) = __upt_val; break; \
246 case DS: UPT_DS(regs) = __upt_val; break; \ 215 case DS: UPT_DS(regs) = __upt_val; break; \
247 case ES: UPT_ES(regs) = __upt_val; break; \ 216 case ES: UPT_ES(regs) = __upt_val; break; \
248 case FS: UPT_FS(regs) = __upt_val; break; \ 217 case FS: UPT_FS(regs) = __upt_val; break; \
249 case GS: UPT_GS(regs) = __upt_val; break; \ 218 case GS: UPT_GS(regs) = __upt_val; break; \
250 case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \ 219 case EFLAGS: UPT_EFLAGS(regs) = __upt_val; break; \
251 default : \ 220 default : \
252 panic("Bad register in UPT_SET : %d\n", reg); \ 221 panic("Bad register in UPT_SET : %d\n", reg); \
253 break; \ 222 break; \
254 } \ 223 } \
255 __upt_val; \ 224 __upt_val; \
256 }) 225 })
257 226
258#define UPT_SET_SYSCALL_RETURN(r, res) \ 227#define UPT_SET_SYSCALL_RETURN(r, res) \
259 CHOOSE_MODE(SC_SET_SYSCALL_RETURN(UPT_SC(r), (res)), \ 228 REGS_SET_SYSCALL_RETURN((r)->regs, (res))
260 REGS_SET_SYSCALL_RETURN((r)->skas.regs, (res))) 229
230#define UPT_RESTART_SYSCALL(r) REGS_RESTART_SYSCALL((r)->gp)
261 231
262#define UPT_RESTART_SYSCALL(r) \ 232#define UPT_SEGV_IS_FIXABLE(r) REGS_SEGV_IS_FIXABLE(&r->skas)
263 CHOOSE_MODE(SC_RESTART_SYSCALL(UPT_SC(r)), \
264 REGS_RESTART_SYSCALL((r)->skas.regs))
265 233
266#define UPT_SEGV_IS_FIXABLE(r) \ 234#define UPT_FAULTINFO(r) (&(r)->faultinfo)
267 CHOOSE_MODE(SC_SEGV_IS_FIXABLE(UPT_SC(r)), \
268 REGS_SEGV_IS_FIXABLE(&r->skas))
269 235
270#define UPT_FAULTINFO(r) \ 236static inline void arch_init_registers(int pid)
271 CHOOSE_MODE((&(r)->tt.faultinfo), (&(r)->skas.faultinfo)) 237{
238}
272 239
273#endif 240#endif
diff --git a/arch/um/include/sysdep-x86_64/sigcontext.h b/arch/um/include/sysdep-x86_64/sigcontext.h
index 41073235e7ad..0155133b1458 100644
--- a/arch/um/include/sysdep-x86_64/sigcontext.h
+++ b/arch/um/include/sysdep-x86_64/sigcontext.h
@@ -11,43 +11,17 @@
11 11
12#define IP_RESTART_SYSCALL(ip) ((ip) -= 2) 12#define IP_RESTART_SYSCALL(ip) ((ip) -= 2)
13 13
14#define SC_RESTART_SYSCALL(sc) IP_RESTART_SYSCALL(SC_IP(sc)) 14#define GET_FAULTINFO_FROM_SC(fi, sc) \
15#define SC_SET_SYSCALL_RETURN(sc, result) SC_RAX(sc) = (result)
16
17#define SC_FAULT_ADDR(sc) SC_CR2(sc)
18#define SC_FAULT_TYPE(sc) SC_ERR(sc)
19
20#define GET_FAULTINFO_FROM_SC(fi,sc) \
21 { \ 15 { \
22 (fi).cr2 = SC_CR2(sc); \ 16 (fi).cr2 = SC_CR2(sc); \
23 (fi).error_code = SC_ERR(sc); \ 17 (fi).error_code = SC_ERR(sc); \
24 (fi).trap_no = SC_TRAPNO(sc); \ 18 (fi).trap_no = SC_TRAPNO(sc); \
25 } 19 }
26 20
27/* ptrace expects that, at the start of a system call, %eax contains
28 * -ENOSYS, so this makes it so.
29 */
30
31#define SC_START_SYSCALL(sc) do SC_RAX(sc) = -ENOSYS; while(0)
32
33/* This is Page Fault */ 21/* This is Page Fault */
34#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14) 22#define SEGV_IS_FIXABLE(fi) ((fi)->trap_no == 14)
35 23
36/* No broken SKAS API, which doesn't pass trap_no, here. */ 24/* No broken SKAS API, which doesn't pass trap_no, here. */
37#define SEGV_MAYBE_FIXABLE(fi) 0 25#define SEGV_MAYBE_FIXABLE(fi) 0
38 26
39extern unsigned long *sc_sigmask(void *sc_ptr);
40
41#endif 27#endif
42
43/*
44 * Overrides for Emacs so that we follow Linus's tabbing style.
45 * Emacs will notice this stuff at the end of the file and automatically
46 * adjust the settings for this buffer only. This must remain at the end
47 * of the file.
48 * ---------------------------------------------------------------------------
49 * Local variables:
50 * c-file-style: "linux"
51 * End:
52 */
53
diff --git a/arch/um/include/sysdep-x86_64/stub.h b/arch/um/include/sysdep-x86_64/stub.h
index 92e989f81761..655f9c2de3ac 100644
--- a/arch/um/include/sysdep-x86_64/stub.h
+++ b/arch/um/include/sysdep-x86_64/stub.h
@@ -9,6 +9,7 @@
9#include <sys/mman.h> 9#include <sys/mman.h>
10#include <asm/unistd.h> 10#include <asm/unistd.h>
11#include <sysdep/ptrace_user.h> 11#include <sysdep/ptrace_user.h>
12#include "as-layout.h"
12#include "stub-data.h" 13#include "stub-data.h"
13#include "kern_constants.h" 14#include "kern_constants.h"
14#include "uml-config.h" 15#include "uml-config.h"
@@ -94,13 +95,13 @@ static inline void remap_stack(long fd, unsigned long offset)
94{ 95{
95 __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; " 96 __asm__ volatile ("movq %4,%%r10 ; movq %5,%%r8 ; "
96 "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; " 97 "movq %6, %%r9; " __syscall "; movq %7, %%rbx ; "
97 "movq %%rax, (%%rbx)": 98 "movq %%rax, (%%rbx)":
98 : "a" (STUB_MMAP_NR), "D" (UML_CONFIG_STUB_DATA), 99 : "a" (STUB_MMAP_NR), "D" (STUB_DATA),
99 "S" (UM_KERN_PAGE_SIZE), 100 "S" (UM_KERN_PAGE_SIZE),
100 "d" (PROT_READ | PROT_WRITE), 101 "d" (PROT_READ | PROT_WRITE),
101 "g" (MAP_FIXED | MAP_SHARED), "g" (fd), 102 "g" (MAP_FIXED | MAP_SHARED), "g" (fd),
102 "g" (offset), 103 "g" (offset),
103 "i" (&((struct stub_data *) UML_CONFIG_STUB_DATA)->err) 104 "i" (&((struct stub_data *) STUB_DATA)->err)
104 : __syscall_clobber, "r10", "r8", "r9" ); 105 : __syscall_clobber, "r10", "r8", "r9" );
105} 106}
106 107
diff --git a/arch/um/include/sysdep-x86_64/thread.h b/arch/um/include/sysdep-x86_64/thread.h
deleted file mode 100644
index cbef3e1697f4..000000000000
--- a/arch/um/include/sysdep-x86_64/thread.h
+++ /dev/null
@@ -1,10 +0,0 @@
1#ifndef __UM_THREAD_H
2#define __UM_THREAD_H
3
4#include <kern_constants.h>
5
6#ifdef UML_CONFIG_MODE_TT
7#define TASK_EXTERN_PID(task) *((int *) &(((char *) (task))[HOST_TASK_EXTERN_PID]))
8#endif
9
10#endif
diff --git a/arch/um/include/task.h b/arch/um/include/task.h
index 6375ba7203c9..3fe726b3cf48 100644
--- a/arch/um/include/task.h
+++ b/arch/um/include/task.h
@@ -3,7 +3,7 @@
3 3
4#include <kern_constants.h> 4#include <kern_constants.h>
5 5
6#define TASK_REGS(task) ((union uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS])) 6#define TASK_REGS(task) ((struct uml_pt_regs *) &(((char *) (task))[HOST_TASK_REGS]))
7#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID])) 7#define TASK_PID(task) *((int *) &(((char *) (task))[HOST_TASK_PID]))
8 8
9#endif 9#endif
diff --git a/arch/um/include/tlb.h b/arch/um/include/tlb.h
index bcd1a4afb842..ecd2265b301b 100644
--- a/arch/um/include/tlb.h
+++ b/arch/um/include/tlb.h
@@ -8,34 +8,7 @@
8 8
9#include "um_mmu.h" 9#include "um_mmu.h"
10 10
11struct host_vm_op {
12 enum { NONE, MMAP, MUNMAP, MPROTECT } type;
13 union {
14 struct {
15 unsigned long addr;
16 unsigned long len;
17 unsigned int prot;
18 int fd;
19 __u64 offset;
20 } mmap;
21 struct {
22 unsigned long addr;
23 unsigned long len;
24 } munmap;
25 struct {
26 unsigned long addr;
27 unsigned long len;
28 unsigned int prot;
29 } mprotect;
30 } u;
31};
32
33extern void force_flush_all(void); 11extern void force_flush_all(void);
34extern void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
35 unsigned long end_addr, int force,
36 int (*do_ops)(union mm_context *,
37 struct host_vm_op *, int, int,
38 void **));
39extern int flush_tlb_kernel_range_common(unsigned long start, 12extern int flush_tlb_kernel_range_common(unsigned long start,
40 unsigned long end); 13 unsigned long end);
41 14
diff --git a/arch/um/include/tt/debug.h b/arch/um/include/tt/debug.h
deleted file mode 100644
index 9778fa838296..000000000000
--- a/arch/um/include/tt/debug.h
+++ /dev/null
@@ -1,18 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) and
3 * Lars Brinkhoff.
4 * Licensed under the GPL
5 */
6
7#ifndef __UML_TT_DEBUG_H
8#define __UML_TT_DEBUG_H
9
10extern int debugger_proxy(int status, pid_t pid);
11extern void child_proxy(pid_t pid, int status);
12extern void init_proxy (pid_t pid, int waiting, int status);
13extern int start_debugger(char *prog, int startup, int stop, int *debugger_fd);
14extern void fake_child_exit(void);
15extern int gdb_config(char *str);
16extern int gdb_remove(int unused);
17
18#endif
diff --git a/arch/um/include/tt/mmu-tt.h b/arch/um/include/tt/mmu-tt.h
deleted file mode 100644
index 572a78b22587..000000000000
--- a/arch/um/include/tt/mmu-tt.h
+++ /dev/null
@@ -1,12 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TT_MMU_H
7#define __TT_MMU_H
8
9struct mmu_context_tt {
10};
11
12#endif
diff --git a/arch/um/include/tt/mode-tt.h b/arch/um/include/tt/mode-tt.h
deleted file mode 100644
index 2823cd56eea2..000000000000
--- a/arch/um/include/tt/mode-tt.h
+++ /dev/null
@@ -1,23 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MODE_TT_H__
7#define __MODE_TT_H__
8
9#include "sysdep/ptrace.h"
10
11enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
12
13extern int tracing_pid;
14
15extern int tracer(int (*init_proc)(void *), void *sp);
16extern void sig_handler_common_tt(int sig, void *sc);
17extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
18extern void reboot_tt(void);
19extern void halt_tt(void);
20extern int is_tracer_winch(int pid, int fd, void *data);
21extern void kill_off_processes_tt(void);
22
23#endif
diff --git a/arch/um/include/tt/mode_kern_tt.h b/arch/um/include/tt/mode_kern_tt.h
deleted file mode 100644
index a4fc63057195..000000000000
--- a/arch/um/include/tt/mode_kern_tt.h
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TT_MODE_KERN_H__
7#define __TT_MODE_KERN_H__
8
9#include "linux/sched.h"
10#include "asm/page.h"
11#include "asm/ptrace.h"
12#include "asm/uaccess.h"
13
14extern void switch_to_tt(void *prev, void *next);
15extern void flush_thread_tt(void);
16extern void start_thread_tt(struct pt_regs *regs, unsigned long eip,
17 unsigned long esp);
18extern int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
19 unsigned long stack_top, struct task_struct *p,
20 struct pt_regs *regs);
21extern void release_thread_tt(struct task_struct *task);
22extern void initial_thread_cb_tt(void (*proc)(void *), void *arg);
23extern void init_idle_tt(void);
24extern void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end);
25extern void flush_tlb_kernel_vm_tt(void);
26extern void __flush_tlb_one_tt(unsigned long addr);
27extern void flush_tlb_range_tt(struct vm_area_struct *vma,
28 unsigned long start, unsigned long end);
29extern void flush_tlb_mm_tt(struct mm_struct *mm);
30extern void force_flush_all_tt(void);
31extern long execute_syscall_tt(void *r);
32extern void before_mem_tt(unsigned long brk_start);
33extern unsigned long set_task_sizes_tt(unsigned long *task_size_out);
34extern int start_uml_tt(void);
35extern int external_pid_tt(struct task_struct *task);
36extern int thread_pid_tt(struct task_struct *task);
37
38#define kmem_end_tt (host_task_size - ABOVE_KMEM)
39
40#endif
diff --git a/arch/um/include/tt/tt.h b/arch/um/include/tt/tt.h
deleted file mode 100644
index acb8356e1f98..000000000000
--- a/arch/um/include/tt/tt.h
+++ /dev/null
@@ -1,37 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TT_H__
7#define __TT_H__
8
9#include "sysdep/ptrace.h"
10
11extern int gdb_pid;
12extern int debug;
13extern int debug_stop;
14extern int debug_trace;
15
16extern int honeypot;
17
18extern int fork_tramp(void *sig_stack);
19extern int do_proc_op(void *t, int proc_id);
20extern int tracer(int (*init_proc)(void *), void *sp);
21extern void attach_process(int pid);
22extern void tracer_panic(char *format, ...)
23 __attribute__ ((format (printf, 1, 2)));
24extern void set_init_pid(int pid);
25extern int set_user_mode(void *task);
26extern void set_tracing(void *t, int tracing);
27extern int is_tracing(void *task);
28extern void syscall_handler(int sig, union uml_pt_regs *regs);
29extern void exit_kernel(int pid, void *task);
30extern void do_syscall(void *task, int pid, int local_using_sysemu);
31extern void do_sigtrap(void *task);
32extern int is_valid_pid(int pid);
33extern void remap_data(void *segment_start, void *segment_end, int w);
34extern long execute_syscall_tt(void *r);
35
36#endif
37
diff --git a/arch/um/include/tt/uaccess-tt.h b/arch/um/include/tt/uaccess-tt.h
deleted file mode 100644
index 13a64f61fcf4..000000000000
--- a/arch/um/include/tt/uaccess-tt.h
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __TT_UACCESS_H
7#define __TT_UACCESS_H
8
9#include "linux/string.h"
10#include "linux/sched.h"
11#include "asm/processor.h"
12#include "asm/errno.h"
13#include "asm/current.h"
14#include "asm/a.out.h"
15#include "uml_uaccess.h"
16
17#define ABOVE_KMEM (16 * 1024 * 1024)
18
19extern unsigned long end_vm;
20extern unsigned long uml_physmem;
21
22#define is_stack(addr, size) \
23 (((unsigned long) (addr) < STACK_TOP) && \
24 ((unsigned long) (addr) >= STACK_TOP - ABOVE_KMEM) && \
25 (((unsigned long) (addr) + (size)) <= STACK_TOP))
26
27#define access_ok_tt(type, addr, size) \
28 (is_stack(addr, size))
29
30extern int __do_copy_from_user(void *to, const void *from, int n,
31 void **fault_addr, void **fault_catcher);
32extern int __do_strncpy_from_user(char *dst, const char *src, size_t n,
33 void **fault_addr, void **fault_catcher);
34extern int __do_clear_user(void *mem, size_t len, void **fault_addr,
35 void **fault_catcher);
36extern int __do_strnlen_user(const char *str, unsigned long n,
37 void **fault_addr, void **fault_catcher);
38
39extern int copy_from_user_tt(void *to, const void __user *from, int n);
40extern int copy_to_user_tt(void __user *to, const void *from, int n);
41extern int strncpy_from_user_tt(char *dst, const char __user *src, int count);
42extern int __clear_user_tt(void __user *mem, int len);
43extern int clear_user_tt(void __user *mem, int len);
44extern int strnlen_user_tt(const void __user *str, int len);
45
46#endif
diff --git a/arch/um/include/um_mmu.h b/arch/um/include/um_mmu.h
index 0fa643238300..8855d8df512f 100644
--- a/arch/um/include/um_mmu.h
+++ b/arch/um/include/um_mmu.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -7,34 +7,22 @@
7#define __ARCH_UM_MMU_H 7#define __ARCH_UM_MMU_H
8 8
9#include "uml-config.h" 9#include "uml-config.h"
10#include "choose-mode.h" 10#include "mm_id.h"
11#include "asm/ldt.h"
11 12
12#ifdef UML_CONFIG_MODE_TT 13typedef struct mm_context {
13#include "mmu-tt.h" 14 struct mm_id id;
15 unsigned long last_page_table;
16#ifdef CONFIG_3_LEVEL_PGTABLES
17 unsigned long last_pmd;
14#endif 18#endif
19 struct uml_ldt ldt;
20} mm_context_t;
15 21
16#ifdef UML_CONFIG_MODE_SKAS 22extern void __switch_mm(struct mm_id * mm_idp);
17#include "mmu-skas.h"
18#endif
19 23
20typedef union mm_context { 24/* Avoid tangled inclusion with asm/ldt.h */
21#ifdef UML_CONFIG_MODE_TT 25extern long init_new_ldt(struct mm_context *to_mm, struct mm_context *from_mm);
22 struct mmu_context_tt tt; 26extern void free_ldt(struct mm_context *mm);
23#endif
24#ifdef UML_CONFIG_MODE_SKAS
25 struct mmu_context_skas skas;
26#endif
27} mm_context_t;
28 27
29#endif 28#endif
30
31/*
32 * Overrides for Emacs so that we follow Linus's tabbing style.
33 * Emacs will notice this stuff at the end of the file and automatically
34 * adjust the settings for this buffer only. This must remain at the end
35 * of the file.
36 * ---------------------------------------------------------------------------
37 * Local variables:
38 * c-file-style: "linux"
39 * End:
40 */
diff --git a/arch/um/include/um_uaccess.h b/arch/um/include/um_uaccess.h
index 5126a99b5961..fdfc06b85605 100644
--- a/arch/um/include/um_uaccess.h
+++ b/arch/um/include/um_uaccess.h
@@ -1,26 +1,16 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#ifndef __ARCH_UM_UACCESS_H 6#ifndef __ARCH_UM_UACCESS_H
7#define __ARCH_UM_UACCESS_H 7#define __ARCH_UM_UACCESS_H
8 8
9#include "choose-mode.h"
10
11#ifdef CONFIG_MODE_TT
12#include "uaccess-tt.h"
13#endif
14
15#ifdef CONFIG_MODE_SKAS
16#include "uaccess-skas.h"
17#endif
18
19#include "asm/fixmap.h" 9#include "asm/fixmap.h"
20 10
21#define __under_task_size(addr, size) \ 11#define __under_task_size(addr, size) \
22 (((unsigned long) (addr) < TASK_SIZE) && \ 12 (((unsigned long) (addr) < TASK_SIZE) && \
23 (((unsigned long) (addr) + (size)) < TASK_SIZE)) 13 (((unsigned long) (addr) + (size)) < TASK_SIZE))
24 14
25#define __access_ok_vsyscall(type, addr, size) \ 15#define __access_ok_vsyscall(type, addr, size) \
26 ((type == VERIFY_READ) && \ 16 ((type == VERIFY_READ) && \
@@ -35,20 +25,14 @@
35 (__addr_range_nowrap(addr, size) && \ 25 (__addr_range_nowrap(addr, size) && \
36 (__under_task_size(addr, size) || \ 26 (__under_task_size(addr, size) || \
37 __access_ok_vsyscall(type, addr, size) || \ 27 __access_ok_vsyscall(type, addr, size) || \
38 segment_eq(get_fs(), KERNEL_DS) || \ 28 segment_eq(get_fs(), KERNEL_DS)))
39 CHOOSE_MODE_PROC(access_ok_tt, access_ok_skas, type, addr, size)))
40 29
41static inline int copy_from_user(void *to, const void __user *from, int n) 30extern int copy_from_user(void *to, const void __user *from, int n);
42{ 31extern int copy_to_user(void __user *to, const void *from, int n);
43 return(CHOOSE_MODE_PROC(copy_from_user_tt, copy_from_user_skas, to,
44 from, n));
45}
46 32
47static inline int copy_to_user(void __user *to, const void *from, int n) 33extern int __do_copy_to_user(void *to, const void *from, int n,
48{ 34 void **fault_addr, jmp_buf **fault_catcher);
49 return(CHOOSE_MODE_PROC(copy_to_user_tt, copy_to_user_skas, to, 35extern void __do_copy(void *to, const void *from, int n);
50 from, n));
51}
52 36
53/* 37/*
54 * strncpy_from_user: - Copy a NUL terminated string from userspace. 38 * strncpy_from_user: - Copy a NUL terminated string from userspace.
@@ -69,11 +53,7 @@ static inline int copy_to_user(void __user *to, const void *from, int n)
69 * and returns @count. 53 * and returns @count.
70 */ 54 */
71 55
72static inline int strncpy_from_user(char *dst, const char __user *src, int count) 56extern int strncpy_from_user(char *dst, const char __user *src, int count);
73{
74 return(CHOOSE_MODE_PROC(strncpy_from_user_tt, strncpy_from_user_skas,
75 dst, src, count));
76}
77 57
78/* 58/*
79 * __clear_user: - Zero a block of memory in user space, with less checking. 59 * __clear_user: - Zero a block of memory in user space, with less checking.
@@ -86,10 +66,7 @@ static inline int strncpy_from_user(char *dst, const char __user *src, int count
86 * Returns number of bytes that could not be cleared. 66 * Returns number of bytes that could not be cleared.
87 * On success, this will be zero. 67 * On success, this will be zero.
88 */ 68 */
89static inline int __clear_user(void *mem, int len) 69extern int __clear_user(void __user *mem, int len);
90{
91 return(CHOOSE_MODE_PROC(__clear_user_tt, __clear_user_skas, mem, len));
92}
93 70
94/* 71/*
95 * clear_user: - Zero a block of memory in user space. 72 * clear_user: - Zero a block of memory in user space.
@@ -101,10 +78,7 @@ static inline int __clear_user(void *mem, int len)
101 * Returns number of bytes that could not be cleared. 78 * Returns number of bytes that could not be cleared.
102 * On success, this will be zero. 79 * On success, this will be zero.
103 */ 80 */
104static inline int clear_user(void __user *mem, int len) 81extern int clear_user(void __user *mem, int len);
105{
106 return(CHOOSE_MODE_PROC(clear_user_tt, clear_user_skas, mem, len));
107}
108 82
109/* 83/*
110 * strlen_user: - Get the size of a string in user space. 84 * strlen_user: - Get the size of a string in user space.
@@ -117,20 +91,6 @@ static inline int clear_user(void __user *mem, int len)
117 * On exception, returns 0. 91 * On exception, returns 0.
118 * If the string is too long, returns a value greater than @n. 92 * If the string is too long, returns a value greater than @n.
119 */ 93 */
120static inline int strnlen_user(const void __user *str, long len) 94extern int strnlen_user(const void __user *str, int len);
121{
122 return(CHOOSE_MODE_PROC(strnlen_user_tt, strnlen_user_skas, str, len));
123}
124 95
125#endif 96#endif
126
127/*
128 * Overrides for Emacs so that we follow Linus's tabbing style.
129 * Emacs will notice this stuff at the end of the file and automatically
130 * adjust the settings for this buffer only. This must remain at the end
131 * of the file.
132 * ---------------------------------------------------------------------------
133 * Local variables:
134 * c-file-style: "linux"
135 * End:
136 */
diff --git a/arch/um/include/uml_uaccess.h b/arch/um/include/uml_uaccess.h
deleted file mode 100644
index c0df11d06f5e..000000000000
--- a/arch/um/include/uml_uaccess.h
+++ /dev/null
@@ -1,24 +0,0 @@
1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __UML_UACCESS_H__
7#define __UML_UACCESS_H__
8
9extern int __do_copy_to_user(void *to, const void *from, int n,
10 void **fault_addr, void **fault_catcher);
11void __do_copy(void *to, const void *from, int n);
12
13#endif
14
15/*
16 * Overrides for Emacs so that we follow Linus's tabbing style.
17 * Emacs will notice this stuff at the end of the file and automatically
18 * adjust the settings for this buffer only. This must remain at the end
19 * of the file.
20 * ---------------------------------------------------------------------------
21 * Local variables:
22 * c-file-style: "linux"
23 * End:
24 */
diff --git a/arch/um/include/user.h b/arch/um/include/user.h
index d380e6d91a90..99033ff28a78 100644
--- a/arch/um/include/user.h
+++ b/arch/um/include/user.h
@@ -14,10 +14,12 @@
14 */ 14 */
15#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0])) 15#define ARRAY_SIZE(x) (sizeof(x) / sizeof((x)[0]))
16 16
17/* 17/* This is to get size_t */
18 * This will provide the size_t definition in both kernel and userspace builds 18#ifdef __KERNEL__
19 */
20#include <linux/types.h> 19#include <linux/types.h>
20#else
21#include <stddef.h>
22#endif
21 23
22extern void panic(const char *fmt, ...) 24extern void panic(const char *fmt, ...)
23 __attribute__ ((format (printf, 1, 2))); 25 __attribute__ ((format (printf, 1, 2)));
diff --git a/arch/um/kernel/Makefile b/arch/um/kernel/Makefile
index c5cf4a0827b0..499e5e95e609 100644
--- a/arch/um/kernel/Makefile
+++ b/arch/um/kernel/Makefile
@@ -1,5 +1,5 @@
1# 1#
2# Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux,intel}.com)
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
@@ -9,15 +9,12 @@ clean-files :=
9obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \ 9obj-y = config.o exec.o exitcode.o init_task.o irq.o ksyms.o mem.o \
10 physmem.o process.o ptrace.o reboot.o sigio.o \ 10 physmem.o process.o ptrace.o reboot.o sigio.o \
11 signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \ 11 signal.o smp.o syscall.o sysrq.o time.o tlb.o trap.o uaccess.o \
12 um_arch.o umid.o 12 um_arch.o umid.o skas/
13 13
14obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o 14obj-$(CONFIG_BLK_DEV_INITRD) += initrd.o
15obj-$(CONFIG_GPROF) += gprof_syms.o 15obj-$(CONFIG_GPROF) += gprof_syms.o
16obj-$(CONFIG_GCOV) += gmon_syms.o 16obj-$(CONFIG_GCOV) += gmon_syms.o
17 17
18obj-$(CONFIG_MODE_TT) += tt/
19obj-$(CONFIG_MODE_SKAS) += skas/
20
21USER_OBJS := config.o 18USER_OBJS := config.o
22 19
23include arch/um/scripts/Makefile.rules 20include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/dyn.lds.S b/arch/um/kernel/dyn.lds.S
index 41850906116e..3866f4960f04 100644
--- a/arch/um/kernel/dyn.lds.S
+++ b/arch/um/kernel/dyn.lds.S
@@ -10,8 +10,6 @@ SECTIONS
10 PROVIDE (__executable_start = START); 10 PROVIDE (__executable_start = START);
11 . = START + SIZEOF_HEADERS; 11 . = START + SIZEOF_HEADERS;
12 .interp : { *(.interp) } 12 .interp : { *(.interp) }
13 /* Used in arch/um/kernel/mem.c. Any memory between START and __binary_start
14 * is remapped.*/
15 __binary_start = .; 13 __binary_start = .;
16 . = ALIGN(4096); /* Init code and data */ 14 . = ALIGN(4096); /* Init code and data */
17 _text = .; 15 _text = .;
diff --git a/arch/um/kernel/exec.c b/arch/um/kernel/exec.c
index ce6828fd396f..8196450451cd 100644
--- a/arch/um/kernel/exec.c
+++ b/arch/um/kernel/exec.c
@@ -1,35 +1,44 @@
1/* 1/*
2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/slab.h" 6#include "linux/stddef.h"
7#include "linux/fs.h"
7#include "linux/smp_lock.h" 8#include "linux/smp_lock.h"
8#include "linux/ptrace.h" 9#include "linux/ptrace.h"
9#include "linux/fs.h" 10#include "linux/sched.h"
10#include "asm/ptrace.h" 11#include "asm/current.h"
11#include "asm/pgtable.h" 12#include "asm/processor.h"
12#include "asm/tlbflush.h"
13#include "asm/uaccess.h" 13#include "asm/uaccess.h"
14#include "kern_util.h"
15#include "as-layout.h" 14#include "as-layout.h"
16#include "mem_user.h" 15#include "mem_user.h"
17#include "kern.h" 16#include "skas.h"
18#include "irq_user.h"
19#include "tlb.h"
20#include "os.h" 17#include "os.h"
21#include "choose-mode.h"
22#include "mode_kern.h"
23 18
24void flush_thread(void) 19void flush_thread(void)
25{ 20{
21 void *data = NULL;
22 unsigned long end = proc_mm ? task_size : STUB_START;
23 int ret;
24
26 arch_flush_thread(&current->thread.arch); 25 arch_flush_thread(&current->thread.arch);
27 CHOOSE_MODE(flush_thread_tt(), flush_thread_skas()); 26
27 ret = unmap(&current->mm->context.id, 0, end, 1, &data);
28 if (ret) {
29 printk(KERN_ERR "flush_thread - clearing address space failed, "
30 "err = %d\n", ret);
31 force_sig(SIGKILL, current);
32 }
33
34 __switch_mm(&current->mm->context.id);
28} 35}
29 36
30void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp) 37void start_thread(struct pt_regs *regs, unsigned long eip, unsigned long esp)
31{ 38{
32 CHOOSE_MODE_PROC(start_thread_tt, start_thread_skas, regs, eip, esp); 39 set_fs(USER_DS);
40 PT_REGS_IP(regs) = eip;
41 PT_REGS_SP(regs) = esp;
33} 42}
34 43
35#ifdef CONFIG_TTY_LOG 44#ifdef CONFIG_TTY_LOG
@@ -39,7 +48,7 @@ extern void log_exec(char **argv, void *tty);
39static long execve1(char *file, char __user * __user *argv, 48static long execve1(char *file, char __user * __user *argv,
40 char __user *__user *env) 49 char __user *__user *env)
41{ 50{
42 long error; 51 long error;
43#ifdef CONFIG_TTY_LOG 52#ifdef CONFIG_TTY_LOG
44 struct tty_struct *tty; 53 struct tty_struct *tty;
45 54
@@ -49,17 +58,16 @@ static long execve1(char *file, char __user * __user *argv,
49 log_exec(argv, tty); 58 log_exec(argv, tty);
50 mutex_unlock(&tty_mutex); 59 mutex_unlock(&tty_mutex);
51#endif 60#endif
52 error = do_execve(file, argv, env, &current->thread.regs); 61 error = do_execve(file, argv, env, &current->thread.regs);
53 if (error == 0){ 62 if (error == 0) {
54 task_lock(current); 63 task_lock(current);
55 current->ptrace &= ~PT_DTRACE; 64 current->ptrace &= ~PT_DTRACE;
56#ifdef SUBARCH_EXECVE1 65#ifdef SUBARCH_EXECVE1
57 SUBARCH_EXECVE1(&current->thread.regs.regs); 66 SUBARCH_EXECVE1(&current->thread.regs.regs);
58#endif 67#endif
59 task_unlock(current); 68 task_unlock(current);
60 set_cmdline(current_cmd()); 69 }
61 } 70 return error;
62 return(error);
63} 71}
64 72
65long um_execve(char *file, char __user *__user *argv, char __user *__user *env) 73long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
@@ -67,9 +75,9 @@ long um_execve(char *file, char __user *__user *argv, char __user *__user *env)
67 long err; 75 long err;
68 76
69 err = execve1(file, argv, env); 77 err = execve1(file, argv, env);
70 if(!err) 78 if (!err)
71 do_longjmp(current->thread.exec_buf, 1); 79 UML_LONGJMP(current->thread.exec_buf, 1);
72 return(err); 80 return err;
73} 81}
74 82
75long sys_execve(char __user *file, char __user *__user *argv, 83long sys_execve(char __user *file, char __user *__user *argv,
@@ -86,5 +94,5 @@ long sys_execve(char __user *file, char __user *__user *argv,
86 putname(filename); 94 putname(filename);
87 out: 95 out:
88 unlock_kernel(); 96 unlock_kernel();
89 return(error); 97 return error;
90} 98}
diff --git a/arch/um/kernel/init_task.c b/arch/um/kernel/init_task.c
index cba516e6c99a..dcfceca95052 100644
--- a/arch/um/kernel/init_task.c
+++ b/arch/um/kernel/init_task.c
@@ -3,16 +3,12 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/mm.h"
7#include "linux/fs.h"
8#include "linux/module.h"
9#include "linux/sched.h" 6#include "linux/sched.h"
10#include "linux/init_task.h" 7#include "linux/init_task.h"
8#include "linux/fs.h"
9#include "linux/module.h"
11#include "linux/mqueue.h" 10#include "linux/mqueue.h"
12#include "asm/uaccess.h" 11#include "asm/uaccess.h"
13#include "asm/pgtable.h"
14#include "mem_user.h"
15#include "os.h"
16 12
17static struct fs_struct init_fs = INIT_FS; 13static struct fs_struct init_fs = INIT_FS;
18struct mm_struct init_mm = INIT_MM(init_mm); 14struct mm_struct init_mm = INIT_MM(init_mm);
@@ -46,8 +42,3 @@ union thread_union init_thread_union
46union thread_union cpu0_irqstack 42union thread_union cpu0_irqstack
47 __attribute__((__section__(".data.init_irqstack"))) = 43 __attribute__((__section__(".data.init_irqstack"))) =
48 { INIT_THREAD_INFO(init_task) }; 44 { INIT_THREAD_INFO(init_task) };
49
50void unprotect_stack(unsigned long stack)
51{
52 os_protect_memory((void *) stack, THREAD_SIZE, 1, 1, 0);
53}
diff --git a/arch/um/kernel/irq.c b/arch/um/kernel/irq.c
index cf0dd9cf8c43..277fce17b088 100644
--- a/arch/um/kernel/irq.c
+++ b/arch/um/kernel/irq.c
@@ -1,37 +1,19 @@
1/* 1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c: 4 * Derived (i.e. mostly copied) from arch/i386/kernel/irq.c:
5 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar 5 * Copyright (C) 1992, 1998 Linus Torvalds, Ingo Molnar
6 */ 6 */
7 7
8#include "linux/kernel.h" 8#include "linux/cpumask.h"
9#include "linux/module.h" 9#include "linux/hardirq.h"
10#include "linux/smp.h"
11#include "linux/kernel_stat.h"
12#include "linux/interrupt.h" 10#include "linux/interrupt.h"
13#include "linux/random.h" 11#include "linux/kernel_stat.h"
14#include "linux/slab.h" 12#include "linux/module.h"
15#include "linux/file.h"
16#include "linux/proc_fs.h"
17#include "linux/init.h"
18#include "linux/seq_file.h" 13#include "linux/seq_file.h"
19#include "linux/profile.h" 14#include "as-layout.h"
20#include "linux/hardirq.h"
21#include "asm/irq.h"
22#include "asm/hw_irq.h"
23#include "asm/atomic.h"
24#include "asm/signal.h"
25#include "asm/system.h"
26#include "asm/errno.h"
27#include "asm/uaccess.h"
28#include "kern_util.h" 15#include "kern_util.h"
29#include "irq_user.h"
30#include "irq_kern.h"
31#include "os.h" 16#include "os.h"
32#include "sigio.h"
33#include "misc_constants.h"
34#include "as-layout.h"
35 17
36/* 18/*
37 * Generic, controller-independent functions: 19 * Generic, controller-independent functions:
@@ -71,9 +53,8 @@ int show_interrupts(struct seq_file *p, void *v)
71 seq_putc(p, '\n'); 53 seq_putc(p, '\n');
72skip: 54skip:
73 spin_unlock_irqrestore(&irq_desc[i].lock, flags); 55 spin_unlock_irqrestore(&irq_desc[i].lock, flags);
74 } else if (i == NR_IRQS) { 56 } else if (i == NR_IRQS)
75 seq_putc(p, '\n'); 57 seq_putc(p, '\n');
76 }
77 58
78 return 0; 59 return 0;
79} 60}
@@ -91,7 +72,7 @@ static struct irq_fd **last_irq_ptr = &active_fds;
91 72
92extern void free_irqs(void); 73extern void free_irqs(void);
93 74
94void sigio_handler(int sig, union uml_pt_regs *regs) 75void sigio_handler(int sig, struct uml_pt_regs *regs)
95{ 76{
96 struct irq_fd *irq_fd; 77 struct irq_fd *irq_fd;
97 int n; 78 int n;
@@ -102,11 +83,13 @@ void sigio_handler(int sig, union uml_pt_regs *regs)
102 while (1) { 83 while (1) {
103 n = os_waiting_for_events(active_fds); 84 n = os_waiting_for_events(active_fds);
104 if (n <= 0) { 85 if (n <= 0) {
105 if(n == -EINTR) continue; 86 if (n == -EINTR)
87 continue;
106 else break; 88 else break;
107 } 89 }
108 90
109 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { 91 for (irq_fd = active_fds; irq_fd != NULL;
92 irq_fd = irq_fd->next) {
110 if (irq_fd->current_events != 0) { 93 if (irq_fd->current_events != 0) {
111 irq_fd->current_events = 0; 94 irq_fd->current_events = 0;
112 do_IRQ(irq_fd->irq, regs); 95 do_IRQ(irq_fd->irq, regs);
@@ -138,8 +121,7 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
138 121
139 if (type == IRQ_READ) 122 if (type == IRQ_READ)
140 events = UM_POLLIN | UM_POLLPRI; 123 events = UM_POLLIN | UM_POLLPRI;
141 else 124 else events = UM_POLLOUT;
142 events = UM_POLLOUT;
143 *new_fd = ((struct irq_fd) { .next = NULL, 125 *new_fd = ((struct irq_fd) { .next = NULL,
144 .id = dev_id, 126 .id = dev_id,
145 .fd = fd, 127 .fd = fd,
@@ -153,9 +135,10 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
153 spin_lock_irqsave(&irq_lock, flags); 135 spin_lock_irqsave(&irq_lock, flags);
154 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) { 136 for (irq_fd = active_fds; irq_fd != NULL; irq_fd = irq_fd->next) {
155 if ((irq_fd->fd == fd) && (irq_fd->type == type)) { 137 if ((irq_fd->fd == fd) && (irq_fd->type == type)) {
156 printk("Registering fd %d twice\n", fd); 138 printk(KERN_ERR "Registering fd %d twice\n", fd);
157 printk("Irqs : %d, %d\n", irq_fd->irq, irq); 139 printk(KERN_ERR "Irqs : %d, %d\n", irq_fd->irq, irq);
158 printk("Ids : 0x%p, 0x%p\n", irq_fd->id, dev_id); 140 printk(KERN_ERR "Ids : 0x%p, 0x%p\n", irq_fd->id,
141 dev_id);
159 goto out_unlock; 142 goto out_unlock;
160 } 143 }
161 } 144 }
@@ -171,7 +154,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
171 if (n == 0) 154 if (n == 0)
172 break; 155 break;
173 156
174 /* n > 0 157 /*
158 * n > 0
175 * It means we couldn't put new pollfd to current pollfds 159 * It means we couldn't put new pollfd to current pollfds
176 * and tmp_fds is NULL or too small for new pollfds array. 160 * and tmp_fds is NULL or too small for new pollfds array.
177 * Needed size is equal to n as minimum. 161 * Needed size is equal to n as minimum.
@@ -197,7 +181,8 @@ int activate_fd(int irq, int fd, int type, void *dev_id)
197 181
198 spin_unlock_irqrestore(&irq_lock, flags); 182 spin_unlock_irqrestore(&irq_lock, flags);
199 183
200 /* This calls activate_fd, so it has to be outside the critical 184 /*
185 * This calls activate_fd, so it has to be outside the critical
201 * section. 186 * section.
202 */ 187 */
203 maybe_sigio_broken(fd, (type == IRQ_READ)); 188 maybe_sigio_broken(fd, (type == IRQ_READ));
@@ -264,13 +249,14 @@ static struct irq_fd *find_irq_by_fd(int fd, int irqnum, int *index_out)
264 i++; 249 i++;
265 } 250 }
266 if (irq == NULL) { 251 if (irq == NULL) {
267 printk("find_irq_by_fd doesn't have descriptor %d\n", fd); 252 printk(KERN_ERR "find_irq_by_fd doesn't have descriptor %d\n",
253 fd);
268 goto out; 254 goto out;
269 } 255 }
270 fdi = os_get_pollfd(i); 256 fdi = os_get_pollfd(i);
271 if ((fdi != -1) && (fdi != fd)) { 257 if ((fdi != -1) && (fdi != fd)) {
272 printk("find_irq_by_fd - mismatch between active_fds and " 258 printk(KERN_ERR "find_irq_by_fd - mismatch between active_fds "
273 "pollfds, fd %d vs %d, need %d\n", irq->fd, 259 "and pollfds, fd %d vs %d, need %d\n", irq->fd,
274 fdi, fd); 260 fdi, fd);
275 irq = NULL; 261 irq = NULL;
276 goto out; 262 goto out;
@@ -306,7 +292,7 @@ void deactivate_fd(int fd, int irqnum)
306 292
307 spin_lock_irqsave(&irq_lock, flags); 293 spin_lock_irqsave(&irq_lock, flags);
308 irq = find_irq_by_fd(fd, irqnum, &i); 294 irq = find_irq_by_fd(fd, irqnum, &i);
309 if(irq == NULL){ 295 if (irq == NULL) {
310 spin_unlock_irqrestore(&irq_lock, flags); 296 spin_unlock_irqrestore(&irq_lock, flags);
311 return; 297 return;
312 } 298 }
@@ -339,36 +325,12 @@ int deactivate_all_fds(void)
339 return 0; 325 return 0;
340} 326}
341 327
342#ifdef CONFIG_MODE_TT
343void forward_interrupts(int pid)
344{
345 struct irq_fd *irq;
346 unsigned long flags;
347 int err;
348
349 spin_lock_irqsave(&irq_lock, flags);
350 for (irq = active_fds; irq != NULL; irq = irq->next) {
351 err = os_set_owner(irq->fd, pid);
352 if (err < 0) {
353 /* XXX Just remove the irq rather than
354 * print out an infinite stream of these
355 */
356 printk("Failed to forward %d to pid %d, err = %d\n",
357 irq->fd, pid, -err);
358 }
359
360 irq->pid = pid;
361 }
362 spin_unlock_irqrestore(&irq_lock, flags);
363}
364#endif
365
366/* 328/*
367 * do_IRQ handles all normal device IRQ's (the special 329 * do_IRQ handles all normal device IRQ's (the special
368 * SMP cross-CPU interrupts have their own specific 330 * SMP cross-CPU interrupts have their own specific
369 * handlers). 331 * handlers).
370 */ 332 */
371unsigned int do_IRQ(int irq, union uml_pt_regs *regs) 333unsigned int do_IRQ(int irq, struct uml_pt_regs *regs)
372{ 334{
373 struct pt_regs *old_regs = set_irq_regs((struct pt_regs *)regs); 335 struct pt_regs *old_regs = set_irq_regs((struct pt_regs *)regs);
374 irq_enter(); 336 irq_enter();
@@ -396,8 +358,10 @@ int um_request_irq(unsigned int irq, int fd, int type,
396EXPORT_SYMBOL(um_request_irq); 358EXPORT_SYMBOL(um_request_irq);
397EXPORT_SYMBOL(reactivate_fd); 359EXPORT_SYMBOL(reactivate_fd);
398 360
399/* hw_interrupt_type must define (startup || enable) && 361/*
400 * (shutdown || disable) && end */ 362 * hw_interrupt_type must define (startup || enable) &&
363 * (shutdown || disable) && end
364 */
401static void dummy(unsigned int irq) 365static void dummy(unsigned int irq)
402{ 366{
403} 367}
@@ -446,7 +410,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler)
446 410
447 err = os_pipe(fds, 1, 1); 411 err = os_pipe(fds, 1, 1);
448 if (err) { 412 if (err) {
449 printk("init_aio_irq - os_pipe failed, err = %d\n", -err); 413 printk(KERN_ERR "init_aio_irq - os_pipe failed, err = %d\n",
414 -err);
450 goto out; 415 goto out;
451 } 416 }
452 417
@@ -454,7 +419,8 @@ int init_aio_irq(int irq, char *name, irq_handler_t handler)
454 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name, 419 IRQF_DISABLED | IRQF_SAMPLE_RANDOM, name,
455 (void *) (long) fds[0]); 420 (void *) (long) fds[0]);
456 if (err) { 421 if (err) {
457 printk("init_aio_irq - : um_request_irq failed, err = %d\n", 422 printk(KERN_ERR "init_aio_irq - : um_request_irq failed, "
423 "err = %d\n",
458 err); 424 err);
459 goto out_close; 425 goto out_close;
460 } 426 }
@@ -525,8 +491,9 @@ unsigned long to_irq_stack(unsigned long *mask_out)
525 int nested; 491 int nested;
526 492
527 mask = xchg(&pending_mask, *mask_out); 493 mask = xchg(&pending_mask, *mask_out);
528 if(mask != 0){ 494 if (mask != 0) {
529 /* If any interrupts come in at this point, we want to 495 /*
496 * If any interrupts come in at this point, we want to
530 * make sure that their bits aren't lost by our 497 * make sure that their bits aren't lost by our
531 * putting our bit in. So, this loop accumulates bits 498 * putting our bit in. So, this loop accumulates bits
532 * until xchg returns the same value that we put in. 499 * until xchg returns the same value that we put in.
@@ -538,13 +505,13 @@ unsigned long to_irq_stack(unsigned long *mask_out)
538 do { 505 do {
539 old |= mask; 506 old |= mask;
540 mask = xchg(&pending_mask, old); 507 mask = xchg(&pending_mask, old);
541 } while(mask != old); 508 } while (mask != old);
542 return 1; 509 return 1;
543 } 510 }
544 511
545 ti = current_thread_info(); 512 ti = current_thread_info();
546 nested = (ti->real_thread != NULL); 513 nested = (ti->real_thread != NULL);
547 if(!nested){ 514 if (!nested) {
548 struct task_struct *task; 515 struct task_struct *task;
549 struct thread_info *tti; 516 struct thread_info *tti;
550 517
diff --git a/arch/um/kernel/ksyms.c b/arch/um/kernel/ksyms.c
index 7b3e53fb8070..1b388b41d95d 100644
--- a/arch/um/kernel/ksyms.c
+++ b/arch/um/kernel/ksyms.c
@@ -1,22 +1,15 @@
1/* 1/*
2 * Copyright (C) 2001 - 2004 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/module.h" 6#include "linux/module.h"
7#include "linux/string.h" 7#include "linux/syscalls.h"
8#include "linux/smp_lock.h" 8#include "asm/a.out.h"
9#include "linux/spinlock.h"
10#include "linux/highmem.h"
11#include "asm/current.h"
12#include "asm/processor.h"
13#include "asm/unistd.h"
14#include "asm/pgalloc.h"
15#include "asm/pgtable.h"
16#include "asm/page.h"
17#include "asm/tlbflush.h" 9#include "asm/tlbflush.h"
18#include "kern_util.h" 10#include "asm/uaccess.h"
19#include "as-layout.h" 11#include "as-layout.h"
12#include "kern_util.h"
20#include "mem_user.h" 13#include "mem_user.h"
21#include "os.h" 14#include "os.h"
22 15
@@ -34,30 +27,19 @@ EXPORT_SYMBOL(get_kmem_end);
34EXPORT_SYMBOL(high_physmem); 27EXPORT_SYMBOL(high_physmem);
35EXPORT_SYMBOL(empty_zero_page); 28EXPORT_SYMBOL(empty_zero_page);
36EXPORT_SYMBOL(um_virt_to_phys); 29EXPORT_SYMBOL(um_virt_to_phys);
37EXPORT_SYMBOL(mode_tt);
38EXPORT_SYMBOL(handle_page_fault); 30EXPORT_SYMBOL(handle_page_fault);
39EXPORT_SYMBOL(find_iomem); 31EXPORT_SYMBOL(find_iomem);
40 32
41#ifdef CONFIG_MODE_TT 33EXPORT_SYMBOL(strnlen_user);
42EXPORT_SYMBOL(stop); 34EXPORT_SYMBOL(strncpy_from_user);
43EXPORT_SYMBOL(strncpy_from_user_tt); 35EXPORT_SYMBOL(copy_to_user);
44EXPORT_SYMBOL(copy_from_user_tt); 36EXPORT_SYMBOL(copy_from_user);
45EXPORT_SYMBOL(copy_to_user_tt); 37EXPORT_SYMBOL(clear_user);
46#endif
47
48#ifdef CONFIG_MODE_SKAS
49EXPORT_SYMBOL(strnlen_user_skas);
50EXPORT_SYMBOL(strncpy_from_user_skas);
51EXPORT_SYMBOL(copy_to_user_skas);
52EXPORT_SYMBOL(copy_from_user_skas);
53EXPORT_SYMBOL(clear_user_skas);
54#endif
55EXPORT_SYMBOL(uml_strdup); 38EXPORT_SYMBOL(uml_strdup);
56 39
57EXPORT_SYMBOL(os_stat_fd); 40EXPORT_SYMBOL(os_stat_fd);
58EXPORT_SYMBOL(os_stat_file); 41EXPORT_SYMBOL(os_stat_file);
59EXPORT_SYMBOL(os_access); 42EXPORT_SYMBOL(os_access);
60EXPORT_SYMBOL(os_print_error);
61EXPORT_SYMBOL(os_get_exec_close); 43EXPORT_SYMBOL(os_get_exec_close);
62EXPORT_SYMBOL(os_set_exec_close); 44EXPORT_SYMBOL(os_set_exec_close);
63EXPORT_SYMBOL(os_getpid); 45EXPORT_SYMBOL(os_getpid);
@@ -85,9 +67,6 @@ EXPORT_SYMBOL(run_helper);
85EXPORT_SYMBOL(start_thread); 67EXPORT_SYMBOL(start_thread);
86EXPORT_SYMBOL(dump_thread); 68EXPORT_SYMBOL(dump_thread);
87 69
88EXPORT_SYMBOL(do_gettimeofday);
89EXPORT_SYMBOL(do_settimeofday);
90
91#ifdef CONFIG_SMP 70#ifdef CONFIG_SMP
92 71
93/* required for SMP */ 72/* required for SMP */
diff --git a/arch/um/kernel/mem.c b/arch/um/kernel/mem.c
index d2b11f242698..8456397f5f4d 100644
--- a/arch/um/kernel/mem.c
+++ b/arch/um/kernel/mem.c
@@ -17,7 +17,7 @@
17#include "as-layout.h" 17#include "as-layout.h"
18#include "kern.h" 18#include "kern.h"
19#include "mem_user.h" 19#include "mem_user.h"
20#include "uml_uaccess.h" 20#include "um_uaccess.h"
21#include "os.h" 21#include "os.h"
22#include "linux/types.h" 22#include "linux/types.h"
23#include "linux/string.h" 23#include "linux/string.h"
diff --git a/arch/um/kernel/physmem.c b/arch/um/kernel/physmem.c
index 5ee7e851bbc1..e66432f42485 100644
--- a/arch/um/kernel/physmem.c
+++ b/arch/um/kernel/physmem.c
@@ -1,25 +1,17 @@
1/* 1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/mm.h"
7#include "linux/rbtree.h"
8#include "linux/slab.h"
9#include "linux/vmalloc.h"
10#include "linux/bootmem.h" 6#include "linux/bootmem.h"
11#include "linux/module.h" 7#include "linux/mm.h"
12#include "linux/pfn.h" 8#include "linux/pfn.h"
13#include "asm/types.h" 9#include "asm/page.h"
14#include "asm/pgtable.h"
15#include "kern_util.h"
16#include "as-layout.h" 10#include "as-layout.h"
17#include "mode_kern.h" 11#include "init.h"
18#include "mem.h" 12#include "kern.h"
19#include "mem_user.h" 13#include "mem_user.h"
20#include "os.h" 14#include "os.h"
21#include "kern.h"
22#include "init.h"
23 15
24static int physmem_fd = -1; 16static int physmem_fd = -1;
25 17
@@ -49,10 +41,10 @@ int __init init_maps(unsigned long physmem, unsigned long iomem,
49 total_len = phys_len + iomem_len + highmem_len; 41 total_len = phys_len + iomem_len + highmem_len;
50 42
51 map = alloc_bootmem_low_pages(total_len); 43 map = alloc_bootmem_low_pages(total_len);
52 if(map == NULL) 44 if (map == NULL)
53 return -ENOMEM; 45 return -ENOMEM;
54 46
55 for(i = 0; i < total_pages; i++){ 47 for (i = 0; i < total_pages; i++) {
56 p = &map[i]; 48 p = &map[i];
57 memset(p, 0, sizeof(struct page)); 49 memset(p, 0, sizeof(struct page));
58 SetPageReserved(p); 50 SetPageReserved(p);
@@ -68,8 +60,8 @@ static unsigned long kmem_top = 0;
68 60
69unsigned long get_kmem_end(void) 61unsigned long get_kmem_end(void)
70{ 62{
71 if(kmem_top == 0) 63 if (kmem_top == 0)
72 kmem_top = CHOOSE_MODE(kmem_end_tt, kmem_end_skas); 64 kmem_top = host_task_size - 1024 * 1024;
73 return kmem_top; 65 return kmem_top;
74} 66}
75 67
@@ -81,9 +73,9 @@ void map_memory(unsigned long virt, unsigned long phys, unsigned long len,
81 73
82 fd = phys_mapping(phys, &offset); 74 fd = phys_mapping(phys, &offset);
83 err = os_map_memory((void *) virt, fd, offset, len, r, w, x); 75 err = os_map_memory((void *) virt, fd, offset, len, r, w, x);
84 if(err) { 76 if (err) {
85 if(err == -ENOMEM) 77 if (err == -ENOMEM)
86 printk("try increasing the host's " 78 printk(KERN_ERR "try increasing the host's "
87 "/proc/sys/vm/max_map_count to <physical " 79 "/proc/sys/vm/max_map_count to <physical "
88 "memory size>/4096\n"); 80 "memory size>/4096\n");
89 panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, " 81 panic("map_memory(0x%lx, %d, 0x%llx, %ld, %d, %d, %d) failed, "
@@ -105,13 +97,16 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
105 97
106 offset = uml_reserved - uml_physmem; 98 offset = uml_reserved - uml_physmem;
107 err = os_map_memory((void *) uml_reserved, physmem_fd, offset, 99 err = os_map_memory((void *) uml_reserved, physmem_fd, offset,
108 len - offset, 1, 1, 0); 100 len - offset, 1, 1, 1);
109 if(err < 0){ 101 if (err < 0) {
110 os_print_error(err, "Mapping memory"); 102 printf("setup_physmem - mapping %ld bytes of memory at 0x%p "
103 "failed - errno = %d\n", len - offset,
104 (void *) uml_reserved, err);
111 exit(1); 105 exit(1);
112 } 106 }
113 107
114 /* Special kludge - This page will be mapped in to userspace processes 108 /*
109 * Special kludge - This page will be mapped in to userspace processes
115 * from physmem_fd, so it needs to be written out there. 110 * from physmem_fd, so it needs to be written out there.
116 */ 111 */
117 os_seek_file(physmem_fd, __pa(&__syscall_stub_start)); 112 os_seek_file(physmem_fd, __pa(&__syscall_stub_start));
@@ -122,20 +117,20 @@ void __init setup_physmem(unsigned long start, unsigned long reserve_end,
122 len - bootmap_size - reserve); 117 len - bootmap_size - reserve);
123} 118}
124 119
125int phys_mapping(unsigned long phys, __u64 *offset_out) 120int phys_mapping(unsigned long phys, unsigned long long *offset_out)
126{ 121{
127 int fd = -1; 122 int fd = -1;
128 123
129 if(phys < physmem_size){ 124 if (phys < physmem_size) {
130 fd = physmem_fd; 125 fd = physmem_fd;
131 *offset_out = phys; 126 *offset_out = phys;
132 } 127 }
133 else if(phys < __pa(end_iomem)){ 128 else if (phys < __pa(end_iomem)) {
134 struct iomem_region *region = iomem_regions; 129 struct iomem_region *region = iomem_regions;
135 130
136 while(region != NULL){ 131 while (region != NULL) {
137 if((phys >= region->phys) && 132 if ((phys >= region->phys) &&
138 (phys < region->phys + region->size)){ 133 (phys < region->phys + region->size)) {
139 fd = region->fd; 134 fd = region->fd;
140 *offset_out = phys - region->phys; 135 *offset_out = phys - region->phys;
141 break; 136 break;
@@ -143,7 +138,7 @@ int phys_mapping(unsigned long phys, __u64 *offset_out)
143 region = region->next; 138 region = region->next;
144 } 139 }
145 } 140 }
146 else if(phys < __pa(end_iomem) + highmem){ 141 else if (phys < __pa(end_iomem) + highmem) {
147 fd = physmem_fd; 142 fd = physmem_fd;
148 *offset_out = phys - iomem_size; 143 *offset_out = phys - iomem_size;
149 } 144 }
@@ -188,8 +183,8 @@ unsigned long find_iomem(char *driver, unsigned long *len_out)
188{ 183{
189 struct iomem_region *region = iomem_regions; 184 struct iomem_region *region = iomem_regions;
190 185
191 while(region != NULL){ 186 while (region != NULL) {
192 if(!strcmp(region->driver, driver)){ 187 if (!strcmp(region->driver, driver)) {
193 *len_out = region->size; 188 *len_out = region->size;
194 return region->virt; 189 return region->virt;
195 } 190 }
@@ -206,12 +201,12 @@ int setup_iomem(void)
206 unsigned long iomem_start = high_physmem + PAGE_SIZE; 201 unsigned long iomem_start = high_physmem + PAGE_SIZE;
207 int err; 202 int err;
208 203
209 while(region != NULL){ 204 while (region != NULL) {
210 err = os_map_memory((void *) iomem_start, region->fd, 0, 205 err = os_map_memory((void *) iomem_start, region->fd, 0,
211 region->size, 1, 1, 0); 206 region->size, 1, 1, 0);
212 if(err) 207 if (err)
213 printk("Mapping iomem region for driver '%s' failed, " 208 printk(KERN_ERR "Mapping iomem region for driver '%s' "
214 "errno = %d\n", region->driver, -err); 209 "failed, errno = %d\n", region->driver, -err);
215 else { 210 else {
216 region->virt = iomem_start; 211 region->virt = iomem_start;
217 region->phys = __pa(region->virt); 212 region->phys = __pa(region->virt);
diff --git a/arch/um/kernel/process.c b/arch/um/kernel/process.c
index bfa52f206bb6..0eae00b3e588 100644
--- a/arch/um/kernel/process.c
+++ b/arch/um/kernel/process.c
@@ -1,53 +1,30 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Copyright 2003 PathScale, Inc. 3 * Copyright 2003 PathScale, Inc.
4 * Licensed under the GPL 4 * Licensed under the GPL
5 */ 5 */
6 6
7#include "linux/kernel.h" 7#include "linux/stddef.h"
8#include "linux/sched.h" 8#include "linux/err.h"
9#include "linux/interrupt.h" 9#include "linux/hardirq.h"
10#include "linux/string.h"
11#include "linux/mm.h" 10#include "linux/mm.h"
12#include "linux/slab.h" 11#include "linux/personality.h"
13#include "linux/utsname.h"
14#include "linux/fs.h"
15#include "linux/utime.h"
16#include "linux/smp_lock.h"
17#include "linux/module.h"
18#include "linux/init.h"
19#include "linux/capability.h"
20#include "linux/vmalloc.h"
21#include "linux/spinlock.h"
22#include "linux/proc_fs.h" 12#include "linux/proc_fs.h"
23#include "linux/ptrace.h" 13#include "linux/ptrace.h"
24#include "linux/random.h" 14#include "linux/random.h"
25#include "linux/personality.h" 15#include "linux/sched.h"
26#include "asm/unistd.h" 16#include "linux/tick.h"
27#include "asm/mman.h" 17#include "linux/threads.h"
28#include "asm/segment.h"
29#include "asm/stat.h"
30#include "asm/pgtable.h" 18#include "asm/pgtable.h"
31#include "asm/processor.h"
32#include "asm/tlbflush.h"
33#include "asm/uaccess.h" 19#include "asm/uaccess.h"
34#include "asm/user.h"
35#include "kern_util.h"
36#include "as-layout.h" 20#include "as-layout.h"
37#include "kern.h" 21#include "kern_util.h"
38#include "signal_kern.h"
39#include "init.h"
40#include "irq_user.h"
41#include "mem_user.h"
42#include "tlb.h"
43#include "frame_kern.h"
44#include "sigcontext.h"
45#include "os.h" 22#include "os.h"
46#include "mode.h" 23#include "skas.h"
47#include "mode_kern.h" 24#include "tlb.h"
48#include "choose-mode.h"
49 25
50/* This is a per-cpu array. A processor only modifies its entry and it only 26/*
27 * This is a per-cpu array. A processor only modifies its entry and it only
51 * cares about its entry, so it's OK if another processor is modifying its 28 * cares about its entry, so it's OK if another processor is modifying its
52 * entry. 29 * entry.
53 */ 30 */
@@ -55,15 +32,16 @@ struct cpu_task cpu_tasks[NR_CPUS] = { [0 ... NR_CPUS - 1] = { -1, NULL } };
55 32
56static inline int external_pid(struct task_struct *task) 33static inline int external_pid(struct task_struct *task)
57{ 34{
58 return CHOOSE_MODE_PROC(external_pid_tt, external_pid_skas, task); 35 /* FIXME: Need to look up userspace_pid by cpu */
36 return userspace_pid[0];
59} 37}
60 38
61int pid_to_processor_id(int pid) 39int pid_to_processor_id(int pid)
62{ 40{
63 int i; 41 int i;
64 42
65 for(i = 0; i < ncpus; i++){ 43 for(i = 0; i < ncpus; i++) {
66 if(cpu_tasks[i].pid == pid) 44 if (cpu_tasks[i].pid == pid)
67 return i; 45 return i;
68 } 46 }
69 return -1; 47 return -1;
@@ -82,9 +60,9 @@ unsigned long alloc_stack(int order, int atomic)
82 if (atomic) 60 if (atomic)
83 flags = GFP_ATOMIC; 61 flags = GFP_ATOMIC;
84 page = __get_free_pages(flags, order); 62 page = __get_free_pages(flags, order);
85 if(page == 0) 63 if (page == 0)
86 return 0; 64 return 0;
87 stack_protections(page); 65
88 return page; 66 return page;
89} 67}
90 68
@@ -105,6 +83,8 @@ static inline void set_current(struct task_struct *task)
105 { external_pid(task), task }); 83 { external_pid(task), task });
106} 84}
107 85
86extern void arch_switch_to(struct task_struct *from, struct task_struct *to);
87
108void *_switch_to(void *prev, void *next, void *last) 88void *_switch_to(void *prev, void *next, void *last)
109{ 89{
110 struct task_struct *from = prev; 90 struct task_struct *from = prev;
@@ -114,9 +94,14 @@ void *_switch_to(void *prev, void *next, void *last)
114 set_current(to); 94 set_current(to);
115 95
116 do { 96 do {
117 current->thread.saved_task = NULL ; 97 current->thread.saved_task = NULL;
118 CHOOSE_MODE_PROC(switch_to_tt, switch_to_skas, prev, next); 98
119 if(current->thread.saved_task) 99 switch_threads(&from->thread.switch_buf,
100 &to->thread.switch_buf);
101
102 arch_switch_to(current->thread.prev_sched, current);
103
104 if (current->thread.saved_task)
120 show_regs(&(current->thread.regs)); 105 show_regs(&(current->thread.regs));
121 next= current->thread.saved_task; 106 next= current->thread.saved_task;
122 prev= current; 107 prev= current;
@@ -128,20 +113,14 @@ void *_switch_to(void *prev, void *next, void *last)
128 113
129void interrupt_end(void) 114void interrupt_end(void)
130{ 115{
131 if(need_resched()) 116 if (need_resched())
132 schedule(); 117 schedule();
133 if(test_tsk_thread_flag(current, TIF_SIGPENDING)) 118 if (test_tsk_thread_flag(current, TIF_SIGPENDING))
134 do_signal(); 119 do_signal();
135} 120}
136 121
137void release_thread(struct task_struct *task)
138{
139 CHOOSE_MODE(release_thread_tt(task), release_thread_skas(task));
140}
141
142void exit_thread(void) 122void exit_thread(void)
143{ 123{
144 unprotect_stack((unsigned long) current_thread);
145} 124}
146 125
147void *get_current(void) 126void *get_current(void)
@@ -149,28 +128,99 @@ void *get_current(void)
149 return current; 128 return current;
150} 129}
151 130
131extern void schedule_tail(struct task_struct *prev);
132
133/*
134 * This is called magically, by its address being stuffed in a jmp_buf
135 * and being longjmp-d to.
136 */
137void new_thread_handler(void)
138{
139 int (*fn)(void *), n;
140 void *arg;
141
142 if (current->thread.prev_sched != NULL)
143 schedule_tail(current->thread.prev_sched);
144 current->thread.prev_sched = NULL;
145
146 fn = current->thread.request.u.thread.proc;
147 arg = current->thread.request.u.thread.arg;
148
149 /*
150 * The return value is 1 if the kernel thread execs a process,
151 * 0 if it just exits
152 */
153 n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
154 if (n == 1) {
155 /* Handle any immediate reschedules or signals */
156 interrupt_end();
157 userspace(&current->thread.regs.regs);
158 }
159 else do_exit(0);
160}
161
162/* Called magically, see new_thread_handler above */
163void fork_handler(void)
164{
165 force_flush_all();
166 if (current->thread.prev_sched == NULL)
167 panic("blech");
168
169 schedule_tail(current->thread.prev_sched);
170
171 /*
172 * XXX: if interrupt_end() calls schedule, this call to
173 * arch_switch_to isn't needed. We could want to apply this to
174 * improve performance. -bb
175 */
176 arch_switch_to(current->thread.prev_sched, current);
177
178 current->thread.prev_sched = NULL;
179
180 /* Handle any immediate reschedules or signals */
181 interrupt_end();
182
183 userspace(&current->thread.regs.regs);
184}
185
152int copy_thread(int nr, unsigned long clone_flags, unsigned long sp, 186int copy_thread(int nr, unsigned long clone_flags, unsigned long sp,
153 unsigned long stack_top, struct task_struct * p, 187 unsigned long stack_top, struct task_struct * p,
154 struct pt_regs *regs) 188 struct pt_regs *regs)
155{ 189{
156 int ret; 190 void (*handler)(void);
191 int ret = 0;
157 192
158 p->thread = (struct thread_struct) INIT_THREAD; 193 p->thread = (struct thread_struct) INIT_THREAD;
159 ret = CHOOSE_MODE_PROC(copy_thread_tt, copy_thread_skas, nr,
160 clone_flags, sp, stack_top, p, regs);
161 194
162 if (ret || !current->thread.forking) 195 if (current->thread.forking) {
163 goto out; 196 memcpy(&p->thread.regs.regs, &regs->regs,
197 sizeof(p->thread.regs.regs));
198 REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.gp, 0);
199 if (sp != 0)
200 REGS_SP(p->thread.regs.regs.gp) = sp;
164 201
165 clear_flushed_tls(p); 202 handler = fork_handler;
166 203
167 /* 204 arch_copy_thread(&current->thread.arch, &p->thread.arch);
168 * Set a new TLS for the child thread? 205 }
169 */ 206 else {
170 if (clone_flags & CLONE_SETTLS) 207 init_thread_registers(&p->thread.regs.regs);
171 ret = arch_copy_tls(p); 208 p->thread.request.u.thread = current->thread.request.u.thread;
209 handler = new_thread_handler;
210 }
211
212 new_thread(task_stack_page(p), &p->thread.switch_buf, handler);
213
214 if (current->thread.forking) {
215 clear_flushed_tls(p);
216
217 /*
218 * Set a new TLS for the child thread?
219 */
220 if (clone_flags & CLONE_SETTLS)
221 ret = arch_copy_tls(p);
222 }
172 223
173out:
174 return ret; 224 return ret;
175} 225}
176 226
@@ -179,39 +229,35 @@ void initial_thread_cb(void (*proc)(void *), void *arg)
179 int save_kmalloc_ok = kmalloc_ok; 229 int save_kmalloc_ok = kmalloc_ok;
180 230
181 kmalloc_ok = 0; 231 kmalloc_ok = 0;
182 CHOOSE_MODE_PROC(initial_thread_cb_tt, initial_thread_cb_skas, proc, 232 initial_thread_cb_skas(proc, arg);
183 arg);
184 kmalloc_ok = save_kmalloc_ok; 233 kmalloc_ok = save_kmalloc_ok;
185} 234}
186 235
187#ifdef CONFIG_MODE_TT
188unsigned long stack_sp(unsigned long page)
189{
190 return page + PAGE_SIZE - sizeof(void *);
191}
192#endif
193
194void default_idle(void) 236void default_idle(void)
195{ 237{
196 CHOOSE_MODE(uml_idle_timer(), (void) 0); 238 unsigned long long nsecs;
197 239
198 while(1){ 240 while(1) {
199 /* endless idle loop with no priority at all */ 241 /* endless idle loop with no priority at all */
200 242
201 /* 243 /*
202 * although we are an idle CPU, we do not want to 244 * although we are an idle CPU, we do not want to
203 * get into the scheduler unnecessarily. 245 * get into the scheduler unnecessarily.
204 */ 246 */
205 if(need_resched()) 247 if (need_resched())
206 schedule(); 248 schedule();
207 249
208 idle_sleep(10); 250 tick_nohz_stop_sched_tick();
251 nsecs = disable_timer();
252 idle_sleep(nsecs);
253 tick_nohz_restart_sched_tick();
209 } 254 }
210} 255}
211 256
212void cpu_idle(void) 257void cpu_idle(void)
213{ 258{
214 CHOOSE_MODE(init_idle_tt(), init_idle_skas()); 259 cpu_tasks[current_thread->cpu].pid = os_getpid();
260 default_idle();
215} 261}
216 262
217void *um_virt_to_phys(struct task_struct *task, unsigned long addr, 263void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
@@ -223,26 +269,26 @@ void *um_virt_to_phys(struct task_struct *task, unsigned long addr,
223 pte_t *pte; 269 pte_t *pte;
224 pte_t ptent; 270 pte_t ptent;
225 271
226 if(task->mm == NULL) 272 if (task->mm == NULL)
227 return ERR_PTR(-EINVAL); 273 return ERR_PTR(-EINVAL);
228 pgd = pgd_offset(task->mm, addr); 274 pgd = pgd_offset(task->mm, addr);
229 if(!pgd_present(*pgd)) 275 if (!pgd_present(*pgd))
230 return ERR_PTR(-EINVAL); 276 return ERR_PTR(-EINVAL);
231 277
232 pud = pud_offset(pgd, addr); 278 pud = pud_offset(pgd, addr);
233 if(!pud_present(*pud)) 279 if (!pud_present(*pud))
234 return ERR_PTR(-EINVAL); 280 return ERR_PTR(-EINVAL);
235 281
236 pmd = pmd_offset(pud, addr); 282 pmd = pmd_offset(pud, addr);
237 if(!pmd_present(*pmd)) 283 if (!pmd_present(*pmd))
238 return ERR_PTR(-EINVAL); 284 return ERR_PTR(-EINVAL);
239 285
240 pte = pte_offset_kernel(pmd, addr); 286 pte = pte_offset_kernel(pmd, addr);
241 ptent = *pte; 287 ptent = *pte;
242 if(!pte_present(ptent)) 288 if (!pte_present(ptent))
243 return ERR_PTR(-EINVAL); 289 return ERR_PTR(-EINVAL);
244 290
245 if(pte_out != NULL) 291 if (pte_out != NULL)
246 *pte_out = ptent; 292 *pte_out = ptent;
247 return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK); 293 return (void *) (pte_val(ptent) & PAGE_MASK) + (addr & ~PAGE_MASK);
248} 294}
@@ -315,7 +361,7 @@ int smp_sigio_handler(void)
315#ifdef CONFIG_SMP 361#ifdef CONFIG_SMP
316 int cpu = current_thread->cpu; 362 int cpu = current_thread->cpu;
317 IPI_handler(cpu); 363 IPI_handler(cpu);
318 if(cpu != 0) 364 if (cpu != 0)
319 return 1; 365 return 1;
320#endif 366#endif
321 return 0; 367 return 0;
@@ -343,7 +389,8 @@ int get_using_sysemu(void)
343 389
344static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data) 390static int proc_read_sysemu(char *buf, char **start, off_t offset, int size,int *eof, void *data)
345{ 391{
346 if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size) /*No overflow*/ 392 if (snprintf(buf, size, "%d\n", get_using_sysemu()) < size)
393 /* No overflow */
347 *eof = 1; 394 *eof = 1;
348 395
349 return strlen(buf); 396 return strlen(buf);
@@ -358,7 +405,8 @@ static int proc_write_sysemu(struct file *file,const char __user *buf, unsigned
358 405
359 if (tmp[0] >= '0' && tmp[0] <= '2') 406 if (tmp[0] >= '0' && tmp[0] <= '2')
360 set_using_sysemu(tmp[0] - '0'); 407 set_using_sysemu(tmp[0] - '0');
361 return count; /*We use the first char, but pretend to write everything*/ 408 /* We use the first char, but pretend to write everything */
409 return count;
362} 410}
363 411
364int __init make_proc_sysemu(void) 412int __init make_proc_sysemu(void)
@@ -388,10 +436,10 @@ int singlestepping(void * t)
388 struct task_struct *task = t ? t : current; 436 struct task_struct *task = t ? t : current;
389 437
390 if ( ! (task->ptrace & PT_DTRACE) ) 438 if ( ! (task->ptrace & PT_DTRACE) )
391 return(0); 439 return 0;
392 440
393 if (task->thread.singlestep_syscall) 441 if (task->thread.singlestep_syscall)
394 return(1); 442 return 1;
395 443
396 return 2; 444 return 2;
397} 445}
diff --git a/arch/um/kernel/ptrace.c b/arch/um/kernel/ptrace.c
index 6916c8888dba..a0eba0833068 100644
--- a/arch/um/kernel/ptrace.c
+++ b/arch/um/kernel/ptrace.c
@@ -1,35 +1,27 @@
1/* 1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/sched.h"
7#include "linux/mm.h"
8#include "linux/errno.h"
9#include "linux/smp_lock.h"
10#include "linux/security.h"
11#include "linux/ptrace.h"
12#include "linux/audit.h" 6#include "linux/audit.h"
7#include "linux/ptrace.h"
8#include "linux/sched.h"
9#include "asm/uaccess.h"
13#ifdef CONFIG_PROC_MM 10#ifdef CONFIG_PROC_MM
14#include "linux/proc_mm.h" 11#include "proc_mm.h"
15#endif 12#endif
16#include "asm/ptrace.h"
17#include "asm/uaccess.h"
18#include "kern_util.h"
19#include "skas_ptrace.h" 13#include "skas_ptrace.h"
20#include "sysdep/ptrace.h"
21#include "os.h"
22 14
23static inline void set_singlestepping(struct task_struct *child, int on) 15static inline void set_singlestepping(struct task_struct *child, int on)
24{ 16{
25 if (on) 17 if (on)
26 child->ptrace |= PT_DTRACE; 18 child->ptrace |= PT_DTRACE;
27 else 19 else
28 child->ptrace &= ~PT_DTRACE; 20 child->ptrace &= ~PT_DTRACE;
29 child->thread.singlestep_syscall = 0; 21 child->thread.singlestep_syscall = 0;
30 22
31#ifdef SUBARCH_SET_SINGLESTEPPING 23#ifdef SUBARCH_SET_SINGLESTEPPING
32 SUBARCH_SET_SINGLESTEPPING(child, on); 24 SUBARCH_SET_SINGLESTEPPING(child, on);
33#endif 25#endif
34} 26}
35 27
@@ -37,8 +29,8 @@ static inline void set_singlestepping(struct task_struct *child, int on)
37 * Called by kernel/ptrace.c when detaching.. 29 * Called by kernel/ptrace.c when detaching..
38 */ 30 */
39void ptrace_disable(struct task_struct *child) 31void ptrace_disable(struct task_struct *child)
40{ 32{
41 set_singlestepping(child,0); 33 set_singlestepping(child,0);
42} 34}
43 35
44extern int peek_user(struct task_struct * child, long addr, long data); 36extern int peek_user(struct task_struct * child, long addr, long data);
@@ -50,40 +42,40 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
50 unsigned long __user *p = (void __user *)(unsigned long)data; 42 unsigned long __user *p = (void __user *)(unsigned long)data;
51 43
52 switch (request) { 44 switch (request) {
53 /* when I and D space are separate, these will need to be fixed. */ 45 /* read word at location addr. */
54 case PTRACE_PEEKTEXT: /* read word at location addr. */ 46 case PTRACE_PEEKTEXT:
55 case PTRACE_PEEKDATA: 47 case PTRACE_PEEKDATA:
56 ret = generic_ptrace_peekdata(child, addr, data); 48 ret = generic_ptrace_peekdata(child, addr, data);
57 break; 49 break;
58 50
59 /* read the word at location addr in the USER area. */ 51 /* read the word at location addr in the USER area. */
60 case PTRACE_PEEKUSR: 52 case PTRACE_PEEKUSR:
61 ret = peek_user(child, addr, data); 53 ret = peek_user(child, addr, data);
62 break; 54 break;
63 55
64 /* when I and D space are separate, this will have to be fixed. */ 56 /* write the word at location addr. */
65 case PTRACE_POKETEXT: /* write the word at location addr. */ 57 case PTRACE_POKETEXT:
66 case PTRACE_POKEDATA: 58 case PTRACE_POKEDATA:
67 ret = generic_ptrace_pokedata(child, addr, data); 59 ret = generic_ptrace_pokedata(child, addr, data);
68 break; 60 break;
69 61
70 case PTRACE_POKEUSR: /* write the word at location addr in the USER area */ 62 /* write the word at location addr in the USER area */
71 ret = poke_user(child, addr, data); 63 case PTRACE_POKEUSR:
72 break; 64 ret = poke_user(child, addr, data);
65 break;
73 66
74 case PTRACE_SYSCALL: /* continue and stop at next (return from) syscall */ 67 /* continue and stop at next (return from) syscall */
75 case PTRACE_CONT: { /* restart after signal. */ 68 case PTRACE_SYSCALL:
69 /* restart after signal. */
70 case PTRACE_CONT: {
76 ret = -EIO; 71 ret = -EIO;
77 if (!valid_signal(data)) 72 if (!valid_signal(data))
78 break; 73 break;
79 74
80 set_singlestepping(child, 0); 75 set_singlestepping(child, 0);
81 if (request == PTRACE_SYSCALL) { 76 if (request == PTRACE_SYSCALL)
82 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 77 set_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
83 } 78 else clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
84 else {
85 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
86 }
87 child->exit_code = data; 79 child->exit_code = data;
88 wake_up_process(child); 80 wake_up_process(child);
89 ret = 0; 81 ret = 0;
@@ -91,8 +83,8 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
91 } 83 }
92 84
93/* 85/*
94 * make the child exit. Best I can do is send it a sigkill. 86 * make the child exit. Best I can do is send it a sigkill.
95 * perhaps it should be put in the status that it wants to 87 * perhaps it should be put in the status that it wants to
96 * exit. 88 * exit.
97 */ 89 */
98 case PTRACE_KILL: { 90 case PTRACE_KILL: {
@@ -100,7 +92,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
100 if (child->exit_state == EXIT_ZOMBIE) /* already dead */ 92 if (child->exit_state == EXIT_ZOMBIE) /* already dead */
101 break; 93 break;
102 94
103 set_singlestepping(child, 0); 95 set_singlestepping(child, 0);
104 child->exit_code = SIGKILL; 96 child->exit_code = SIGKILL;
105 wake_up_process(child); 97 wake_up_process(child);
106 break; 98 break;
@@ -111,7 +103,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
111 if (!valid_signal(data)) 103 if (!valid_signal(data))
112 break; 104 break;
113 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE); 105 clear_tsk_thread_flag(child, TIF_SYSCALL_TRACE);
114 set_singlestepping(child, 1); 106 set_singlestepping(child, 1);
115 child->exit_code = data; 107 child->exit_code = data;
116 /* give it a chance to run. */ 108 /* give it a chance to run. */
117 wake_up_process(child); 109 wake_up_process(child);
@@ -119,11 +111,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
119 break; 111 break;
120 } 112 }
121 113
122 case PTRACE_DETACH:
123 /* detach a process that was attached. */
124 ret = ptrace_detach(child, data);
125 break;
126
127#ifdef PTRACE_GETREGS 114#ifdef PTRACE_GETREGS
128 case PTRACE_GETREGS: { /* Get all gp regs from the child. */ 115 case PTRACE_GETREGS: { /* Get all gp regs from the child. */
129 if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) { 116 if (!access_ok(VERIFY_WRITE, p, MAX_REG_OFFSET)) {
@@ -156,22 +143,14 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
156#endif 143#endif
157#ifdef PTRACE_GETFPREGS 144#ifdef PTRACE_GETFPREGS
158 case PTRACE_GETFPREGS: /* Get the child FPU state. */ 145 case PTRACE_GETFPREGS: /* Get the child FPU state. */
159 ret = get_fpregs(data, child); 146 ret = get_fpregs((struct user_i387_struct __user *) data,
147 child);
160 break; 148 break;
161#endif 149#endif
162#ifdef PTRACE_SETFPREGS 150#ifdef PTRACE_SETFPREGS
163 case PTRACE_SETFPREGS: /* Set the child FPU state. */ 151 case PTRACE_SETFPREGS: /* Set the child FPU state. */
164 ret = set_fpregs(data, child); 152 ret = set_fpregs((struct user_i387_struct __user *) data,
165 break; 153 child);
166#endif
167#ifdef PTRACE_GETFPXREGS
168 case PTRACE_GETFPXREGS: /* Get the child FPU state. */
169 ret = get_fpxregs(data, child);
170 break;
171#endif
172#ifdef PTRACE_SETFPXREGS
173 case PTRACE_SETFPXREGS: /* Set the child FPU state. */
174 ret = set_fpxregs(data, child);
175 break; 154 break;
176#endif 155#endif
177 case PTRACE_GET_THREAD_AREA: 156 case PTRACE_GET_THREAD_AREA:
@@ -185,14 +164,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
185 break; 164 break;
186 165
187 case PTRACE_FAULTINFO: { 166 case PTRACE_FAULTINFO: {
188 /* Take the info from thread->arch->faultinfo, 167 /*
168 * Take the info from thread->arch->faultinfo,
189 * but transfer max. sizeof(struct ptrace_faultinfo). 169 * but transfer max. sizeof(struct ptrace_faultinfo).
190 * On i386, ptrace_faultinfo is smaller! 170 * On i386, ptrace_faultinfo is smaller!
191 */ 171 */
192 ret = copy_to_user(p, &child->thread.arch.faultinfo, 172 ret = copy_to_user(p, &child->thread.arch.faultinfo,
193 sizeof(struct ptrace_faultinfo)); 173 sizeof(struct ptrace_faultinfo));
194 if(ret)
195 break;
196 break; 174 break;
197 } 175 }
198 176
@@ -200,12 +178,13 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
200 case PTRACE_LDT: { 178 case PTRACE_LDT: {
201 struct ptrace_ldt ldt; 179 struct ptrace_ldt ldt;
202 180
203 if(copy_from_user(&ldt, p, sizeof(ldt))){ 181 if (copy_from_user(&ldt, p, sizeof(ldt))) {
204 ret = -EIO; 182 ret = -EIO;
205 break; 183 break;
206 } 184 }
207 185
208 /* This one is confusing, so just punt and return -EIO for 186 /*
187 * This one is confusing, so just punt and return -EIO for
209 * now 188 * now
210 */ 189 */
211 ret = -EIO; 190 ret = -EIO;
@@ -217,7 +196,7 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
217 struct mm_struct *old = child->mm; 196 struct mm_struct *old = child->mm;
218 struct mm_struct *new = proc_mm_get_mm(data); 197 struct mm_struct *new = proc_mm_get_mm(data);
219 198
220 if(IS_ERR(new)){ 199 if (IS_ERR(new)) {
221 ret = PTR_ERR(new); 200 ret = PTR_ERR(new);
222 break; 201 break;
223 } 202 }
@@ -231,20 +210,22 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
231 } 210 }
232#endif 211#endif
233#ifdef PTRACE_ARCH_PRCTL 212#ifdef PTRACE_ARCH_PRCTL
234 case PTRACE_ARCH_PRCTL: 213 case PTRACE_ARCH_PRCTL:
235 /* XXX Calls ptrace on the host - needs some SMP thinking */ 214 /* XXX Calls ptrace on the host - needs some SMP thinking */
236 ret = arch_prctl_skas(child, data, (void *) addr); 215 ret = arch_prctl(child, data, (void *) addr);
237 break; 216 break;
238#endif 217#endif
239 default: 218 default:
240 ret = ptrace_request(child, request, addr, data); 219 ret = ptrace_request(child, request, addr, data);
220 if (ret == -EIO)
221 ret = subarch_ptrace(child, request, addr, data);
241 break; 222 break;
242 } 223 }
243 224
244 return ret; 225 return ret;
245} 226}
246 227
247void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs, 228void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
248 int error_code) 229 int error_code)
249{ 230{
250 struct siginfo info; 231 struct siginfo info;
@@ -260,10 +241,11 @@ void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs,
260 force_sig_info(SIGTRAP, &info, tsk); 241 force_sig_info(SIGTRAP, &info, tsk);
261} 242}
262 243
263/* XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and 244/*
245 * XXX Check PT_DTRACE vs TIF_SINGLESTEP for singlestepping check and
264 * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check 246 * PT_PTRACED vs TIF_SYSCALL_TRACE for syscall tracing check
265 */ 247 */
266void syscall_trace(union uml_pt_regs *regs, int entryexit) 248void syscall_trace(struct uml_pt_regs *regs, int entryexit)
267{ 249{
268 int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit; 250 int is_singlestep = (current->ptrace & PT_DTRACE) && entryexit;
269 int tracesysgood; 251 int tracesysgood;
@@ -277,7 +259,7 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
277 UPT_SYSCALL_ARG3(regs), 259 UPT_SYSCALL_ARG3(regs),
278 UPT_SYSCALL_ARG4(regs)); 260 UPT_SYSCALL_ARG4(regs));
279 else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)), 261 else audit_syscall_exit(AUDITSC_RESULT(UPT_SYSCALL_RET(regs)),
280 UPT_SYSCALL_RET(regs)); 262 UPT_SYSCALL_RET(regs));
281 } 263 }
282 264
283 /* Fake a debug trap */ 265 /* Fake a debug trap */
@@ -290,15 +272,18 @@ void syscall_trace(union uml_pt_regs *regs, int entryexit)
290 if (!(current->ptrace & PT_PTRACED)) 272 if (!(current->ptrace & PT_PTRACED))
291 return; 273 return;
292 274
293 /* the 0x80 provides a way for the tracing parent to distinguish 275 /*
294 between a syscall stop and SIGTRAP delivery */ 276 * the 0x80 provides a way for the tracing parent to distinguish
277 * between a syscall stop and SIGTRAP delivery
278 */
295 tracesysgood = (current->ptrace & PT_TRACESYSGOOD); 279 tracesysgood = (current->ptrace & PT_TRACESYSGOOD);
296 ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0)); 280 ptrace_notify(SIGTRAP | (tracesysgood ? 0x80 : 0));
297 281
298 if (entryexit) /* force do_signal() --> is_syscall() */ 282 if (entryexit) /* force do_signal() --> is_syscall() */
299 set_thread_flag(TIF_SIGPENDING); 283 set_thread_flag(TIF_SIGPENDING);
300 284
301 /* this isn't the same as continuing with a signal, but it will do 285 /*
286 * this isn't the same as continuing with a signal, but it will do
302 * for normal use. strace only continues with a signal if the 287 * for normal use. strace only continues with a signal if the
303 * stopping signal is not SIGTRAP. -brl 288 * stopping signal is not SIGTRAP. -brl
304 */ 289 */
diff --git a/arch/um/kernel/reboot.c b/arch/um/kernel/reboot.c
index 7e4305a1fd3c..04cebcf0679f 100644
--- a/arch/um/kernel/reboot.c
+++ b/arch/um/kernel/reboot.c
@@ -1,60 +1,53 @@
1/* 1/*
2 * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/module.h"
7#include "linux/sched.h" 6#include "linux/sched.h"
8#include "asm/smp.h"
9#include "kern_util.h"
10#include "kern.h"
11#include "os.h" 7#include "os.h"
12#include "mode.h" 8#include "skas.h"
13#include "choose-mode.h"
14 9
15void (*pm_power_off)(void); 10void (*pm_power_off)(void);
16 11
17#ifdef CONFIG_SMP
18static void kill_idlers(int me)
19{
20#ifdef CONFIG_MODE_TT
21 struct task_struct *p;
22 int i;
23
24 for(i = 0; i < ARRAY_SIZE(idle_threads); i++){
25 p = idle_threads[i];
26 if((p != NULL) && (p->thread.mode.tt.extern_pid != me))
27 os_kill_process(p->thread.mode.tt.extern_pid, 0);
28 }
29#endif
30}
31#endif
32
33static void kill_off_processes(void) 12static void kill_off_processes(void)
34{ 13{
35 CHOOSE_MODE(kill_off_processes_tt(), kill_off_processes_skas()); 14 if(proc_mm)
36#ifdef CONFIG_SMP 15 /*
37 kill_idlers(os_getpid()); 16 * FIXME: need to loop over userspace_pids
38#endif 17 */
18 os_kill_ptraced_process(userspace_pid[0], 1);
19 else {
20 struct task_struct *p;
21 int pid, me;
22
23 me = os_getpid();
24 for_each_process(p){
25 if(p->mm == NULL)
26 continue;
27
28 pid = p->mm->context.id.u.pid;
29 os_kill_ptraced_process(pid, 1);
30 }
31 }
39} 32}
40 33
41void uml_cleanup(void) 34void uml_cleanup(void)
42{ 35{
43 kmalloc_ok = 0; 36 kmalloc_ok = 0;
44 do_uml_exitcalls(); 37 do_uml_exitcalls();
45 kill_off_processes(); 38 kill_off_processes();
46} 39}
47 40
48void machine_restart(char * __unused) 41void machine_restart(char * __unused)
49{ 42{
50 uml_cleanup(); 43 uml_cleanup();
51 CHOOSE_MODE(reboot_tt(), reboot_skas()); 44 reboot_skas();
52} 45}
53 46
54void machine_power_off(void) 47void machine_power_off(void)
55{ 48{
56 uml_cleanup(); 49 uml_cleanup();
57 CHOOSE_MODE(halt_tt(), halt_skas()); 50 halt_skas();
58} 51}
59 52
60void machine_halt(void) 53void machine_halt(void)
diff --git a/arch/um/kernel/signal.c b/arch/um/kernel/signal.c
index c4020c3d7857..19cb97733937 100644
--- a/arch/um/kernel/signal.c
+++ b/arch/um/kernel/signal.c
@@ -1,29 +1,17 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/stddef.h"
7#include "linux/sys.h"
8#include "linux/sched.h"
9#include "linux/wait.h"
10#include "linux/kernel.h"
11#include "linux/smp_lock.h"
12#include "linux/module.h" 6#include "linux/module.h"
13#include "linux/slab.h"
14#include "linux/tty.h"
15#include "linux/binfmts.h"
16#include "linux/ptrace.h" 7#include "linux/ptrace.h"
8#include "linux/sched.h"
9#include "asm/siginfo.h"
17#include "asm/signal.h" 10#include "asm/signal.h"
18#include "asm/uaccess.h"
19#include "asm/unistd.h" 11#include "asm/unistd.h"
20#include "asm/ucontext.h"
21#include "kern_util.h"
22#include "signal_kern.h"
23#include "kern.h"
24#include "frame_kern.h" 12#include "frame_kern.h"
13#include "kern_util.h"
25#include "sigcontext.h" 14#include "sigcontext.h"
26#include "mode.h"
27 15
28EXPORT_SYMBOL(block_signals); 16EXPORT_SYMBOL(block_signals);
29EXPORT_SYMBOL(unblock_signals); 17EXPORT_SYMBOL(unblock_signals);
@@ -46,9 +34,9 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
46 current_thread_info()->restart_block.fn = do_no_restart_syscall; 34 current_thread_info()->restart_block.fn = do_no_restart_syscall;
47 35
48 /* Did we come from a system call? */ 36 /* Did we come from a system call? */
49 if(PT_REGS_SYSCALL_NR(regs) >= 0){ 37 if (PT_REGS_SYSCALL_NR(regs) >= 0) {
50 /* If so, check system call restarting.. */ 38 /* If so, check system call restarting.. */
51 switch(PT_REGS_SYSCALL_RET(regs)){ 39 switch(PT_REGS_SYSCALL_RET(regs)) {
52 case -ERESTART_RESTARTBLOCK: 40 case -ERESTART_RESTARTBLOCK:
53 case -ERESTARTNOHAND: 41 case -ERESTARTNOHAND:
54 PT_REGS_SYSCALL_RET(regs) = -EINTR; 42 PT_REGS_SYSCALL_RET(regs) = -EINTR;
@@ -68,17 +56,17 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
68 } 56 }
69 57
70 sp = PT_REGS_SP(regs); 58 sp = PT_REGS_SP(regs);
71 if((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0)) 59 if ((ka->sa.sa_flags & SA_ONSTACK) && (sas_ss_flags(sp) == 0))
72 sp = current->sas_ss_sp + current->sas_ss_size; 60 sp = current->sas_ss_sp + current->sas_ss_size;
73 61
74#ifdef CONFIG_ARCH_HAS_SC_SIGNALS 62#ifdef CONFIG_ARCH_HAS_SC_SIGNALS
75 if(!(ka->sa.sa_flags & SA_SIGINFO)) 63 if (!(ka->sa.sa_flags & SA_SIGINFO))
76 err = setup_signal_stack_sc(sp, signr, ka, regs, oldset); 64 err = setup_signal_stack_sc(sp, signr, ka, regs, oldset);
77 else 65 else
78#endif 66#endif
79 err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset); 67 err = setup_signal_stack_si(sp, signr, ka, regs, info, oldset);
80 68
81 if(err){ 69 if (err) {
82 spin_lock_irq(&current->sighand->siglock); 70 spin_lock_irq(&current->sighand->siglock);
83 current->blocked = *oldset; 71 current->blocked = *oldset;
84 recalc_sigpending(); 72 recalc_sigpending();
@@ -88,7 +76,7 @@ static int handle_signal(struct pt_regs *regs, unsigned long signr,
88 spin_lock_irq(&current->sighand->siglock); 76 spin_lock_irq(&current->sighand->siglock);
89 sigorsets(&current->blocked, &current->blocked, 77 sigorsets(&current->blocked, &current->blocked,
90 &ka->sa.sa_mask); 78 &ka->sa.sa_mask);
91 if(!(ka->sa.sa_flags & SA_NODEFER)) 79 if (!(ka->sa.sa_flags & SA_NODEFER))
92 sigaddset(&current->blocked, signr); 80 sigaddset(&current->blocked, signr);
93 recalc_sigpending(); 81 recalc_sigpending();
94 spin_unlock_irq(&current->sighand->siglock); 82 spin_unlock_irq(&current->sighand->siglock);
@@ -109,14 +97,16 @@ static int kern_do_signal(struct pt_regs *regs)
109 else 97 else
110 oldset = &current->blocked; 98 oldset = &current->blocked;
111 99
112 while((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0){ 100 while ((sig = get_signal_to_deliver(&info, &ka_copy, regs, NULL)) > 0) {
113 handled_sig = 1; 101 handled_sig = 1;
114 /* Whee! Actually deliver the signal. */ 102 /* Whee! Actually deliver the signal. */
115 if(!handle_signal(regs, sig, &ka_copy, &info, oldset)){ 103 if (!handle_signal(regs, sig, &ka_copy, &info, oldset)) {
116 /* a signal was successfully delivered; the saved 104 /*
105 * a signal was successfully delivered; the saved
117 * sigmask will have been stored in the signal frame, 106 * sigmask will have been stored in the signal frame,
118 * and will be restored by sigreturn, so we can simply 107 * and will be restored by sigreturn, so we can simply
119 * clear the TIF_RESTORE_SIGMASK flag */ 108 * clear the TIF_RESTORE_SIGMASK flag
109 */
120 if (test_thread_flag(TIF_RESTORE_SIGMASK)) 110 if (test_thread_flag(TIF_RESTORE_SIGMASK))
121 clear_thread_flag(TIF_RESTORE_SIGMASK); 111 clear_thread_flag(TIF_RESTORE_SIGMASK);
122 break; 112 break;
@@ -124,9 +114,9 @@ static int kern_do_signal(struct pt_regs *regs)
124 } 114 }
125 115
126 /* Did we come from a system call? */ 116 /* Did we come from a system call? */
127 if(!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)){ 117 if (!handled_sig && (PT_REGS_SYSCALL_NR(regs) >= 0)) {
128 /* Restart the system call - no handlers present */ 118 /* Restart the system call - no handlers present */
129 switch(PT_REGS_SYSCALL_RET(regs)){ 119 switch(PT_REGS_SYSCALL_RET(regs)) {
130 case -ERESTARTNOHAND: 120 case -ERESTARTNOHAND:
131 case -ERESTARTSYS: 121 case -ERESTARTSYS:
132 case -ERESTARTNOINTR: 122 case -ERESTARTNOINTR:
@@ -137,22 +127,25 @@ static int kern_do_signal(struct pt_regs *regs)
137 PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall; 127 PT_REGS_ORIG_SYSCALL(regs) = __NR_restart_syscall;
138 PT_REGS_RESTART_SYSCALL(regs); 128 PT_REGS_RESTART_SYSCALL(regs);
139 break; 129 break;
140 } 130 }
141 } 131 }
142 132
143 /* This closes a way to execute a system call on the host. If 133 /*
134 * This closes a way to execute a system call on the host. If
144 * you set a breakpoint on a system call instruction and singlestep 135 * you set a breakpoint on a system call instruction and singlestep
145 * from it, the tracing thread used to PTRACE_SINGLESTEP the process 136 * from it, the tracing thread used to PTRACE_SINGLESTEP the process
146 * rather than PTRACE_SYSCALL it, allowing the system call to execute 137 * rather than PTRACE_SYSCALL it, allowing the system call to execute
147 * on the host. The tracing thread will check this flag and 138 * on the host. The tracing thread will check this flag and
148 * PTRACE_SYSCALL if necessary. 139 * PTRACE_SYSCALL if necessary.
149 */ 140 */
150 if(current->ptrace & PT_DTRACE) 141 if (current->ptrace & PT_DTRACE)
151 current->thread.singlestep_syscall = 142 current->thread.singlestep_syscall =
152 is_syscall(PT_REGS_IP(&current->thread.regs)); 143 is_syscall(PT_REGS_IP(&current->thread.regs));
153 144
154 /* if there's no signal to deliver, we just put the saved sigmask 145 /*
155 * back */ 146 * if there's no signal to deliver, we just put the saved sigmask
147 * back
148 */
156 if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) { 149 if (!handled_sig && test_thread_flag(TIF_RESTORE_SIGMASK)) {
157 clear_thread_flag(TIF_RESTORE_SIGMASK); 150 clear_thread_flag(TIF_RESTORE_SIGMASK);
158 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL); 151 sigprocmask(SIG_SETMASK, &current->saved_sigmask, NULL);
diff --git a/arch/um/kernel/skas/Makefile b/arch/um/kernel/skas/Makefile
index 3e3fa7e7e3cf..0b76d8869c94 100644
--- a/arch/um/kernel/skas/Makefile
+++ b/arch/um/kernel/skas/Makefile
@@ -1,9 +1,9 @@
1# 1#
2# Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) 2# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y := clone.o exec.o mem.o mmu.o process.o syscall.o tlb.o uaccess.o 6obj-y := clone.o mmu.o process.o syscall.o uaccess.o
7 7
8# clone.o is in the stub, so it can't be built with profiling 8# clone.o is in the stub, so it can't be built with profiling
9# GCC hardened also auto-enables -fpic, but we need %ebx so it can't work -> 9# GCC hardened also auto-enables -fpic, but we need %ebx so it can't work ->
diff --git a/arch/um/kernel/skas/clone.c b/arch/um/kernel/skas/clone.c
index 47b812b3bca8..d119f4f7d897 100644
--- a/arch/um/kernel/skas/clone.c
+++ b/arch/um/kernel/skas/clone.c
@@ -4,6 +4,7 @@
4#include <sys/time.h> 4#include <sys/time.h>
5#include <asm/unistd.h> 5#include <asm/unistd.h>
6#include <asm/page.h> 6#include <asm/page.h>
7#include "as-layout.h"
7#include "ptrace_user.h" 8#include "ptrace_user.h"
8#include "skas.h" 9#include "skas.h"
9#include "stub-data.h" 10#include "stub-data.h"
@@ -21,12 +22,11 @@
21void __attribute__ ((__section__ (".__syscall_stub"))) 22void __attribute__ ((__section__ (".__syscall_stub")))
22stub_clone_handler(void) 23stub_clone_handler(void)
23{ 24{
24 struct stub_data *data = (struct stub_data *) UML_CONFIG_STUB_DATA; 25 struct stub_data *data = (struct stub_data *) STUB_DATA;
25 long err; 26 long err;
26 27
27 err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD, 28 err = stub_syscall2(__NR_clone, CLONE_PARENT | CLONE_FILES | SIGCHLD,
28 UML_CONFIG_STUB_DATA + UM_KERN_PAGE_SIZE / 2 - 29 STUB_DATA + UM_KERN_PAGE_SIZE / 2 - sizeof(void *));
29 sizeof(void *));
30 if(err != 0) 30 if(err != 0)
31 goto out; 31 goto out;
32 32
diff --git a/arch/um/kernel/skas/exec.c b/arch/um/kernel/skas/exec.c
deleted file mode 100644
index 580eb6468949..000000000000
--- a/arch/um/kernel/skas/exec.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/kernel.h"
7#include "asm/current.h"
8#include "asm/page.h"
9#include "asm/signal.h"
10#include "asm/ptrace.h"
11#include "asm/uaccess.h"
12#include "asm/mmu_context.h"
13#include "tlb.h"
14#include "skas.h"
15#include "um_mmu.h"
16#include "os.h"
17
18void flush_thread_skas(void)
19{
20 void *data = NULL;
21 unsigned long end = proc_mm ? task_size : CONFIG_STUB_START;
22 int ret;
23
24 ret = unmap(&current->mm->context.skas.id, 0, end, 1, &data);
25 if(ret){
26 printk("flush_thread_skas - clearing address space failed, "
27 "err = %d\n", ret);
28 force_sig(SIGKILL, current);
29 }
30
31 switch_mm_skas(&current->mm->context.skas.id);
32}
33
34void start_thread_skas(struct pt_regs *regs, unsigned long eip,
35 unsigned long esp)
36{
37 set_fs(USER_DS);
38 PT_REGS_IP(regs) = eip;
39 PT_REGS_SP(regs) = esp;
40}
diff --git a/arch/um/kernel/skas/mem.c b/arch/um/kernel/skas/mem.c
deleted file mode 100644
index 7c18dfcd7d8e..000000000000
--- a/arch/um/kernel/skas/mem.c
+++ /dev/null
@@ -1,22 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/mm.h"
7#include "asm/pgtable.h"
8#include "mem_user.h"
9#include "skas.h"
10
11unsigned long set_task_sizes_skas(unsigned long *task_size_out)
12{
13 /* Round up to the nearest 4M */
14 unsigned long host_task_size = ROUND_4M((unsigned long)
15 &host_task_size);
16
17 if (!skas_needs_stub)
18 *task_size_out = host_task_size;
19 else *task_size_out = CONFIG_STUB_START & PGDIR_MASK;
20
21 return host_task_size;
22}
diff --git a/arch/um/kernel/skas/mmu.c b/arch/um/kernel/skas/mmu.c
index 2c6d090a2e87..f859ec306cd5 100644
--- a/arch/um/kernel/skas/mmu.c
+++ b/arch/um/kernel/skas/mmu.c
@@ -1,20 +1,13 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/sched.h"
7#include "linux/list.h"
8#include "linux/spinlock.h"
9#include "linux/slab.h"
10#include "linux/errno.h"
11#include "linux/mm.h" 6#include "linux/mm.h"
12#include "asm/current.h" 7#include "linux/sched.h"
13#include "asm/segment.h"
14#include "asm/mmu.h"
15#include "asm/pgalloc.h" 8#include "asm/pgalloc.h"
16#include "asm/pgtable.h" 9#include "asm/pgtable.h"
17#include "asm/ldt.h" 10#include "as-layout.h"
18#include "os.h" 11#include "os.h"
19#include "skas.h" 12#include "skas.h"
20 13
@@ -41,10 +34,11 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
41 if (!pte) 34 if (!pte)
42 goto out_pte; 35 goto out_pte;
43 36
44 /* There's an interaction between the skas0 stub pages, stack 37 /*
38 * There's an interaction between the skas0 stub pages, stack
45 * randomization, and the BUG at the end of exit_mmap. exit_mmap 39 * randomization, and the BUG at the end of exit_mmap. exit_mmap
46 * checks that the number of page tables freed is the same as had 40 * checks that the number of page tables freed is the same as had
47 * been allocated. If the stack is on the last page table page, 41 * been allocated. If the stack is on the last page table page,
48 * then the stack pte page will be freed, and if not, it won't. To 42 * then the stack pte page will be freed, and if not, it won't. To
49 * avoid having to know where the stack is, or if the process mapped 43 * avoid having to know where the stack is, or if the process mapped
50 * something at the top of its address space for some other reason, 44 * something at the top of its address space for some other reason,
@@ -54,76 +48,77 @@ static int init_stub_pte(struct mm_struct *mm, unsigned long proc,
54 * destroy_context_skas. 48 * destroy_context_skas.
55 */ 49 */
56 50
57 mm->context.skas.last_page_table = pmd_page_vaddr(*pmd); 51 mm->context.last_page_table = pmd_page_vaddr(*pmd);
58#ifdef CONFIG_3_LEVEL_PGTABLES 52#ifdef CONFIG_3_LEVEL_PGTABLES
59 mm->context.skas.last_pmd = (unsigned long) __va(pud_val(*pud)); 53 mm->context.last_pmd = (unsigned long) __va(pud_val(*pud));
60#endif 54#endif
61 55
62 *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT)); 56 *pte = mk_pte(virt_to_page(kernel), __pgprot(_PAGE_PRESENT));
63 *pte = pte_mkread(*pte); 57 *pte = pte_mkread(*pte);
64 return(0); 58 return 0;
65 59
66 out_pmd: 60 out_pmd:
67 pud_free(pud); 61 pud_free(pud);
68 out_pte: 62 out_pte:
69 pmd_free(pmd); 63 pmd_free(pmd);
70 out: 64 out:
71 return(-ENOMEM); 65 return -ENOMEM;
72} 66}
73 67
74int init_new_context_skas(struct task_struct *task, struct mm_struct *mm) 68int init_new_context(struct task_struct *task, struct mm_struct *mm)
75{ 69{
76 struct mmu_context_skas *from_mm = NULL; 70 struct mm_context *from_mm = NULL;
77 struct mmu_context_skas *to_mm = &mm->context.skas; 71 struct mm_context *to_mm = &mm->context;
78 unsigned long stack = 0; 72 unsigned long stack = 0;
79 int ret = -ENOMEM; 73 int ret = -ENOMEM;
80 74
81 if(skas_needs_stub){ 75 if (skas_needs_stub) {
82 stack = get_zeroed_page(GFP_KERNEL); 76 stack = get_zeroed_page(GFP_KERNEL);
83 if(stack == 0) 77 if (stack == 0)
84 goto out; 78 goto out;
85 79
86 /* This zeros the entry that pgd_alloc didn't, needed since 80 /*
81 * This zeros the entry that pgd_alloc didn't, needed since
87 * we are about to reinitialize it, and want mm.nr_ptes to 82 * we are about to reinitialize it, and want mm.nr_ptes to
88 * be accurate. 83 * be accurate.
89 */ 84 */
90 mm->pgd[USER_PTRS_PER_PGD] = __pgd(0); 85 mm->pgd[USER_PTRS_PER_PGD] = __pgd(0);
91 86
92 ret = init_stub_pte(mm, CONFIG_STUB_CODE, 87 ret = init_stub_pte(mm, STUB_CODE,
93 (unsigned long) &__syscall_stub_start); 88 (unsigned long) &__syscall_stub_start);
94 if(ret) 89 if (ret)
95 goto out_free; 90 goto out_free;
96 91
97 ret = init_stub_pte(mm, CONFIG_STUB_DATA, stack); 92 ret = init_stub_pte(mm, STUB_DATA, stack);
98 if(ret) 93 if (ret)
99 goto out_free; 94 goto out_free;
100 95
101 mm->nr_ptes--; 96 mm->nr_ptes--;
102 } 97 }
103 98
104 to_mm->id.stack = stack; 99 to_mm->id.stack = stack;
105 if(current->mm != NULL && current->mm != &init_mm) 100 if (current->mm != NULL && current->mm != &init_mm)
106 from_mm = &current->mm->context.skas; 101 from_mm = &current->mm->context;
107 102
108 if(proc_mm){ 103 if (proc_mm) {
109 ret = new_mm(stack); 104 ret = new_mm(stack);
110 if(ret < 0){ 105 if (ret < 0) {
111 printk("init_new_context_skas - new_mm failed, " 106 printk(KERN_ERR "init_new_context_skas - "
112 "errno = %d\n", ret); 107 "new_mm failed, errno = %d\n", ret);
113 goto out_free; 108 goto out_free;
114 } 109 }
115 to_mm->id.u.mm_fd = ret; 110 to_mm->id.u.mm_fd = ret;
116 } 111 }
117 else { 112 else {
118 if(from_mm) 113 if (from_mm)
119 to_mm->id.u.pid = copy_context_skas0(stack, 114 to_mm->id.u.pid = copy_context_skas0(stack,
120 from_mm->id.u.pid); 115 from_mm->id.u.pid);
121 else to_mm->id.u.pid = start_userspace(stack); 116 else to_mm->id.u.pid = start_userspace(stack);
122 } 117 }
123 118
124 ret = init_new_ldt(to_mm, from_mm); 119 ret = init_new_ldt(to_mm, from_mm);
125 if(ret < 0){ 120 if (ret < 0) {
126 printk("init_new_context_skas - init_ldt" 121 printk(KERN_ERR "init_new_context_skas - init_ldt"
127 " failed, errno = %d\n", ret); 122 " failed, errno = %d\n", ret);
128 goto out_free; 123 goto out_free;
129 } 124 }
@@ -131,22 +126,22 @@ int init_new_context_skas(struct task_struct *task, struct mm_struct *mm)
131 return 0; 126 return 0;
132 127
133 out_free: 128 out_free:
134 if(to_mm->id.stack != 0) 129 if (to_mm->id.stack != 0)
135 free_page(to_mm->id.stack); 130 free_page(to_mm->id.stack);
136 out: 131 out:
137 return ret; 132 return ret;
138} 133}
139 134
140void destroy_context_skas(struct mm_struct *mm) 135void destroy_context(struct mm_struct *mm)
141{ 136{
142 struct mmu_context_skas *mmu = &mm->context.skas; 137 struct mm_context *mmu = &mm->context;
143 138
144 if(proc_mm) 139 if (proc_mm)
145 os_close_file(mmu->id.u.mm_fd); 140 os_close_file(mmu->id.u.mm_fd);
146 else 141 else
147 os_kill_ptraced_process(mmu->id.u.pid, 1); 142 os_kill_ptraced_process(mmu->id.u.pid, 1);
148 143
149 if(!proc_mm || !ptrace_faultinfo){ 144 if (!proc_mm || !ptrace_faultinfo) {
150 free_page(mmu->id.stack); 145 free_page(mmu->id.stack);
151 pte_lock_deinit(virt_to_page(mmu->last_page_table)); 146 pte_lock_deinit(virt_to_page(mmu->last_page_table));
152 pte_free_kernel((pte_t *) mmu->last_page_table); 147 pte_free_kernel((pte_t *) mmu->last_page_table);
@@ -155,4 +150,6 @@ void destroy_context_skas(struct mm_struct *mm)
155 pmd_free((pmd_t *) mmu->last_pmd); 150 pmd_free((pmd_t *) mmu->last_pmd);
156#endif 151#endif
157 } 152 }
153
154 free_ldt(mmu);
158} 155}
diff --git a/arch/um/kernel/skas/process.c b/arch/um/kernel/skas/process.c
index 48051a98525f..fce389c2342f 100644
--- a/arch/um/kernel/skas/process.c
+++ b/arch/um/kernel/skas/process.c
@@ -1,146 +1,26 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/sched.h"
7#include "linux/slab.h"
8#include "linux/ptrace.h"
9#include "linux/proc_fs.h"
10#include "linux/file.h"
11#include "linux/errno.h"
12#include "linux/init.h" 6#include "linux/init.h"
13#include "asm/uaccess.h" 7#include "linux/sched.h"
14#include "asm/atomic.h"
15#include "kern_util.h"
16#include "as-layout.h" 8#include "as-layout.h"
17#include "skas.h"
18#include "os.h" 9#include "os.h"
19#include "tlb.h" 10#include "skas.h"
20#include "kern.h"
21#include "mode.h"
22#include "registers.h"
23
24void switch_to_skas(void *prev, void *next)
25{
26 struct task_struct *from, *to;
27
28 from = prev;
29 to = next;
30
31 /* XXX need to check runqueues[cpu].idle */
32 if(current->pid == 0)
33 switch_timers(0);
34
35 switch_threads(&from->thread.mode.skas.switch_buf,
36 &to->thread.mode.skas.switch_buf);
37
38 arch_switch_to_skas(current->thread.prev_sched, current);
39
40 if(current->pid == 0)
41 switch_timers(1);
42}
43
44extern void schedule_tail(struct task_struct *prev);
45
46/* This is called magically, by its address being stuffed in a jmp_buf
47 * and being longjmp-d to.
48 */
49void new_thread_handler(void)
50{
51 int (*fn)(void *), n;
52 void *arg;
53
54 if(current->thread.prev_sched != NULL)
55 schedule_tail(current->thread.prev_sched);
56 current->thread.prev_sched = NULL;
57
58 fn = current->thread.request.u.thread.proc;
59 arg = current->thread.request.u.thread.arg;
60
61 /* The return value is 1 if the kernel thread execs a process,
62 * 0 if it just exits
63 */
64 n = run_kernel_thread(fn, arg, &current->thread.exec_buf);
65 if(n == 1){
66 /* Handle any immediate reschedules or signals */
67 interrupt_end();
68 userspace(&current->thread.regs.regs);
69 }
70 else do_exit(0);
71}
72
73void release_thread_skas(struct task_struct *task)
74{
75}
76
77/* Called magically, see new_thread_handler above */
78void fork_handler(void)
79{
80 force_flush_all();
81 if(current->thread.prev_sched == NULL)
82 panic("blech");
83
84 schedule_tail(current->thread.prev_sched);
85
86 /* XXX: if interrupt_end() calls schedule, this call to
87 * arch_switch_to_skas isn't needed. We could want to apply this to
88 * improve performance. -bb */
89 arch_switch_to_skas(current->thread.prev_sched, current);
90
91 current->thread.prev_sched = NULL;
92
93/* Handle any immediate reschedules or signals */
94 interrupt_end();
95
96 userspace(&current->thread.regs.regs);
97}
98
99int copy_thread_skas(int nr, unsigned long clone_flags, unsigned long sp,
100 unsigned long stack_top, struct task_struct * p,
101 struct pt_regs *regs)
102{
103 void (*handler)(void);
104
105 if(current->thread.forking){
106 memcpy(&p->thread.regs.regs.skas, &regs->regs.skas,
107 sizeof(p->thread.regs.regs.skas));
108 REGS_SET_SYSCALL_RETURN(p->thread.regs.regs.skas.regs, 0);
109 if(sp != 0) REGS_SP(p->thread.regs.regs.skas.regs) = sp;
110
111 handler = fork_handler;
112
113 arch_copy_thread(&current->thread.arch, &p->thread.arch);
114 }
115 else {
116 init_thread_registers(&p->thread.regs.regs);
117 p->thread.request.u.thread = current->thread.request.u.thread;
118 handler = new_thread_handler;
119 }
120
121 new_thread(task_stack_page(p), &p->thread.mode.skas.switch_buf,
122 handler);
123 return(0);
124}
125 11
126int new_mm(unsigned long stack) 12int new_mm(unsigned long stack)
127{ 13{
128 int fd; 14 int fd;
129 15
130 fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0); 16 fd = os_open_file("/proc/mm", of_cloexec(of_write(OPENFLAGS())), 0);
131 if(fd < 0) 17 if (fd < 0)
132 return(fd); 18 return fd;
133 19
134 if(skas_needs_stub) 20 if (skas_needs_stub)
135 map_stub_pages(fd, CONFIG_STUB_CODE, CONFIG_STUB_DATA, stack); 21 map_stub_pages(fd, STUB_CODE, STUB_DATA, stack);
136 22
137 return(fd); 23 return fd;
138}
139
140void init_idle_skas(void)
141{
142 cpu_tasks[current_thread->cpu].pid = os_getpid();
143 default_idle();
144} 24}
145 25
146extern void start_kernel(void); 26extern void start_kernel(void);
@@ -158,67 +38,32 @@ static int __init start_kernel_proc(void *unused)
158 cpu_online_map = cpumask_of_cpu(0); 38 cpu_online_map = cpumask_of_cpu(0);
159#endif 39#endif
160 start_kernel(); 40 start_kernel();
161 return(0); 41 return 0;
162} 42}
163 43
164extern int userspace_pid[]; 44extern int userspace_pid[];
165 45
166extern char cpu0_irqstack[]; 46extern char cpu0_irqstack[];
167 47
168int __init start_uml_skas(void) 48int __init start_uml(void)
169{ 49{
170 stack_protections((unsigned long) &cpu0_irqstack); 50 stack_protections((unsigned long) &cpu0_irqstack);
171 set_sigstack(cpu0_irqstack, THREAD_SIZE); 51 set_sigstack(cpu0_irqstack, THREAD_SIZE);
172 if(proc_mm) 52 if (proc_mm)
173 userspace_pid[0] = start_userspace(0); 53 userspace_pid[0] = start_userspace(0);
174 54
175 init_new_thread_signals(); 55 init_new_thread_signals();
176 56
177 init_task.thread.request.u.thread.proc = start_kernel_proc; 57 init_task.thread.request.u.thread.proc = start_kernel_proc;
178 init_task.thread.request.u.thread.arg = NULL; 58 init_task.thread.request.u.thread.arg = NULL;
179 return(start_idle_thread(task_stack_page(&init_task), 59 return start_idle_thread(task_stack_page(&init_task),
180 &init_task.thread.mode.skas.switch_buf)); 60 &init_task.thread.switch_buf);
181}
182
183int external_pid_skas(struct task_struct *task)
184{
185 /* FIXME: Need to look up userspace_pid by cpu */
186 return(userspace_pid[0]);
187}
188
189int thread_pid_skas(struct task_struct *task)
190{
191 /* FIXME: Need to look up userspace_pid by cpu */
192 return(userspace_pid[0]);
193}
194
195void kill_off_processes_skas(void)
196{
197 if(proc_mm)
198 /*
199 * FIXME: need to loop over userspace_pids in
200 * kill_off_processes_skas
201 */
202 os_kill_ptraced_process(userspace_pid[0], 1);
203 else {
204 struct task_struct *p;
205 int pid, me;
206
207 me = os_getpid();
208 for_each_process(p){
209 if(p->mm == NULL)
210 continue;
211
212 pid = p->mm->context.skas.id.u.pid;
213 os_kill_ptraced_process(pid, 1);
214 }
215 }
216} 61}
217 62
218unsigned long current_stub_stack(void) 63unsigned long current_stub_stack(void)
219{ 64{
220 if(current->mm == NULL) 65 if (current->mm == NULL)
221 return(0); 66 return 0;
222 67
223 return(current->mm->context.skas.id.stack); 68 return current->mm->context.id.stack;
224} 69}
diff --git a/arch/um/kernel/skas/syscall.c b/arch/um/kernel/skas/syscall.c
index 0ae4eea21be4..50b476f2b38d 100644
--- a/arch/um/kernel/skas/syscall.c
+++ b/arch/um/kernel/skas/syscall.c
@@ -1,19 +1,15 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/sys.h" 6#include "linux/kernel.h"
7#include "linux/ptrace.h" 7#include "linux/ptrace.h"
8#include "asm/errno.h"
9#include "asm/unistd.h"
10#include "asm/ptrace.h"
11#include "asm/current.h"
12#include "sysdep/syscalls.h"
13#include "kern_util.h" 8#include "kern_util.h"
14#include "syscall.h" 9#include "sysdep/ptrace.h"
10#include "sysdep/syscalls.h"
15 11
16void handle_syscall(union uml_pt_regs *r) 12void handle_syscall(struct uml_pt_regs *r)
17{ 13{
18 struct pt_regs *regs = container_of(r, struct pt_regs, regs); 14 struct pt_regs *regs = container_of(r, struct pt_regs, regs);
19 long result; 15 long result;
@@ -24,7 +20,8 @@ void handle_syscall(union uml_pt_regs *r)
24 current->thread.nsyscalls++; 20 current->thread.nsyscalls++;
25 nsyscalls++; 21 nsyscalls++;
26 22
27 /* This should go in the declaration of syscall, but when I do that, 23 /*
24 * This should go in the declaration of syscall, but when I do that,
28 * strace -f -c bash -c 'ls ; ls' breaks, sometimes not tracing 25 * strace -f -c bash -c 'ls ; ls' breaks, sometimes not tracing
29 * children at all, sometimes hanging when bash doesn't see the first 26 * children at all, sometimes hanging when bash doesn't see the first
30 * ls exit. 27 * ls exit.
@@ -33,11 +30,11 @@ void handle_syscall(union uml_pt_regs *r)
33 * in case it's a compiler bug. 30 * in case it's a compiler bug.
34 */ 31 */
35 syscall = UPT_SYSCALL_NR(r); 32 syscall = UPT_SYSCALL_NR(r);
36 if((syscall >= NR_syscalls) || (syscall < 0)) 33 if ((syscall >= NR_syscalls) || (syscall < 0))
37 result = -ENOSYS; 34 result = -ENOSYS;
38 else result = EXECUTE_SYSCALL(syscall, regs); 35 else result = EXECUTE_SYSCALL(syscall, regs);
39 36
40 REGS_SET_SYSCALL_RETURN(r->skas.regs, result); 37 REGS_SET_SYSCALL_RETURN(r->gp, result);
41 38
42 syscall_trace(r, 1); 39 syscall_trace(r, 1);
43} 40}
diff --git a/arch/um/kernel/skas/tlb.c b/arch/um/kernel/skas/tlb.c
deleted file mode 100644
index c0f0693743ba..000000000000
--- a/arch/um/kernel/skas/tlb.c
+++ /dev/null
@@ -1,164 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Copyright 2003 PathScale, Inc.
4 * Licensed under the GPL
5 */
6
7#include "linux/stddef.h"
8#include "linux/sched.h"
9#include "linux/mm.h"
10#include "asm/page.h"
11#include "asm/pgtable.h"
12#include "asm/mmu.h"
13#include "mem_user.h"
14#include "mem.h"
15#include "skas.h"
16#include "os.h"
17#include "tlb.h"
18
19static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last,
20 int finished, void **flush)
21{
22 struct host_vm_op *op;
23 int i, ret = 0;
24
25 for(i = 0; i <= last && !ret; i++){
26 op = &ops[i];
27 switch(op->type){
28 case MMAP:
29 ret = map(&mmu->skas.id, op->u.mmap.addr,
30 op->u.mmap.len, op->u.mmap.prot,
31 op->u.mmap.fd, op->u.mmap.offset, finished,
32 flush);
33 break;
34 case MUNMAP:
35 ret = unmap(&mmu->skas.id, op->u.munmap.addr,
36 op->u.munmap.len, finished, flush);
37 break;
38 case MPROTECT:
39 ret = protect(&mmu->skas.id, op->u.mprotect.addr,
40 op->u.mprotect.len, op->u.mprotect.prot,
41 finished, flush);
42 break;
43 default:
44 printk("Unknown op type %d in do_ops\n", op->type);
45 break;
46 }
47 }
48
49 return ret;
50}
51
52extern int proc_mm;
53
54static void fix_range(struct mm_struct *mm, unsigned long start_addr,
55 unsigned long end_addr, int force)
56{
57 if(!proc_mm && (end_addr > CONFIG_STUB_START))
58 end_addr = CONFIG_STUB_START;
59
60 fix_range_common(mm, start_addr, end_addr, force, do_ops);
61}
62
63void __flush_tlb_one_skas(unsigned long addr)
64{
65 flush_tlb_kernel_range_common(addr, addr + PAGE_SIZE);
66}
67
68void flush_tlb_range_skas(struct vm_area_struct *vma, unsigned long start,
69 unsigned long end)
70{
71 if(vma->vm_mm == NULL)
72 flush_tlb_kernel_range_common(start, end);
73 else fix_range(vma->vm_mm, start, end, 0);
74}
75
76void flush_tlb_mm_skas(struct mm_struct *mm)
77{
78 unsigned long end;
79
80 /* Don't bother flushing if this address space is about to be
81 * destroyed.
82 */
83 if(atomic_read(&mm->mm_users) == 0)
84 return;
85
86 end = proc_mm ? task_size : CONFIG_STUB_START;
87 fix_range(mm, 0, end, 0);
88}
89
90void force_flush_all_skas(void)
91{
92 struct mm_struct *mm = current->mm;
93 struct vm_area_struct *vma = mm->mmap;
94
95 while(vma != NULL) {
96 fix_range(mm, vma->vm_start, vma->vm_end, 1);
97 vma = vma->vm_next;
98 }
99}
100
101void flush_tlb_page_skas(struct vm_area_struct *vma, unsigned long address)
102{
103 pgd_t *pgd;
104 pud_t *pud;
105 pmd_t *pmd;
106 pte_t *pte;
107 struct mm_struct *mm = vma->vm_mm;
108 void *flush = NULL;
109 int r, w, x, prot, err = 0;
110 struct mm_id *mm_id;
111
112 pgd = pgd_offset(mm, address);
113 if(!pgd_present(*pgd))
114 goto kill;
115
116 pud = pud_offset(pgd, address);
117 if(!pud_present(*pud))
118 goto kill;
119
120 pmd = pmd_offset(pud, address);
121 if(!pmd_present(*pmd))
122 goto kill;
123
124 pte = pte_offset_kernel(pmd, address);
125
126 r = pte_read(*pte);
127 w = pte_write(*pte);
128 x = pte_exec(*pte);
129 if (!pte_young(*pte)) {
130 r = 0;
131 w = 0;
132 } else if (!pte_dirty(*pte)) {
133 w = 0;
134 }
135
136 mm_id = &mm->context.skas.id;
137 prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
138 (x ? UM_PROT_EXEC : 0));
139 if(pte_newpage(*pte)){
140 if(pte_present(*pte)){
141 unsigned long long offset;
142 int fd;
143
144 fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset);
145 err = map(mm_id, address, PAGE_SIZE, prot, fd, offset,
146 1, &flush);
147 }
148 else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush);
149 }
150 else if(pte_newprot(*pte))
151 err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush);
152
153 if(err)
154 goto kill;
155
156 *pte = pte_mkuptodate(*pte);
157
158 return;
159
160kill:
161 printk("Failed to flush page for address 0x%lx\n", address);
162 force_sig(SIGKILL, current);
163}
164
diff --git a/arch/um/kernel/skas/uaccess.c b/arch/um/kernel/skas/uaccess.c
index 8912cec0fe43..1d8b119f2d0e 100644
--- a/arch/um/kernel/skas/uaccess.c
+++ b/arch/um/kernel/skas/uaccess.c
@@ -1,18 +1,14 @@
1/* 1/*
2 * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/compiler.h" 6#include "linux/err.h"
7#include "linux/stddef.h"
8#include "linux/kernel.h"
9#include "linux/string.h"
10#include "linux/fs.h"
11#include "linux/hardirq.h"
12#include "linux/highmem.h" 7#include "linux/highmem.h"
8#include "linux/mm.h"
9#include "asm/current.h"
13#include "asm/page.h" 10#include "asm/page.h"
14#include "asm/pgtable.h" 11#include "asm/pgtable.h"
15#include "asm/uaccess.h"
16#include "kern_util.h" 12#include "kern_util.h"
17#include "os.h" 13#include "os.h"
18 14
@@ -27,16 +23,16 @@ static unsigned long maybe_map(unsigned long virt, int is_write)
27 void *phys = um_virt_to_phys(current, virt, &pte); 23 void *phys = um_virt_to_phys(current, virt, &pte);
28 int dummy_code; 24 int dummy_code;
29 25
30 if(IS_ERR(phys) || (is_write && !pte_write(pte))){ 26 if (IS_ERR(phys) || (is_write && !pte_write(pte))) {
31 err = handle_page_fault(virt, 0, is_write, 1, &dummy_code); 27 err = handle_page_fault(virt, 0, is_write, 1, &dummy_code);
32 if(err) 28 if (err)
33 return(-1UL); 29 return -1UL;
34 phys = um_virt_to_phys(current, virt, NULL); 30 phys = um_virt_to_phys(current, virt, NULL);
35 } 31 }
36 if(IS_ERR(phys)) 32 if (IS_ERR(phys))
37 phys = (void *) -1; 33 phys = (void *) -1;
38 34
39 return((unsigned long) phys); 35 return (unsigned long) phys;
40} 36}
41 37
42static int do_op_one_page(unsigned long addr, int len, int is_write, 38static int do_op_one_page(unsigned long addr, int len, int is_write,
@@ -46,17 +42,18 @@ static int do_op_one_page(unsigned long addr, int len, int is_write,
46 int n; 42 int n;
47 43
48 addr = maybe_map(addr, is_write); 44 addr = maybe_map(addr, is_write);
49 if(addr == -1UL) 45 if (addr == -1UL)
50 return(-1); 46 return -1;
51 47
52 page = phys_to_page(addr); 48 page = phys_to_page(addr);
53 addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) + (addr & ~PAGE_MASK); 49 addr = (unsigned long) kmap_atomic(page, KM_UML_USERCOPY) +
50 (addr & ~PAGE_MASK);
54 51
55 n = (*op)(addr, len, arg); 52 n = (*op)(addr, len, arg);
56 53
57 kunmap_atomic(page, KM_UML_USERCOPY); 54 kunmap_atomic(page, KM_UML_USERCOPY);
58 55
59 return(n); 56 return n;
60} 57}
61 58
62static void do_buffer_op(void *jmpbuf, void *arg_ptr) 59static void do_buffer_op(void *jmpbuf, void *arg_ptr)
@@ -81,21 +78,21 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
81 78
82 current->thread.fault_catcher = jmpbuf; 79 current->thread.fault_catcher = jmpbuf;
83 n = do_op_one_page(addr, size, is_write, op, arg); 80 n = do_op_one_page(addr, size, is_write, op, arg);
84 if(n != 0){ 81 if (n != 0) {
85 *res = (n < 0 ? remain : 0); 82 *res = (n < 0 ? remain : 0);
86 goto out; 83 goto out;
87 } 84 }
88 85
89 addr += size; 86 addr += size;
90 remain -= size; 87 remain -= size;
91 if(remain == 0){ 88 if (remain == 0) {
92 *res = 0; 89 *res = 0;
93 goto out; 90 goto out;
94 } 91 }
95 92
96 while(addr < ((addr + remain) & PAGE_MASK)){ 93 while(addr < ((addr + remain) & PAGE_MASK)) {
97 n = do_op_one_page(addr, PAGE_SIZE, is_write, op, arg); 94 n = do_op_one_page(addr, PAGE_SIZE, is_write, op, arg);
98 if(n != 0){ 95 if (n != 0) {
99 *res = (n < 0 ? remain : 0); 96 *res = (n < 0 ? remain : 0);
100 goto out; 97 goto out;
101 } 98 }
@@ -103,13 +100,13 @@ static void do_buffer_op(void *jmpbuf, void *arg_ptr)
103 addr += PAGE_SIZE; 100 addr += PAGE_SIZE;
104 remain -= PAGE_SIZE; 101 remain -= PAGE_SIZE;
105 } 102 }
106 if(remain == 0){ 103 if (remain == 0) {
107 *res = 0; 104 *res = 0;
108 goto out; 105 goto out;
109 } 106 }
110 107
111 n = do_op_one_page(addr, remain, is_write, op, arg); 108 n = do_op_one_page(addr, remain, is_write, op, arg);
112 if(n != 0) 109 if (n != 0)
113 *res = (n < 0 ? remain : 0); 110 *res = (n < 0 ? remain : 0);
114 else *res = 0; 111 else *res = 0;
115 out: 112 out:
@@ -124,10 +121,10 @@ static int buffer_op(unsigned long addr, int len, int is_write,
124 121
125 faulted = setjmp_wrapper(do_buffer_op, addr, len, is_write, op, arg, 122 faulted = setjmp_wrapper(do_buffer_op, addr, len, is_write, op, arg,
126 &res); 123 &res);
127 if(!faulted) 124 if (!faulted)
128 return(res); 125 return res;
129 126
130 return(addr + len - (unsigned long) current->thread.fault_addr); 127 return addr + len - (unsigned long) current->thread.fault_addr;
131} 128}
132 129
133static int copy_chunk_from_user(unsigned long from, int len, void *arg) 130static int copy_chunk_from_user(unsigned long from, int len, void *arg)
@@ -136,19 +133,19 @@ static int copy_chunk_from_user(unsigned long from, int len, void *arg)
136 133
137 memcpy((void *) to, (void *) from, len); 134 memcpy((void *) to, (void *) from, len);
138 *to_ptr += len; 135 *to_ptr += len;
139 return(0); 136 return 0;
140} 137}
141 138
142int copy_from_user_skas(void *to, const void __user *from, int n) 139int copy_from_user(void *to, const void __user *from, int n)
143{ 140{
144 if(segment_eq(get_fs(), KERNEL_DS)){ 141 if (segment_eq(get_fs(), KERNEL_DS)) {
145 memcpy(to, (__force void*)from, n); 142 memcpy(to, (__force void*)from, n);
146 return(0); 143 return 0;
147 } 144 }
148 145
149 return(access_ok(VERIFY_READ, from, n) ? 146 return access_ok(VERIFY_READ, from, n) ?
150 buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to): 147 buffer_op((unsigned long) from, n, 0, copy_chunk_from_user, &to):
151 n); 148 n;
152} 149}
153 150
154static int copy_chunk_to_user(unsigned long to, int len, void *arg) 151static int copy_chunk_to_user(unsigned long to, int len, void *arg)
@@ -157,19 +154,19 @@ static int copy_chunk_to_user(unsigned long to, int len, void *arg)
157 154
158 memcpy((void *) to, (void *) from, len); 155 memcpy((void *) to, (void *) from, len);
159 *from_ptr += len; 156 *from_ptr += len;
160 return(0); 157 return 0;
161} 158}
162 159
163int copy_to_user_skas(void __user *to, const void *from, int n) 160int copy_to_user(void __user *to, const void *from, int n)
164{ 161{
165 if(segment_eq(get_fs(), KERNEL_DS)){ 162 if (segment_eq(get_fs(), KERNEL_DS)) {
166 memcpy((__force void*)to, from, n); 163 memcpy((__force void *) to, from, n);
167 return(0); 164 return 0;
168 } 165 }
169 166
170 return(access_ok(VERIFY_WRITE, to, n) ? 167 return access_ok(VERIFY_WRITE, to, n) ?
171 buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) : 168 buffer_op((unsigned long) to, n, 1, copy_chunk_to_user, &from) :
172 n); 169 n;
173} 170}
174 171
175static int strncpy_chunk_from_user(unsigned long from, int len, void *arg) 172static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
@@ -181,51 +178,51 @@ static int strncpy_chunk_from_user(unsigned long from, int len, void *arg)
181 n = strnlen(to, len); 178 n = strnlen(to, len);
182 *to_ptr += n; 179 *to_ptr += n;
183 180
184 if(n < len) 181 if (n < len)
185 return(1); 182 return 1;
186 return(0); 183 return 0;
187} 184}
188 185
189int strncpy_from_user_skas(char *dst, const char __user *src, int count) 186int strncpy_from_user(char *dst, const char __user *src, int count)
190{ 187{
191 int n; 188 int n;
192 char *ptr = dst; 189 char *ptr = dst;
193 190
194 if(segment_eq(get_fs(), KERNEL_DS)){ 191 if (segment_eq(get_fs(), KERNEL_DS)) {
195 strncpy(dst, (__force void*)src, count); 192 strncpy(dst, (__force void *) src, count);
196 return(strnlen(dst, count)); 193 return strnlen(dst, count);
197 } 194 }
198 195
199 if(!access_ok(VERIFY_READ, src, 1)) 196 if (!access_ok(VERIFY_READ, src, 1))
200 return(-EFAULT); 197 return -EFAULT;
201 198
202 n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user, 199 n = buffer_op((unsigned long) src, count, 0, strncpy_chunk_from_user,
203 &ptr); 200 &ptr);
204 if(n != 0) 201 if (n != 0)
205 return(-EFAULT); 202 return -EFAULT;
206 return(strnlen(dst, count)); 203 return strnlen(dst, count);
207} 204}
208 205
209static int clear_chunk(unsigned long addr, int len, void *unused) 206static int clear_chunk(unsigned long addr, int len, void *unused)
210{ 207{
211 memset((void *) addr, 0, len); 208 memset((void *) addr, 0, len);
212 return(0); 209 return 0;
213} 210}
214 211
215int __clear_user_skas(void __user *mem, int len) 212int __clear_user(void __user *mem, int len)
216{ 213{
217 return(buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL)); 214 return buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL);
218} 215}
219 216
220int clear_user_skas(void __user *mem, int len) 217int clear_user(void __user *mem, int len)
221{ 218{
222 if(segment_eq(get_fs(), KERNEL_DS)){ 219 if (segment_eq(get_fs(), KERNEL_DS)) {
223 memset((__force void*)mem, 0, len); 220 memset((__force void*)mem, 0, len);
224 return(0); 221 return 0;
225 } 222 }
226 223
227 return(access_ok(VERIFY_WRITE, mem, len) ? 224 return access_ok(VERIFY_WRITE, mem, len) ?
228 buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len); 225 buffer_op((unsigned long) mem, len, 1, clear_chunk, NULL) : len;
229} 226}
230 227
231static int strnlen_chunk(unsigned long str, int len, void *arg) 228static int strnlen_chunk(unsigned long str, int len, void *arg)
@@ -235,31 +232,20 @@ static int strnlen_chunk(unsigned long str, int len, void *arg)
235 n = strnlen((void *) str, len); 232 n = strnlen((void *) str, len);
236 *len_ptr += n; 233 *len_ptr += n;
237 234
238 if(n < len) 235 if (n < len)
239 return(1); 236 return 1;
240 return(0); 237 return 0;
241} 238}
242 239
243int strnlen_user_skas(const void __user *str, int len) 240int strnlen_user(const void __user *str, int len)
244{ 241{
245 int count = 0, n; 242 int count = 0, n;
246 243
247 if(segment_eq(get_fs(), KERNEL_DS)) 244 if (segment_eq(get_fs(), KERNEL_DS))
248 return(strnlen((__force char*)str, len) + 1); 245 return strnlen((__force char*)str, len) + 1;
249 246
250 n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count); 247 n = buffer_op((unsigned long) str, len, 0, strnlen_chunk, &count);
251 if(n == 0) 248 if (n == 0)
252 return(count + 1); 249 return count + 1;
253 return(-EFAULT); 250 return -EFAULT;
254} 251}
255
256/*
257 * Overrides for Emacs so that we follow Linus's tabbing style.
258 * Emacs will notice this stuff at the end of the file and automatically
259 * adjust the settings for this buffer only. This must remain at the end
260 * of the file.
261 * ---------------------------------------------------------------------------
262 * Local variables:
263 * c-file-style: "linux"
264 * End:
265 */
diff --git a/arch/um/kernel/smp.c b/arch/um/kernel/smp.c
index e6a7778006ad..36d89cf8d20b 100644
--- a/arch/um/kernel/smp.c
+++ b/arch/um/kernel/smp.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -56,12 +56,12 @@ void smp_send_stop(void)
56 int i; 56 int i;
57 57
58 printk(KERN_INFO "Stopping all CPUs..."); 58 printk(KERN_INFO "Stopping all CPUs...");
59 for(i = 0; i < num_online_cpus(); i++){ 59 for (i = 0; i < num_online_cpus(); i++) {
60 if(i == current_thread->cpu) 60 if (i == current_thread->cpu)
61 continue; 61 continue;
62 os_write_file(cpu_data[i].ipi_pipe[1], "S", 1); 62 os_write_file(cpu_data[i].ipi_pipe[1], "S", 1);
63 } 63 }
64 printk("done\n"); 64 printk(KERN_INFO "done\n");
65} 65}
66 66
67static cpumask_t smp_commenced_mask = CPU_MASK_NONE; 67static cpumask_t smp_commenced_mask = CPU_MASK_NONE;
@@ -72,7 +72,7 @@ static int idle_proc(void *cpup)
72 int cpu = (int) cpup, err; 72 int cpu = (int) cpup, err;
73 73
74 err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1); 74 err = os_pipe(cpu_data[cpu].ipi_pipe, 1, 1);
75 if(err < 0) 75 if (err < 0)
76 panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err); 76 panic("CPU#%d failed to create IPI pipe, err = %d", cpu, -err);
77 77
78 os_set_fd_async(cpu_data[cpu].ipi_pipe[0], 78 os_set_fd_async(cpu_data[cpu].ipi_pipe[0],
@@ -80,7 +80,7 @@ static int idle_proc(void *cpup)
80 80
81 wmb(); 81 wmb();
82 if (cpu_test_and_set(cpu, cpu_callin_map)) { 82 if (cpu_test_and_set(cpu, cpu_callin_map)) {
83 printk("huh, CPU#%d already present??\n", cpu); 83 printk(KERN_ERR "huh, CPU#%d already present??\n", cpu);
84 BUG(); 84 BUG();
85 } 85 }
86 86
@@ -95,12 +95,11 @@ static int idle_proc(void *cpup)
95static struct task_struct *idle_thread(int cpu) 95static struct task_struct *idle_thread(int cpu)
96{ 96{
97 struct task_struct *new_task; 97 struct task_struct *new_task;
98 unsigned char c;
99 98
100 current->thread.request.u.thread.proc = idle_proc; 99 current->thread.request.u.thread.proc = idle_proc;
101 current->thread.request.u.thread.arg = (void *) cpu; 100 current->thread.request.u.thread.arg = (void *) cpu;
102 new_task = fork_idle(cpu); 101 new_task = fork_idle(cpu);
103 if(IS_ERR(new_task)) 102 if (IS_ERR(new_task))
104 panic("copy_process failed in idle_thread, error = %ld", 103 panic("copy_process failed in idle_thread, error = %ld",
105 PTR_ERR(new_task)); 104 PTR_ERR(new_task));
106 105
@@ -108,9 +107,7 @@ static struct task_struct *idle_thread(int cpu)
108 { .pid = new_task->thread.mode.tt.extern_pid, 107 { .pid = new_task->thread.mode.tt.extern_pid,
109 .task = new_task } ); 108 .task = new_task } );
110 idle_threads[cpu] = new_task; 109 idle_threads[cpu] = new_task;
111 CHOOSE_MODE(os_write_file(new_task->thread.mode.tt.switch_pipe[1], &c, 110 panic("skas mode doesn't support SMP");
112 sizeof(c)),
113 ({ panic("skas mode doesn't support SMP"); }));
114 return new_task; 111 return new_task;
115} 112}
116 113
@@ -129,14 +126,14 @@ void smp_prepare_cpus(unsigned int maxcpus)
129 cpu_set(me, cpu_callin_map); 126 cpu_set(me, cpu_callin_map);
130 127
131 err = os_pipe(cpu_data[me].ipi_pipe, 1, 1); 128 err = os_pipe(cpu_data[me].ipi_pipe, 1, 1);
132 if(err < 0) 129 if (err < 0)
133 panic("CPU#0 failed to create IPI pipe, errno = %d", -err); 130 panic("CPU#0 failed to create IPI pipe, errno = %d", -err);
134 131
135 os_set_fd_async(cpu_data[me].ipi_pipe[0], 132 os_set_fd_async(cpu_data[me].ipi_pipe[0],
136 current->thread.mode.tt.extern_pid); 133 current->thread.mode.tt.extern_pid);
137 134
138 for(cpu = 1; cpu < ncpus; cpu++){ 135 for (cpu = 1; cpu < ncpus; cpu++) {
139 printk("Booting processor %d...\n", cpu); 136 printk(KERN_INFO "Booting processor %d...\n", cpu);
140 137
141 idle = idle_thread(cpu); 138 idle = idle_thread(cpu);
142 139
@@ -147,8 +144,8 @@ void smp_prepare_cpus(unsigned int maxcpus)
147 cpu_relax(); 144 cpu_relax();
148 145
149 if (cpu_isset(cpu, cpu_callin_map)) 146 if (cpu_isset(cpu, cpu_callin_map))
150 printk("done\n"); 147 printk(KERN_INFO "done\n");
151 else printk("failed\n"); 148 else printk(KERN_INFO "failed\n");
152 } 149 }
153} 150}
154 151
@@ -190,13 +187,14 @@ void IPI_handler(int cpu)
190 break; 187 break;
191 188
192 case 'S': 189 case 'S':
193 printk("CPU#%d stopping\n", cpu); 190 printk(KERN_INFO "CPU#%d stopping\n", cpu);
194 while(1) 191 while (1)
195 pause(); 192 pause();
196 break; 193 break;
197 194
198 default: 195 default:
199 printk("CPU#%d received unknown IPI [%c]!\n", cpu, c); 196 printk(KERN_ERR "CPU#%d received unknown IPI [%c]!\n",
197 cpu, c);
200 break; 198 break;
201 } 199 }
202 } 200 }
diff --git a/arch/um/kernel/syscall.c b/arch/um/kernel/syscall.c
index 7b3b67333ff3..b9d92b2089ae 100644
--- a/arch/um/kernel/syscall.c
+++ b/arch/um/kernel/syscall.c
@@ -1,27 +1,17 @@
1/* 1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/sched.h"
7#include "linux/file.h" 6#include "linux/file.h"
8#include "linux/smp_lock.h"
9#include "linux/mm.h"
10#include "linux/fs.h" 7#include "linux/fs.h"
8#include "linux/mm.h"
9#include "linux/sched.h"
11#include "linux/utsname.h" 10#include "linux/utsname.h"
12#include "linux/msg.h" 11#include "asm/current.h"
13#include "linux/shm.h"
14#include "linux/sys.h"
15#include "linux/syscalls.h"
16#include "linux/unistd.h"
17#include "linux/slab.h"
18#include "linux/utime.h"
19#include "asm/mman.h" 12#include "asm/mman.h"
20#include "asm/uaccess.h" 13#include "asm/uaccess.h"
21#include "kern_util.h" 14#include "asm/unistd.h"
22#include "sysdep/syscalls.h"
23#include "mode_kern.h"
24#include "choose-mode.h"
25 15
26/* Unlocked, I don't care if this is a bit off */ 16/* Unlocked, I don't care if this is a bit off */
27int nsyscalls = 0; 17int nsyscalls = 0;
@@ -34,7 +24,7 @@ long sys_fork(void)
34 ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs), 24 ret = do_fork(SIGCHLD, UPT_SP(&current->thread.regs.regs),
35 &current->thread.regs, 0, NULL, NULL); 25 &current->thread.regs, 0, NULL, NULL);
36 current->thread.forking = 0; 26 current->thread.forking = 0;
37 return(ret); 27 return ret;
38} 28}
39 29
40long sys_vfork(void) 30long sys_vfork(void)
@@ -46,7 +36,7 @@ long sys_vfork(void)
46 UPT_SP(&current->thread.regs.regs), 36 UPT_SP(&current->thread.regs.regs),
47 &current->thread.regs, 0, NULL, NULL); 37 &current->thread.regs, 0, NULL, NULL);
48 current->thread.forking = 0; 38 current->thread.forking = 0;
49 return(ret); 39 return ret;
50} 40}
51 41
52/* common code for old and new mmaps */ 42/* common code for old and new mmaps */
@@ -92,15 +82,15 @@ long old_mmap(unsigned long addr, unsigned long len,
92 */ 82 */
93long sys_pipe(unsigned long __user * fildes) 83long sys_pipe(unsigned long __user * fildes)
94{ 84{
95 int fd[2]; 85 int fd[2];
96 long error; 86 long error;
97 87
98 error = do_pipe(fd); 88 error = do_pipe(fd);
99 if (!error) { 89 if (!error) {
100 if (copy_to_user(fildes, fd, sizeof(fd))) 90 if (copy_to_user(fildes, fd, sizeof(fd)))
101 error = -EFAULT; 91 error = -EFAULT;
102 } 92 }
103 return error; 93 return error;
104} 94}
105 95
106 96
@@ -124,7 +114,7 @@ long sys_olduname(struct oldold_utsname __user * name)
124 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname))) 114 if (!access_ok(VERIFY_WRITE,name,sizeof(struct oldold_utsname)))
125 return -EFAULT; 115 return -EFAULT;
126 116
127 down_read(&uts_sem); 117 down_read(&uts_sem);
128 118
129 error = __copy_to_user(&name->sysname, &utsname()->sysname, 119 error = __copy_to_user(&name->sysname, &utsname()->sysname,
130 __OLD_UTS_LEN); 120 __OLD_UTS_LEN);
diff --git a/arch/um/kernel/time.c b/arch/um/kernel/time.c
index 259c49da7ff5..1ac746a9eae1 100644
--- a/arch/um/kernel/time.c
+++ b/arch/um/kernel/time.c
@@ -1,189 +1,126 @@
1/* 1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/kernel.h" 6#include "linux/clockchips.h"
7#include "linux/module.h"
8#include "linux/unistd.h"
9#include "linux/stddef.h"
10#include "linux/spinlock.h"
11#include "linux/time.h"
12#include "linux/sched.h"
13#include "linux/interrupt.h" 7#include "linux/interrupt.h"
14#include "linux/init.h" 8#include "linux/jiffies.h"
15#include "linux/delay.h" 9#include "linux/threads.h"
16#include "linux/hrtimer.h"
17#include "asm/irq.h" 10#include "asm/irq.h"
18#include "asm/param.h" 11#include "asm/param.h"
19#include "asm/current.h"
20#include "kern_util.h" 12#include "kern_util.h"
21#include "mode.h"
22#include "os.h" 13#include "os.h"
23 14
24int hz(void)
25{
26 return(HZ);
27}
28
29/* 15/*
30 * Scheduler clock - returns current time in nanosec units. 16 * Scheduler clock - returns current time in nanosec units.
31 */ 17 */
32unsigned long long sched_clock(void) 18unsigned long long sched_clock(void)
33{ 19{
34 return (unsigned long long)jiffies_64 * (1000000000 / HZ); 20 return (unsigned long long)jiffies_64 * (NSEC_PER_SEC / HZ);
35} 21}
36 22
37#ifdef CONFIG_UML_REAL_TIME_CLOCK 23void timer_handler(int sig, struct uml_pt_regs *regs)
38static unsigned long long prev_nsecs[NR_CPUS]; 24{
39static long long delta[NR_CPUS]; /* Deviation per interval */ 25 unsigned long flags;
40#endif 26
27 local_irq_save(flags);
28 do_IRQ(TIMER_IRQ, regs);
29 local_irq_restore(flags);
30}
41 31
42void timer_irq(union uml_pt_regs *regs) 32static void itimer_set_mode(enum clock_event_mode mode,
33 struct clock_event_device *evt)
43{ 34{
44 unsigned long long ticks = 0; 35 switch(mode) {
45#ifdef CONFIG_UML_REAL_TIME_CLOCK 36 case CLOCK_EVT_MODE_PERIODIC:
46 int c = cpu(); 37 set_interval();
47 if(prev_nsecs[c]){ 38 break;
48 /* We've had 1 tick */ 39
49 unsigned long long nsecs = os_nsecs(); 40 case CLOCK_EVT_MODE_SHUTDOWN:
50 41 case CLOCK_EVT_MODE_UNUSED:
51 delta[c] += nsecs - prev_nsecs[c]; 42 case CLOCK_EVT_MODE_ONESHOT:
52 prev_nsecs[c] = nsecs; 43 disable_timer();
53 44 break;
54 /* Protect against the host clock being set backwards */ 45
55 if(delta[c] < 0) 46 case CLOCK_EVT_MODE_RESUME:
56 delta[c] = 0; 47 break;
57
58 ticks += (delta[c] * HZ) / BILLION;
59 delta[c] -= (ticks * BILLION) / HZ;
60 }
61 else prev_nsecs[c] = os_nsecs();
62#else
63 ticks = 1;
64#endif
65 while(ticks > 0){
66 do_IRQ(TIMER_IRQ, regs);
67 ticks--;
68 } 48 }
69} 49}
70 50
71/* Protects local_offset */ 51static int itimer_next_event(unsigned long delta,
72static DEFINE_SPINLOCK(timer_spinlock); 52 struct clock_event_device *evt)
73static unsigned long long local_offset = 0;
74
75static inline unsigned long long get_time(void)
76{ 53{
77 unsigned long long nsecs; 54 return timer_one_shot(delta + 1);
78 unsigned long flags;
79
80 spin_lock_irqsave(&timer_spinlock, flags);
81 nsecs = os_nsecs();
82 nsecs += local_offset;
83 spin_unlock_irqrestore(&timer_spinlock, flags);
84
85 return nsecs;
86} 55}
87 56
88irqreturn_t um_timer(int irq, void *dev) 57static struct clock_event_device itimer_clockevent = {
58 .name = "itimer",
59 .rating = 250,
60 .cpumask = CPU_MASK_ALL,
61 .features = CLOCK_EVT_FEAT_PERIODIC | CLOCK_EVT_FEAT_ONESHOT,
62 .set_mode = itimer_set_mode,
63 .set_next_event = itimer_next_event,
64 .shift = 32,
65 .irq = 0,
66};
67
68static irqreturn_t um_timer(int irq, void *dev)
89{ 69{
90 unsigned long long nsecs; 70 (*itimer_clockevent.event_handler)(&itimer_clockevent);
91 unsigned long flags;
92
93 write_seqlock_irqsave(&xtime_lock, flags);
94
95 do_timer(1);
96
97#ifdef CONFIG_UML_REAL_TIME_CLOCK
98 nsecs = get_time();
99#else
100 nsecs = (unsigned long long) xtime.tv_sec * BILLION + xtime.tv_nsec +
101 BILLION / HZ;
102#endif
103 xtime.tv_sec = nsecs / NSEC_PER_SEC;
104 xtime.tv_nsec = nsecs - xtime.tv_sec * NSEC_PER_SEC;
105
106 write_sequnlock_irqrestore(&xtime_lock, flags);
107 71
108 return IRQ_HANDLED; 72 return IRQ_HANDLED;
109} 73}
110 74
111static void register_timer(void) 75static cycle_t itimer_read(void)
76{
77 return os_nsecs();
78}
79
80static struct clocksource itimer_clocksource = {
81 .name = "itimer",
82 .rating = 300,
83 .read = itimer_read,
84 .mask = CLOCKSOURCE_MASK(64),
85 .mult = 1,
86 .shift = 0,
87 .flags = CLOCK_SOURCE_IS_CONTINUOUS,
88};
89
90static void __init setup_itimer(void)
112{ 91{
113 int err; 92 int err;
114 93
115 err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL); 94 err = request_irq(TIMER_IRQ, um_timer, IRQF_DISABLED, "timer", NULL);
116 if(err != 0) 95 if (err != 0)
117 printk(KERN_ERR "register_timer : request_irq failed - " 96 printk(KERN_ERR "register_timer : request_irq failed - "
118 "errno = %d\n", -err); 97 "errno = %d\n", -err);
119 98
120 err = set_interval(1); 99 itimer_clockevent.mult = div_sc(HZ, NSEC_PER_SEC, 32);
121 if(err != 0) 100 itimer_clockevent.max_delta_ns =
122 printk(KERN_ERR "register_timer : set_interval failed - " 101 clockevent_delta2ns(60 * HZ, &itimer_clockevent);
123 "errno = %d\n", -err); 102 itimer_clockevent.min_delta_ns =
103 clockevent_delta2ns(1, &itimer_clockevent);
104 err = clocksource_register(&itimer_clocksource);
105 if (err) {
106 printk(KERN_ERR "clocksource_register returned %d\n", err);
107 return;
108 }
109 clockevents_register_device(&itimer_clockevent);
124} 110}
125 111
126extern void (*late_time_init)(void); 112extern void (*late_time_init)(void);
127 113
128void time_init(void) 114void __init time_init(void)
129{ 115{
130 long long nsecs; 116 long long nsecs;
131 117
132 nsecs = os_nsecs(); 118 timer_init();
133 set_normalized_timespec(&wall_to_monotonic, -nsecs / BILLION,
134 -nsecs % BILLION);
135 set_normalized_timespec(&xtime, nsecs / BILLION, nsecs % BILLION);
136 late_time_init = register_timer;
137}
138
139void do_gettimeofday(struct timeval *tv)
140{
141#ifdef CONFIG_UML_REAL_TIME_CLOCK
142 unsigned long long nsecs = get_time();
143#else
144 unsigned long long nsecs = (unsigned long long) xtime.tv_sec * BILLION +
145 xtime.tv_nsec;
146#endif
147 tv->tv_sec = nsecs / NSEC_PER_SEC;
148 /* Careful about calculations here - this was originally done as
149 * (nsecs - tv->tv_sec * NSEC_PER_SEC) / NSEC_PER_USEC
150 * which gave bogus (> 1000000) values. Dunno why, suspect gcc
151 * (4.0.0) miscompiled it, or there's a subtle 64/32-bit conversion
152 * problem that I missed.
153 */
154 nsecs -= tv->tv_sec * NSEC_PER_SEC;
155 tv->tv_usec = (unsigned long) nsecs / NSEC_PER_USEC;
156}
157
158static inline void set_time(unsigned long long nsecs)
159{
160 unsigned long long now;
161 unsigned long flags;
162
163 spin_lock_irqsave(&timer_spinlock, flags);
164 now = os_nsecs();
165 local_offset = nsecs - now;
166 spin_unlock_irqrestore(&timer_spinlock, flags);
167
168 clock_was_set();
169}
170
171int do_settimeofday(struct timespec *tv)
172{
173 set_time((unsigned long long) tv->tv_sec * NSEC_PER_SEC + tv->tv_nsec);
174
175 return 0;
176}
177 119
178void timer_handler(int sig, union uml_pt_regs *regs) 120 nsecs = os_nsecs();
179{ 121 set_normalized_timespec(&wall_to_monotonic, -nsecs / NSEC_PER_SEC,
180 if(current_thread->cpu == 0) 122 -nsecs % NSEC_PER_SEC);
181 timer_irq(regs); 123 set_normalized_timespec(&xtime, nsecs / NSEC_PER_SEC,
182 local_irq_disable(); 124 nsecs % NSEC_PER_SEC);
183 irq_enter(); 125 late_time_init = setup_itimer;
184 update_process_times(CHOOSE_MODE(
185 (UPT_SC(regs) && user_context(UPT_SP(regs))),
186 (regs)->skas.is_user));
187 irq_exit();
188 local_irq_enable();
189} 126}
diff --git a/arch/um/kernel/tlb.c b/arch/um/kernel/tlb.c
index 8a8d52851443..f4a0e407eee4 100644
--- a/arch/um/kernel/tlb.c
+++ b/arch/um/kernel/tlb.c
@@ -1,130 +1,182 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/mm.h" 6#include "linux/mm.h"
7#include "asm/page.h"
8#include "asm/pgalloc.h"
9#include "asm/pgtable.h" 7#include "asm/pgtable.h"
10#include "asm/tlbflush.h" 8#include "asm/tlbflush.h"
11#include "choose-mode.h"
12#include "mode_kern.h"
13#include "as-layout.h" 9#include "as-layout.h"
14#include "tlb.h"
15#include "mem.h"
16#include "mem_user.h" 10#include "mem_user.h"
17#include "os.h" 11#include "os.h"
12#include "skas.h"
13#include "tlb.h"
14
15struct host_vm_change {
16 struct host_vm_op {
17 enum { NONE, MMAP, MUNMAP, MPROTECT } type;
18 union {
19 struct {
20 unsigned long addr;
21 unsigned long len;
22 unsigned int prot;
23 int fd;
24 __u64 offset;
25 } mmap;
26 struct {
27 unsigned long addr;
28 unsigned long len;
29 } munmap;
30 struct {
31 unsigned long addr;
32 unsigned long len;
33 unsigned int prot;
34 } mprotect;
35 } u;
36 } ops[1];
37 int index;
38 struct mm_id *id;
39 void *data;
40 int force;
41};
42
43#define INIT_HVC(mm, force) \
44 ((struct host_vm_change) \
45 { .ops = { { .type = NONE } }, \
46 .id = &mm->context.id, \
47 .data = NULL, \
48 .index = 0, \
49 .force = force })
50
51static int do_ops(struct host_vm_change *hvc, int end,
52 int finished)
53{
54 struct host_vm_op *op;
55 int i, ret = 0;
56
57 for (i = 0; i < end && !ret; i++) {
58 op = &hvc->ops[i];
59 switch(op->type) {
60 case MMAP:
61 ret = map(hvc->id, op->u.mmap.addr, op->u.mmap.len,
62 op->u.mmap.prot, op->u.mmap.fd,
63 op->u.mmap.offset, finished, &hvc->data);
64 break;
65 case MUNMAP:
66 ret = unmap(hvc->id, op->u.munmap.addr,
67 op->u.munmap.len, finished, &hvc->data);
68 break;
69 case MPROTECT:
70 ret = protect(hvc->id, op->u.mprotect.addr,
71 op->u.mprotect.len, op->u.mprotect.prot,
72 finished, &hvc->data);
73 break;
74 default:
75 printk(KERN_ERR "Unknown op type %d in do_ops\n",
76 op->type);
77 break;
78 }
79 }
80
81 return ret;
82}
18 83
19static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len, 84static int add_mmap(unsigned long virt, unsigned long phys, unsigned long len,
20 unsigned int prot, struct host_vm_op *ops, int *index, 85 unsigned int prot, struct host_vm_change *hvc)
21 int last_filled, union mm_context *mmu, void **flush,
22 int (*do_ops)(union mm_context *, struct host_vm_op *,
23 int, int, void **))
24{ 86{
25 __u64 offset; 87 __u64 offset;
26 struct host_vm_op *last; 88 struct host_vm_op *last;
27 int fd, ret = 0; 89 int fd, ret = 0;
28 90
29 fd = phys_mapping(phys, &offset); 91 fd = phys_mapping(phys, &offset);
30 if(*index != -1){ 92 if (hvc->index != 0) {
31 last = &ops[*index]; 93 last = &hvc->ops[hvc->index - 1];
32 if((last->type == MMAP) && 94 if ((last->type == MMAP) &&
33 (last->u.mmap.addr + last->u.mmap.len == virt) && 95 (last->u.mmap.addr + last->u.mmap.len == virt) &&
34 (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) && 96 (last->u.mmap.prot == prot) && (last->u.mmap.fd == fd) &&
35 (last->u.mmap.offset + last->u.mmap.len == offset)){ 97 (last->u.mmap.offset + last->u.mmap.len == offset)) {
36 last->u.mmap.len += len; 98 last->u.mmap.len += len;
37 return 0; 99 return 0;
38 } 100 }
39 } 101 }
40 102
41 if(*index == last_filled){ 103 if (hvc->index == ARRAY_SIZE(hvc->ops)) {
42 ret = (*do_ops)(mmu, ops, last_filled, 0, flush); 104 ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0);
43 *index = -1; 105 hvc->index = 0;
44 } 106 }
45 107
46 ops[++*index] = ((struct host_vm_op) { .type = MMAP, 108 hvc->ops[hvc->index++] = ((struct host_vm_op)
47 .u = { .mmap = { 109 { .type = MMAP,
48 .addr = virt, 110 .u = { .mmap = { .addr = virt,
49 .len = len, 111 .len = len,
50 .prot = prot, 112 .prot = prot,
51 .fd = fd, 113 .fd = fd,
52 .offset = offset } 114 .offset = offset }
53 } }); 115 } });
54 return ret; 116 return ret;
55} 117}
56 118
57static int add_munmap(unsigned long addr, unsigned long len, 119static int add_munmap(unsigned long addr, unsigned long len,
58 struct host_vm_op *ops, int *index, int last_filled, 120 struct host_vm_change *hvc)
59 union mm_context *mmu, void **flush,
60 int (*do_ops)(union mm_context *, struct host_vm_op *,
61 int, int, void **))
62{ 121{
63 struct host_vm_op *last; 122 struct host_vm_op *last;
64 int ret = 0; 123 int ret = 0;
65 124
66 if(*index != -1){ 125 if (hvc->index != 0) {
67 last = &ops[*index]; 126 last = &hvc->ops[hvc->index - 1];
68 if((last->type == MUNMAP) && 127 if ((last->type == MUNMAP) &&
69 (last->u.munmap.addr + last->u.mmap.len == addr)){ 128 (last->u.munmap.addr + last->u.mmap.len == addr)) {
70 last->u.munmap.len += len; 129 last->u.munmap.len += len;
71 return 0; 130 return 0;
72 } 131 }
73 } 132 }
74 133
75 if(*index == last_filled){ 134 if (hvc->index == ARRAY_SIZE(hvc->ops)) {
76 ret = (*do_ops)(mmu, ops, last_filled, 0, flush); 135 ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0);
77 *index = -1; 136 hvc->index = 0;
78 } 137 }
79 138
80 ops[++*index] = ((struct host_vm_op) { .type = MUNMAP, 139 hvc->ops[hvc->index++] = ((struct host_vm_op)
81 .u = { .munmap = { 140 { .type = MUNMAP,
82 .addr = addr, 141 .u = { .munmap = { .addr = addr,
83 .len = len } } }); 142 .len = len } } });
84 return ret; 143 return ret;
85} 144}
86 145
87static int add_mprotect(unsigned long addr, unsigned long len, 146static int add_mprotect(unsigned long addr, unsigned long len,
88 unsigned int prot, struct host_vm_op *ops, int *index, 147 unsigned int prot, struct host_vm_change *hvc)
89 int last_filled, union mm_context *mmu, void **flush,
90 int (*do_ops)(union mm_context *, struct host_vm_op *,
91 int, int, void **))
92{ 148{
93 struct host_vm_op *last; 149 struct host_vm_op *last;
94 int ret = 0; 150 int ret = 0;
95 151
96 if(*index != -1){ 152 if (hvc->index != 0) {
97 last = &ops[*index]; 153 last = &hvc->ops[hvc->index - 1];
98 if((last->type == MPROTECT) && 154 if ((last->type == MPROTECT) &&
99 (last->u.mprotect.addr + last->u.mprotect.len == addr) && 155 (last->u.mprotect.addr + last->u.mprotect.len == addr) &&
100 (last->u.mprotect.prot == prot)){ 156 (last->u.mprotect.prot == prot)) {
101 last->u.mprotect.len += len; 157 last->u.mprotect.len += len;
102 return 0; 158 return 0;
103 } 159 }
104 } 160 }
105 161
106 if(*index == last_filled){ 162 if (hvc->index == ARRAY_SIZE(hvc->ops)) {
107 ret = (*do_ops)(mmu, ops, last_filled, 0, flush); 163 ret = do_ops(hvc, ARRAY_SIZE(hvc->ops), 0);
108 *index = -1; 164 hvc->index = 0;
109 } 165 }
110 166
111 ops[++*index] = ((struct host_vm_op) { .type = MPROTECT, 167 hvc->ops[hvc->index++] = ((struct host_vm_op)
112 .u = { .mprotect = { 168 { .type = MPROTECT,
113 .addr = addr, 169 .u = { .mprotect = { .addr = addr,
114 .len = len, 170 .len = len,
115 .prot = prot } } }); 171 .prot = prot } } });
116 return ret; 172 return ret;
117} 173}
118 174
119#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1)) 175#define ADD_ROUND(n, inc) (((n) + (inc)) & ~((inc) - 1))
120 176
121static inline int update_pte_range(pmd_t *pmd, unsigned long addr, 177static inline int update_pte_range(pmd_t *pmd, unsigned long addr,
122 unsigned long end, struct host_vm_op *ops, 178 unsigned long end,
123 int last_op, int *op_index, int force, 179 struct host_vm_change *hvc)
124 union mm_context *mmu, void **flush,
125 int (*do_ops)(union mm_context *,
126 struct host_vm_op *, int, int,
127 void **))
128{ 180{
129 pte_t *pte; 181 pte_t *pte;
130 int r, w, x, prot, ret = 0; 182 int r, w, x, prot, ret = 0;
@@ -142,29 +194,22 @@ static inline int update_pte_range(pmd_t *pmd, unsigned long addr,
142 } 194 }
143 prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) | 195 prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
144 (x ? UM_PROT_EXEC : 0)); 196 (x ? UM_PROT_EXEC : 0));
145 if(force || pte_newpage(*pte)){ 197 if (hvc->force || pte_newpage(*pte)) {
146 if(pte_present(*pte)) 198 if (pte_present(*pte))
147 ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK, 199 ret = add_mmap(addr, pte_val(*pte) & PAGE_MASK,
148 PAGE_SIZE, prot, ops, op_index, 200 PAGE_SIZE, prot, hvc);
149 last_op, mmu, flush, do_ops); 201 else ret = add_munmap(addr, PAGE_SIZE, hvc);
150 else ret = add_munmap(addr, PAGE_SIZE, ops, op_index,
151 last_op, mmu, flush, do_ops);
152 } 202 }
153 else if(pte_newprot(*pte)) 203 else if (pte_newprot(*pte))
154 ret = add_mprotect(addr, PAGE_SIZE, prot, ops, op_index, 204 ret = add_mprotect(addr, PAGE_SIZE, prot, hvc);
155 last_op, mmu, flush, do_ops);
156 *pte = pte_mkuptodate(*pte); 205 *pte = pte_mkuptodate(*pte);
157 } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret)); 206 } while (pte++, addr += PAGE_SIZE, ((addr != end) && !ret));
158 return ret; 207 return ret;
159} 208}
160 209
161static inline int update_pmd_range(pud_t *pud, unsigned long addr, 210static inline int update_pmd_range(pud_t *pud, unsigned long addr,
162 unsigned long end, struct host_vm_op *ops, 211 unsigned long end,
163 int last_op, int *op_index, int force, 212 struct host_vm_change *hvc)
164 union mm_context *mmu, void **flush,
165 int (*do_ops)(union mm_context *,
166 struct host_vm_op *, int, int,
167 void **))
168{ 213{
169 pmd_t *pmd; 214 pmd_t *pmd;
170 unsigned long next; 215 unsigned long next;
@@ -173,28 +218,20 @@ static inline int update_pmd_range(pud_t *pud, unsigned long addr,
173 pmd = pmd_offset(pud, addr); 218 pmd = pmd_offset(pud, addr);
174 do { 219 do {
175 next = pmd_addr_end(addr, end); 220 next = pmd_addr_end(addr, end);
176 if(!pmd_present(*pmd)){ 221 if (!pmd_present(*pmd)) {
177 if(force || pmd_newpage(*pmd)){ 222 if (hvc->force || pmd_newpage(*pmd)) {
178 ret = add_munmap(addr, next - addr, ops, 223 ret = add_munmap(addr, next - addr, hvc);
179 op_index, last_op, mmu,
180 flush, do_ops);
181 pmd_mkuptodate(*pmd); 224 pmd_mkuptodate(*pmd);
182 } 225 }
183 } 226 }
184 else ret = update_pte_range(pmd, addr, next, ops, last_op, 227 else ret = update_pte_range(pmd, addr, next, hvc);
185 op_index, force, mmu, flush,
186 do_ops);
187 } while (pmd++, addr = next, ((addr != end) && !ret)); 228 } while (pmd++, addr = next, ((addr != end) && !ret));
188 return ret; 229 return ret;
189} 230}
190 231
191static inline int update_pud_range(pgd_t *pgd, unsigned long addr, 232static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
192 unsigned long end, struct host_vm_op *ops, 233 unsigned long end,
193 int last_op, int *op_index, int force, 234 struct host_vm_change *hvc)
194 union mm_context *mmu, void **flush,
195 int (*do_ops)(union mm_context *,
196 struct host_vm_op *, int, int,
197 void **))
198{ 235{
199 pud_t *pud; 236 pud_t *pud;
200 unsigned long next; 237 unsigned long next;
@@ -203,56 +240,45 @@ static inline int update_pud_range(pgd_t *pgd, unsigned long addr,
203 pud = pud_offset(pgd, addr); 240 pud = pud_offset(pgd, addr);
204 do { 241 do {
205 next = pud_addr_end(addr, end); 242 next = pud_addr_end(addr, end);
206 if(!pud_present(*pud)){ 243 if (!pud_present(*pud)) {
207 if(force || pud_newpage(*pud)){ 244 if (hvc->force || pud_newpage(*pud)) {
208 ret = add_munmap(addr, next - addr, ops, 245 ret = add_munmap(addr, next - addr, hvc);
209 op_index, last_op, mmu,
210 flush, do_ops);
211 pud_mkuptodate(*pud); 246 pud_mkuptodate(*pud);
212 } 247 }
213 } 248 }
214 else ret = update_pmd_range(pud, addr, next, ops, last_op, 249 else ret = update_pmd_range(pud, addr, next, hvc);
215 op_index, force, mmu, flush,
216 do_ops);
217 } while (pud++, addr = next, ((addr != end) && !ret)); 250 } while (pud++, addr = next, ((addr != end) && !ret));
218 return ret; 251 return ret;
219} 252}
220 253
221void fix_range_common(struct mm_struct *mm, unsigned long start_addr, 254void fix_range_common(struct mm_struct *mm, unsigned long start_addr,
222 unsigned long end_addr, int force, 255 unsigned long end_addr, int force)
223 int (*do_ops)(union mm_context *, struct host_vm_op *,
224 int, int, void **))
225{ 256{
226 pgd_t *pgd; 257 pgd_t *pgd;
227 union mm_context *mmu = &mm->context; 258 struct host_vm_change hvc;
228 struct host_vm_op ops[1];
229 unsigned long addr = start_addr, next; 259 unsigned long addr = start_addr, next;
230 int ret = 0, last_op = ARRAY_SIZE(ops) - 1, op_index = -1; 260 int ret = 0;
231 void *flush = NULL;
232 261
233 ops[0].type = NONE; 262 hvc = INIT_HVC(mm, force);
234 pgd = pgd_offset(mm, addr); 263 pgd = pgd_offset(mm, addr);
235 do { 264 do {
236 next = pgd_addr_end(addr, end_addr); 265 next = pgd_addr_end(addr, end_addr);
237 if(!pgd_present(*pgd)){ 266 if (!pgd_present(*pgd)) {
238 if (force || pgd_newpage(*pgd)){ 267 if (force || pgd_newpage(*pgd)) {
239 ret = add_munmap(addr, next - addr, ops, 268 ret = add_munmap(addr, next - addr, &hvc);
240 &op_index, last_op, mmu,
241 &flush, do_ops);
242 pgd_mkuptodate(*pgd); 269 pgd_mkuptodate(*pgd);
243 } 270 }
244 } 271 }
245 else ret = update_pud_range(pgd, addr, next, ops, last_op, 272 else ret = update_pud_range(pgd, addr, next, &hvc);
246 &op_index, force, mmu, &flush,
247 do_ops);
248 } while (pgd++, addr = next, ((addr != end_addr) && !ret)); 273 } while (pgd++, addr = next, ((addr != end_addr) && !ret));
249 274
250 if(!ret) 275 if (!ret)
251 ret = (*do_ops)(mmu, ops, op_index, 1, &flush); 276 ret = do_ops(&hvc, hvc.index, 1);
252 277
253 /* This is not an else because ret is modified above */ 278 /* This is not an else because ret is modified above */
254 if(ret) { 279 if (ret) {
255 printk("fix_range_common: failed, killing current process\n"); 280 printk(KERN_ERR "fix_range_common: failed, killing current "
281 "process\n");
256 force_sig(SIGKILL, current); 282 force_sig(SIGKILL, current);
257 } 283 }
258} 284}
@@ -268,17 +294,17 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
268 int updated = 0, err; 294 int updated = 0, err;
269 295
270 mm = &init_mm; 296 mm = &init_mm;
271 for(addr = start; addr < end;){ 297 for (addr = start; addr < end;) {
272 pgd = pgd_offset(mm, addr); 298 pgd = pgd_offset(mm, addr);
273 if(!pgd_present(*pgd)){ 299 if (!pgd_present(*pgd)) {
274 last = ADD_ROUND(addr, PGDIR_SIZE); 300 last = ADD_ROUND(addr, PGDIR_SIZE);
275 if(last > end) 301 if (last > end)
276 last = end; 302 last = end;
277 if(pgd_newpage(*pgd)){ 303 if (pgd_newpage(*pgd)) {
278 updated = 1; 304 updated = 1;
279 err = os_unmap_memory((void *) addr, 305 err = os_unmap_memory((void *) addr,
280 last - addr); 306 last - addr);
281 if(err < 0) 307 if (err < 0)
282 panic("munmap failed, errno = %d\n", 308 panic("munmap failed, errno = %d\n",
283 -err); 309 -err);
284 } 310 }
@@ -287,15 +313,15 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
287 } 313 }
288 314
289 pud = pud_offset(pgd, addr); 315 pud = pud_offset(pgd, addr);
290 if(!pud_present(*pud)){ 316 if (!pud_present(*pud)) {
291 last = ADD_ROUND(addr, PUD_SIZE); 317 last = ADD_ROUND(addr, PUD_SIZE);
292 if(last > end) 318 if (last > end)
293 last = end; 319 last = end;
294 if(pud_newpage(*pud)){ 320 if (pud_newpage(*pud)) {
295 updated = 1; 321 updated = 1;
296 err = os_unmap_memory((void *) addr, 322 err = os_unmap_memory((void *) addr,
297 last - addr); 323 last - addr);
298 if(err < 0) 324 if (err < 0)
299 panic("munmap failed, errno = %d\n", 325 panic("munmap failed, errno = %d\n",
300 -err); 326 -err);
301 } 327 }
@@ -304,15 +330,15 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
304 } 330 }
305 331
306 pmd = pmd_offset(pud, addr); 332 pmd = pmd_offset(pud, addr);
307 if(!pmd_present(*pmd)){ 333 if (!pmd_present(*pmd)) {
308 last = ADD_ROUND(addr, PMD_SIZE); 334 last = ADD_ROUND(addr, PMD_SIZE);
309 if(last > end) 335 if (last > end)
310 last = end; 336 last = end;
311 if(pmd_newpage(*pmd)){ 337 if (pmd_newpage(*pmd)) {
312 updated = 1; 338 updated = 1;
313 err = os_unmap_memory((void *) addr, 339 err = os_unmap_memory((void *) addr,
314 last - addr); 340 last - addr);
315 if(err < 0) 341 if (err < 0)
316 panic("munmap failed, errno = %d\n", 342 panic("munmap failed, errno = %d\n",
317 -err); 343 -err);
318 } 344 }
@@ -321,45 +347,110 @@ int flush_tlb_kernel_range_common(unsigned long start, unsigned long end)
321 } 347 }
322 348
323 pte = pte_offset_kernel(pmd, addr); 349 pte = pte_offset_kernel(pmd, addr);
324 if(!pte_present(*pte) || pte_newpage(*pte)){ 350 if (!pte_present(*pte) || pte_newpage(*pte)) {
325 updated = 1; 351 updated = 1;
326 err = os_unmap_memory((void *) addr, 352 err = os_unmap_memory((void *) addr,
327 PAGE_SIZE); 353 PAGE_SIZE);
328 if(err < 0) 354 if (err < 0)
329 panic("munmap failed, errno = %d\n", 355 panic("munmap failed, errno = %d\n",
330 -err); 356 -err);
331 if(pte_present(*pte)) 357 if (pte_present(*pte))
332 map_memory(addr, 358 map_memory(addr,
333 pte_val(*pte) & PAGE_MASK, 359 pte_val(*pte) & PAGE_MASK,
334 PAGE_SIZE, 1, 1, 1); 360 PAGE_SIZE, 1, 1, 1);
335 } 361 }
336 else if(pte_newprot(*pte)){ 362 else if (pte_newprot(*pte)) {
337 updated = 1; 363 updated = 1;
338 os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1); 364 os_protect_memory((void *) addr, PAGE_SIZE, 1, 1, 1);
339 } 365 }
340 addr += PAGE_SIZE; 366 addr += PAGE_SIZE;
341 } 367 }
342 return(updated); 368 return updated;
369}
370
371void flush_tlb_page(struct vm_area_struct *vma, unsigned long address)
372{
373 pgd_t *pgd;
374 pud_t *pud;
375 pmd_t *pmd;
376 pte_t *pte;
377 struct mm_struct *mm = vma->vm_mm;
378 void *flush = NULL;
379 int r, w, x, prot, err = 0;
380 struct mm_id *mm_id;
381
382 address &= PAGE_MASK;
383 pgd = pgd_offset(mm, address);
384 if (!pgd_present(*pgd))
385 goto kill;
386
387 pud = pud_offset(pgd, address);
388 if (!pud_present(*pud))
389 goto kill;
390
391 pmd = pmd_offset(pud, address);
392 if (!pmd_present(*pmd))
393 goto kill;
394
395 pte = pte_offset_kernel(pmd, address);
396
397 r = pte_read(*pte);
398 w = pte_write(*pte);
399 x = pte_exec(*pte);
400 if (!pte_young(*pte)) {
401 r = 0;
402 w = 0;
403 } else if (!pte_dirty(*pte)) {
404 w = 0;
405 }
406
407 mm_id = &mm->context.id;
408 prot = ((r ? UM_PROT_READ : 0) | (w ? UM_PROT_WRITE : 0) |
409 (x ? UM_PROT_EXEC : 0));
410 if (pte_newpage(*pte)) {
411 if (pte_present(*pte)) {
412 unsigned long long offset;
413 int fd;
414
415 fd = phys_mapping(pte_val(*pte) & PAGE_MASK, &offset);
416 err = map(mm_id, address, PAGE_SIZE, prot, fd, offset,
417 1, &flush);
418 }
419 else err = unmap(mm_id, address, PAGE_SIZE, 1, &flush);
420 }
421 else if (pte_newprot(*pte))
422 err = protect(mm_id, address, PAGE_SIZE, prot, 1, &flush);
423
424 if (err)
425 goto kill;
426
427 *pte = pte_mkuptodate(*pte);
428
429 return;
430
431kill:
432 printk(KERN_ERR "Failed to flush page for address 0x%lx\n", address);
433 force_sig(SIGKILL, current);
343} 434}
344 435
345pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address) 436pgd_t *pgd_offset_proc(struct mm_struct *mm, unsigned long address)
346{ 437{
347 return(pgd_offset(mm, address)); 438 return pgd_offset(mm, address);
348} 439}
349 440
350pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address) 441pud_t *pud_offset_proc(pgd_t *pgd, unsigned long address)
351{ 442{
352 return(pud_offset(pgd, address)); 443 return pud_offset(pgd, address);
353} 444}
354 445
355pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address) 446pmd_t *pmd_offset_proc(pud_t *pud, unsigned long address)
356{ 447{
357 return(pmd_offset(pud, address)); 448 return pmd_offset(pud, address);
358} 449}
359 450
360pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address) 451pte_t *pte_offset_proc(pmd_t *pmd, unsigned long address)
361{ 452{
362 return(pte_offset_kernel(pmd, address)); 453 return pte_offset_kernel(pmd, address);
363} 454}
364 455
365pte_t *addr_pte(struct task_struct *task, unsigned long addr) 456pte_t *addr_pte(struct task_struct *task, unsigned long addr)
@@ -368,7 +459,7 @@ pte_t *addr_pte(struct task_struct *task, unsigned long addr)
368 pud_t *pud = pud_offset(pgd, addr); 459 pud_t *pud = pud_offset(pgd, addr);
369 pmd_t *pmd = pmd_offset(pud, addr); 460 pmd_t *pmd = pmd_offset(pud, addr);
370 461
371 return(pte_offset_map(pmd, addr)); 462 return pte_offset_map(pmd, addr);
372} 463}
373 464
374void flush_tlb_all(void) 465void flush_tlb_all(void)
@@ -378,35 +469,58 @@ void flush_tlb_all(void)
378 469
379void flush_tlb_kernel_range(unsigned long start, unsigned long end) 470void flush_tlb_kernel_range(unsigned long start, unsigned long end)
380{ 471{
381 CHOOSE_MODE_PROC(flush_tlb_kernel_range_tt, 472 flush_tlb_kernel_range_common(start, end);
382 flush_tlb_kernel_range_common, start, end);
383} 473}
384 474
385void flush_tlb_kernel_vm(void) 475void flush_tlb_kernel_vm(void)
386{ 476{
387 CHOOSE_MODE(flush_tlb_kernel_vm_tt(), 477 flush_tlb_kernel_range_common(start_vm, end_vm);
388 flush_tlb_kernel_range_common(start_vm, end_vm));
389} 478}
390 479
391void __flush_tlb_one(unsigned long addr) 480void __flush_tlb_one(unsigned long addr)
392{ 481{
393 CHOOSE_MODE_PROC(__flush_tlb_one_tt, __flush_tlb_one_skas, addr); 482 flush_tlb_kernel_range_common(addr, addr + PAGE_SIZE);
483}
484
485static void fix_range(struct mm_struct *mm, unsigned long start_addr,
486 unsigned long end_addr, int force)
487{
488 if (!proc_mm && (end_addr > STUB_START))
489 end_addr = STUB_START;
490
491 fix_range_common(mm, start_addr, end_addr, force);
394} 492}
395 493
396void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 494void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
397 unsigned long end) 495 unsigned long end)
398{ 496{
399 CHOOSE_MODE_PROC(flush_tlb_range_tt, flush_tlb_range_skas, vma, start, 497 if (vma->vm_mm == NULL)
400 end); 498 flush_tlb_kernel_range_common(start, end);
499 else fix_range(vma->vm_mm, start, end, 0);
401} 500}
402 501
403void flush_tlb_mm(struct mm_struct *mm) 502void flush_tlb_mm(struct mm_struct *mm)
404{ 503{
405 CHOOSE_MODE_PROC(flush_tlb_mm_tt, flush_tlb_mm_skas, mm); 504 unsigned long end;
505
506 /*
507 * Don't bother flushing if this address space is about to be
508 * destroyed.
509 */
510 if (atomic_read(&mm->mm_users) == 0)
511 return;
512
513 end = proc_mm ? task_size : STUB_START;
514 fix_range(mm, 0, end, 0);
406} 515}
407 516
408void force_flush_all(void) 517void force_flush_all(void)
409{ 518{
410 CHOOSE_MODE(force_flush_all_tt(), force_flush_all_skas()); 519 struct mm_struct *mm = current->mm;
411} 520 struct vm_area_struct *vma = mm->mmap;
412 521
522 while (vma != NULL) {
523 fix_range(mm, vma->vm_start, vma->vm_end, 1);
524 vma = vma->vm_next;
525 }
526}
diff --git a/arch/um/kernel/trap.c b/arch/um/kernel/trap.c
index 3850d53f79fd..bd060551e619 100644
--- a/arch/um/kernel/trap.c
+++ b/arch/um/kernel/trap.c
@@ -1,40 +1,24 @@
1/* 1/*
2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/kernel.h" 6#include <linux/mm.h>
7#include "asm/errno.h" 7#include <linux/sched.h>
8#include "linux/sched.h" 8#include <linux/hardirq.h>
9#include "linux/mm.h" 9#include <asm/current.h>
10#include "linux/spinlock.h" 10#include <asm/pgtable.h>
11#include "linux/init.h" 11#include <asm/tlbflush.h>
12#include "linux/ptrace.h"
13#include "asm/semaphore.h"
14#include "asm/pgtable.h"
15#include "asm/pgalloc.h"
16#include "asm/tlbflush.h"
17#include "asm/a.out.h"
18#include "asm/current.h"
19#include "asm/irq.h"
20#include "sysdep/sigcontext.h"
21#include "kern_util.h"
22#include "as-layout.h"
23#include "arch.h" 12#include "arch.h"
24#include "kern.h" 13#include "as-layout.h"
25#include "chan_kern.h" 14#include "kern_util.h"
26#include "mconsole_kern.h"
27#include "mem.h"
28#include "mem_kern.h"
29#include "sysdep/sigcontext.h"
30#include "sysdep/ptrace.h"
31#include "os.h"
32#ifdef CONFIG_MODE_SKAS
33#include "skas.h"
34#endif
35#include "os.h" 15#include "os.h"
16#include "sysdep/sigcontext.h"
36 17
37/* Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by segv(). */ 18/*
19 * Note this is constrained to return 0, -EFAULT, -EACCESS, -ENOMEM by
20 * segv().
21 */
38int handle_page_fault(unsigned long address, unsigned long ip, 22int handle_page_fault(unsigned long address, unsigned long ip,
39 int is_write, int is_user, int *code_out) 23 int is_write, int is_user, int *code_out)
40{ 24{
@@ -48,31 +32,33 @@ int handle_page_fault(unsigned long address, unsigned long ip,
48 32
49 *code_out = SEGV_MAPERR; 33 *code_out = SEGV_MAPERR;
50 34
51 /* If the fault was during atomic operation, don't take the fault, just 35 /*
52 * fail. */ 36 * If the fault was during atomic operation, don't take the fault, just
37 * fail.
38 */
53 if (in_atomic()) 39 if (in_atomic())
54 goto out_nosemaphore; 40 goto out_nosemaphore;
55 41
56 down_read(&mm->mmap_sem); 42 down_read(&mm->mmap_sem);
57 vma = find_vma(mm, address); 43 vma = find_vma(mm, address);
58 if(!vma) 44 if (!vma)
59 goto out; 45 goto out;
60 else if(vma->vm_start <= address) 46 else if (vma->vm_start <= address)
61 goto good_area; 47 goto good_area;
62 else if(!(vma->vm_flags & VM_GROWSDOWN)) 48 else if (!(vma->vm_flags & VM_GROWSDOWN))
63 goto out; 49 goto out;
64 else if(is_user && !ARCH_IS_STACKGROW(address)) 50 else if (is_user && !ARCH_IS_STACKGROW(address))
65 goto out; 51 goto out;
66 else if(expand_stack(vma, address)) 52 else if (expand_stack(vma, address))
67 goto out; 53 goto out;
68 54
69good_area: 55good_area:
70 *code_out = SEGV_ACCERR; 56 *code_out = SEGV_ACCERR;
71 if(is_write && !(vma->vm_flags & VM_WRITE)) 57 if (is_write && !(vma->vm_flags & VM_WRITE))
72 goto out; 58 goto out;
73 59
74 /* Don't require VM_READ|VM_EXEC for write faults! */ 60 /* Don't require VM_READ|VM_EXEC for write faults! */
75 if(!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC))) 61 if (!is_write && !(vma->vm_flags & (VM_READ | VM_EXEC)))
76 goto out; 62 goto out;
77 63
78 do { 64 do {
@@ -98,9 +84,10 @@ survive:
98 pud = pud_offset(pgd, address); 84 pud = pud_offset(pgd, address);
99 pmd = pmd_offset(pud, address); 85 pmd = pmd_offset(pud, address);
100 pte = pte_offset_kernel(pmd, address); 86 pte = pte_offset_kernel(pmd, address);
101 } while(!pte_present(*pte)); 87 } while (!pte_present(*pte));
102 err = 0; 88 err = 0;
103 /* The below warning was added in place of 89 /*
90 * The below warning was added in place of
104 * pte_mkyoung(); if (is_write) pte_mkdirty(); 91 * pte_mkyoung(); if (is_write) pte_mkdirty();
105 * If it's triggered, we'd see normally a hang here (a clean pte is 92 * If it's triggered, we'd see normally a hang here (a clean pte is
106 * marked read-only to emulate the dirty bit). 93 * marked read-only to emulate the dirty bit).
@@ -114,7 +101,7 @@ survive:
114out: 101out:
115 up_read(&mm->mmap_sem); 102 up_read(&mm->mmap_sem);
116out_nosemaphore: 103out_nosemaphore:
117 return(err); 104 return err;
118 105
119/* 106/*
120 * We ran out of memory, or some other thing happened to us that made 107 * We ran out of memory, or some other thing happened to us that made
@@ -141,11 +128,11 @@ static void bad_segv(struct faultinfo fi, unsigned long ip)
141 force_sig_info(SIGSEGV, &si, current); 128 force_sig_info(SIGSEGV, &si, current);
142} 129}
143 130
144static void segv_handler(int sig, union uml_pt_regs *regs) 131static void segv_handler(int sig, struct uml_pt_regs *regs)
145{ 132{
146 struct faultinfo * fi = UPT_FAULTINFO(regs); 133 struct faultinfo * fi = UPT_FAULTINFO(regs);
147 134
148 if(UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)){ 135 if (UPT_IS_USER(regs) && !SEGV_IS_FIXABLE(fi)) {
149 bad_segv(*fi, UPT_IP(regs)); 136 bad_segv(*fi, UPT_IP(regs));
150 return; 137 return;
151 } 138 }
@@ -159,45 +146,49 @@ static void segv_handler(int sig, union uml_pt_regs *regs)
159 * give us bad data! 146 * give us bad data!
160 */ 147 */
161unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user, 148unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
162 union uml_pt_regs *regs) 149 struct uml_pt_regs *regs)
163{ 150{
164 struct siginfo si; 151 struct siginfo si;
165 void *catcher; 152 jmp_buf *catcher;
166 int err; 153 int err;
167 int is_write = FAULT_WRITE(fi); 154 int is_write = FAULT_WRITE(fi);
168 unsigned long address = FAULT_ADDRESS(fi); 155 unsigned long address = FAULT_ADDRESS(fi);
169 156
170 if(!is_user && (address >= start_vm) && (address < end_vm)){ 157 if (!is_user && (address >= start_vm) && (address < end_vm)) {
171 flush_tlb_kernel_vm(); 158 flush_tlb_kernel_vm();
172 return 0; 159 return 0;
173 } 160 }
174 else if(current->mm == NULL) { 161 else if (current->mm == NULL) {
175 show_regs(container_of(regs, struct pt_regs, regs)); 162 show_regs(container_of(regs, struct pt_regs, regs));
176 panic("Segfault with no mm"); 163 panic("Segfault with no mm");
177 } 164 }
178 165
179 if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi)) 166 if (SEGV_IS_FIXABLE(&fi) || SEGV_MAYBE_FIXABLE(&fi))
180 err = handle_page_fault(address, ip, is_write, is_user, &si.si_code); 167 err = handle_page_fault(address, ip, is_write, is_user,
168 &si.si_code);
181 else { 169 else {
182 err = -EFAULT; 170 err = -EFAULT;
183 /* A thread accessed NULL, we get a fault, but CR2 is invalid. 171 /*
184 * This code is used in __do_copy_from_user() of TT mode. */ 172 * A thread accessed NULL, we get a fault, but CR2 is invalid.
173 * This code is used in __do_copy_from_user() of TT mode.
174 * XXX tt mode is gone, so maybe this isn't needed any more
175 */
185 address = 0; 176 address = 0;
186 } 177 }
187 178
188 catcher = current->thread.fault_catcher; 179 catcher = current->thread.fault_catcher;
189 if(!err) 180 if (!err)
190 return 0; 181 return 0;
191 else if(catcher != NULL){ 182 else if (catcher != NULL) {
192 current->thread.fault_addr = (void *) address; 183 current->thread.fault_addr = (void *) address;
193 do_longjmp(catcher, 1); 184 UML_LONGJMP(catcher, 1);
194 } 185 }
195 else if(current->thread.fault_addr != NULL) 186 else if (current->thread.fault_addr != NULL)
196 panic("fault_addr set but no fault catcher"); 187 panic("fault_addr set but no fault catcher");
197 else if(!is_user && arch_fixup(ip, regs)) 188 else if (!is_user && arch_fixup(ip, regs))
198 return 0; 189 return 0;
199 190
200 if(!is_user) { 191 if (!is_user) {
201 show_regs(container_of(regs, struct pt_regs, regs)); 192 show_regs(container_of(regs, struct pt_regs, regs));
202 panic("Kernel mode fault at addr 0x%lx, ip 0x%lx", 193 panic("Kernel mode fault at addr 0x%lx, ip 0x%lx",
203 address, ip); 194 address, ip);
@@ -211,7 +202,7 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
211 current->thread.arch.faultinfo = fi; 202 current->thread.arch.faultinfo = fi;
212 force_sig_info(SIGBUS, &si, current); 203 force_sig_info(SIGBUS, &si, current);
213 } else if (err == -ENOMEM) { 204 } else if (err == -ENOMEM) {
214 printk("VM: killing process %s\n", current->comm); 205 printk(KERN_INFO "VM: killing process %s\n", current->comm);
215 do_exit(SIGKILL); 206 do_exit(SIGKILL);
216 } else { 207 } else {
217 BUG_ON(err != -EFAULT); 208 BUG_ON(err != -EFAULT);
@@ -223,15 +214,15 @@ unsigned long segv(struct faultinfo fi, unsigned long ip, int is_user,
223 return 0; 214 return 0;
224} 215}
225 216
226void relay_signal(int sig, union uml_pt_regs *regs) 217void relay_signal(int sig, struct uml_pt_regs *regs)
227{ 218{
228 if(arch_handle_signal(sig, regs)) 219 if (arch_handle_signal(sig, regs))
229 return; 220 return;
230 221
231 if(!UPT_IS_USER(regs)){ 222 if (!UPT_IS_USER(regs)) {
232 if(sig == SIGBUS) 223 if (sig == SIGBUS)
233 printk("Bus error - the host /dev/shm or /tmp mount " 224 printk(KERN_ERR "Bus error - the host /dev/shm or /tmp "
234 "likely just ran out of space\n"); 225 "mount likely just ran out of space\n");
235 panic("Kernel mode signal %d", sig); 226 panic("Kernel mode signal %d", sig);
236 } 227 }
237 228
@@ -239,14 +230,14 @@ void relay_signal(int sig, union uml_pt_regs *regs)
239 force_sig(sig, current); 230 force_sig(sig, current);
240} 231}
241 232
242static void bus_handler(int sig, union uml_pt_regs *regs) 233static void bus_handler(int sig, struct uml_pt_regs *regs)
243{ 234{
244 if(current->thread.fault_catcher != NULL) 235 if (current->thread.fault_catcher != NULL)
245 do_longjmp(current->thread.fault_catcher, 1); 236 UML_LONGJMP(current->thread.fault_catcher, 1);
246 else relay_signal(sig, regs); 237 else relay_signal(sig, regs);
247} 238}
248 239
249static void winch(int sig, union uml_pt_regs *regs) 240static void winch(int sig, struct uml_pt_regs *regs)
250{ 241{
251 do_IRQ(WINCH_IRQ, regs); 242 do_IRQ(WINCH_IRQ, regs);
252} 243}
diff --git a/arch/um/kernel/tt/Makefile b/arch/um/kernel/tt/Makefile
deleted file mode 100644
index 6939e5af8472..000000000000
--- a/arch/um/kernel/tt/Makefile
+++ /dev/null
@@ -1,14 +0,0 @@
1#
2# Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com)
3# Licensed under the GPL
4#
5
6obj-y = exec_kern.o exec_user.o gdb.o ksyms.o mem.o mem_user.o process_kern.o \
7 syscall_kern.o syscall_user.o tlb.o tracer.o trap_user.o \
8 uaccess.o uaccess_user.o
9
10obj-$(CONFIG_PT_PROXY) += gdb_kern.o ptproxy/
11
12USER_OBJS := gdb.o tracer.o
13
14include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/tt/exec_kern.c b/arch/um/kernel/tt/exec_kern.c
deleted file mode 100644
index 40126cb51801..000000000000
--- a/arch/um/kernel/tt/exec_kern.c
+++ /dev/null
@@ -1,84 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/kernel.h"
7#include "linux/mm.h"
8#include "asm/signal.h"
9#include "asm/ptrace.h"
10#include "asm/uaccess.h"
11#include "asm/pgalloc.h"
12#include "asm/tlbflush.h"
13#include "kern_util.h"
14#include "irq_user.h"
15#include "mem_user.h"
16#include "os.h"
17#include "tlb.h"
18#include "mode.h"
19
20static int exec_tramp(void *sig_stack)
21{
22 init_new_thread_stack(sig_stack, NULL);
23 init_new_thread_signals();
24 os_stop_process(os_getpid());
25 return(0);
26}
27
28void flush_thread_tt(void)
29{
30 unsigned long stack;
31 int new_pid;
32
33 stack = alloc_stack(0, 0);
34 if(stack == 0){
35 printk(KERN_ERR
36 "flush_thread : failed to allocate temporary stack\n");
37 do_exit(SIGKILL);
38 }
39
40 new_pid = start_fork_tramp(task_stack_page(current), stack, 0, exec_tramp);
41 if(new_pid < 0){
42 printk(KERN_ERR
43 "flush_thread : new thread failed, errno = %d\n",
44 -new_pid);
45 do_exit(SIGKILL);
46 }
47
48 if(current_thread->cpu == 0)
49 forward_interrupts(new_pid);
50 current->thread.request.op = OP_EXEC;
51 current->thread.request.u.exec.pid = new_pid;
52 unprotect_stack((unsigned long) current_thread);
53 os_usr1_process(os_getpid());
54 change_sig(SIGUSR1, 1);
55
56 change_sig(SIGUSR1, 0);
57 enable_timer();
58 free_page(stack);
59 protect_memory(uml_reserved, high_physmem - uml_reserved, 1, 1, 0, 1);
60 stack_protections((unsigned long) current_thread);
61 force_flush_all();
62 unblock_signals();
63}
64
65void start_thread_tt(struct pt_regs *regs, unsigned long eip,
66 unsigned long esp)
67{
68 set_fs(USER_DS);
69 flush_tlb_mm(current->mm);
70 PT_REGS_IP(regs) = eip;
71 PT_REGS_SP(regs) = esp;
72 PT_FIX_EXEC_STACK(esp);
73}
74
75/*
76 * Overrides for Emacs so that we follow Linus's tabbing style.
77 * Emacs will notice this stuff at the end of the file and automatically
78 * adjust the settings for this buffer only. This must remain at the end
79 * of the file.
80 * ---------------------------------------------------------------------------
81 * Local variables:
82 * c-file-style: "linux"
83 * End:
84 */
diff --git a/arch/um/kernel/tt/exec_user.c b/arch/um/kernel/tt/exec_user.c
deleted file mode 100644
index 7b5f2181cf51..000000000000
--- a/arch/um/kernel/tt/exec_user.c
+++ /dev/null
@@ -1,56 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdio.h>
7#include <unistd.h>
8#include <stdlib.h>
9#include <sched.h>
10#include <errno.h>
11#include <sys/wait.h>
12#include <signal.h>
13#include "kern_util.h"
14#include "user.h"
15#include "ptrace_user.h"
16#include "os.h"
17
18void do_exec(int old_pid, int new_pid)
19{
20 unsigned long regs[FRAME_SIZE];
21 int err;
22
23 if((ptrace(PTRACE_ATTACH, new_pid, 0, 0) < 0) ||
24 (ptrace(PTRACE_CONT, new_pid, 0, 0) < 0))
25 tracer_panic("do_exec failed to attach proc - errno = %d",
26 errno);
27
28 CATCH_EINTR(err = waitpid(new_pid, 0, WUNTRACED));
29 if (err < 0)
30 tracer_panic("do_exec failed to attach proc in waitpid - errno = %d",
31 errno);
32
33 if(ptrace_getregs(old_pid, regs) < 0)
34 tracer_panic("do_exec failed to get registers - errno = %d",
35 errno);
36
37 os_kill_ptraced_process(old_pid, 0);
38
39 if (ptrace(PTRACE_OLDSETOPTIONS, new_pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
40 tracer_panic("do_exec: PTRACE_SETOPTIONS failed, errno = %d", errno);
41
42 if(ptrace_setregs(new_pid, regs) < 0)
43 tracer_panic("do_exec failed to start new proc - errno = %d",
44 errno);
45}
46
47/*
48 * Overrides for Emacs so that we follow Linus's tabbing style.
49 * Emacs will notice this stuff at the end of the file and automatically
50 * adjust the settings for this buffer only. This must remain at the end
51 * of the file.
52 * ---------------------------------------------------------------------------
53 * Local variables:
54 * c-file-style: "linux"
55 * End:
56 */
diff --git a/arch/um/kernel/tt/gdb.c b/arch/um/kernel/tt/gdb.c
deleted file mode 100644
index 030e4658f36b..000000000000
--- a/arch/um/kernel/tt/gdb.c
+++ /dev/null
@@ -1,280 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <errno.h>
9#include <string.h>
10#include <signal.h>
11#include <sys/types.h>
12#include "ptrace_user.h"
13#include "uml-config.h"
14#include "kern_constants.h"
15#include "chan_user.h"
16#include "init.h"
17#include "user.h"
18#include "debug.h"
19#include "kern_util.h"
20#include "tt.h"
21#include "sysdep/thread.h"
22#include "os.h"
23
24extern int debugger_pid;
25extern int debugger_fd;
26extern int debugger_parent;
27
28int detach(int pid, int sig)
29{
30 return(ptrace(PTRACE_DETACH, pid, 0, sig));
31}
32
33int attach(int pid)
34{
35 int err;
36
37 err = ptrace(PTRACE_ATTACH, pid, 0, 0);
38 if(err < 0) return(-errno);
39 else return(err);
40}
41
42int cont(int pid)
43{
44 return(ptrace(PTRACE_CONT, pid, 0, 0));
45}
46
47#ifdef UML_CONFIG_PT_PROXY
48
49int debugger_signal(int status, pid_t pid)
50{
51 return(debugger_proxy(status, pid));
52}
53
54void child_signal(pid_t pid, int status)
55{
56 child_proxy(pid, status);
57}
58
59static void gdb_announce(char *dev_name, int dev)
60{
61 printf("gdb assigned device '%s'\n", dev_name);
62}
63
64static struct chan_opts opts = {
65 .announce = gdb_announce,
66 .xterm_title = "UML kernel debugger",
67 .raw = 0,
68 .tramp_stack = 0,
69 .in_kernel = 0,
70};
71
72/* Accessed by the tracing thread, which automatically serializes access */
73static void *xterm_data;
74static int xterm_fd;
75
76extern void *xterm_init(char *, int, struct chan_opts *);
77extern int xterm_open(int, int, int, void *, char **);
78extern void xterm_close(int, void *);
79
80int open_gdb_chan(void)
81{
82 char stack[UM_KERN_PAGE_SIZE], *dummy;
83
84 opts.tramp_stack = (unsigned long) stack;
85 xterm_data = xterm_init("", 0, &opts);
86 xterm_fd = xterm_open(1, 1, 1, xterm_data, &dummy);
87 return(xterm_fd);
88}
89
90static void exit_debugger_cb(void *unused)
91{
92 if(debugger_pid != -1){
93 if(gdb_pid != -1){
94 fake_child_exit();
95 gdb_pid = -1;
96 }
97 else kill_child_dead(debugger_pid);
98 debugger_pid = -1;
99 if(debugger_parent != -1)
100 detach(debugger_parent, SIGINT);
101 }
102 if(xterm_data != NULL) xterm_close(xterm_fd, xterm_data);
103}
104
105static void exit_debugger(void)
106{
107 initial_thread_cb(exit_debugger_cb, NULL);
108}
109
110__uml_exitcall(exit_debugger);
111
112struct gdb_data {
113 char *str;
114 int err;
115};
116
117extern char *linux_prog;
118
119static void config_gdb_cb(void *arg)
120{
121 struct gdb_data *data = arg;
122 void *task;
123 int pid;
124
125 data->err = -1;
126 if(debugger_pid != -1) exit_debugger_cb(NULL);
127 if(!strncmp(data->str, "pid,", strlen("pid,"))){
128 data->str += strlen("pid,");
129 pid = strtoul(data->str, NULL, 0);
130 task = cpu_tasks[0].task;
131 debugger_pid = attach_debugger(TASK_EXTERN_PID(task), pid, 0);
132 if(debugger_pid != -1){
133 data->err = 0;
134 gdb_pid = pid;
135 }
136 return;
137 }
138 data->err = 0;
139 debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
140 init_proxy(debugger_pid, 0, 0);
141}
142
143int gdb_config(char *str, char **error_out)
144{
145 struct gdb_data data;
146
147 if(*str++ != '=') return(-1);
148 data.str = str;
149 initial_thread_cb(config_gdb_cb, &data);
150 return(data.err);
151}
152
153void remove_gdb_cb(void *unused)
154{
155 exit_debugger_cb(NULL);
156}
157
158int gdb_remove(int unused, char **error_out)
159{
160 initial_thread_cb(remove_gdb_cb, NULL);
161 return 0;
162}
163
164void signal_usr1(int sig)
165{
166 if(debugger_pid != -1){
167 printf("The debugger is already running\n");
168 return;
169 }
170 debugger_pid = start_debugger(linux_prog, 0, 0, &debugger_fd);
171 init_proxy(debugger_pid, 0, 0);
172}
173
174int init_ptrace_proxy(int idle_pid, int startup, int stop)
175{
176 int pid, status;
177
178 pid = start_debugger(linux_prog, startup, stop, &debugger_fd);
179 status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
180 if(pid < 0){
181 cont(idle_pid);
182 return(-1);
183 }
184 init_proxy(pid, 1, status);
185 return(pid);
186}
187
188int attach_debugger(int idle_pid, int pid, int stop)
189{
190 int status = 0, err;
191
192 err = attach(pid);
193 if(err < 0){
194 printf("Failed to attach pid %d, errno = %d\n", pid, -err);
195 return(-1);
196 }
197 if(stop) status = wait_for_stop(idle_pid, SIGSTOP, PTRACE_CONT, NULL);
198 init_proxy(pid, 1, status);
199 return(pid);
200}
201
202#ifdef notdef /* Put this back in when it does something useful */
203static int __init uml_gdb_init_setup(char *line, int *add)
204{
205 gdb_init = uml_strdup(line);
206 return 0;
207}
208
209__uml_setup("gdb=", uml_gdb_init_setup,
210"gdb=<channel description>\n\n"
211);
212#endif
213
214static int __init uml_gdb_pid_setup(char *line, int *add)
215{
216 gdb_pid = strtoul(line, NULL, 0);
217 *add = 0;
218 return 0;
219}
220
221__uml_setup("gdb-pid=", uml_gdb_pid_setup,
222"gdb-pid=<pid>\n"
223" gdb-pid is used to attach an external debugger to UML. This may be\n"
224" an already-running gdb or a debugger-like process like strace.\n\n"
225);
226
227#else
228
229int debugger_signal(int status, pid_t pid){ return(0); }
230void child_signal(pid_t pid, int status){ }
231int init_ptrace_proxy(int idle_pid, int startup, int stop)
232{
233 printf("debug requested when CONFIG_PT_PROXY is off\n");
234 kill_child_dead(idle_pid);
235 exit(1);
236}
237
238void signal_usr1(int sig)
239{
240 printf("debug requested when CONFIG_PT_PROXY is off\n");
241}
242
243int attach_debugger(int idle_pid, int pid, int stop)
244{
245 printf("attach_debugger called when CONFIG_PT_PROXY "
246 "is off\n");
247 return(-1);
248}
249
250int config_gdb(char *str)
251{
252 return(-1);
253}
254
255int remove_gdb(void)
256{
257 return(-1);
258}
259
260int init_parent_proxy(int pid)
261{
262 return(-1);
263}
264
265void debugger_parent_signal(int status, int pid)
266{
267}
268
269#endif
270
271/*
272 * Overrides for Emacs so that we follow Linus's tabbing style.
273 * Emacs will notice this stuff at the end of the file and automatically
274 * adjust the settings for this buffer only. This must remain at the end
275 * of the file.
276 * ---------------------------------------------------------------------------
277 * Local variables:
278 * c-file-style: "linux"
279 * End:
280 */
diff --git a/arch/um/kernel/tt/gdb_kern.c b/arch/um/kernel/tt/gdb_kern.c
deleted file mode 100644
index 03b06bc00771..000000000000
--- a/arch/um/kernel/tt/gdb_kern.c
+++ /dev/null
@@ -1,40 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/init.h"
7#include "mconsole_kern.h"
8
9#ifdef CONFIG_MCONSOLE
10
11extern int gdb_config(char *str, char **error_out);
12extern int gdb_remove(int n, char **error_out);
13
14static struct mc_device gdb_mc = {
15 .list = INIT_LIST_HEAD(gdb_mc.list),
16 .name = "gdb",
17 .config = gdb_config,
18 .remove = gdb_remove,
19};
20
21int gdb_mc_init(void)
22{
23 mconsole_register_dev(&gdb_mc);
24 return(0);
25}
26
27__initcall(gdb_mc_init);
28
29#endif
30
31/*
32 * Overrides for Emacs so that we follow Linus's tabbing style.
33 * Emacs will notice this stuff at the end of the file and automatically
34 * adjust the settings for this buffer only. This must remain at the end
35 * of the file.
36 * ---------------------------------------------------------------------------
37 * Local variables:
38 * c-file-style: "linux"
39 * End:
40 */
diff --git a/arch/um/kernel/tt/include/mode-tt.h b/arch/um/kernel/tt/include/mode-tt.h
deleted file mode 100644
index e171e15fead5..000000000000
--- a/arch/um/kernel/tt/include/mode-tt.h
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#ifndef __MODE_TT_H__
7#define __MODE_TT_H__
8
9#include "sysdep/ptrace.h"
10
11enum { OP_NONE, OP_EXEC, OP_FORK, OP_TRACE_ON, OP_REBOOT, OP_HALT, OP_CB };
12
13extern int tracing_pid;
14
15extern int tracer(int (*init_proc)(void *), void *sp);
16extern void sig_handler_common_tt(int sig, void *sc);
17extern void syscall_handler_tt(int sig, union uml_pt_regs *regs);
18extern void reboot_tt(void);
19extern void halt_tt(void);
20extern int is_tracer_winch(int pid, int fd, void *data);
21extern void kill_off_processes_tt(void);
22
23#endif
24
25/*
26 * Overrides for Emacs so that we follow Linus's tabbing style.
27 * Emacs will notice this stuff at the end of the file and automatically
28 * adjust the settings for this buffer only. This must remain at the end
29 * of the file.
30 * ---------------------------------------------------------------------------
31 * Local variables:
32 * c-file-style: "linux"
33 * End:
34 */
diff --git a/arch/um/kernel/tt/ksyms.c b/arch/um/kernel/tt/ksyms.c
deleted file mode 100644
index 84a9385a8fef..000000000000
--- a/arch/um/kernel/tt/ksyms.c
+++ /dev/null
@@ -1,29 +0,0 @@
1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/module.h"
7#include "asm/uaccess.h"
8#include "mode.h"
9
10EXPORT_SYMBOL(__do_copy_from_user);
11EXPORT_SYMBOL(__do_copy_to_user);
12EXPORT_SYMBOL(__do_strncpy_from_user);
13EXPORT_SYMBOL(__do_strnlen_user);
14EXPORT_SYMBOL(__do_clear_user);
15EXPORT_SYMBOL(clear_user_tt);
16
17EXPORT_SYMBOL(tracing_pid);
18EXPORT_SYMBOL(honeypot);
19
20/*
21 * Overrides for Emacs so that we follow Linus's tabbing style.
22 * Emacs will notice this stuff at the end of the file and automatically
23 * adjust the settings for this buffer only. This must remain at the end
24 * of the file.
25 * ---------------------------------------------------------------------------
26 * Local variables:
27 * c-file-style: "linux"
28 * End:
29 */
diff --git a/arch/um/kernel/tt/mem.c b/arch/um/kernel/tt/mem.c
deleted file mode 100644
index d0c3c4975f28..000000000000
--- a/arch/um/kernel/tt/mem.c
+++ /dev/null
@@ -1,34 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/stddef.h"
7#include "linux/mm.h"
8#include "asm/uaccess.h"
9#include "mem_user.h"
10#include "kern_util.h"
11#include "kern.h"
12#include "tt.h"
13
14void before_mem_tt(unsigned long brk_start)
15{
16 if(debug)
17 remap_data(UML_ROUND_DOWN(&_stext), UML_ROUND_UP(&_etext), 1);
18 remap_data(UML_ROUND_DOWN(&_sdata), UML_ROUND_UP(&_edata), 1);
19 remap_data(UML_ROUND_DOWN(&__bss_start), UML_ROUND_UP(&_end), 1);
20}
21
22#define SIZE ((CONFIG_NEST_LEVEL + CONFIG_KERNEL_HALF_GIGS) * 0x20000000)
23#define START (CONFIG_TOP_ADDR - SIZE)
24
25unsigned long set_task_sizes_tt(unsigned long *task_size_out)
26{
27 unsigned long host_task_size;
28
29 /* Round up to the nearest 4M */
30 host_task_size = ROUND_4M((unsigned long) &host_task_size);
31 *task_size_out = START;
32
33 return host_task_size;
34}
diff --git a/arch/um/kernel/tt/mem_user.c b/arch/um/kernel/tt/mem_user.c
deleted file mode 100644
index 9774f6360c32..000000000000
--- a/arch/um/kernel/tt/mem_user.c
+++ /dev/null
@@ -1,49 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdlib.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <string.h>
10#include <errno.h>
11#include <sys/mman.h>
12#include "tt.h"
13#include "mem_user.h"
14#include "os.h"
15
16void remap_data(void *segment_start, void *segment_end, int w)
17{
18 void *addr;
19 unsigned long size;
20 int data, prot;
21
22 if(w) prot = PROT_WRITE;
23 else prot = 0;
24 prot |= PROT_READ | PROT_EXEC;
25 size = (unsigned long) segment_end -
26 (unsigned long) segment_start;
27 data = create_mem_file(size);
28 addr = mmap(NULL, size, PROT_WRITE | PROT_READ, MAP_SHARED, data, 0);
29 if(addr == MAP_FAILED){
30 perror("mapping new data segment");
31 exit(1);
32 }
33 memcpy(addr, segment_start, size);
34 if(switcheroo(data, prot, addr, segment_start, size) < 0){
35 printf("switcheroo failed\n");
36 exit(1);
37 }
38}
39
40/*
41 * Overrides for Emacs so that we follow Linus's tabbing style.
42 * Emacs will notice this stuff at the end of the file and automatically
43 * adjust the settings for this buffer only. This must remain at the end
44 * of the file.
45 * ---------------------------------------------------------------------------
46 * Local variables:
47 * c-file-style: "linux"
48 * End:
49 */
diff --git a/arch/um/kernel/tt/process_kern.c b/arch/um/kernel/tt/process_kern.c
deleted file mode 100644
index 74347adf81bf..000000000000
--- a/arch/um/kernel/tt/process_kern.c
+++ /dev/null
@@ -1,461 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/sched.h"
7#include "linux/signal.h"
8#include "linux/kernel.h"
9#include "linux/interrupt.h"
10#include "linux/ptrace.h"
11#include "asm/system.h"
12#include "asm/pgalloc.h"
13#include "asm/ptrace.h"
14#include "asm/tlbflush.h"
15#include "irq_user.h"
16#include "kern_util.h"
17#include "os.h"
18#include "kern.h"
19#include "sigcontext.h"
20#include "mem_user.h"
21#include "tlb.h"
22#include "mode.h"
23#include "mode_kern.h"
24#include "init.h"
25#include "tt.h"
26
27void switch_to_tt(void *prev, void *next)
28{
29 struct task_struct *from, *to, *prev_sched;
30 unsigned long flags;
31 int err, vtalrm, alrm, prof, cpu;
32 char c;
33
34 from = prev;
35 to = next;
36
37 cpu = task_thread_info(from)->cpu;
38 if(cpu == 0)
39 forward_interrupts(to->thread.mode.tt.extern_pid);
40#ifdef CONFIG_SMP
41 forward_ipi(cpu_data[cpu].ipi_pipe[0], to->thread.mode.tt.extern_pid);
42#endif
43 local_irq_save(flags);
44
45 vtalrm = change_sig(SIGVTALRM, 0);
46 alrm = change_sig(SIGALRM, 0);
47 prof = change_sig(SIGPROF, 0);
48
49 forward_pending_sigio(to->thread.mode.tt.extern_pid);
50
51 c = 0;
52
53 /* Notice that here we "up" the semaphore on which "to" is waiting, and
54 * below (the read) we wait on this semaphore (which is implemented by
55 * switch_pipe) and go sleeping. Thus, after that, we have resumed in
56 * "to", and can't use any more the value of "from" (which is outdated),
57 * nor the value in "to" (since it was the task which stole us the CPU,
58 * which we don't care about). */
59
60 err = os_write_file(to->thread.mode.tt.switch_pipe[1], &c, sizeof(c));
61 if(err != sizeof(c))
62 panic("write of switch_pipe failed, err = %d", -err);
63
64 if(from->thread.mode.tt.switch_pipe[0] == -1)
65 os_kill_process(os_getpid(), 0);
66
67 err = os_read_file(from->thread.mode.tt.switch_pipe[0], &c,
68 sizeof(c));
69 if(err != sizeof(c))
70 panic("read of switch_pipe failed, errno = %d", -err);
71
72 /* If the process that we have just scheduled away from has exited,
73 * then it needs to be killed here. The reason is that, even though
74 * it will kill itself when it next runs, that may be too late. Its
75 * stack will be freed, possibly before then, and if that happens,
76 * we have a use-after-free situation. So, it gets killed here
77 * in case it has not already killed itself.
78 */
79 prev_sched = current->thread.prev_sched;
80 if(prev_sched->thread.mode.tt.switch_pipe[0] == -1)
81 os_kill_process(prev_sched->thread.mode.tt.extern_pid, 1);
82
83 change_sig(SIGVTALRM, vtalrm);
84 change_sig(SIGALRM, alrm);
85 change_sig(SIGPROF, prof);
86
87 arch_switch_to_tt(prev_sched, current);
88
89 flush_tlb_all();
90 local_irq_restore(flags);
91}
92
93void release_thread_tt(struct task_struct *task)
94{
95 int pid = task->thread.mode.tt.extern_pid;
96
97 /*
98 * We first have to kill the other process, before
99 * closing its switch_pipe. Else it might wake up
100 * and receive "EOF" before we could kill it.
101 */
102 if(os_getpid() != pid)
103 os_kill_process(pid, 0);
104
105 os_close_file(task->thread.mode.tt.switch_pipe[0]);
106 os_close_file(task->thread.mode.tt.switch_pipe[1]);
107 /* use switch_pipe as flag: thread is released */
108 task->thread.mode.tt.switch_pipe[0] = -1;
109}
110
111void suspend_new_thread(int fd)
112{
113 int err;
114 char c;
115
116 os_stop_process(os_getpid());
117 err = os_read_file(fd, &c, sizeof(c));
118 if(err != sizeof(c))
119 panic("read failed in suspend_new_thread, err = %d", -err);
120}
121
122void schedule_tail(struct task_struct *prev);
123
124static void new_thread_handler(int sig)
125{
126 unsigned long disable;
127 int (*fn)(void *);
128 void *arg;
129
130 fn = current->thread.request.u.thread.proc;
131 arg = current->thread.request.u.thread.arg;
132
133 UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
134 disable = (1 << (SIGVTALRM - 1)) | (1 << (SIGALRM - 1)) |
135 (1 << (SIGIO - 1)) | (1 << (SIGPROF - 1));
136 SC_SIGMASK(UPT_SC(&current->thread.regs.regs)) &= ~disable;
137
138 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
139
140 force_flush_all();
141 if(current->thread.prev_sched != NULL)
142 schedule_tail(current->thread.prev_sched);
143 current->thread.prev_sched = NULL;
144
145 init_new_thread_signals();
146 enable_timer();
147 free_page(current->thread.temp_stack);
148 set_cmdline("(kernel thread)");
149
150 change_sig(SIGUSR1, 1);
151 change_sig(SIGPROF, 1);
152 local_irq_enable();
153 if(!run_kernel_thread(fn, arg, &current->thread.exec_buf))
154 do_exit(0);
155
156 /* XXX No set_user_mode here because a newly execed process will
157 * immediately segfault on its non-existent IP, coming straight back
158 * to the signal handler, which will call set_user_mode on its way
159 * out. This should probably change since it's confusing.
160 */
161}
162
163static int new_thread_proc(void *stack)
164{
165 /* local_irq_disable is needed to block out signals until this thread is
166 * properly scheduled. Otherwise, the tracing thread will get mighty
167 * upset about any signals that arrive before that.
168 * This has the complication that it sets the saved signal mask in
169 * the sigcontext to block signals. This gets restored when this
170 * thread (or a descendant, since they get a copy of this sigcontext)
171 * returns to userspace.
172 * So, this is compensated for elsewhere.
173 * XXX There is still a small window until local_irq_disable() actually
174 * finishes where signals are possible - shouldn't be a problem in
175 * practice since SIGIO hasn't been forwarded here yet, and the
176 * local_irq_disable should finish before a SIGVTALRM has time to be
177 * delivered.
178 */
179
180 local_irq_disable();
181 init_new_thread_stack(stack, new_thread_handler);
182 os_usr1_process(os_getpid());
183 change_sig(SIGUSR1, 1);
184 return(0);
185}
186
187/* Signal masking - signals are blocked at the start of fork_tramp. They
188 * are re-enabled when finish_fork_handler is entered by fork_tramp hitting
189 * itself with a SIGUSR1. set_user_mode has to be run with SIGUSR1 off,
190 * so it is blocked before it's called. They are re-enabled on sigreturn
191 * despite the fact that they were blocked when the SIGUSR1 was issued because
192 * copy_thread copies the parent's sigcontext, including the signal mask
193 * onto the signal frame.
194 */
195
196void finish_fork_handler(int sig)
197{
198 UPT_SC(&current->thread.regs.regs) = (void *) (&sig + 1);
199 suspend_new_thread(current->thread.mode.tt.switch_pipe[0]);
200
201 force_flush_all();
202 if(current->thread.prev_sched != NULL)
203 schedule_tail(current->thread.prev_sched);
204 current->thread.prev_sched = NULL;
205
206 enable_timer();
207 change_sig(SIGVTALRM, 1);
208 local_irq_enable();
209 if(current->mm != current->parent->mm)
210 protect_memory(uml_reserved, high_physmem - uml_reserved, 1,
211 1, 0, 1);
212 stack_protections((unsigned long) current_thread);
213
214 free_page(current->thread.temp_stack);
215 local_irq_disable();
216 change_sig(SIGUSR1, 0);
217 set_user_mode(current);
218}
219
220int fork_tramp(void *stack)
221{
222 local_irq_disable();
223 arch_init_thread();
224 init_new_thread_stack(stack, finish_fork_handler);
225
226 os_usr1_process(os_getpid());
227 change_sig(SIGUSR1, 1);
228 return(0);
229}
230
231int copy_thread_tt(int nr, unsigned long clone_flags, unsigned long sp,
232 unsigned long stack_top, struct task_struct * p,
233 struct pt_regs *regs)
234{
235 int (*tramp)(void *);
236 int new_pid, err;
237 unsigned long stack;
238
239 if(current->thread.forking)
240 tramp = fork_tramp;
241 else {
242 tramp = new_thread_proc;
243 p->thread.request.u.thread = current->thread.request.u.thread;
244 }
245
246 err = os_pipe(p->thread.mode.tt.switch_pipe, 1, 1);
247 if(err < 0){
248 printk("copy_thread : pipe failed, err = %d\n", -err);
249 return(err);
250 }
251
252 stack = alloc_stack(0, 0);
253 if(stack == 0){
254 printk(KERN_ERR "copy_thread : failed to allocate "
255 "temporary stack\n");
256 return(-ENOMEM);
257 }
258
259 clone_flags &= CLONE_VM;
260 p->thread.temp_stack = stack;
261 new_pid = start_fork_tramp(task_stack_page(p), stack, clone_flags, tramp);
262 if(new_pid < 0){
263 printk(KERN_ERR "copy_thread : clone failed - errno = %d\n",
264 -new_pid);
265 return(new_pid);
266 }
267
268 if(current->thread.forking){
269 sc_to_sc(UPT_SC(&p->thread.regs.regs), UPT_SC(&regs->regs));
270 SC_SET_SYSCALL_RETURN(UPT_SC(&p->thread.regs.regs), 0);
271 if(sp != 0)
272 SC_SP(UPT_SC(&p->thread.regs.regs)) = sp;
273 }
274 p->thread.mode.tt.extern_pid = new_pid;
275
276 current->thread.request.op = OP_FORK;
277 current->thread.request.u.fork.pid = new_pid;
278 os_usr1_process(os_getpid());
279
280 /* Enable the signal and then disable it to ensure that it is handled
281 * here, and nowhere else.
282 */
283 change_sig(SIGUSR1, 1);
284
285 change_sig(SIGUSR1, 0);
286 err = 0;
287 return(err);
288}
289
290void reboot_tt(void)
291{
292 current->thread.request.op = OP_REBOOT;
293 os_usr1_process(os_getpid());
294 change_sig(SIGUSR1, 1);
295}
296
297void halt_tt(void)
298{
299 current->thread.request.op = OP_HALT;
300 os_usr1_process(os_getpid());
301 change_sig(SIGUSR1, 1);
302}
303
304void kill_off_processes_tt(void)
305{
306 struct task_struct *p;
307 int me;
308
309 me = os_getpid();
310 for_each_process(p){
311 if(p->thread.mode.tt.extern_pid != me)
312 os_kill_process(p->thread.mode.tt.extern_pid, 0);
313 }
314 if(init_task.thread.mode.tt.extern_pid != me)
315 os_kill_process(init_task.thread.mode.tt.extern_pid, 0);
316}
317
318void initial_thread_cb_tt(void (*proc)(void *), void *arg)
319{
320 if(os_getpid() == tracing_pid){
321 (*proc)(arg);
322 }
323 else {
324 current->thread.request.op = OP_CB;
325 current->thread.request.u.cb.proc = proc;
326 current->thread.request.u.cb.arg = arg;
327 os_usr1_process(os_getpid());
328 change_sig(SIGUSR1, 1);
329
330 change_sig(SIGUSR1, 0);
331 }
332}
333
334int do_proc_op(void *t, int proc_id)
335{
336 struct task_struct *task;
337 struct thread_struct *thread;
338 int op, pid;
339
340 task = t;
341 thread = &task->thread;
342 op = thread->request.op;
343 switch(op){
344 case OP_NONE:
345 case OP_TRACE_ON:
346 break;
347 case OP_EXEC:
348 pid = thread->request.u.exec.pid;
349 do_exec(thread->mode.tt.extern_pid, pid);
350 thread->mode.tt.extern_pid = pid;
351 cpu_tasks[task_thread_info(task)->cpu].pid = pid;
352 break;
353 case OP_FORK:
354 attach_process(thread->request.u.fork.pid);
355 break;
356 case OP_CB:
357 (*thread->request.u.cb.proc)(thread->request.u.cb.arg);
358 break;
359 case OP_REBOOT:
360 case OP_HALT:
361 break;
362 default:
363 tracer_panic("Bad op in do_proc_op");
364 break;
365 }
366 thread->request.op = OP_NONE;
367 return(op);
368}
369
370void init_idle_tt(void)
371{
372 default_idle();
373}
374
375extern void start_kernel(void);
376
377static int start_kernel_proc(void *unused)
378{
379 int pid;
380
381 block_signals();
382 pid = os_getpid();
383
384 cpu_tasks[0].pid = pid;
385 cpu_tasks[0].task = current;
386#ifdef CONFIG_SMP
387 cpu_online_map = cpumask_of_cpu(0);
388#endif
389 if(debug) os_stop_process(pid);
390 start_kernel();
391 return(0);
392}
393
394void set_tracing(void *task, int tracing)
395{
396 ((struct task_struct *) task)->thread.mode.tt.tracing = tracing;
397}
398
399int is_tracing(void *t)
400{
401 return (((struct task_struct *) t)->thread.mode.tt.tracing);
402}
403
404int set_user_mode(void *t)
405{
406 struct task_struct *task;
407
408 task = t ? t : current;
409 if(task->thread.mode.tt.tracing)
410 return(1);
411 task->thread.request.op = OP_TRACE_ON;
412 os_usr1_process(os_getpid());
413 return(0);
414}
415
416void set_init_pid(int pid)
417{
418 int err;
419
420 init_task.thread.mode.tt.extern_pid = pid;
421 err = os_pipe(init_task.thread.mode.tt.switch_pipe, 1, 1);
422 if(err)
423 panic("Can't create switch pipe for init_task, errno = %d",
424 -err);
425}
426
427int start_uml_tt(void)
428{
429 void *sp;
430 int pages;
431
432 pages = (1 << CONFIG_KERNEL_STACK_ORDER);
433 sp = task_stack_page(&init_task) +
434 pages * PAGE_SIZE - sizeof(unsigned long);
435 return(tracer(start_kernel_proc, sp));
436}
437
438int external_pid_tt(struct task_struct *task)
439{
440 return(task->thread.mode.tt.extern_pid);
441}
442
443int thread_pid_tt(struct task_struct *task)
444{
445 return(task->thread.mode.tt.extern_pid);
446}
447
448int is_valid_pid(int pid)
449{
450 struct task_struct *task;
451
452 read_lock(&tasklist_lock);
453 for_each_process(task){
454 if(task->thread.mode.tt.extern_pid == pid){
455 read_unlock(&tasklist_lock);
456 return(1);
457 }
458 }
459 read_unlock(&tasklist_lock);
460 return(0);
461}
diff --git a/arch/um/kernel/tt/ptproxy/Makefile b/arch/um/kernel/tt/ptproxy/Makefile
deleted file mode 100644
index 3ad5b774de59..000000000000
--- a/arch/um/kernel/tt/ptproxy/Makefile
+++ /dev/null
@@ -1,10 +0,0 @@
1#
2# Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3# Licensed under the GPL
4#
5
6obj-y = proxy.o ptrace.o sysdep.o wait.o
7
8USER_OBJS := $(obj-y)
9
10include arch/um/scripts/Makefile.rules
diff --git a/arch/um/kernel/tt/ptproxy/proxy.c b/arch/um/kernel/tt/ptproxy/proxy.c
deleted file mode 100644
index 420c23f311f3..000000000000
--- a/arch/um/kernel/tt/ptproxy/proxy.c
+++ /dev/null
@@ -1,377 +0,0 @@
1/**********************************************************************
2proxy.c
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6
7Jeff Dike (jdike@karaya.com) : Modified for integration into uml
8**********************************************************************/
9
10/* XXX This file shouldn't refer to CONFIG_* */
11
12#include <errno.h>
13#include <stdio.h>
14#include <stdlib.h>
15#include <unistd.h>
16#include <signal.h>
17#include <string.h>
18#include <termios.h>
19#include <sys/wait.h>
20#include <sys/types.h>
21#include <sys/ioctl.h>
22#include <asm/unistd.h>
23#include "ptrace_user.h"
24
25#include "ptproxy.h"
26#include "sysdep.h"
27#include "wait.h"
28
29#include "user.h"
30#include "os.h"
31#include "tempfile.h"
32
33static int debugger_wait(debugger_state *debugger, int *status, int options,
34 int (*syscall)(debugger_state *debugger, pid_t child),
35 int (*normal_return)(debugger_state *debugger,
36 pid_t unused),
37 int (*wait_return)(debugger_state *debugger,
38 pid_t unused))
39{
40 if(debugger->real_wait){
41 debugger->handle_trace = normal_return;
42 syscall_continue(debugger->pid);
43 debugger->real_wait = 0;
44 return(1);
45 }
46 debugger->wait_status_ptr = status;
47 debugger->wait_options = options;
48 if((debugger->debugee != NULL) && debugger->debugee->event){
49 syscall_continue(debugger->pid);
50 wait_for_stop(debugger->pid, SIGTRAP, PTRACE_SYSCALL,
51 NULL);
52 (*wait_return)(debugger, -1);
53 return(0);
54 }
55 else if(debugger->wait_options & WNOHANG){
56 syscall_cancel(debugger->pid, 0);
57 debugger->handle_trace = syscall;
58 return(0);
59 }
60 else {
61 syscall_pause(debugger->pid);
62 debugger->handle_trace = wait_return;
63 debugger->waiting = 1;
64 }
65 return(1);
66}
67
68/*
69 * Handle debugger trap, i.e. syscall.
70 */
71
72int debugger_syscall(debugger_state *debugger, pid_t child)
73{
74 long arg1, arg2, arg3, arg4, arg5, result;
75 int syscall, ret = 0;
76
77 syscall = get_syscall(debugger->pid, &arg1, &arg2, &arg3, &arg4,
78 &arg5);
79
80 switch(syscall){
81 case __NR_execve:
82 /* execve never returns */
83 debugger->handle_trace = debugger_syscall;
84 break;
85
86 case __NR_ptrace:
87 if(debugger->debugee->pid != 0) arg2 = debugger->debugee->pid;
88 if(!debugger->debugee->in_context)
89 child = debugger->debugee->pid;
90 result = proxy_ptrace(debugger, arg1, arg2, arg3, arg4, child,
91 &ret);
92 syscall_cancel(debugger->pid, result);
93 debugger->handle_trace = debugger_syscall;
94 return(ret);
95
96#ifdef __NR_waitpid
97 case __NR_waitpid:
98#endif
99 case __NR_wait4:
100 if(!debugger_wait(debugger, (int *) arg2, arg3,
101 debugger_syscall, debugger_normal_return,
102 proxy_wait_return))
103 return(0);
104 break;
105
106 case __NR_kill:
107 if(!debugger->debugee->in_context)
108 child = debugger->debugee->pid;
109 if(arg1 == debugger->debugee->pid){
110 result = kill(child, arg2);
111 syscall_cancel(debugger->pid, result);
112 debugger->handle_trace = debugger_syscall;
113 return(0);
114 }
115 else debugger->handle_trace = debugger_normal_return;
116 break;
117
118 default:
119 debugger->handle_trace = debugger_normal_return;
120 }
121
122 syscall_continue(debugger->pid);
123 return(0);
124}
125
126/* Used by the tracing thread */
127static debugger_state parent;
128static int parent_syscall(debugger_state *debugger, int pid);
129
130int init_parent_proxy(int pid)
131{
132 parent = ((debugger_state) { .pid = pid,
133 .wait_options = 0,
134 .wait_status_ptr = NULL,
135 .waiting = 0,
136 .real_wait = 0,
137 .expecting_child = 0,
138 .handle_trace = parent_syscall,
139 .debugee = NULL } );
140 return(0);
141}
142
143int parent_normal_return(debugger_state *debugger, pid_t unused)
144{
145 debugger->handle_trace = parent_syscall;
146 syscall_continue(debugger->pid);
147 return(0);
148}
149
150static int parent_syscall(debugger_state *debugger, int pid)
151{
152 long arg1, arg2, arg3, arg4, arg5;
153 int syscall;
154
155 syscall = get_syscall(pid, &arg1, &arg2, &arg3, &arg4, &arg5);
156
157 if((syscall == __NR_wait4)
158#ifdef __NR_waitpid
159 || (syscall == __NR_waitpid)
160#endif
161 ){
162 debugger_wait(&parent, (int *) arg2, arg3, parent_syscall,
163 parent_normal_return, parent_wait_return);
164 }
165 else ptrace(PTRACE_SYSCALL, pid, 0, 0);
166 return(0);
167}
168
169int debugger_normal_return(debugger_state *debugger, pid_t unused)
170{
171 debugger->handle_trace = debugger_syscall;
172 syscall_continue(debugger->pid);
173 return(0);
174}
175
176void debugger_cancelled_return(debugger_state *debugger, int result)
177{
178 debugger->handle_trace = debugger_syscall;
179 syscall_set_result(debugger->pid, result);
180 syscall_continue(debugger->pid);
181}
182
183/* Used by the tracing thread */
184static debugger_state debugger;
185static debugee_state debugee;
186
187void init_proxy (pid_t debugger_pid, int stopped, int status)
188{
189 debugger.pid = debugger_pid;
190 debugger.handle_trace = debugger_syscall;
191 debugger.debugee = &debugee;
192 debugger.waiting = 0;
193 debugger.real_wait = 0;
194 debugger.expecting_child = 0;
195
196 debugee.pid = 0;
197 debugee.traced = 0;
198 debugee.stopped = stopped;
199 debugee.event = 0;
200 debugee.zombie = 0;
201 debugee.died = 0;
202 debugee.wait_status = status;
203 debugee.in_context = 1;
204}
205
206int debugger_proxy(int status, int pid)
207{
208 int ret = 0, sig;
209
210 if(WIFSTOPPED(status)){
211 sig = WSTOPSIG(status);
212 if (sig == SIGTRAP)
213 ret = (*debugger.handle_trace)(&debugger, pid);
214
215 else if(sig == SIGCHLD){
216 if(debugger.expecting_child){
217 ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
218 debugger.expecting_child = 0;
219 }
220 else if(debugger.waiting)
221 real_wait_return(&debugger);
222 else {
223 ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
224 debugger.real_wait = 1;
225 }
226 }
227 else ptrace(PTRACE_SYSCALL, debugger.pid, 0, sig);
228 }
229 else if(WIFEXITED(status)){
230 tracer_panic("debugger (pid %d) exited with status %d",
231 debugger.pid, WEXITSTATUS(status));
232 }
233 else if(WIFSIGNALED(status)){
234 tracer_panic("debugger (pid %d) exited with signal %d",
235 debugger.pid, WTERMSIG(status));
236 }
237 else {
238 tracer_panic("proxy got unknown status (0x%x) on debugger "
239 "(pid %d)", status, debugger.pid);
240 }
241 return(ret);
242}
243
244void child_proxy(pid_t pid, int status)
245{
246 debugee.event = 1;
247 debugee.wait_status = status;
248
249 if(WIFSTOPPED(status)){
250 debugee.stopped = 1;
251 debugger.expecting_child = 1;
252 kill(debugger.pid, SIGCHLD);
253 }
254 else if(WIFEXITED(status) || WIFSIGNALED(status)){
255 debugee.zombie = 1;
256 debugger.expecting_child = 1;
257 kill(debugger.pid, SIGCHLD);
258 }
259 else panic("proxy got unknown status (0x%x) on child (pid %d)",
260 status, pid);
261}
262
263void debugger_parent_signal(int status, int pid)
264{
265 int sig;
266
267 if(WIFSTOPPED(status)){
268 sig = WSTOPSIG(status);
269 if(sig == SIGTRAP) (*parent.handle_trace)(&parent, pid);
270 else ptrace(PTRACE_SYSCALL, pid, 0, sig);
271 }
272}
273
274void fake_child_exit(void)
275{
276 int status, pid;
277
278 child_proxy(1, W_EXITCODE(0, 0));
279 while(debugger.waiting == 1){
280 CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
281 if(pid != debugger.pid){
282 printk("fake_child_exit - waitpid failed, "
283 "errno = %d\n", errno);
284 return;
285 }
286 debugger_proxy(status, debugger.pid);
287 }
288 CATCH_EINTR(pid = waitpid(debugger.pid, &status, WUNTRACED));
289 if(pid != debugger.pid){
290 printk("fake_child_exit - waitpid failed, "
291 "errno = %d\n", errno);
292 return;
293 }
294 if(ptrace(PTRACE_DETACH, debugger.pid, 0, SIGCONT) < 0)
295 printk("fake_child_exit - PTRACE_DETACH failed, errno = %d\n",
296 errno);
297}
298
299char gdb_init_string[] =
300"att 1 \n\
301b panic \n\
302b stop \n\
303handle SIGWINCH nostop noprint pass \n\
304";
305
306int start_debugger(char *prog, int startup, int stop, int *fd_out)
307{
308 int slave, child;
309
310 slave = open_gdb_chan();
311 child = fork();
312 if(child == 0){
313 char *tempname = NULL;
314 int fd;
315
316 if(setsid() < 0) perror("setsid");
317 if((dup2(slave, 0) < 0) || (dup2(slave, 1) < 0) ||
318 (dup2(slave, 2) < 0)){
319 printk("start_debugger : dup2 failed, errno = %d\n",
320 errno);
321 exit(1);
322 }
323 if(ioctl(0, TIOCSCTTY, 0) < 0){
324 printk("start_debugger : TIOCSCTTY failed, "
325 "errno = %d\n", errno);
326 exit(1);
327 }
328 if(tcsetpgrp (1, os_getpid()) < 0){
329 printk("start_debugger : tcsetpgrp failed, "
330 "errno = %d\n", errno);
331#ifdef notdef
332 exit(1);
333#endif
334 }
335 fd = make_tempfile("/tmp/gdb_init-XXXXXX", &tempname, 0);
336 if(fd < 0){
337 printk("start_debugger : make_tempfile failed,"
338 "err = %d\n", -fd);
339 exit(1);
340 }
341 os_write_file(fd, gdb_init_string,
342 sizeof(gdb_init_string) - 1);
343 if(startup){
344 if(stop){
345 os_write_file(fd, "b start_kernel\n",
346 strlen("b start_kernel\n"));
347 }
348 os_write_file(fd, "c\n", strlen("c\n"));
349 }
350 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){
351 printk("start_debugger : PTRACE_TRACEME failed, "
352 "errno = %d\n", errno);
353 exit(1);
354 }
355 execlp("gdb", "gdb", "--command", tempname, prog, NULL);
356 printk("start_debugger : exec of gdb failed, errno = %d\n",
357 errno);
358 }
359 if(child < 0){
360 printk("start_debugger : fork for gdb failed, errno = %d\n",
361 errno);
362 return(-1);
363 }
364 *fd_out = slave;
365 return(child);
366}
367
368/*
369 * Overrides for Emacs so that we follow Linus's tabbing style.
370 * Emacs will notice this stuff at the end of the file and automatically
371 * adjust the settings for this buffer only. This must remain at the end
372 * of the file.
373 * ---------------------------------------------------------------------------
374 * Local variables:
375 * c-file-style: "linux"
376 * End:
377 */
diff --git a/arch/um/kernel/tt/ptproxy/ptproxy.h b/arch/um/kernel/tt/ptproxy/ptproxy.h
deleted file mode 100644
index 5eb0285b1968..000000000000
--- a/arch/um/kernel/tt/ptproxy/ptproxy.h
+++ /dev/null
@@ -1,61 +0,0 @@
1/**********************************************************************
2ptproxy.h
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6**********************************************************************/
7
8#ifndef __PTPROXY_H
9#define __PTPROXY_H
10
11#include <sys/types.h>
12
13typedef struct debugger debugger_state;
14typedef struct debugee debugee_state;
15
16struct debugger
17{
18 pid_t pid;
19 int wait_options;
20 int *wait_status_ptr;
21 unsigned int waiting : 1;
22 unsigned int real_wait : 1;
23 unsigned int expecting_child : 1;
24 int (*handle_trace) (debugger_state *, pid_t);
25
26 debugee_state *debugee;
27};
28
29struct debugee
30{
31 pid_t pid;
32 int wait_status;
33 unsigned int died : 1;
34 unsigned int event : 1;
35 unsigned int stopped : 1;
36 unsigned int trace_singlestep : 1;
37 unsigned int trace_syscall : 1;
38 unsigned int traced : 1;
39 unsigned int zombie : 1;
40 unsigned int in_context : 1;
41};
42
43extern int debugger_syscall(debugger_state *debugger, pid_t pid);
44extern int debugger_normal_return (debugger_state *debugger, pid_t unused);
45
46extern long proxy_ptrace (struct debugger *, int, pid_t, long, long, pid_t,
47 int *strace_out);
48extern void debugger_cancelled_return(debugger_state *debugger, int result);
49
50#endif
51
52/*
53 * Overrides for Emacs so that we follow Linus's tabbing style.
54 * Emacs will notice this stuff at the end of the file and automatically
55 * adjust the settings for this buffer only. This must remain at the end
56 * of the file.
57 * ---------------------------------------------------------------------------
58 * Local variables:
59 * c-file-style: "linux"
60 * End:
61 */
diff --git a/arch/um/kernel/tt/ptproxy/ptrace.c b/arch/um/kernel/tt/ptproxy/ptrace.c
deleted file mode 100644
index 4b4f6179b212..000000000000
--- a/arch/um/kernel/tt/ptproxy/ptrace.c
+++ /dev/null
@@ -1,237 +0,0 @@
1/**********************************************************************
2ptrace.c
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6
7Jeff Dike (jdike@karaya.com) : Modified for integration into uml
8**********************************************************************/
9
10#include <errno.h>
11#include <unistd.h>
12#include <signal.h>
13#include <sys/types.h>
14#include <sys/time.h>
15#include <sys/wait.h>
16
17#include "ptproxy.h"
18#include "debug.h"
19#include "kern_util.h"
20#include "ptrace_user.h"
21#include "tt.h"
22#include "os.h"
23
24long proxy_ptrace(struct debugger *debugger, int arg1, pid_t arg2,
25 long arg3, long arg4, pid_t child, int *ret)
26{
27 sigset_t relay;
28 long result;
29 int status;
30
31 *ret = 0;
32 if(debugger->debugee->died) return(-ESRCH);
33
34 switch(arg1){
35 case PTRACE_ATTACH:
36 if(debugger->debugee->traced) return(-EPERM);
37
38 debugger->debugee->pid = arg2;
39 debugger->debugee->traced = 1;
40
41 if(is_valid_pid(arg2) && (arg2 != child)){
42 debugger->debugee->in_context = 0;
43 kill(arg2, SIGSTOP);
44 debugger->debugee->event = 1;
45 debugger->debugee->wait_status = W_STOPCODE(SIGSTOP);
46 }
47 else {
48 debugger->debugee->in_context = 1;
49 if(debugger->debugee->stopped)
50 child_proxy(child, W_STOPCODE(SIGSTOP));
51 else kill(child, SIGSTOP);
52 }
53
54 return(0);
55
56 case PTRACE_DETACH:
57 if(!debugger->debugee->traced) return(-EPERM);
58
59 debugger->debugee->traced = 0;
60 debugger->debugee->pid = 0;
61 if(!debugger->debugee->in_context)
62 kill(child, SIGCONT);
63
64 return(0);
65
66 case PTRACE_CONT:
67 if(!debugger->debugee->in_context) return(-EPERM);
68 *ret = PTRACE_CONT;
69 return(ptrace(PTRACE_CONT, child, arg3, arg4));
70
71#ifdef UM_HAVE_GETFPREGS
72 case PTRACE_GETFPREGS:
73 {
74 long regs[FP_FRAME_SIZE];
75 int i, result;
76
77 result = ptrace(PTRACE_GETFPREGS, child, 0, regs);
78 if(result == -1) return(-errno);
79
80 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
81 ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
82 regs[i]);
83 return(result);
84 }
85#endif
86
87#ifdef UM_HAVE_GETFPXREGS
88 case PTRACE_GETFPXREGS:
89 {
90 long regs[FPX_FRAME_SIZE];
91 int i, result;
92
93 result = ptrace(PTRACE_GETFPXREGS, child, 0, regs);
94 if(result == -1) return(-errno);
95
96 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
97 ptrace(PTRACE_POKEDATA, debugger->pid, arg4 + 4 * i,
98 regs[i]);
99 return(result);
100 }
101#endif
102
103#ifdef UM_HAVE_GETREGS
104 case PTRACE_GETREGS:
105 {
106 long regs[FRAME_SIZE];
107 int i, result;
108
109 result = ptrace(PTRACE_GETREGS, child, 0, regs);
110 if(result == -1) return(-errno);
111
112 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
113 ptrace (PTRACE_POKEDATA, debugger->pid,
114 arg4 + 4 * i, regs[i]);
115 return(result);
116 }
117 break;
118#endif
119
120 case PTRACE_KILL:
121 result = ptrace(PTRACE_KILL, child, arg3, arg4);
122 if(result == -1) return(-errno);
123
124 return(result);
125
126 case PTRACE_PEEKDATA:
127 case PTRACE_PEEKTEXT:
128 case PTRACE_PEEKUSR:
129 /* The value being read out could be -1, so we have to
130 * check errno to see if there's an error, and zero it
131 * beforehand so we're not faked out by an old error
132 */
133
134 errno = 0;
135 result = ptrace(arg1, child, arg3, 0);
136 if((result == -1) && (errno != 0)) return(-errno);
137
138 result = ptrace(PTRACE_POKEDATA, debugger->pid, arg4, result);
139 if(result == -1) return(-errno);
140
141 return(result);
142
143 case PTRACE_POKEDATA:
144 case PTRACE_POKETEXT:
145 case PTRACE_POKEUSR:
146 result = ptrace(arg1, child, arg3, arg4);
147 if(result == -1) return(-errno);
148
149 if(arg1 == PTRACE_POKEUSR) ptrace_pokeuser(arg3, arg4);
150 return(result);
151
152#ifdef UM_HAVE_SETFPREGS
153 case PTRACE_SETFPREGS:
154 {
155 long regs[FP_FRAME_SIZE];
156 int i;
157
158 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
159 regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
160 arg4 + 4 * i, 0);
161 result = ptrace(PTRACE_SETFPREGS, child, 0, regs);
162 if(result == -1) return(-errno);
163
164 return(result);
165 }
166#endif
167
168#ifdef UM_HAVE_SETFPXREGS
169 case PTRACE_SETFPXREGS:
170 {
171 long regs[FPX_FRAME_SIZE];
172 int i;
173
174 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
175 regs[i] = ptrace (PTRACE_PEEKDATA, debugger->pid,
176 arg4 + 4 * i, 0);
177 result = ptrace(PTRACE_SETFPXREGS, child, 0, regs);
178 if(result == -1) return(-errno);
179
180 return(result);
181 }
182#endif
183
184#ifdef UM_HAVE_SETREGS
185 case PTRACE_SETREGS:
186 {
187 long regs[FRAME_SIZE];
188 int i;
189
190 for (i = 0; i < sizeof(regs)/sizeof(regs[0]); i++)
191 regs[i] = ptrace(PTRACE_PEEKDATA, debugger->pid,
192 arg4 + 4 * i, 0);
193 result = ptrace(PTRACE_SETREGS, child, 0, regs);
194 if(result == -1) return(-errno);
195
196 return(result);
197 }
198#endif
199
200 case PTRACE_SINGLESTEP:
201 if(!debugger->debugee->in_context) return(-EPERM);
202 sigemptyset(&relay);
203 sigaddset(&relay, SIGSEGV);
204 sigaddset(&relay, SIGILL);
205 sigaddset(&relay, SIGBUS);
206 result = ptrace(PTRACE_SINGLESTEP, child, arg3, arg4);
207 if(result == -1) return(-errno);
208
209 status = wait_for_stop(child, SIGTRAP, PTRACE_SINGLESTEP,
210 &relay);
211 child_proxy(child, status);
212 return(result);
213
214 case PTRACE_SYSCALL:
215 if(!debugger->debugee->in_context) return(-EPERM);
216 result = ptrace(PTRACE_SYSCALL, child, arg3, arg4);
217 if(result == -1) return(-errno);
218
219 *ret = PTRACE_SYSCALL;
220 return(result);
221
222 case PTRACE_TRACEME:
223 default:
224 return(-EINVAL);
225 }
226}
227
228/*
229 * Overrides for Emacs so that we follow Linus's tabbing style.
230 * Emacs will notice this stuff at the end of the file and automatically
231 * adjust the settings for this buffer only. This must remain at the end
232 * of the file.
233 * ---------------------------------------------------------------------------
234 * Local variables:
235 * c-file-style: "linux"
236 * End:
237 */
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.c b/arch/um/kernel/tt/ptproxy/sysdep.c
deleted file mode 100644
index e0e1ab0588ad..000000000000
--- a/arch/um/kernel/tt/ptproxy/sysdep.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/**********************************************************************
2sysdep.c
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6**********************************************************************/
7
8#include <stdio.h>
9#include <string.h>
10#include <stdlib.h>
11#include <signal.h>
12#include <errno.h>
13#include <sys/types.h>
14#include <linux/unistd.h>
15#include "ptrace_user.h"
16#include "user.h"
17#include "os.h"
18
19int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3, long *arg4,
20 long *arg5)
21{
22 *arg1 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG1_OFFSET, 0);
23 *arg2 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG2_OFFSET, 0);
24 *arg3 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG3_OFFSET, 0);
25 *arg4 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG4_OFFSET, 0);
26 *arg5 = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_ARG5_OFFSET, 0);
27 return(ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, 0));
28}
29
30void syscall_cancel(pid_t pid, int result)
31{
32 if((ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
33 __NR_getpid) < 0) ||
34 (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) ||
35 (wait_for_stop(pid, SIGTRAP, PTRACE_SYSCALL, NULL) < 0) ||
36 (ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, result) < 0) ||
37 (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0))
38 printk("ptproxy: couldn't cancel syscall: errno = %d\n",
39 errno);
40}
41
42void syscall_set_result(pid_t pid, long result)
43{
44 ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, result);
45}
46
47void syscall_continue(pid_t pid)
48{
49 ptrace(PTRACE_SYSCALL, pid, 0, 0);
50}
51
52int syscall_pause(pid_t pid)
53{
54 if(ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, __NR_pause) < 0){
55 printk("syscall_change - ptrace failed, errno = %d\n", errno);
56 return(-1);
57 }
58 return(0);
59}
60
61/*
62 * Overrides for Emacs so that we follow Linus's tabbing style.
63 * Emacs will notice this stuff at the end of the file and automatically
64 * adjust the settings for this buffer only. This must remain at the end
65 * of the file.
66 * ---------------------------------------------------------------------------
67 * Local variables:
68 * c-file-style: "linux"
69 * End:
70 */
diff --git a/arch/um/kernel/tt/ptproxy/sysdep.h b/arch/um/kernel/tt/ptproxy/sysdep.h
deleted file mode 100644
index 735f488049aa..000000000000
--- a/arch/um/kernel/tt/ptproxy/sysdep.h
+++ /dev/null
@@ -1,25 +0,0 @@
1/**********************************************************************
2sysdep.h
3
4Copyright (C) 1999 Lars Brinkhoff.
5Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
6See the file COPYING for licensing terms and conditions.
7**********************************************************************/
8
9extern int get_syscall(pid_t pid, long *arg1, long *arg2, long *arg3,
10 long *arg4, long *arg5);
11extern void syscall_cancel (pid_t pid, long result);
12extern void syscall_set_result (pid_t pid, long result);
13extern void syscall_continue (pid_t pid);
14extern int syscall_pause(pid_t pid);
15
16/*
17 * Overrides for Emacs so that we follow Linus's tabbing style.
18 * Emacs will notice this stuff at the end of the file and automatically
19 * adjust the settings for this buffer only. This must remain at the end
20 * of the file.
21 * ---------------------------------------------------------------------------
22 * Local variables:
23 * c-file-style: "linux"
24 * End:
25 */
diff --git a/arch/um/kernel/tt/ptproxy/wait.c b/arch/um/kernel/tt/ptproxy/wait.c
deleted file mode 100644
index bdd4af4b65fc..000000000000
--- a/arch/um/kernel/tt/ptproxy/wait.c
+++ /dev/null
@@ -1,85 +0,0 @@
1/**********************************************************************
2wait.c
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6
7**********************************************************************/
8
9#include <errno.h>
10#include <signal.h>
11#include <sys/wait.h>
12
13#include "ptproxy.h"
14#include "sysdep.h"
15#include "wait.h"
16#include "ptrace_user.h"
17#include "sysdep/ptrace.h"
18#include "sysdep/sigcontext.h"
19
20int proxy_wait_return(struct debugger *debugger, pid_t unused)
21{
22 debugger->waiting = 0;
23
24 if(debugger->debugee->died || (debugger->wait_options & __WCLONE)){
25 debugger_cancelled_return(debugger, -ECHILD);
26 return(0);
27 }
28
29 if(debugger->debugee->zombie && debugger->debugee->event)
30 debugger->debugee->died = 1;
31
32 if(debugger->debugee->event){
33 debugger->debugee->event = 0;
34 ptrace(PTRACE_POKEDATA, debugger->pid,
35 debugger->wait_status_ptr,
36 debugger->debugee->wait_status);
37 /* if (wait4)
38 ptrace (PTRACE_POKEDATA, pid, rusage_ptr, ...); */
39 debugger_cancelled_return(debugger, debugger->debugee->pid);
40 return(0);
41 }
42
43 /* pause will return -EINTR, which happens to be right for wait */
44 debugger_normal_return(debugger, -1);
45 return(0);
46}
47
48int parent_wait_return(struct debugger *debugger, pid_t unused)
49{
50 return(debugger_normal_return(debugger, -1));
51}
52
53int real_wait_return(struct debugger *debugger)
54{
55 unsigned long ip;
56 int pid;
57
58 pid = debugger->pid;
59
60 ip = ptrace(PTRACE_PEEKUSR, pid, PT_IP_OFFSET, 0);
61 IP_RESTART_SYSCALL(ip);
62
63 if(ptrace(PTRACE_POKEUSR, pid, PT_IP_OFFSET, ip) < 0)
64 tracer_panic("real_wait_return : Failed to restart system "
65 "call, errno = %d\n", errno);
66
67 if((ptrace(PTRACE_SYSCALL, debugger->pid, 0, SIGCHLD) < 0) ||
68 (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
69 (ptrace(PTRACE_SYSCALL, debugger->pid, 0, 0) < 0) ||
70 debugger_normal_return(debugger, -1))
71 tracer_panic("real_wait_return : gdb failed to wait, "
72 "errno = %d\n", errno);
73 return(0);
74}
75
76/*
77 * Overrides for Emacs so that we follow Linus's tabbing style.
78 * Emacs will notice this stuff at the end of the file and automatically
79 * adjust the settings for this buffer only. This must remain at the end
80 * of the file.
81 * ---------------------------------------------------------------------------
82 * Local variables:
83 * c-file-style: "linux"
84 * End:
85 */
diff --git a/arch/um/kernel/tt/ptproxy/wait.h b/arch/um/kernel/tt/ptproxy/wait.h
deleted file mode 100644
index 542e73ee2cee..000000000000
--- a/arch/um/kernel/tt/ptproxy/wait.h
+++ /dev/null
@@ -1,15 +0,0 @@
1/**********************************************************************
2wait.h
3
4Copyright (C) 1999 Lars Brinkhoff. See the file COPYING for licensing
5terms and conditions.
6**********************************************************************/
7
8#ifndef __PTPROXY_WAIT_H
9#define __PTPROXY_WAIT_H
10
11extern int proxy_wait_return(struct debugger *debugger, pid_t unused);
12extern int real_wait_return(struct debugger *debugger);
13extern int parent_wait_return(struct debugger *debugger, pid_t unused);
14
15#endif
diff --git a/arch/um/kernel/tt/syscall_kern.c b/arch/um/kernel/tt/syscall_kern.c
deleted file mode 100644
index 293caa6d0c2d..000000000000
--- a/arch/um/kernel/tt/syscall_kern.c
+++ /dev/null
@@ -1,46 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/types.h"
7#include "linux/utime.h"
8#include "linux/sys.h"
9#include "linux/ptrace.h"
10#include "asm/unistd.h"
11#include "asm/ptrace.h"
12#include "asm/uaccess.h"
13#include "asm/stat.h"
14#include "sysdep/syscalls.h"
15#include "sysdep/sigcontext.h"
16#include "kern_util.h"
17#include "syscall.h"
18
19void syscall_handler_tt(int sig, struct pt_regs *regs)
20{
21 void *sc;
22 long result;
23 int syscall;
24
25 sc = UPT_SC(&regs->regs);
26 SC_START_SYSCALL(sc);
27
28 syscall = UPT_SYSCALL_NR(&regs->regs);
29 syscall_trace(&regs->regs, 0);
30
31 current->thread.nsyscalls++;
32 nsyscalls++;
33
34 if((syscall >= NR_syscalls) || (syscall < 0))
35 result = -ENOSYS;
36 else result = EXECUTE_SYSCALL(syscall, regs);
37
38 /* regs->sc may have changed while the system call ran (there may
39 * have been an interrupt or segfault), so it needs to be refreshed.
40 */
41 UPT_SC(&regs->regs) = sc;
42
43 SC_SET_SYSCALL_RETURN(sc, result);
44
45 syscall_trace(&regs->regs, 1);
46}
diff --git a/arch/um/kernel/tt/syscall_user.c b/arch/um/kernel/tt/syscall_user.c
deleted file mode 100644
index f52b47aff1d2..000000000000
--- a/arch/um/kernel/tt/syscall_user.c
+++ /dev/null
@@ -1,60 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <unistd.h>
7#include <signal.h>
8#include <errno.h>
9#include <asm/unistd.h>
10#include "sysdep/ptrace.h"
11#include "sigcontext.h"
12#include "ptrace_user.h"
13#include "task.h"
14#include "kern_util.h"
15#include "syscall.h"
16#include "tt.h"
17
18void do_sigtrap(void *task)
19{
20 UPT_SYSCALL_NR(TASK_REGS(task)) = -1;
21}
22
23void do_syscall(void *task, int pid, int local_using_sysemu)
24{
25 unsigned long proc_regs[FRAME_SIZE];
26
27 if(ptrace_getregs(pid, proc_regs) < 0)
28 tracer_panic("Couldn't read registers");
29
30 UPT_SYSCALL_NR(TASK_REGS(task)) = PT_SYSCALL_NR(proc_regs);
31
32#ifdef UPT_ORIGGPR2
33 UPT_ORIGGPR2(TASK_REGS(task)) = REGS_ORIGGPR2(proc_regs);
34#endif
35
36 if(((unsigned long *) PT_IP(proc_regs) >= &_stext) &&
37 ((unsigned long *) PT_IP(proc_regs) <= &_etext))
38 tracer_panic("I'm tracing myself and I can't get out");
39
40 /* advanced sysemu mode set syscall number to -1 automatically */
41 if (local_using_sysemu==2)
42 return;
43
44 /* syscall number -1 in sysemu skips syscall restarting in host */
45 if(ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
46 local_using_sysemu ? -1 : __NR_getpid) < 0)
47 tracer_panic("do_syscall : Nullifying syscall failed, "
48 "errno = %d", errno);
49}
50
51/*
52 * Overrides for Emacs so that we follow Linus's tabbing style.
53 * Emacs will notice this stuff at the end of the file and automatically
54 * adjust the settings for this buffer only. This must remain at the end
55 * of the file.
56 * ---------------------------------------------------------------------------
57 * Local variables:
58 * c-file-style: "linux"
59 * End:
60 */
diff --git a/arch/um/kernel/tt/tlb.c b/arch/um/kernel/tt/tlb.c
deleted file mode 100644
index 7caa24fe05df..000000000000
--- a/arch/um/kernel/tt/tlb.c
+++ /dev/null
@@ -1,120 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Copyright 2003 PathScale, Inc.
4 * Licensed under the GPL
5 */
6
7#include "linux/stddef.h"
8#include "linux/kernel.h"
9#include "linux/sched.h"
10#include "linux/mm.h"
11#include "asm/page.h"
12#include "asm/pgtable.h"
13#include "asm/uaccess.h"
14#include "asm/tlbflush.h"
15#include "mem_user.h"
16#include "os.h"
17#include "tlb.h"
18
19static int do_ops(union mm_context *mmu, struct host_vm_op *ops, int last,
20 int finished, void **flush)
21{
22 struct host_vm_op *op;
23 int i, ret=0;
24
25 for(i = 0; i <= last && !ret; i++){
26 op = &ops[i];
27 switch(op->type){
28 case MMAP:
29 ret = os_map_memory((void *) op->u.mmap.addr,
30 op->u.mmap.fd, op->u.mmap.offset,
31 op->u.mmap.len, op->u.mmap.r,
32 op->u.mmap.w, op->u.mmap.x);
33 break;
34 case MUNMAP:
35 ret = os_unmap_memory((void *) op->u.munmap.addr,
36 op->u.munmap.len);
37 break;
38 case MPROTECT:
39 ret = protect_memory(op->u.mprotect.addr,
40 op->u.munmap.len,
41 op->u.mprotect.r,
42 op->u.mprotect.w,
43 op->u.mprotect.x, 1);
44 protect_memory(op->u.mprotect.addr, op->u.munmap.len,
45 op->u.mprotect.r, op->u.mprotect.w,
46 op->u.mprotect.x, 1);
47 break;
48 default:
49 printk("Unknown op type %d in do_ops\n", op->type);
50 break;
51 }
52 }
53
54 return ret;
55}
56
57static void fix_range(struct mm_struct *mm, unsigned long start_addr,
58 unsigned long end_addr, int force)
59{
60 if((current->thread.mode.tt.extern_pid != -1) &&
61 (current->thread.mode.tt.extern_pid != os_getpid()))
62 panic("fix_range fixing wrong address space, current = 0x%p",
63 current);
64
65 fix_range_common(mm, start_addr, end_addr, force, do_ops);
66}
67
68atomic_t vmchange_seq = ATOMIC_INIT(1);
69
70void flush_tlb_kernel_range_tt(unsigned long start, unsigned long end)
71{
72 if(flush_tlb_kernel_range_common(start, end))
73 atomic_inc(&vmchange_seq);
74}
75
76void flush_tlb_kernel_vm_tt(void)
77{
78 flush_tlb_kernel_range(start_vm, end_vm);
79}
80
81void __flush_tlb_one_tt(unsigned long addr)
82{
83 flush_tlb_kernel_range(addr, addr + PAGE_SIZE);
84}
85
86void flush_tlb_range_tt(struct vm_area_struct *vma, unsigned long start,
87 unsigned long end)
88{
89 if(vma->vm_mm != current->mm) return;
90
91 /* Assumes that the range start ... end is entirely within
92 * either process memory or kernel vm
93 */
94 if((start >= start_vm) && (start < end_vm)){
95 if(flush_tlb_kernel_range_common(start, end))
96 atomic_inc(&vmchange_seq);
97 }
98 else fix_range(vma->vm_mm, start, end, 0);
99}
100
101void flush_tlb_mm_tt(struct mm_struct *mm)
102{
103 unsigned long seq;
104
105 if(mm != current->mm) return;
106
107 fix_range(mm, 0, STACK_TOP, 0);
108
109 seq = atomic_read(&vmchange_seq);
110 if(current->thread.mode.tt.vm_seq == seq)
111 return;
112 current->thread.mode.tt.vm_seq = seq;
113 flush_tlb_kernel_range_common(start_vm, end_vm);
114}
115
116void force_flush_all_tt(void)
117{
118 fix_range(current->mm, 0, STACK_TOP, 1);
119 flush_tlb_kernel_range_common(start_vm, end_vm);
120}
diff --git a/arch/um/kernel/tt/tracer.c b/arch/um/kernel/tt/tracer.c
deleted file mode 100644
index c23588393f6e..000000000000
--- a/arch/um/kernel/tt/tracer.c
+++ /dev/null
@@ -1,461 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdio.h>
7#include <stdlib.h>
8#include <stdarg.h>
9#include <unistd.h>
10#include <signal.h>
11#include <errno.h>
12#include <sched.h>
13#include <string.h>
14#include <sys/mman.h>
15#include <sys/time.h>
16#include <sys/wait.h>
17#include "user.h"
18#include "sysdep/ptrace.h"
19#include "sigcontext.h"
20#include "sysdep/sigcontext.h"
21#include "os.h"
22#include "mem_user.h"
23#include "process.h"
24#include "kern_util.h"
25#include "chan_user.h"
26#include "ptrace_user.h"
27#include "irq_user.h"
28#include "mode.h"
29#include "tt.h"
30
31static int tracer_winch[2];
32
33int is_tracer_winch(int pid, int fd, void *data)
34{
35 if(pid != os_getpgrp())
36 return(0);
37
38 register_winch_irq(tracer_winch[0], fd, -1, data);
39 return(1);
40}
41
42static void tracer_winch_handler(int sig)
43{
44 int n;
45 char c = 1;
46
47 n = os_write_file(tracer_winch[1], &c, sizeof(c));
48 if(n != sizeof(c))
49 printk("tracer_winch_handler - write failed, err = %d\n", -n);
50}
51
52/* Called only by the tracing thread during initialization */
53
54static void setup_tracer_winch(void)
55{
56 int err;
57
58 err = os_pipe(tracer_winch, 1, 1);
59 if(err < 0){
60 printk("setup_tracer_winch : os_pipe failed, err = %d\n", -err);
61 return;
62 }
63 signal(SIGWINCH, tracer_winch_handler);
64}
65
66void attach_process(int pid)
67{
68 if((ptrace(PTRACE_ATTACH, pid, 0, 0) < 0) ||
69 (ptrace(PTRACE_CONT, pid, 0, 0) < 0))
70 tracer_panic("OP_FORK failed to attach pid");
71 wait_for_stop(pid, SIGSTOP, PTRACE_CONT, NULL);
72 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0)
73 tracer_panic("OP_FORK: PTRACE_SETOPTIONS failed, errno = %d", errno);
74 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0)
75 tracer_panic("OP_FORK failed to continue process");
76}
77
78void tracer_panic(char *format, ...)
79{
80 va_list ap;
81
82 va_start(ap, format);
83 vprintf(format, ap);
84 va_end(ap);
85 printf("\n");
86 while(1) pause();
87}
88
89static void tracer_segv(int sig, struct sigcontext sc)
90{
91 struct faultinfo fi;
92 GET_FAULTINFO_FROM_SC(fi, &sc);
93 printf("Tracing thread segfault at address 0x%lx, ip 0x%lx\n",
94 FAULT_ADDRESS(fi), SC_IP(&sc));
95 while(1)
96 pause();
97}
98
99/* Changed early in boot, and then only read */
100int debug = 0;
101int debug_stop = 1;
102int debug_parent = 0;
103int honeypot = 0;
104
105static int signal_tramp(void *arg)
106{
107 int (*proc)(void *);
108
109 if(honeypot && munmap((void *) (host_task_size - 0x10000000),
110 0x10000000))
111 panic("Unmapping stack failed");
112 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0)
113 panic("ptrace PTRACE_TRACEME failed");
114 os_stop_process(os_getpid());
115 change_sig(SIGWINCH, 0);
116 signal(SIGUSR1, SIG_IGN);
117 change_sig(SIGCHLD, 0);
118 signal(SIGSEGV, (__sighandler_t) sig_handler);
119 set_cmdline("(idle thread)");
120 set_init_pid(os_getpid());
121 init_irq_signals(0);
122 proc = arg;
123 return((*proc)(NULL));
124}
125
126static void sleeping_process_signal(int pid, int sig)
127{
128 switch(sig){
129 /* These two result from UML being ^Z-ed and bg-ed. PTRACE_CONT is
130 * right because the process must be in the kernel already.
131 */
132 case SIGCONT:
133 case SIGTSTP:
134 if(ptrace(PTRACE_CONT, pid, 0, sig) < 0)
135 tracer_panic("sleeping_process_signal : Failed to "
136 "continue pid %d, signal = %d, "
137 "errno = %d\n", pid, sig, errno);
138 break;
139
140 /* This happens when the debugger (e.g. strace) is doing system call
141 * tracing on the kernel. During a context switch, the current task
142 * will be set to the incoming process and the outgoing process will
143 * hop into write and then read. Since it's not the current process
144 * any more, the trace of those will land here. So, we need to just
145 * PTRACE_SYSCALL it.
146 */
147 case (SIGTRAP + 0x80):
148 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
149 tracer_panic("sleeping_process_signal : Failed to "
150 "PTRACE_SYSCALL pid %d, errno = %d\n",
151 pid, errno);
152 break;
153 case SIGSTOP:
154 break;
155 default:
156 tracer_panic("sleeping process %d got unexpected "
157 "signal : %d\n", pid, sig);
158 break;
159 }
160}
161
162/* Accessed only by the tracing thread */
163int debugger_pid = -1;
164int debugger_parent = -1;
165int debugger_fd = -1;
166int gdb_pid = -1;
167
168struct {
169 int pid;
170 int signal;
171 unsigned long addr;
172 struct timeval time;
173} signal_record[1024][32];
174
175int signal_index[32];
176int nsignals = 0;
177int debug_trace = 0;
178
179extern void signal_usr1(int sig);
180
181int tracing_pid = -1;
182
183int tracer(int (*init_proc)(void *), void *sp)
184{
185 void *task = NULL;
186 int status, pid = 0, sig = 0, cont_type, tracing = 0, op = 0;
187 int proc_id = 0, n, err, old_tracing = 0, strace = 0;
188 int local_using_sysemu = 0;
189
190 signal(SIGPIPE, SIG_IGN);
191 setup_tracer_winch();
192 tracing_pid = os_getpid();
193 printf("tracing thread pid = %d\n", tracing_pid);
194
195 pid = clone(signal_tramp, sp, CLONE_FILES | SIGCHLD, init_proc);
196 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
197 if(n < 0){
198 printf("waitpid on idle thread failed, errno = %d\n", errno);
199 exit(1);
200 }
201 if (ptrace(PTRACE_OLDSETOPTIONS, pid, 0, (void *)PTRACE_O_TRACESYSGOOD) < 0) {
202 printf("Failed to PTRACE_SETOPTIONS for idle thread, errno = %d\n", errno);
203 exit(1);
204 }
205 if((ptrace(PTRACE_CONT, pid, 0, 0) < 0)){
206 printf("Failed to continue idle thread, errno = %d\n", errno);
207 exit(1);
208 }
209
210 signal(SIGSEGV, (sighandler_t) tracer_segv);
211 signal(SIGUSR1, signal_usr1);
212 if(debug_trace){
213 printf("Tracing thread pausing to be attached\n");
214 stop();
215 }
216 if(debug){
217 if(gdb_pid != -1)
218 debugger_pid = attach_debugger(pid, gdb_pid, 1);
219 else debugger_pid = init_ptrace_proxy(pid, 1, debug_stop);
220 if(debug_parent){
221 debugger_parent = os_process_parent(debugger_pid);
222 init_parent_proxy(debugger_parent);
223 err = attach(debugger_parent);
224 if(err){
225 printf("Failed to attach debugger parent %d, "
226 "errno = %d\n", debugger_parent, -err);
227 debugger_parent = -1;
228 }
229 else {
230 if(ptrace(PTRACE_SYSCALL, debugger_parent,
231 0, 0) < 0){
232 printf("Failed to continue debugger "
233 "parent, errno = %d\n", errno);
234 debugger_parent = -1;
235 }
236 }
237 }
238 }
239 set_cmdline("(tracing thread)");
240 while(1){
241 CATCH_EINTR(pid = waitpid(-1, &status, WUNTRACED));
242 if(pid <= 0){
243 if(errno != ECHILD){
244 printf("wait failed - errno = %d\n", errno);
245 }
246 continue;
247 }
248 if(pid == debugger_pid){
249 int cont = 0;
250
251 if(WIFEXITED(status) || WIFSIGNALED(status))
252 debugger_pid = -1;
253 /* XXX Figure out how to deal with gdb and SMP */
254 else cont = debugger_signal(status, cpu_tasks[0].pid);
255 if(cont == PTRACE_SYSCALL) strace = 1;
256 continue;
257 }
258 else if(pid == debugger_parent){
259 debugger_parent_signal(status, pid);
260 continue;
261 }
262 nsignals++;
263 if(WIFEXITED(status)) ;
264#ifdef notdef
265 {
266 printf("Child %d exited with status %d\n", pid,
267 WEXITSTATUS(status));
268 }
269#endif
270 else if(WIFSIGNALED(status)){
271 sig = WTERMSIG(status);
272 if(sig != 9){
273 printf("Child %d exited with signal %d\n", pid,
274 sig);
275 }
276 }
277 else if(WIFSTOPPED(status)){
278 proc_id = pid_to_processor_id(pid);
279 sig = WSTOPSIG(status);
280 if(proc_id == -1){
281 sleeping_process_signal(pid, sig);
282 continue;
283 }
284
285 task = cpu_tasks[proc_id].task;
286 tracing = is_tracing(task);
287 old_tracing = tracing;
288
289 /* Assume: no syscall, when coming from user */
290 if ( tracing )
291 do_sigtrap(task);
292
293 switch(sig){
294 case SIGUSR1:
295 sig = 0;
296 op = do_proc_op(task, proc_id);
297 switch(op){
298 /*
299 * This is called when entering user mode; after
300 * this, we start intercepting syscalls.
301 *
302 * In fact, a process is started in kernel mode,
303 * so with is_tracing() == 0 (and that is reset
304 * when executing syscalls, since UML kernel has
305 * the right to do syscalls);
306 */
307 case OP_TRACE_ON:
308 arch_leave_kernel(task, pid);
309 tracing = 1;
310 break;
311 case OP_REBOOT:
312 case OP_HALT:
313 unmap_physmem();
314 kmalloc_ok = 0;
315 os_kill_ptraced_process(pid, 0);
316 /* Now let's reap remaining zombies */
317 errno = 0;
318 do {
319 waitpid(-1, &status,
320 WUNTRACED);
321 } while (errno != ECHILD);
322 return(op == OP_REBOOT);
323 case OP_NONE:
324 printf("Detaching pid %d\n", pid);
325 detach(pid, SIGSTOP);
326 continue;
327 default:
328 break;
329 }
330 /* OP_EXEC switches host processes on us,
331 * we want to continue the new one.
332 */
333 pid = cpu_tasks[proc_id].pid;
334 break;
335 case (SIGTRAP + 0x80):
336 if(!tracing && (debugger_pid != -1)){
337 child_signal(pid, status & 0x7fff);
338 continue;
339 }
340 tracing = 0;
341 /* local_using_sysemu has been already set
342 * below, since if we are here, is_tracing() on
343 * the traced task was 1, i.e. the process had
344 * already run through one iteration of the
345 * loop which executed a OP_TRACE_ON request.*/
346 do_syscall(task, pid, local_using_sysemu);
347 sig = SIGUSR2;
348 break;
349 case SIGTRAP:
350 if(!tracing && (debugger_pid != -1)){
351 child_signal(pid, status);
352 continue;
353 }
354 tracing = 0;
355 break;
356 case SIGPROF:
357 if(tracing) sig = 0;
358 break;
359 case SIGCHLD:
360 case SIGHUP:
361 sig = 0;
362 break;
363 case SIGSEGV:
364 case SIGIO:
365 case SIGALRM:
366 case SIGVTALRM:
367 case SIGFPE:
368 case SIGBUS:
369 case SIGILL:
370 case SIGWINCH:
371
372 default:
373 tracing = 0;
374 break;
375 }
376 set_tracing(task, tracing);
377
378 if(!tracing && old_tracing)
379 arch_enter_kernel(task, pid);
380
381 if(!tracing && (debugger_pid != -1) && (sig != 0) &&
382 (sig != SIGALRM) && (sig != SIGVTALRM) &&
383 (sig != SIGSEGV) && (sig != SIGTRAP) &&
384 (sig != SIGUSR2) && (sig != SIGIO) &&
385 (sig != SIGFPE)){
386 child_signal(pid, status);
387 continue;
388 }
389
390 local_using_sysemu = get_using_sysemu();
391
392 if(tracing)
393 cont_type = SELECT_PTRACE_OPERATION(local_using_sysemu,
394 singlestepping(task));
395 else if((debugger_pid != -1) && strace)
396 cont_type = PTRACE_SYSCALL;
397 else
398 cont_type = PTRACE_CONT;
399
400 if(ptrace(cont_type, pid, 0, sig) != 0){
401 tracer_panic("ptrace failed to continue "
402 "process - errno = %d\n",
403 errno);
404 }
405 }
406 }
407 return(0);
408}
409
410static int __init uml_debug_setup(char *line, int *add)
411{
412 char *next;
413
414 debug = 1;
415 *add = 0;
416 if(*line != '=') return(0);
417 line++;
418
419 while(line != NULL){
420 next = strchr(line, ',');
421 if(next) *next++ = '\0';
422
423 if(!strcmp(line, "go")) debug_stop = 0;
424 else if(!strcmp(line, "parent")) debug_parent = 1;
425 else printf("Unknown debug option : '%s'\n", line);
426
427 line = next;
428 }
429 return(0);
430}
431
432__uml_setup("debug", uml_debug_setup,
433"debug\n"
434" Starts up the kernel under the control of gdb. See the \n"
435" kernel debugging tutorial and the debugging session pages\n"
436" at http://user-mode-linux.sourceforge.net/ for more information.\n\n"
437);
438
439static int __init uml_debugtrace_setup(char *line, int *add)
440{
441 debug_trace = 1;
442 return 0;
443}
444__uml_setup("debugtrace", uml_debugtrace_setup,
445"debugtrace\n"
446" Causes the tracing thread to pause until it is attached by a\n"
447" debugger and continued. This is mostly for debugging crashes\n"
448" early during boot, and should be pretty much obsoleted by\n"
449" the debug switch.\n\n"
450);
451
452/*
453 * Overrides for Emacs so that we follow Linus's tabbing style.
454 * Emacs will notice this stuff at the end of the file and automatically
455 * adjust the settings for this buffer only. This must remain at the end
456 * of the file.
457 * ---------------------------------------------------------------------------
458 * Local variables:
459 * c-file-style: "linux"
460 * End:
461 */
diff --git a/arch/um/kernel/tt/trap_user.c b/arch/um/kernel/tt/trap_user.c
deleted file mode 100644
index 3032eb5e2467..000000000000
--- a/arch/um/kernel/tt/trap_user.c
+++ /dev/null
@@ -1,70 +0,0 @@
1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdlib.h>
7#include <errno.h>
8#include <signal.h>
9#include "sysdep/ptrace.h"
10#include "sysdep/sigcontext.h"
11#include "kern_util.h"
12#include "task.h"
13#include "tt.h"
14#include "os.h"
15
16void sig_handler_common_tt(int sig, void *sc_ptr)
17{
18 struct sigcontext *sc = sc_ptr;
19 struct tt_regs save_regs, *r;
20 int save_errno = errno, is_user = 0;
21 void (*handler)(int, union uml_pt_regs *);
22
23 /* This is done because to allow SIGSEGV to be delivered inside a SEGV
24 * handler. This can happen in copy_user, and if SEGV is disabled,
25 * the process will die.
26 */
27 if(sig == SIGSEGV)
28 change_sig(SIGSEGV, 1);
29
30 r = &TASK_REGS(get_current())->tt;
31 if ( sig == SIGFPE || sig == SIGSEGV ||
32 sig == SIGBUS || sig == SIGILL ||
33 sig == SIGTRAP ) {
34 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
35 }
36 save_regs = *r;
37 if (sc)
38 is_user = user_context(SC_SP(sc));
39 r->sc = sc;
40 if(sig != SIGUSR2)
41 r->syscall = -1;
42
43 handler = sig_info[sig];
44
45 /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */
46 if (sig != SIGIO && sig != SIGWINCH &&
47 sig != SIGVTALRM && sig != SIGALRM)
48 unblock_signals();
49
50 handler(sig, (union uml_pt_regs *) r);
51
52 if(is_user){
53 interrupt_end();
54 block_signals();
55 set_user_mode(NULL);
56 }
57 *r = save_regs;
58 errno = save_errno;
59}
60
61/*
62 * Overrides for Emacs so that we follow Linus's tabbing style.
63 * Emacs will notice this stuff at the end of the file and automatically
64 * adjust the settings for this buffer only. This must remain at the end
65 * of the file.
66 * ---------------------------------------------------------------------------
67 * Local variables:
68 * c-file-style: "linux"
69 * End:
70 */
diff --git a/arch/um/kernel/tt/uaccess.c b/arch/um/kernel/tt/uaccess.c
deleted file mode 100644
index 1cb60726567e..000000000000
--- a/arch/um/kernel/tt/uaccess.c
+++ /dev/null
@@ -1,73 +0,0 @@
1/*
2 * Copyright (C) 2000 - 2003 Jeff Dike (jdike@addtoit.com)
3 * Licensed under the GPL
4 */
5
6#include "linux/sched.h"
7#include "asm/uaccess.h"
8
9int copy_from_user_tt(void *to, const void __user *from, int n)
10{
11 if(!access_ok(VERIFY_READ, from, n))
12 return(n);
13
14 return(__do_copy_from_user(to, from, n, &current->thread.fault_addr,
15 &current->thread.fault_catcher));
16}
17
18int copy_to_user_tt(void __user *to, const void *from, int n)
19{
20 if(!access_ok(VERIFY_WRITE, to, n))
21 return(n);
22
23 return(__do_copy_to_user(to, from, n, &current->thread.fault_addr,
24 &current->thread.fault_catcher));
25}
26
27int strncpy_from_user_tt(char *dst, const char __user *src, int count)
28{
29 int n;
30
31 if(!access_ok(VERIFY_READ, src, 1))
32 return(-EFAULT);
33
34 n = __do_strncpy_from_user(dst, src, count,
35 &current->thread.fault_addr,
36 &current->thread.fault_catcher);
37 if(n < 0) return(-EFAULT);
38 return(n);
39}
40
41int __clear_user_tt(void __user *mem, int len)
42{
43 return(__do_clear_user(mem, len,
44 &current->thread.fault_addr,
45 &current->thread.fault_catcher));
46}
47
48int clear_user_tt(void __user *mem, int len)
49{
50 if(!access_ok(VERIFY_WRITE, mem, len))
51 return(len);
52
53 return(__do_clear_user(mem, len, &current->thread.fault_addr,
54 &current->thread.fault_catcher));
55}
56
57int strnlen_user_tt(const void __user *str, int len)
58{
59 return(__do_strnlen_user(str, len,
60 &current->thread.fault_addr,
61 &current->thread.fault_catcher));
62}
63
64/*
65 * Overrides for Emacs so that we follow Linus's tabbing style.
66 * Emacs will notice this stuff at the end of the file and automatically
67 * adjust the settings for this buffer only. This must remain at the end
68 * of the file.
69 * ---------------------------------------------------------------------------
70 * Local variables:
71 * c-file-style: "linux"
72 * End:
73 */
diff --git a/arch/um/kernel/tt/uaccess_user.c b/arch/um/kernel/tt/uaccess_user.c
deleted file mode 100644
index 0e5c82c5e5b7..000000000000
--- a/arch/um/kernel/tt/uaccess_user.c
+++ /dev/null
@@ -1,105 +0,0 @@
1/*
2 * Copyright (C) 2001 Chris Emerson (cemerson@chiark.greenend.org.uk)
3 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com)
4 * Licensed under the GPL
5 */
6
7#include <string.h>
8#include "uml_uaccess.h"
9#include "task.h"
10#include "kern_util.h"
11#include "os.h"
12#include "longjmp.h"
13
14int __do_copy_from_user(void *to, const void *from, int n,
15 void **fault_addr, void **fault_catcher)
16{
17 struct tt_regs save = TASK_REGS(get_current())->tt;
18 unsigned long fault;
19 int faulted;
20
21 fault = __do_user_copy(to, from, n, fault_addr, fault_catcher,
22 __do_copy, &faulted);
23 TASK_REGS(get_current())->tt = save;
24
25 if(!faulted)
26 return 0;
27 else if (fault)
28 return n - (fault - (unsigned long) from);
29 else
30 /* In case of a general protection fault, we don't have the
31 * fault address, so NULL is used instead. Pretend we didn't
32 * copy anything. */
33 return n;
34}
35
36static void __do_strncpy(void *dst, const void *src, int count)
37{
38 strncpy(dst, src, count);
39}
40
41int __do_strncpy_from_user(char *dst, const char *src, unsigned long count,
42 void **fault_addr, void **fault_catcher)
43{
44 struct tt_regs save = TASK_REGS(get_current())->tt;
45 unsigned long fault;
46 int faulted;
47
48 fault = __do_user_copy(dst, src, count, fault_addr, fault_catcher,
49 __do_strncpy, &faulted);
50 TASK_REGS(get_current())->tt = save;
51
52 if(!faulted) return(strlen(dst));
53 else return(-1);
54}
55
56static void __do_clear(void *to, const void *from, int n)
57{
58 memset(to, 0, n);
59}
60
61int __do_clear_user(void *mem, unsigned long len,
62 void **fault_addr, void **fault_catcher)
63{
64 struct tt_regs save = TASK_REGS(get_current())->tt;
65 unsigned long fault;
66 int faulted;
67
68 fault = __do_user_copy(mem, NULL, len, fault_addr, fault_catcher,
69 __do_clear, &faulted);
70 TASK_REGS(get_current())->tt = save;
71
72 if(!faulted) return(0);
73 else return(len - (fault - (unsigned long) mem));
74}
75
76int __do_strnlen_user(const char *str, unsigned long n,
77 void **fault_addr, void **fault_catcher)
78{
79 struct tt_regs save = TASK_REGS(get_current())->tt;
80 int ret;
81 unsigned long *faddrp = (unsigned long *)fault_addr;
82 jmp_buf jbuf;
83
84 *fault_catcher = &jbuf;
85 if(UML_SETJMP(&jbuf) == 0)
86 ret = strlen(str) + 1;
87 else ret = *faddrp - (unsigned long) str;
88
89 *fault_addr = NULL;
90 *fault_catcher = NULL;
91
92 TASK_REGS(get_current())->tt = save;
93 return ret;
94}
95
96/*
97 * Overrides for Emacs so that we follow Linus's tabbing style.
98 * Emacs will notice this stuff at the end of the file and automatically
99 * adjust the settings for this buffer only. This must remain at the end
100 * of the file.
101 * ---------------------------------------------------------------------------
102 * Local variables:
103 * c-file-style: "linux"
104 * End:
105 */
diff --git a/arch/um/kernel/uaccess.c b/arch/um/kernel/uaccess.c
index 054e3de0784e..d7436aacd26f 100644
--- a/arch/um/kernel/uaccess.c
+++ b/arch/um/kernel/uaccess.c
@@ -18,7 +18,7 @@ void __do_copy(void *to, const void *from, int n)
18 18
19 19
20int __do_copy_to_user(void *to, const void *from, int n, 20int __do_copy_to_user(void *to, const void *from, int n,
21 void **fault_addr, void **fault_catcher) 21 void **fault_addr, jmp_buf **fault_catcher)
22{ 22{
23 unsigned long fault; 23 unsigned long fault;
24 int faulted; 24 int faulted;
diff --git a/arch/um/kernel/um_arch.c b/arch/um/kernel/um_arch.c
index ecc458fe51b9..f1c71393f578 100644
--- a/arch/um/kernel/um_arch.c
+++ b/arch/um/kernel/um_arch.c
@@ -1,46 +1,24 @@
1/* 1/*
2 * Copyright (C) 2000, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/kernel.h"
7#include "linux/sched.h"
8#include "linux/notifier.h"
9#include "linux/mm.h"
10#include "linux/types.h"
11#include "linux/tty.h"
12#include "linux/init.h"
13#include "linux/bootmem.h"
14#include "linux/spinlock.h"
15#include "linux/utsname.h"
16#include "linux/sysrq.h"
17#include "linux/seq_file.h"
18#include "linux/delay.h" 6#include "linux/delay.h"
7#include "linux/mm.h"
19#include "linux/module.h" 8#include "linux/module.h"
9#include "linux/seq_file.h"
10#include "linux/string.h"
20#include "linux/utsname.h" 11#include "linux/utsname.h"
21#include "asm/page.h"
22#include "asm/pgtable.h" 12#include "asm/pgtable.h"
23#include "asm/ptrace.h" 13#include "asm/processor.h"
24#include "asm/elf.h"
25#include "asm/user.h"
26#include "asm/setup.h" 14#include "asm/setup.h"
27#include "ubd_user.h"
28#include "asm/current.h"
29#include "kern_util.h"
30#include "as-layout.h"
31#include "arch.h" 15#include "arch.h"
16#include "as-layout.h"
17#include "init.h"
32#include "kern.h" 18#include "kern.h"
33#include "mem_user.h" 19#include "mem_user.h"
34#include "mem.h"
35#include "initrd.h"
36#include "init.h"
37#include "os.h" 20#include "os.h"
38#include "choose-mode.h"
39#include "mode_kern.h"
40#include "mode.h"
41#ifdef UML_CONFIG_MODE_SKAS
42#include "skas.h" 21#include "skas.h"
43#endif
44 22
45#define DEFAULT_COMMAND_LINE "root=98:0" 23#define DEFAULT_COMMAND_LINE "root=98:0"
46 24
@@ -53,7 +31,7 @@ static void __init add_arg(char *arg)
53 printf("add_arg: Too many command line arguments!\n"); 31 printf("add_arg: Too many command line arguments!\n");
54 exit(1); 32 exit(1);
55 } 33 }
56 if(strlen(command_line) > 0) 34 if (strlen(command_line) > 0)
57 strcat(command_line, " "); 35 strcat(command_line, " ");
58 strcat(command_line, arg); 36 strcat(command_line, arg);
59} 37}
@@ -70,8 +48,8 @@ struct cpuinfo_um boot_cpu_data = {
70 48
71unsigned long thread_saved_pc(struct task_struct *task) 49unsigned long thread_saved_pc(struct task_struct *task)
72{ 50{
73 return os_process_pc(CHOOSE_MODE_PROC(thread_pid_tt, thread_pid_skas, 51 /* FIXME: Need to look up userspace_pid by cpu */
74 task)); 52 return os_process_pc(userspace_pid[0]);
75} 53}
76 54
77/* Changed in setup_arch, which is called in early boot */ 55/* Changed in setup_arch, which is called in early boot */
@@ -90,7 +68,7 @@ static int show_cpuinfo(struct seq_file *m, void *v)
90 seq_printf(m, "processor\t: %d\n", index); 68 seq_printf(m, "processor\t: %d\n", index);
91 seq_printf(m, "vendor_id\t: User Mode Linux\n"); 69 seq_printf(m, "vendor_id\t: User Mode Linux\n");
92 seq_printf(m, "model name\t: UML\n"); 70 seq_printf(m, "model name\t: UML\n");
93 seq_printf(m, "mode\t\t: %s\n", CHOOSE_MODE("tt", "skas")); 71 seq_printf(m, "mode\t\t: skas\n");
94 seq_printf(m, "host\t\t: %s\n", host_info); 72 seq_printf(m, "host\t\t: %s\n", host_info);
95 seq_printf(m, "bogomips\t: %lu.%02lu\n\n", 73 seq_printf(m, "bogomips\t: %lu.%02lu\n\n",
96 loops_per_jiffy/(500000/HZ), 74 loops_per_jiffy/(500000/HZ),
@@ -132,44 +110,13 @@ unsigned long end_vm;
132/* Set in uml_ncpus_setup */ 110/* Set in uml_ncpus_setup */
133int ncpus = 1; 111int ncpus = 1;
134 112
135#ifdef CONFIG_CMDLINE_ON_HOST
136/* Pointer set in linux_main, the array itself is private to each thread,
137 * and changed at address space creation time so this poses no concurrency
138 * problems.
139 */
140static char *argv1_begin = NULL;
141static char *argv1_end = NULL;
142#endif
143
144/* Set in early boot */ 113/* Set in early boot */
145static int have_root __initdata = 0; 114static int have_root __initdata = 0;
146 115
147/* Set in uml_mem_setup and modified in linux_main */ 116/* Set in uml_mem_setup and modified in linux_main */
148long long physmem_size = 32 * 1024 * 1024; 117long long physmem_size = 32 * 1024 * 1024;
149 118
150void set_cmdline(char *cmd) 119static char *usage_string =
151{
152#ifdef CONFIG_CMDLINE_ON_HOST
153 char *umid, *ptr;
154
155 if(CHOOSE_MODE(honeypot, 0)) return;
156
157 umid = get_umid();
158 if(*umid != '\0'){
159 snprintf(argv1_begin,
160 (argv1_end - argv1_begin) * sizeof(*ptr),
161 "(%s) ", umid);
162 ptr = &argv1_begin[strlen(argv1_begin)];
163 }
164 else ptr = argv1_begin;
165
166 snprintf(ptr, (argv1_end - ptr) * sizeof(*ptr), "[%s]", cmd);
167 memset(argv1_begin + strlen(argv1_begin), '\0',
168 argv1_end - argv1_begin - strlen(argv1_begin));
169#endif
170}
171
172static char *usage_string =
173"User Mode Linux v%s\n" 120"User Mode Linux v%s\n"
174" available at http://user-mode-linux.sourceforge.net/\n\n"; 121" available at http://user-mode-linux.sourceforge.net/\n\n";
175 122
@@ -201,13 +148,10 @@ __uml_setup("root=", uml_root_setup,
201" root=/dev/ubd5\n\n" 148" root=/dev/ubd5\n\n"
202); 149);
203 150
204#ifndef CONFIG_MODE_TT
205
206static int __init no_skas_debug_setup(char *line, int *add) 151static int __init no_skas_debug_setup(char *line, int *add)
207{ 152{
208 printf("'debug' is not necessary to gdb UML in skas mode - run \n"); 153 printf("'debug' is not necessary to gdb UML in skas mode - run \n");
209 printf("'gdb linux' and disable CONFIG_CMDLINE_ON_HOST if gdb \n"); 154 printf("'gdb linux'");
210 printf("doesn't work as expected\n");
211 155
212 return 0; 156 return 0;
213} 157}
@@ -217,8 +161,6 @@ __uml_setup("debug", no_skas_debug_setup,
217" this flag is not needed to run gdb on UML in skas mode\n\n" 161" this flag is not needed to run gdb on UML in skas mode\n\n"
218); 162);
219 163
220#endif
221
222#ifdef CONFIG_SMP 164#ifdef CONFIG_SMP
223static int __init uml_ncpus_setup(char *line, int *add) 165static int __init uml_ncpus_setup(char *line, int *add)
224{ 166{
@@ -232,56 +174,10 @@ static int __init uml_ncpus_setup(char *line, int *add)
232 174
233__uml_setup("ncpus=", uml_ncpus_setup, 175__uml_setup("ncpus=", uml_ncpus_setup,
234"ncpus=<# of desired CPUs>\n" 176"ncpus=<# of desired CPUs>\n"
235" This tells an SMP kernel how many virtual processors to start.\n\n" 177" This tells an SMP kernel how many virtual processors to start.\n\n"
236); 178);
237#endif 179#endif
238 180
239static int force_tt = 0;
240
241#if defined(CONFIG_MODE_TT) && defined(CONFIG_MODE_SKAS)
242#define DEFAULT_TT 0
243
244static int __init mode_tt_setup(char *line, int *add)
245{
246 force_tt = 1;
247 return 0;
248}
249
250#else
251#ifdef CONFIG_MODE_SKAS
252
253#define DEFAULT_TT 0
254
255static int __init mode_tt_setup(char *line, int *add)
256{
257 printf("CONFIG_MODE_TT disabled - 'mode=tt' ignored\n");
258 return 0;
259}
260
261#else
262#ifdef CONFIG_MODE_TT
263
264#define DEFAULT_TT 1
265
266static int __init mode_tt_setup(char *line, int *add)
267{
268 printf("CONFIG_MODE_SKAS disabled - 'mode=tt' redundant\n");
269 return 0;
270}
271
272#endif
273#endif
274#endif
275
276__uml_setup("mode=tt", mode_tt_setup,
277"mode=tt\n"
278" When both CONFIG_MODE_TT and CONFIG_MODE_SKAS are enabled, this option\n"
279" forces UML to run in tt (tracing thread) mode. It is not the default\n"
280" because it's slower and less secure than skas mode.\n\n"
281);
282
283int mode_tt = DEFAULT_TT;
284
285static int __init Usage(char *line, int *add) 181static int __init Usage(char *line, int *add)
286{ 182{
287 const char **p; 183 const char **p;
@@ -310,9 +206,8 @@ static int __init uml_checksetup(char *line, int *add)
310 int n; 206 int n;
311 207
312 n = strlen(p->str); 208 n = strlen(p->str);
313 if(!strncmp(line, p->str, n)){ 209 if (!strncmp(line, p->str, n) && p->setup_func(line + n, add))
314 if (p->setup_func(line + n, add)) return 1; 210 return 1;
315 }
316 p++; 211 p++;
317 } 212 }
318 return 0; 213 return 0;
@@ -323,7 +218,7 @@ static void __init uml_postsetup(void)
323 initcall_t *p; 218 initcall_t *p;
324 219
325 p = &__uml_postsetup_start; 220 p = &__uml_postsetup_start;
326 while(p < &__uml_postsetup_end){ 221 while(p < &__uml_postsetup_end) {
327 (*p)(); 222 (*p)();
328 p++; 223 p++;
329 } 224 }
@@ -339,6 +234,20 @@ EXPORT_SYMBOL(end_iomem);
339 234
340extern char __binary_start; 235extern char __binary_start;
341 236
237static unsigned long set_task_sizes_skas(unsigned long *task_size_out)
238{
239 /* Round up to the nearest 4M */
240 unsigned long host_task_size = ROUND_4M((unsigned long)
241 &host_task_size);
242
243 if (!skas_needs_stub)
244 *task_size_out = host_task_size;
245 else
246 *task_size_out = STUB_START & PGDIR_MASK;
247
248 return host_task_size;
249}
250
342int __init linux_main(int argc, char **argv) 251int __init linux_main(int argc, char **argv)
343{ 252{
344 unsigned long avail, diff; 253 unsigned long avail, diff;
@@ -346,45 +255,30 @@ int __init linux_main(int argc, char **argv)
346 unsigned int i, add; 255 unsigned int i, add;
347 char * mode; 256 char * mode;
348 257
349 for (i = 1; i < argc; i++){ 258 for (i = 1; i < argc; i++) {
350 if((i == 1) && (argv[i][0] == ' ')) continue; 259 if ((i == 1) && (argv[i][0] == ' '))
260 continue;
351 add = 1; 261 add = 1;
352 uml_checksetup(argv[i], &add); 262 uml_checksetup(argv[i], &add);
353 if (add) 263 if (add)
354 add_arg(argv[i]); 264 add_arg(argv[i]);
355 } 265 }
356 if(have_root == 0) 266 if (have_root == 0)
357 add_arg(DEFAULT_COMMAND_LINE); 267 add_arg(DEFAULT_COMMAND_LINE);
358 268
269 /* OS sanity checks that need to happen before the kernel runs */
359 os_early_checks(); 270 os_early_checks();
360 if (force_tt)
361 clear_can_do_skas();
362 mode_tt = force_tt ? 1 : !can_do_skas();
363#ifndef CONFIG_MODE_TT
364 if (mode_tt) {
365 /*Since CONFIG_MODE_TT is #undef'ed, force_tt cannot be 1. So,
366 * can_do_skas() returned 0, and the message is correct. */
367 printf("Support for TT mode is disabled, and no SKAS support is present on the host.\n");
368 exit(1);
369 }
370#endif
371 271
372#ifndef CONFIG_MODE_SKAS 272 can_do_skas();
373 mode = "TT"; 273
374#else 274 if (proc_mm && ptrace_faultinfo)
375 /* Show to the user the result of selection */
376 if (mode_tt)
377 mode = "TT";
378 else if (proc_mm && ptrace_faultinfo)
379 mode = "SKAS3"; 275 mode = "SKAS3";
380 else 276 else
381 mode = "SKAS0"; 277 mode = "SKAS0";
382#endif
383 278
384 printf("UML running in %s mode\n", mode); 279 printf("UML running in %s mode\n", mode);
385 280
386 host_task_size = CHOOSE_MODE_PROC(set_task_sizes_tt, 281 host_task_size = set_task_sizes_skas(&task_size);
387 set_task_sizes_skas, &task_size);
388 282
389 /* 283 /*
390 * Setting up handlers to 'sig_info' struct 284 * Setting up handlers to 'sig_info' struct
@@ -392,13 +286,15 @@ int __init linux_main(int argc, char **argv)
392 os_fill_handlinfo(handlinfo_kern); 286 os_fill_handlinfo(handlinfo_kern);
393 287
394 brk_start = (unsigned long) sbrk(0); 288 brk_start = (unsigned long) sbrk(0);
395 CHOOSE_MODE_PROC(before_mem_tt, before_mem_skas, brk_start); 289
396 /* Increase physical memory size for exec-shield users 290 /*
397 so they actually get what they asked for. This should 291 * Increase physical memory size for exec-shield users
398 add zero for non-exec shield users */ 292 * so they actually get what they asked for. This should
293 * add zero for non-exec shield users
294 */
399 295
400 diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); 296 diff = UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
401 if(diff > 1024 * 1024){ 297 if (diff > 1024 * 1024) {
402 printf("Adding %ld bytes to physical memory to account for " 298 printf("Adding %ld bytes to physical memory to account for "
403 "exec-shield gap\n", diff); 299 "exec-shield gap\n", diff);
404 physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end); 300 physmem_size += UML_ROUND_UP(brk_start) - UML_ROUND_UP(&_end);
@@ -411,20 +307,16 @@ int __init linux_main(int argc, char **argv)
411 307
412 setup_machinename(init_utsname()->machine); 308 setup_machinename(init_utsname()->machine);
413 309
414#ifdef CONFIG_CMDLINE_ON_HOST
415 argv1_begin = argv[1];
416 argv1_end = &argv[1][strlen(argv[1])];
417#endif
418
419 highmem = 0; 310 highmem = 0;
420 iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK; 311 iomem_size = (iomem_size + PAGE_SIZE - 1) & PAGE_MASK;
421 max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC; 312 max_physmem = get_kmem_end() - uml_physmem - iomem_size - MIN_VMALLOC;
422 313
423 /* Zones have to begin on a 1 << MAX_ORDER page boundary, 314 /*
315 * Zones have to begin on a 1 << MAX_ORDER page boundary,
424 * so this makes sure that's true for highmem 316 * so this makes sure that's true for highmem
425 */ 317 */
426 max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1); 318 max_physmem &= ~((1 << (PAGE_SHIFT + MAX_ORDER)) - 1);
427 if(physmem_size + iomem_size > max_physmem){ 319 if (physmem_size + iomem_size > max_physmem) {
428 highmem = physmem_size + iomem_size - max_physmem; 320 highmem = physmem_size + iomem_size - max_physmem;
429 physmem_size -= highmem; 321 physmem_size -= highmem;
430#ifndef CONFIG_HIGHMEM 322#ifndef CONFIG_HIGHMEM
@@ -441,7 +333,7 @@ int __init linux_main(int argc, char **argv)
441 start_vm = VMALLOC_START; 333 start_vm = VMALLOC_START;
442 334
443 setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem); 335 setup_physmem(uml_physmem, uml_reserved, physmem_size, highmem);
444 if(init_maps(physmem_size, iomem_size, highmem)){ 336 if (init_maps(physmem_size, iomem_size, highmem)) {
445 printf("Failed to allocate mem_map for %Lu bytes of physical " 337 printf("Failed to allocate mem_map for %Lu bytes of physical "
446 "memory and %Lu bytes of highmem\n", physmem_size, 338 "memory and %Lu bytes of highmem\n", physmem_size,
447 highmem); 339 highmem);
@@ -450,10 +342,11 @@ int __init linux_main(int argc, char **argv)
450 342
451 virtmem_size = physmem_size; 343 virtmem_size = physmem_size;
452 avail = get_kmem_end() - start_vm; 344 avail = get_kmem_end() - start_vm;
453 if(physmem_size > avail) virtmem_size = avail; 345 if (physmem_size > avail)
346 virtmem_size = avail;
454 end_vm = start_vm + virtmem_size; 347 end_vm = start_vm + virtmem_size;
455 348
456 if(virtmem_size < physmem_size) 349 if (virtmem_size < physmem_size)
457 printf("Kernel virtual memory size shrunk to %lu bytes\n", 350 printf("Kernel virtual memory size shrunk to %lu bytes\n",
458 virtmem_size); 351 virtmem_size);
459 352
@@ -462,7 +355,7 @@ int __init linux_main(int argc, char **argv)
462 stack_protections((unsigned long) &init_thread_info); 355 stack_protections((unsigned long) &init_thread_info);
463 os_flush_stdout(); 356 os_flush_stdout();
464 357
465 return CHOOSE_MODE(start_uml_tt(), start_uml_skas()); 358 return start_uml();
466} 359}
467 360
468extern int uml_exitcode; 361extern int uml_exitcode;
diff --git a/arch/um/kernel/uml.lds.S b/arch/um/kernel/uml.lds.S
index 81acdc24348e..13df191e2b41 100644
--- a/arch/um/kernel/uml.lds.S
+++ b/arch/um/kernel/uml.lds.S
@@ -18,13 +18,6 @@ SECTIONS
18 18
19 . = START + SIZEOF_HEADERS; 19 . = START + SIZEOF_HEADERS;
20 20
21#ifdef MODE_TT
22 .remap_data : { UNMAP_PATH (.data .bss) }
23 .remap : { UNMAP_PATH (.text) }
24
25 . = ALIGN(4096); /* Init code and data */
26#endif
27
28 _text = .; 21 _text = .;
29 _stext = .; 22 _stext = .;
30 __init_begin = .; 23 __init_begin = .;
diff --git a/arch/um/os-Linux/Makefile b/arch/um/os-Linux/Makefile
index 2f8c79464015..8e129af8170d 100644
--- a/arch/um/os-Linux/Makefile
+++ b/arch/um/os-Linux/Makefile
@@ -1,23 +1,18 @@
1# 1#
2# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \ 6obj-y = aio.o elf_aux.o execvp.o file.o helper.o irq.o main.o mem.o process.o \
7 sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o umid.o tls.o \ 7 registers.o sigio.o signal.o start_up.o time.o trap.o tty.o uaccess.o \
8 user_syms.o util.o drivers/ sys-$(SUBARCH)/ 8 umid.o tls.o user_syms.o util.o drivers/ sys-$(SUBARCH)/ skas/
9
10obj-$(CONFIG_MODE_SKAS) += skas/
11
12obj-$(CONFIG_MODE_TT) += tt.o
13user-objs-$(CONFIG_MODE_TT) += tt.o
14 9
15obj-$(CONFIG_TTY_LOG) += tty_log.o 10obj-$(CONFIG_TTY_LOG) += tty_log.o
16user-objs-$(CONFIG_TTY_LOG) += tty_log.o 11user-objs-$(CONFIG_TTY_LOG) += tty_log.o
17 12
18USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \ 13USER_OBJS := $(user-objs-y) aio.o elf_aux.o execvp.o file.o helper.o irq.o \
19 main.o mem.o process.o sigio.o signal.o start_up.o time.o trap.o tty.o \ 14 main.o mem.o process.o registers.o sigio.o signal.o start_up.o time.o \
20 tls.o uaccess.o umid.o util.o 15 trap.o tty.o tls.o uaccess.o umid.o util.o
21 16
22CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH) 17CFLAGS_user_syms.o += -DSUBARCH_$(SUBARCH)
23 18
diff --git a/arch/um/os-Linux/aio.c b/arch/um/os-Linux/aio.c
index 59348359f9ab..4158118c4a56 100644
--- a/arch/um/os-Linux/aio.c
+++ b/arch/um/os-Linux/aio.c
@@ -1,20 +1,19 @@
1/* 1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdlib.h>
7#include <unistd.h> 6#include <unistd.h>
7#include <sched.h>
8#include <signal.h> 8#include <signal.h>
9#include <errno.h> 9#include <errno.h>
10#include <sched.h> 10#include <sys/time.h>
11#include <sys/syscall.h> 11#include <asm/unistd.h>
12#include "os.h"
13#include "aio.h" 12#include "aio.h"
14#include "init.h" 13#include "init.h"
15#include "user.h"
16#include "mode.h"
17#include "kern_constants.h" 14#include "kern_constants.h"
15#include "os.h"
16#include "user.h"
18 17
19struct aio_thread_req { 18struct aio_thread_req {
20 enum aio_type type; 19 enum aio_type type;
@@ -28,7 +27,8 @@ struct aio_thread_req {
28#if defined(HAVE_AIO_ABI) 27#if defined(HAVE_AIO_ABI)
29#include <linux/aio_abi.h> 28#include <linux/aio_abi.h>
30 29
31/* If we have the headers, we are going to build with AIO enabled. 30/*
31 * If we have the headers, we are going to build with AIO enabled.
32 * If we don't have aio in libc, we define the necessary stubs here. 32 * If we don't have aio in libc, we define the necessary stubs here.
33 */ 33 */
34 34
@@ -52,7 +52,8 @@ static long io_getevents(aio_context_t ctx_id, long min_nr, long nr,
52 52
53#endif 53#endif
54 54
55/* The AIO_MMAP cases force the mmapped page into memory here 55/*
56 * The AIO_MMAP cases force the mmapped page into memory here
56 * rather than in whatever place first touches the data. I used 57 * rather than in whatever place first touches the data. I used
57 * to do this by touching the page, but that's delicate because 58 * to do this by touching the page, but that's delicate because
58 * gcc is prone to optimizing that away. So, what's done here 59 * gcc is prone to optimizing that away. So, what's done here
@@ -106,12 +107,12 @@ static int aio_thread(void *arg)
106 107
107 signal(SIGWINCH, SIG_IGN); 108 signal(SIGWINCH, SIG_IGN);
108 109
109 while(1){ 110 while (1) {
110 n = io_getevents(ctx, 1, 1, &event, NULL); 111 n = io_getevents(ctx, 1, 1, &event, NULL);
111 if(n < 0){ 112 if (n < 0) {
112 if(errno == EINTR) 113 if (errno == EINTR)
113 continue; 114 continue;
114 printk("aio_thread - io_getevents failed, " 115 printk(UM_KERN_ERR "aio_thread - io_getevents failed, "
115 "errno = %d\n", errno); 116 "errno = %d\n", errno);
116 } 117 }
117 else { 118 else {
@@ -120,9 +121,9 @@ static int aio_thread(void *arg)
120 .err = event.res }); 121 .err = event.res });
121 reply_fd = ((struct aio_context *) reply.data)->reply_fd; 122 reply_fd = ((struct aio_context *) reply.data)->reply_fd;
122 err = write(reply_fd, &reply, sizeof(reply)); 123 err = write(reply_fd, &reply, sizeof(reply));
123 if(err != sizeof(reply)) 124 if (err != sizeof(reply))
124 printk("aio_thread - write failed, fd = %d, " 125 printk(UM_KERN_ERR "aio_thread - write failed, "
125 "err = %d\n", reply_fd, errno); 126 "fd = %d, err = %d\n", reply_fd, errno);
126 } 127 }
127 } 128 }
128 return 0; 129 return 0;
@@ -137,10 +138,10 @@ static int do_not_aio(struct aio_thread_req *req)
137 int n; 138 int n;
138 139
139 actual = lseek64(req->io_fd, req->offset, SEEK_SET); 140 actual = lseek64(req->io_fd, req->offset, SEEK_SET);
140 if(actual != req->offset) 141 if (actual != req->offset)
141 return -errno; 142 return -errno;
142 143
143 switch(req->type){ 144 switch(req->type) {
144 case AIO_READ: 145 case AIO_READ:
145 n = read(req->io_fd, req->buf, req->len); 146 n = read(req->io_fd, req->buf, req->len);
146 break; 147 break;
@@ -151,11 +152,12 @@ static int do_not_aio(struct aio_thread_req *req)
151 n = read(req->io_fd, &c, sizeof(c)); 152 n = read(req->io_fd, &c, sizeof(c));
152 break; 153 break;
153 default: 154 default:
154 printk("do_not_aio - bad request type : %d\n", req->type); 155 printk(UM_KERN_ERR "do_not_aio - bad request type : %d\n",
156 req->type);
155 return -EINVAL; 157 return -EINVAL;
156 } 158 }
157 159
158 if(n < 0) 160 if (n < 0)
159 return -errno; 161 return -errno;
160 return 0; 162 return 0;
161} 163}
@@ -173,16 +175,18 @@ static int not_aio_thread(void *arg)
173 int err; 175 int err;
174 176
175 signal(SIGWINCH, SIG_IGN); 177 signal(SIGWINCH, SIG_IGN);
176 while(1){ 178 while (1) {
177 err = read(aio_req_fd_r, &req, sizeof(req)); 179 err = read(aio_req_fd_r, &req, sizeof(req));
178 if(err != sizeof(req)){ 180 if (err != sizeof(req)) {
179 if(err < 0) 181 if (err < 0)
180 printk("not_aio_thread - read failed, " 182 printk(UM_KERN_ERR "not_aio_thread - "
181 "fd = %d, err = %d\n", aio_req_fd_r, 183 "read failed, fd = %d, err = %d\n",
184 aio_req_fd_r,
182 errno); 185 errno);
183 else { 186 else {
184 printk("not_aio_thread - short read, fd = %d, " 187 printk(UM_KERN_ERR "not_aio_thread - short "
185 "length = %d\n", aio_req_fd_r, err); 188 "read, fd = %d, length = %d\n",
189 aio_req_fd_r, err);
186 } 190 }
187 continue; 191 continue;
188 } 192 }
@@ -190,9 +194,9 @@ static int not_aio_thread(void *arg)
190 reply = ((struct aio_thread_reply) { .data = req.aio, 194 reply = ((struct aio_thread_reply) { .data = req.aio,
191 .err = err }); 195 .err = err });
192 err = write(req.aio->reply_fd, &reply, sizeof(reply)); 196 err = write(req.aio->reply_fd, &reply, sizeof(reply));
193 if(err != sizeof(reply)) 197 if (err != sizeof(reply))
194 printk("not_aio_thread - write failed, fd = %d, " 198 printk(UM_KERN_ERR "not_aio_thread - write failed, "
195 "err = %d\n", req.aio->reply_fd, errno); 199 "fd = %d, err = %d\n", req.aio->reply_fd, errno);
196 } 200 }
197 201
198 return 0; 202 return 0;
@@ -203,35 +207,36 @@ static int init_aio_24(void)
203 int fds[2], err; 207 int fds[2], err;
204 208
205 err = os_pipe(fds, 1, 1); 209 err = os_pipe(fds, 1, 1);
206 if(err) 210 if (err)
207 goto out; 211 goto out;
208 212
209 aio_req_fd_w = fds[0]; 213 aio_req_fd_w = fds[0];
210 aio_req_fd_r = fds[1]; 214 aio_req_fd_r = fds[1];
211 215
212 err = os_set_fd_block(aio_req_fd_w, 0); 216 err = os_set_fd_block(aio_req_fd_w, 0);
213 if(err) 217 if (err)
214 goto out_close_pipe; 218 goto out_close_pipe;
215 219
216 err = run_helper_thread(not_aio_thread, NULL, 220 err = run_helper_thread(not_aio_thread, NULL,
217 CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); 221 CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack);
218 if(err < 0) 222 if (err < 0)
219 goto out_close_pipe; 223 goto out_close_pipe;
220 224
221 aio_pid = err; 225 aio_pid = err;
222 goto out; 226 goto out;
223 227
224out_close_pipe: 228out_close_pipe:
225 os_close_file(fds[0]); 229 close(fds[0]);
226 os_close_file(fds[1]); 230 close(fds[1]);
227 aio_req_fd_w = -1; 231 aio_req_fd_w = -1;
228 aio_req_fd_r = -1; 232 aio_req_fd_r = -1;
229out: 233out:
230#ifndef HAVE_AIO_ABI 234#ifndef HAVE_AIO_ABI
231 printk("/usr/include/linux/aio_abi.h not present during build\n"); 235 printk(UM_KERN_INFO "/usr/include/linux/aio_abi.h not present during "
236 "build\n");
232#endif 237#endif
233 printk("2.6 host AIO support not used - falling back to I/O " 238 printk(UM_KERN_INFO "2.6 host AIO support not used - falling back to "
234 "thread\n"); 239 "I/O thread\n");
235 return 0; 240 return 0;
236} 241}
237 242
@@ -241,21 +246,21 @@ static int init_aio_26(void)
241{ 246{
242 int err; 247 int err;
243 248
244 if(io_setup(256, &ctx)){ 249 if (io_setup(256, &ctx)) {
245 err = -errno; 250 err = -errno;
246 printk("aio_thread failed to initialize context, err = %d\n", 251 printk(UM_KERN_ERR "aio_thread failed to initialize context, "
247 errno); 252 "err = %d\n", errno);
248 return err; 253 return err;
249 } 254 }
250 255
251 err = run_helper_thread(aio_thread, NULL, 256 err = run_helper_thread(aio_thread, NULL,
252 CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack); 257 CLONE_FILES | CLONE_VM | SIGCHLD, &aio_stack);
253 if(err < 0) 258 if (err < 0)
254 return err; 259 return err;
255 260
256 aio_pid = err; 261 aio_pid = err;
257 262
258 printk("Using 2.6 host AIO\n"); 263 printk(UM_KERN_INFO "Using 2.6 host AIO\n");
259 return 0; 264 return 0;
260} 265}
261 266
@@ -266,13 +271,13 @@ static int submit_aio_26(enum aio_type type, int io_fd, char *buf, int len,
266 int err; 271 int err;
267 272
268 err = do_aio(ctx, type, io_fd, buf, len, offset, aio); 273 err = do_aio(ctx, type, io_fd, buf, len, offset, aio);
269 if(err){ 274 if (err) {
270 reply = ((struct aio_thread_reply) { .data = aio, 275 reply = ((struct aio_thread_reply) { .data = aio,
271 .err = err }); 276 .err = err });
272 err = write(aio->reply_fd, &reply, sizeof(reply)); 277 err = write(aio->reply_fd, &reply, sizeof(reply));
273 if(err != sizeof(reply)){ 278 if (err != sizeof(reply)) {
274 err = -errno; 279 err = -errno;
275 printk("submit_aio_26 - write failed, " 280 printk(UM_KERN_ERR "submit_aio_26 - write failed, "
276 "fd = %d, err = %d\n", aio->reply_fd, -err); 281 "fd = %d, err = %d\n", aio->reply_fd, -err);
277 } 282 }
278 else err = 0; 283 else err = 0;
@@ -320,28 +325,24 @@ static int init_aio(void)
320{ 325{
321 int err; 326 int err;
322 327
323 CHOOSE_MODE(({ if(!aio_24){ 328 if (!aio_24) {
324 printk("Disabling 2.6 AIO in tt mode\n");
325 aio_24 = 1;
326 } }), (void) 0);
327
328 if(!aio_24){
329 err = init_aio_26(); 329 err = init_aio_26();
330 if(err && (errno == ENOSYS)){ 330 if (err && (errno == ENOSYS)) {
331 printk("2.6 AIO not supported on the host - " 331 printk(UM_KERN_INFO "2.6 AIO not supported on the "
332 "reverting to 2.4 AIO\n"); 332 "host - reverting to 2.4 AIO\n");
333 aio_24 = 1; 333 aio_24 = 1;
334 } 334 }
335 else return err; 335 else return err;
336 } 336 }
337 337
338 if(aio_24) 338 if (aio_24)
339 return init_aio_24(); 339 return init_aio_24();
340 340
341 return 0; 341 return 0;
342} 342}
343 343
344/* The reason for the __initcall/__uml_exitcall asymmetry is that init_aio 344/*
345 * The reason for the __initcall/__uml_exitcall asymmetry is that init_aio
345 * needs to be called when the kernel is running because it calls run_helper, 346 * needs to be called when the kernel is running because it calls run_helper,
346 * which needs get_free_page. exit_aio is a __uml_exitcall because the generic 347 * which needs get_free_page. exit_aio is a __uml_exitcall because the generic
347 * kernel does not run __exitcalls on shutdown, and can't because many of them 348 * kernel does not run __exitcalls on shutdown, and can't because many of them
@@ -372,7 +373,7 @@ static int submit_aio_24(enum aio_type type, int io_fd, char *buf, int len,
372 int err; 373 int err;
373 374
374 err = write(aio_req_fd_w, &req, sizeof(req)); 375 err = write(aio_req_fd_w, &req, sizeof(req));
375 if(err == sizeof(req)) 376 if (err == sizeof(req))
376 err = 0; 377 err = 0;
377 else err = -errno; 378 else err = -errno;
378 379
@@ -384,9 +385,8 @@ int submit_aio(enum aio_type type, int io_fd, char *buf, int len,
384 struct aio_context *aio) 385 struct aio_context *aio)
385{ 386{
386 aio->reply_fd = reply_fd; 387 aio->reply_fd = reply_fd;
387 if(aio_24) 388 if (aio_24)
388 return submit_aio_24(type, io_fd, buf, len, offset, aio); 389 return submit_aio_24(type, io_fd, buf, len, offset, aio);
389 else { 390 else
390 return submit_aio_26(type, io_fd, buf, len, offset, aio); 391 return submit_aio_26(type, io_fd, buf, len, offset, aio);
391 }
392} 392}
diff --git a/arch/um/os-Linux/drivers/etap.h b/arch/um/os-Linux/drivers/etap.h
index 57ecdaf2f67e..ddffd41c3f3f 100644
--- a/arch/um/os-Linux/drivers/etap.h
+++ b/arch/um/os-Linux/drivers/etap.h
@@ -1,8 +1,11 @@
1/* 1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#ifndef __DRIVERS_ETAP_H
7#define __DRIVERS_ETAP_H
8
6#include "net_user.h" 9#include "net_user.h"
7 10
8struct ethertap_data { 11struct ethertap_data {
@@ -15,13 +18,4 @@ struct ethertap_data {
15 18
16extern const struct net_user_info ethertap_user_info; 19extern const struct net_user_info ethertap_user_info;
17 20
18/* 21#endif
19 * Overrides for Emacs so that we follow Linus's tabbing style.
20 * Emacs will notice this stuff at the end of the file and automatically
21 * adjust the settings for this buffer only. This must remain at the end
22 * of the file.
23 * ---------------------------------------------------------------------------
24 * Local variables:
25 * c-file-style: "linux"
26 * End:
27 */
diff --git a/arch/um/os-Linux/drivers/ethertap_kern.c b/arch/um/os-Linux/drivers/ethertap_kern.c
index 12689141414d..04f11b9f1ac0 100644
--- a/arch/um/os-Linux/drivers/ethertap_kern.c
+++ b/arch/um/os-Linux/drivers/ethertap_kern.c
@@ -1,16 +1,15 @@
1/* 1/*
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
3 * James Leu (jleu@mindspring.net). 3 * James Leu (jleu@mindspring.net).
4 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Copyright (C) 2001 by various other people who didn't put their name here. 5 * Copyright (C) 2001 by various other people who didn't put their name here.
5 * Licensed under the GPL. 6 * Licensed under the GPL.
6 */ 7 */
7 8
8#include "linux/init.h" 9#include "linux/init.h"
9#include "linux/netdevice.h" 10#include <linux/netdevice.h>
10#include "linux/etherdevice.h"
11#include "net_kern.h"
12#include "net_user.h"
13#include "etap.h" 11#include "etap.h"
12#include "net_kern.h"
14 13
15struct ethertap_init { 14struct ethertap_init {
16 char *dev_name; 15 char *dev_name;
@@ -37,32 +36,24 @@ static void etap_init(struct net_device *dev, void *data)
37 printk("\n"); 36 printk("\n");
38} 37}
39 38
40static int etap_read(int fd, struct sk_buff **skb, struct uml_net_private *lp) 39static int etap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
41{ 40{
42 int len; 41 int len;
43 42
44 *skb = ether_adjust_skb(*skb, ETH_HEADER_ETHERTAP); 43 len = net_recvfrom(fd, skb_mac_header(skb),
45 if(*skb == NULL) return(-ENOMEM); 44 skb->dev->mtu + 2 + ETH_HEADER_ETHERTAP);
46 len = net_recvfrom(fd, skb_mac_header(*skb), 45 if (len <= 0)
47 (*skb)->dev->mtu + 2 * ETH_HEADER_ETHERTAP); 46 return(len);
48 if(len <= 0) return(len); 47
49 skb_pull(*skb, 2); 48 skb_pull(skb, 2);
50 len -= 2; 49 len -= 2;
51 return(len); 50 return len;
52} 51}
53 52
54static int etap_write(int fd, struct sk_buff **skb, struct uml_net_private *lp) 53static int etap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
55{ 54{
56 if(skb_headroom(*skb) < 2){ 55 skb_push(skb, 2);
57 struct sk_buff *skb2; 56 return net_send(fd, skb->data, skb->len);
58
59 skb2 = skb_realloc_headroom(*skb, 2);
60 dev_kfree_skb(*skb);
61 if (skb2 == NULL) return(-ENOMEM);
62 *skb = skb2;
63 }
64 skb_push(*skb, 2);
65 return(net_send(fd, (*skb)->data, (*skb)->len));
66} 57}
67 58
68const struct net_kern_info ethertap_kern_info = { 59const struct net_kern_info ethertap_kern_info = {
@@ -79,15 +70,15 @@ int ethertap_setup(char *str, char **mac_out, void *data)
79 *init = ((struct ethertap_init) 70 *init = ((struct ethertap_init)
80 { .dev_name = NULL, 71 { .dev_name = NULL,
81 .gate_addr = NULL }); 72 .gate_addr = NULL });
82 if(tap_setup_common(str, "ethertap", &init->dev_name, mac_out, 73 if (tap_setup_common(str, "ethertap", &init->dev_name, mac_out,
83 &init->gate_addr)) 74 &init->gate_addr))
84 return(0); 75 return 0;
85 if(init->dev_name == NULL){ 76 if (init->dev_name == NULL) {
86 printk("ethertap_setup : Missing tap device name\n"); 77 printk(KERN_ERR "ethertap_setup : Missing tap device name\n");
87 return(0); 78 return 0;
88 } 79 }
89 80
90 return(1); 81 return 1;
91} 82}
92 83
93static struct transport ethertap_transport = { 84static struct transport ethertap_transport = {
@@ -97,6 +88,7 @@ static struct transport ethertap_transport = {
97 .user = &ethertap_user_info, 88 .user = &ethertap_user_info,
98 .kern = &ethertap_kern_info, 89 .kern = &ethertap_kern_info,
99 .private_size = sizeof(struct ethertap_data), 90 .private_size = sizeof(struct ethertap_data),
91 .setup_size = sizeof(struct ethertap_init),
100}; 92};
101 93
102static int register_ethertap(void) 94static int register_ethertap(void)
diff --git a/arch/um/os-Linux/drivers/ethertap_user.c b/arch/um/os-Linux/drivers/ethertap_user.c
index 61d3953c7ac9..4ff553603449 100644
--- a/arch/um/os-Linux/drivers/ethertap_user.c
+++ b/arch/um/os-Linux/drivers/ethertap_user.c
@@ -1,4 +1,5 @@
1/* 1/*
2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
2 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and 3 * Copyright (C) 2001 Lennert Buytenhek (buytenh@gnu.org) and
3 * James Leu (jleu@mindspring.net). 4 * James Leu (jleu@mindspring.net).
4 * Copyright (C) 2001 by various other people who didn't put their name here. 5 * Copyright (C) 2001 by various other people who didn't put their name here.
@@ -7,20 +8,16 @@
7 8
8#include <stdio.h> 9#include <stdio.h>
9#include <unistd.h> 10#include <unistd.h>
10#include <stddef.h> 11#include <errno.h>
11#include <stdlib.h> 12#include <string.h>
12#include <sys/errno.h>
13#include <sys/socket.h> 13#include <sys/socket.h>
14#include <sys/wait.h> 14#include <sys/wait.h>
15#include <sys/un.h>
16#include <net/if.h>
17#include "user.h"
18#include "kern_util.h"
19#include "net_user.h"
20#include "etap.h" 15#include "etap.h"
16#include "kern_constants.h"
21#include "os.h" 17#include "os.h"
18#include "net_user.h"
22#include "um_malloc.h" 19#include "um_malloc.h"
23#include "kern_constants.h" 20#include "user.h"
24 21
25#define MAX_PACKET ETH_MAX_PACKET 22#define MAX_PACKET ETH_MAX_PACKET
26 23
@@ -49,16 +46,18 @@ static void etap_change(int op, unsigned char *addr, unsigned char *netmask,
49 memcpy(change.addr, addr, sizeof(change.addr)); 46 memcpy(change.addr, addr, sizeof(change.addr));
50 memcpy(change.netmask, netmask, sizeof(change.netmask)); 47 memcpy(change.netmask, netmask, sizeof(change.netmask));
51 CATCH_EINTR(n = write(fd, &change, sizeof(change))); 48 CATCH_EINTR(n = write(fd, &change, sizeof(change)));
52 if(n != sizeof(change)){ 49 if (n != sizeof(change)) {
53 printk("etap_change - request failed, err = %d\n", errno); 50 printk(UM_KERN_ERR "etap_change - request failed, err = %d\n",
51 errno);
54 return; 52 return;
55 } 53 }
56 54
57 output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL); 55 output = kmalloc(UM_KERN_PAGE_SIZE, UM_GFP_KERNEL);
58 if(output == NULL) 56 if (output == NULL)
59 printk("etap_change : Failed to allocate output buffer\n"); 57 printk(UM_KERN_ERR "etap_change : Failed to allocate output "
58 "buffer\n");
60 read_output(fd, output, UM_KERN_PAGE_SIZE); 59 read_output(fd, output, UM_KERN_PAGE_SIZE);
61 if(output != NULL){ 60 if (output != NULL) {
62 printk("%s", output); 61 printk("%s", output);
63 kfree(output); 62 kfree(output);
64 } 63 }
@@ -87,11 +86,11 @@ static void etap_pre_exec(void *arg)
87 struct etap_pre_exec_data *data = arg; 86 struct etap_pre_exec_data *data = arg;
88 87
89 dup2(data->control_remote, 1); 88 dup2(data->control_remote, 1);
90 os_close_file(data->data_me); 89 close(data->data_me);
91 os_close_file(data->control_me); 90 close(data->control_me);
92} 91}
93 92
94static int etap_tramp(char *dev, char *gate, int control_me, 93static int etap_tramp(char *dev, char *gate, int control_me,
95 int control_remote, int data_me, int data_remote) 94 int control_remote, int data_me, int data_remote)
96{ 95{
97 struct etap_pre_exec_data pe_data; 96 struct etap_pre_exec_data pe_data;
@@ -101,13 +100,13 @@ static int etap_tramp(char *dev, char *gate, int control_me,
101 char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")]; 100 char gate_buf[sizeof("nnn.nnn.nnn.nnn\0")];
102 char *setup_args[] = { "uml_net", version_buf, "ethertap", dev, 101 char *setup_args[] = { "uml_net", version_buf, "ethertap", dev,
103 data_fd_buf, gate_buf, NULL }; 102 data_fd_buf, gate_buf, NULL };
104 char *nosetup_args[] = { "uml_net", version_buf, "ethertap", 103 char *nosetup_args[] = { "uml_net", version_buf, "ethertap",
105 dev, data_fd_buf, NULL }; 104 dev, data_fd_buf, NULL };
106 char **args, c; 105 char **args, c;
107 106
108 sprintf(data_fd_buf, "%d", data_remote); 107 sprintf(data_fd_buf, "%d", data_remote);
109 sprintf(version_buf, "%d", UML_NET_VERSION); 108 sprintf(version_buf, "%d", UML_NET_VERSION);
110 if(gate != NULL){ 109 if (gate != NULL) {
111 strcpy(gate_buf, gate); 110 strcpy(gate_buf, gate);
112 args = setup_args; 111 args = setup_args;
113 } 112 }
@@ -119,24 +118,26 @@ static int etap_tramp(char *dev, char *gate, int control_me,
119 pe_data.data_me = data_me; 118 pe_data.data_me = data_me;
120 pid = run_helper(etap_pre_exec, &pe_data, args); 119 pid = run_helper(etap_pre_exec, &pe_data, args);
121 120
122 if(pid < 0) 121 if (pid < 0)
123 err = pid; 122 err = pid;
124 os_close_file(data_remote); 123 close(data_remote);
125 os_close_file(control_remote); 124 close(control_remote);
126 CATCH_EINTR(n = read(control_me, &c, sizeof(c))); 125 CATCH_EINTR(n = read(control_me, &c, sizeof(c)));
127 if(n != sizeof(c)){ 126 if (n != sizeof(c)) {
128 err = -errno; 127 err = -errno;
129 printk("etap_tramp : read of status failed, err = %d\n", -err); 128 printk(UM_KERN_ERR "etap_tramp : read of status failed, "
129 "err = %d\n", -err);
130 return err; 130 return err;
131 } 131 }
132 if(c != 1){ 132 if (c != 1) {
133 printk("etap_tramp : uml_net failed\n"); 133 printk(UM_KERN_ERR "etap_tramp : uml_net failed\n");
134 err = -EINVAL; 134 err = -EINVAL;
135 CATCH_EINTR(n = waitpid(pid, &status, 0)); 135 CATCH_EINTR(n = waitpid(pid, &status, 0));
136 if(n < 0) 136 if (n < 0)
137 err = -errno; 137 err = -errno;
138 else if(!WIFEXITED(status) || (WEXITSTATUS(status) != 1)) 138 else if (!WIFEXITED(status) || (WEXITSTATUS(status) != 1))
139 printk("uml_net didn't exit with status 1\n"); 139 printk(UM_KERN_ERR "uml_net didn't exit with "
140 "status 1\n");
140 } 141 }
141 return err; 142 return err;
142} 143}
@@ -148,43 +149,56 @@ static int etap_open(void *data)
148 int data_fds[2], control_fds[2], err, output_len; 149 int data_fds[2], control_fds[2], err, output_len;
149 150
150 err = tap_open_common(pri->dev, pri->gate_addr); 151 err = tap_open_common(pri->dev, pri->gate_addr);
151 if(err) 152 if (err)
152 return err; 153 return err;
153 154
154 err = os_pipe(data_fds, 0, 0); 155 err = socketpair(AF_UNIX, SOCK_DGRAM, 0, data_fds);
155 if(err < 0){ 156 if (err) {
156 printk("data os_pipe failed - err = %d\n", -err); 157 err = -errno;
158 printk(UM_KERN_ERR "etap_open - data socketpair failed - "
159 "err = %d\n", errno);
157 return err; 160 return err;
158 } 161 }
159 162
160 err = os_pipe(control_fds, 1, 0); 163 err = socketpair(AF_UNIX, SOCK_STREAM, 0, control_fds);
161 if(err < 0){ 164 if (err) {
162 printk("control os_pipe failed - err = %d\n", -err); 165 err = -errno;
163 return err; 166 printk(UM_KERN_ERR "etap_open - control socketpair failed - "
167 "err = %d\n", errno);
168 goto out_close_data;
164 } 169 }
165 170
166 err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0], 171 err = etap_tramp(pri->dev_name, pri->gate_addr, control_fds[0],
167 control_fds[1], data_fds[0], data_fds[1]); 172 control_fds[1], data_fds[0], data_fds[1]);
168 output_len = UM_KERN_PAGE_SIZE; 173 output_len = UM_KERN_PAGE_SIZE;
169 output = kmalloc(output_len, UM_GFP_KERNEL); 174 output = kmalloc(output_len, UM_GFP_KERNEL);
170 read_output(control_fds[0], output, output_len); 175 read_output(control_fds[0], output, output_len);
171 176
172 if(output == NULL) 177 if (output == NULL)
173 printk("etap_open : failed to allocate output buffer\n"); 178 printk(UM_KERN_ERR "etap_open : failed to allocate output "
179 "buffer\n");
174 else { 180 else {
175 printk("%s", output); 181 printk("%s", output);
176 kfree(output); 182 kfree(output);
177 } 183 }
178 184
179 if(err < 0){ 185 if (err < 0) {
180 printk("etap_tramp failed - err = %d\n", -err); 186 printk(UM_KERN_ERR "etap_tramp failed - err = %d\n", -err);
181 return err; 187 goto out_close_control;
182 } 188 }
183 189
184 pri->data_fd = data_fds[0]; 190 pri->data_fd = data_fds[0];
185 pri->control_fd = control_fds[0]; 191 pri->control_fd = control_fds[0];
186 iter_addresses(pri->dev, etap_open_addr, &pri->control_fd); 192 iter_addresses(pri->dev, etap_open_addr, &pri->control_fd);
187 return data_fds[0]; 193 return data_fds[0];
194
195out_close_control:
196 close(control_fds[0]);
197 close(control_fds[1]);
198out_close_data:
199 close(data_fds[0]);
200 close(data_fds[1]);
201 return err;
188} 202}
189 203
190static void etap_close(int fd, void *data) 204static void etap_close(int fd, void *data)
@@ -192,37 +206,41 @@ static void etap_close(int fd, void *data)
192 struct ethertap_data *pri = data; 206 struct ethertap_data *pri = data;
193 207
194 iter_addresses(pri->dev, etap_close_addr, &pri->control_fd); 208 iter_addresses(pri->dev, etap_close_addr, &pri->control_fd);
195 os_close_file(fd); 209 close(fd);
196 os_shutdown_socket(pri->data_fd, 1, 1); 210
197 os_close_file(pri->data_fd); 211 if (shutdown(pri->data_fd, SHUT_RDWR) < 0)
212 printk(UM_KERN_ERR "etap_close - shutdown data socket failed, "
213 "errno = %d\n", errno);
214
215 if (shutdown(pri->control_fd, SHUT_RDWR) < 0)
216 printk(UM_KERN_ERR "etap_close - shutdown control socket "
217 "failed, errno = %d\n", errno);
218
219 close(pri->data_fd);
198 pri->data_fd = -1; 220 pri->data_fd = -1;
199 os_close_file(pri->control_fd); 221 close(pri->control_fd);
200 pri->control_fd = -1; 222 pri->control_fd = -1;
201} 223}
202 224
203static int etap_set_mtu(int mtu, void *data)
204{
205 return mtu;
206}
207
208static void etap_add_addr(unsigned char *addr, unsigned char *netmask, 225static void etap_add_addr(unsigned char *addr, unsigned char *netmask,
209 void *data) 226 void *data)
210{ 227{
211 struct ethertap_data *pri = data; 228 struct ethertap_data *pri = data;
212 229
213 tap_check_ips(pri->gate_addr, addr); 230 tap_check_ips(pri->gate_addr, addr);
214 if(pri->control_fd == -1) 231 if (pri->control_fd == -1)
215 return; 232 return;
216 etap_open_addr(addr, netmask, &pri->control_fd); 233 etap_open_addr(addr, netmask, &pri->control_fd);
217} 234}
218 235
219static void etap_del_addr(unsigned char *addr, unsigned char *netmask, 236static void etap_del_addr(unsigned char *addr, unsigned char *netmask,
220 void *data) 237 void *data)
221{ 238{
222 struct ethertap_data *pri = data; 239 struct ethertap_data *pri = data;
223 240
224 if(pri->control_fd == -1) 241 if (pri->control_fd == -1)
225 return; 242 return;
243
226 etap_close_addr(addr, netmask, &pri->control_fd); 244 etap_close_addr(addr, netmask, &pri->control_fd);
227} 245}
228 246
@@ -231,8 +249,8 @@ const struct net_user_info ethertap_user_info = {
231 .open = etap_open, 249 .open = etap_open,
232 .close = etap_close, 250 .close = etap_close,
233 .remove = NULL, 251 .remove = NULL,
234 .set_mtu = etap_set_mtu,
235 .add_address = etap_add_addr, 252 .add_address = etap_add_addr,
236 .delete_address = etap_del_addr, 253 .delete_address = etap_del_addr,
237 .max_packet = MAX_PACKET - ETH_HEADER_ETHERTAP 254 .mtu = ETH_MAX_PACKET,
255 .max_packet = ETH_MAX_PACKET + ETH_HEADER_ETHERTAP,
238}; 256};
diff --git a/arch/um/os-Linux/drivers/tuntap.h b/arch/um/os-Linux/drivers/tuntap.h
index d3e8d3af6245..f17c31586c84 100644
--- a/arch/um/os-Linux/drivers/tuntap.h
+++ b/arch/um/os-Linux/drivers/tuntap.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -19,14 +19,3 @@ struct tuntap_data {
19extern const struct net_user_info tuntap_user_info; 19extern const struct net_user_info tuntap_user_info;
20 20
21#endif 21#endif
22
23/*
24 * Overrides for Emacs so that we follow Linus's tabbing style.
25 * Emacs will notice this stuff at the end of the file and automatically
26 * adjust the settings for this buffer only. This must remain at the end
27 * of the file.
28 * ---------------------------------------------------------------------------
29 * Local variables:
30 * c-file-style: "linux"
31 * End:
32 */
diff --git a/arch/um/os-Linux/drivers/tuntap_kern.c b/arch/um/os-Linux/drivers/tuntap_kern.c
index f1714e7fb1d0..9d384807b077 100644
--- a/arch/um/os-Linux/drivers/tuntap_kern.c
+++ b/arch/um/os-Linux/drivers/tuntap_kern.c
@@ -1,16 +1,13 @@
1/* 1/*
2 * Copyright (C) 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/stddef.h" 6#include <linux/netdevice.h>
7#include "linux/netdevice.h" 7#include <linux/init.h>
8#include "linux/etherdevice.h" 8#include <linux/skbuff.h>
9#include "linux/skbuff.h" 9#include <asm/errno.h>
10#include "linux/init.h"
11#include "asm/errno.h"
12#include "net_kern.h" 10#include "net_kern.h"
13#include "net_user.h"
14#include "tuntap.h" 11#include "tuntap.h"
15 12
16struct tuntap_init { 13struct tuntap_init {
@@ -38,19 +35,15 @@ static void tuntap_init(struct net_device *dev, void *data)
38 printk("\n"); 35 printk("\n");
39} 36}
40 37
41static int tuntap_read(int fd, struct sk_buff **skb, 38static int tuntap_read(int fd, struct sk_buff *skb, struct uml_net_private *lp)
42 struct uml_net_private *lp)
43{ 39{
44 *skb = ether_adjust_skb(*skb, ETH_HEADER_OTHER); 40 return net_read(fd, skb_mac_header(skb),
45 if(*skb == NULL) return(-ENOMEM); 41 skb->dev->mtu + ETH_HEADER_OTHER);
46 return(net_read(fd, skb_mac_header(*skb),
47 (*skb)->dev->mtu + ETH_HEADER_OTHER));
48} 42}
49 43
50static int tuntap_write(int fd, struct sk_buff **skb, 44static int tuntap_write(int fd, struct sk_buff *skb, struct uml_net_private *lp)
51 struct uml_net_private *lp)
52{ 45{
53 return(net_write(fd, (*skb)->data, (*skb)->len)); 46 return net_write(fd, skb->data, skb->len);
54} 47}
55 48
56const struct net_kern_info tuntap_kern_info = { 49const struct net_kern_info tuntap_kern_info = {
@@ -67,11 +60,11 @@ int tuntap_setup(char *str, char **mac_out, void *data)
67 *init = ((struct tuntap_init) 60 *init = ((struct tuntap_init)
68 { .dev_name = NULL, 61 { .dev_name = NULL,
69 .gate_addr = NULL }); 62 .gate_addr = NULL });
70 if(tap_setup_common(str, "tuntap", &init->dev_name, mac_out, 63 if (tap_setup_common(str, "tuntap", &init->dev_name, mac_out,
71 &init->gate_addr)) 64 &init->gate_addr))
72 return(0); 65 return 0;
73 66
74 return(1); 67 return 1;
75} 68}
76 69
77static struct transport tuntap_transport = { 70static struct transport tuntap_transport = {
diff --git a/arch/um/os-Linux/drivers/tuntap_user.c b/arch/um/os-Linux/drivers/tuntap_user.c
index f848b4ea9343..6c55d3c8ead8 100644
--- a/arch/um/os-Linux/drivers/tuntap_user.c
+++ b/arch/um/os-Linux/drivers/tuntap_user.c
@@ -1,27 +1,22 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h> 6#include <stdio.h>
7#include <stddef.h>
8#include <stdlib.h>
9#include <unistd.h> 7#include <unistd.h>
10#include <errno.h> 8#include <errno.h>
11#include <sys/wait.h> 9#include <string.h>
10#include <linux/if_tun.h>
11#include <net/if.h>
12#include <sys/ioctl.h>
12#include <sys/socket.h> 13#include <sys/socket.h>
13#include <sys/un.h> 14#include <sys/wait.h>
14#include <sys/uio.h> 15#include <sys/uio.h>
15#include <sys/ioctl.h> 16#include "kern_constants.h"
16#include <net/if.h> 17#include "os.h"
17#include <linux/if_tun.h>
18#include "net_user.h"
19#include "tuntap.h" 18#include "tuntap.h"
20#include "kern_util.h"
21#include "user.h" 19#include "user.h"
22#include "os.h"
23
24#define MAX_PACKET ETH_MAX_PACKET
25 20
26static int tuntap_user_init(void *data, void *dev) 21static int tuntap_user_init(void *data, void *dev)
27{ 22{
@@ -37,7 +32,7 @@ static void tuntap_add_addr(unsigned char *addr, unsigned char *netmask,
37 struct tuntap_data *pri = data; 32 struct tuntap_data *pri = data;
38 33
39 tap_check_ips(pri->gate_addr, addr); 34 tap_check_ips(pri->gate_addr, addr);
40 if((pri->fd == -1) || pri->fixed_config) 35 if ((pri->fd == -1) || pri->fixed_config)
41 return; 36 return;
42 open_addr(addr, netmask, pri->dev_name); 37 open_addr(addr, netmask, pri->dev_name);
43} 38}
@@ -47,7 +42,7 @@ static void tuntap_del_addr(unsigned char *addr, unsigned char *netmask,
47{ 42{
48 struct tuntap_data *pri = data; 43 struct tuntap_data *pri = data;
49 44
50 if((pri->fd == -1) || pri->fixed_config) 45 if ((pri->fd == -1) || pri->fixed_config)
51 return; 46 return;
52 close_addr(addr, netmask, pri->dev_name); 47 close_addr(addr, netmask, pri->dev_name);
53} 48}
@@ -62,7 +57,7 @@ static void tuntap_pre_exec(void *arg)
62 struct tuntap_pre_exec_data *data = arg; 57 struct tuntap_pre_exec_data *data = arg;
63 58
64 dup2(data->stdout, 1); 59 dup2(data->stdout, 1);
65 os_close_file(data->close_me); 60 close(data->close_me);
66} 61}
67 62
68static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote, 63static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
@@ -85,14 +80,14 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
85 80
86 pid = run_helper(tuntap_pre_exec, &data, argv); 81 pid = run_helper(tuntap_pre_exec, &data, argv);
87 82
88 if(pid < 0) 83 if (pid < 0)
89 return -pid; 84 return -pid;
90 85
91 os_close_file(remote); 86 close(remote);
92 87
93 msg.msg_name = NULL; 88 msg.msg_name = NULL;
94 msg.msg_namelen = 0; 89 msg.msg_namelen = 0;
95 if(buffer != NULL){ 90 if (buffer != NULL) {
96 iov = ((struct iovec) { buffer, buffer_len }); 91 iov = ((struct iovec) { buffer, buffer_len });
97 msg.msg_iov = &iov; 92 msg.msg_iov = &iov;
98 msg.msg_iovlen = 1; 93 msg.msg_iovlen = 1;
@@ -106,26 +101,28 @@ static int tuntap_open_tramp(char *gate, int *fd_out, int me, int remote,
106 msg.msg_flags = 0; 101 msg.msg_flags = 0;
107 n = recvmsg(me, &msg, 0); 102 n = recvmsg(me, &msg, 0);
108 *used_out = n; 103 *used_out = n;
109 if(n < 0){ 104 if (n < 0) {
110 err = -errno; 105 err = -errno;
111 printk("tuntap_open_tramp : recvmsg failed - errno = %d\n", 106 printk(UM_KERN_ERR "tuntap_open_tramp : recvmsg failed - "
112 errno); 107 "errno = %d\n", errno);
113 return err; 108 return err;
114 } 109 }
115 CATCH_EINTR(waitpid(pid, NULL, 0)); 110 CATCH_EINTR(waitpid(pid, NULL, 0));
116 111
117 cmsg = CMSG_FIRSTHDR(&msg); 112 cmsg = CMSG_FIRSTHDR(&msg);
118 if(cmsg == NULL){ 113 if (cmsg == NULL) {
119 printk("tuntap_open_tramp : didn't receive a message\n"); 114 printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
115 "message\n");
120 return -EINVAL; 116 return -EINVAL;
121 } 117 }
122 if((cmsg->cmsg_level != SOL_SOCKET) || 118 if ((cmsg->cmsg_level != SOL_SOCKET) ||
123 (cmsg->cmsg_type != SCM_RIGHTS)){ 119 (cmsg->cmsg_type != SCM_RIGHTS)) {
124 printk("tuntap_open_tramp : didn't receive a descriptor\n"); 120 printk(UM_KERN_ERR "tuntap_open_tramp : didn't receive a "
121 "descriptor\n");
125 return -EINVAL; 122 return -EINVAL;
126 } 123 }
127 *fd_out = ((int *) CMSG_DATA(cmsg))[0]; 124 *fd_out = ((int *) CMSG_DATA(cmsg))[0];
128 os_set_exec_close(*fd_out, 1); 125 os_set_exec_close(*fd_out);
129 return 0; 126 return 0;
130} 127}
131 128
@@ -137,47 +134,51 @@ static int tuntap_open(void *data)
137 int err, fds[2], len, used; 134 int err, fds[2], len, used;
138 135
139 err = tap_open_common(pri->dev, pri->gate_addr); 136 err = tap_open_common(pri->dev, pri->gate_addr);
140 if(err < 0) 137 if (err < 0)
141 return err; 138 return err;
142 139
143 if(pri->fixed_config){ 140 if (pri->fixed_config) {
144 pri->fd = os_open_file("/dev/net/tun", 141 pri->fd = os_open_file("/dev/net/tun",
145 of_cloexec(of_rdwr(OPENFLAGS())), 0); 142 of_cloexec(of_rdwr(OPENFLAGS())), 0);
146 if(pri->fd < 0){ 143 if (pri->fd < 0) {
147 printk("Failed to open /dev/net/tun, err = %d\n", 144 printk(UM_KERN_ERR "Failed to open /dev/net/tun, "
148 -pri->fd); 145 "err = %d\n", -pri->fd);
149 return pri->fd; 146 return pri->fd;
150 } 147 }
151 memset(&ifr, 0, sizeof(ifr)); 148 memset(&ifr, 0, sizeof(ifr));
152 ifr.ifr_flags = IFF_TAP | IFF_NO_PI; 149 ifr.ifr_flags = IFF_TAP | IFF_NO_PI;
153 strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name)); 150 strlcpy(ifr.ifr_name, pri->dev_name, sizeof(ifr.ifr_name));
154 if(ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0){ 151 if (ioctl(pri->fd, TUNSETIFF, (void *) &ifr) < 0) {
155 err = -errno; 152 err = -errno;
156 printk("TUNSETIFF failed, errno = %d\n", errno); 153 printk(UM_KERN_ERR "TUNSETIFF failed, errno = %d\n",
157 os_close_file(pri->fd); 154 errno);
155 close(pri->fd);
158 return err; 156 return err;
159 } 157 }
160 } 158 }
161 else { 159 else {
162 err = os_pipe(fds, 0, 0); 160 err = socketpair(AF_UNIX, SOCK_DGRAM, 0, fds);
163 if(err < 0){ 161 if (err) {
164 printk("tuntap_open : os_pipe failed - err = %d\n", 162 err = -errno;
165 -err); 163 printk(UM_KERN_ERR "tuntap_open : socketpair failed - "
164 "errno = %d\n", errno);
166 return err; 165 return err;
167 } 166 }
168 167
169 buffer = get_output_buffer(&len); 168 buffer = get_output_buffer(&len);
170 if(buffer != NULL) len--; 169 if (buffer != NULL)
170 len--;
171 used = 0; 171 used = 0;
172 172
173 err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0], 173 err = tuntap_open_tramp(pri->gate_addr, &pri->fd, fds[0],
174 fds[1], buffer, len, &used); 174 fds[1], buffer, len, &used);
175 175
176 output = buffer; 176 output = buffer;
177 if(err < 0) { 177 if (err < 0) {
178 printk("%s", output); 178 printk("%s", output);
179 free_output_buffer(buffer); 179 free_output_buffer(buffer);
180 printk("tuntap_open_tramp failed - err = %d\n", -err); 180 printk(UM_KERN_ERR "tuntap_open_tramp failed - "
181 "err = %d\n", -err);
181 return err; 182 return err;
182 } 183 }
183 184
@@ -186,7 +187,7 @@ static int tuntap_open(void *data)
186 printk("%s", output); 187 printk("%s", output);
187 free_output_buffer(buffer); 188 free_output_buffer(buffer);
188 189
189 os_close_file(fds[0]); 190 close(fds[0]);
190 iter_addresses(pri->dev, open_addr, pri->dev_name); 191 iter_addresses(pri->dev, open_addr, pri->dev_name);
191 } 192 }
192 193
@@ -197,24 +198,19 @@ static void tuntap_close(int fd, void *data)
197{ 198{
198 struct tuntap_data *pri = data; 199 struct tuntap_data *pri = data;
199 200
200 if(!pri->fixed_config) 201 if (!pri->fixed_config)
201 iter_addresses(pri->dev, close_addr, pri->dev_name); 202 iter_addresses(pri->dev, close_addr, pri->dev_name);
202 os_close_file(fd); 203 close(fd);
203 pri->fd = -1; 204 pri->fd = -1;
204} 205}
205 206
206static int tuntap_set_mtu(int mtu, void *data)
207{
208 return mtu;
209}
210
211const struct net_user_info tuntap_user_info = { 207const struct net_user_info tuntap_user_info = {
212 .init = tuntap_user_init, 208 .init = tuntap_user_init,
213 .open = tuntap_open, 209 .open = tuntap_open,
214 .close = tuntap_close, 210 .close = tuntap_close,
215 .remove = NULL, 211 .remove = NULL,
216 .set_mtu = tuntap_set_mtu,
217 .add_address = tuntap_add_addr, 212 .add_address = tuntap_add_addr,
218 .delete_address = tuntap_del_addr, 213 .delete_address = tuntap_del_addr,
219 .max_packet = MAX_PACKET 214 .mtu = ETH_MAX_PACKET,
215 .max_packet = ETH_MAX_PACKET + ETH_HEADER_OTHER,
220}; 216};
diff --git a/arch/um/os-Linux/file.c b/arch/um/os-Linux/file.c
index c3ecc2a84e0c..b542a3a021bf 100644
--- a/arch/um/os-Linux/file.c
+++ b/arch/um/os-Linux/file.c
@@ -82,13 +82,6 @@ int os_access(const char* file, int mode)
82 return 0; 82 return 0;
83} 83}
84 84
85void os_print_error(int error, const char* str)
86{
87 errno = error < 0 ? -error : error;
88
89 perror(str);
90}
91
92/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */ 85/* FIXME? required only by hostaudio (because it passes ioctls verbatim) */
93int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg) 86int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
94{ 87{
@@ -101,30 +94,6 @@ int os_ioctl_generic(int fd, unsigned int cmd, unsigned long arg)
101 return err; 94 return err;
102} 95}
103 96
104int os_window_size(int fd, int *rows, int *cols)
105{
106 struct winsize size;
107
108 if(ioctl(fd, TIOCGWINSZ, &size) < 0)
109 return -errno;
110
111 *rows = size.ws_row;
112 *cols = size.ws_col;
113
114 return 0;
115}
116
117int os_new_tty_pgrp(int fd, int pid)
118{
119 if(ioctl(fd, TIOCSCTTY, 0) < 0)
120 return -errno;
121
122 if(tcsetpgrp(fd, pid) < 0)
123 return -errno;
124
125 return 0;
126}
127
128/* FIXME: ensure namebuf in os_get_if_name is big enough */ 97/* FIXME: ensure namebuf in os_get_if_name is big enough */
129int os_get_ifname(int fd, char* namebuf) 98int os_get_ifname(int fd, char* namebuf)
130{ 99{
@@ -205,19 +174,19 @@ int os_file_mode(char *file, struct openflags *mode_out)
205 174
206 *mode_out = OPENFLAGS(); 175 *mode_out = OPENFLAGS();
207 176
208 err = os_access(file, OS_ACC_W_OK); 177 err = access(file, W_OK);
209 if((err < 0) && (err != -EACCES)) 178 if(err && (errno != EACCES))
210 return(err); 179 return -errno;
211 180 else if(!err)
212 *mode_out = of_write(*mode_out); 181 *mode_out = of_write(*mode_out);
213
214 err = os_access(file, OS_ACC_R_OK);
215 if((err < 0) && (err != -EACCES))
216 return(err);
217 182
218 *mode_out = of_read(*mode_out); 183 err = access(file, R_OK);
184 if(err && (errno != EACCES))
185 return -errno;
186 else if(!err)
187 *mode_out = of_read(*mode_out);
219 188
220 return(0); 189 return err;
221} 190}
222 191
223int os_open_file(char *file, struct openflags flags, int mode) 192int os_open_file(char *file, struct openflags flags, int mode)
@@ -236,15 +205,15 @@ int os_open_file(char *file, struct openflags flags, int mode)
236 205
237 fd = open64(file, f, mode); 206 fd = open64(file, f, mode);
238 if(fd < 0) 207 if(fd < 0)
239 return(-errno); 208 return -errno;
240 209
241 if(flags.cl && fcntl(fd, F_SETFD, 1)){ 210 if(flags.cl && fcntl(fd, F_SETFD, 1)){
242 err = -errno; 211 err = -errno;
243 os_close_file(fd); 212 close(fd);
244 return err; 213 return err;
245 } 214 }
246 215
247 return(fd); 216 return fd;
248} 217}
249 218
250int os_connect_socket(char *name) 219int os_connect_socket(char *name)
@@ -280,9 +249,9 @@ void os_close_file(int fd)
280 close(fd); 249 close(fd);
281} 250}
282 251
283int os_seek_file(int fd, __u64 offset) 252int os_seek_file(int fd, unsigned long long offset)
284{ 253{
285 __u64 actual; 254 unsigned long long actual;
286 255
287 actual = lseek64(fd, offset, SEEK_SET); 256 actual = lseek64(fd, offset, SEEK_SET);
288 if(actual != offset) 257 if(actual != offset)
@@ -316,31 +285,33 @@ int os_file_size(char *file, unsigned long long *size_out)
316 err = os_stat_file(file, &buf); 285 err = os_stat_file(file, &buf);
317 if(err < 0){ 286 if(err < 0){
318 printk("Couldn't stat \"%s\" : err = %d\n", file, -err); 287 printk("Couldn't stat \"%s\" : err = %d\n", file, -err);
319 return(err); 288 return err;
320 } 289 }
321 290
322 if(S_ISBLK(buf.ust_mode)){ 291 if(S_ISBLK(buf.ust_mode)){
323 int fd; 292 int fd;
324 long blocks; 293 long blocks;
325 294
326 fd = os_open_file(file, of_read(OPENFLAGS()), 0); 295 fd = open(file, O_RDONLY, 0);
327 if(fd < 0){ 296 if(fd < 0) {
328 printk("Couldn't open \"%s\", errno = %d\n", file, -fd); 297 err = -errno;
329 return(fd); 298 printk("Couldn't open \"%s\", errno = %d\n", file,
299 errno);
300 return err;
330 } 301 }
331 if(ioctl(fd, BLKGETSIZE, &blocks) < 0){ 302 if(ioctl(fd, BLKGETSIZE, &blocks) < 0){
332 err = -errno; 303 err = -errno;
333 printk("Couldn't get the block size of \"%s\", " 304 printk("Couldn't get the block size of \"%s\", "
334 "errno = %d\n", file, errno); 305 "errno = %d\n", file, errno);
335 os_close_file(fd); 306 close(fd);
336 return(err); 307 return err;
337 } 308 }
338 *size_out = ((long long) blocks) * 512; 309 *size_out = ((long long) blocks) * 512;
339 os_close_file(fd); 310 close(fd);
340 return(0);
341 } 311 }
342 *size_out = buf.ust_size; 312 else *size_out = buf.ust_size;
343 return(0); 313
314 return 0;
344} 315}
345 316
346int os_file_modtime(char *file, unsigned long *modtime) 317int os_file_modtime(char *file, unsigned long *modtime)
@@ -358,35 +329,28 @@ int os_file_modtime(char *file, unsigned long *modtime)
358 return 0; 329 return 0;
359} 330}
360 331
361int os_get_exec_close(int fd, int* close_on_exec) 332int os_get_exec_close(int fd, int *close_on_exec)
362{ 333{
363 int ret; 334 int ret;
364 335
365 do { 336 CATCH_EINTR(ret = fcntl(fd, F_GETFD));
366 ret = fcntl(fd, F_GETFD);
367 } while((ret < 0) && (errno == EINTR)) ;
368 337
369 if(ret < 0) 338 if(ret < 0)
370 return(-errno); 339 return -errno;
371 340
372 *close_on_exec = (ret&FD_CLOEXEC) ? 1 : 0; 341 *close_on_exec = (ret & FD_CLOEXEC) ? 1 : 0;
373 return(ret); 342 return ret;
374} 343}
375 344
376int os_set_exec_close(int fd, int close_on_exec) 345int os_set_exec_close(int fd)
377{ 346{
378 int flag, err; 347 int err;
379
380 if(close_on_exec) flag = FD_CLOEXEC;
381 else flag = 0;
382 348
383 do { 349 CATCH_EINTR(err = fcntl(fd, F_SETFD, FD_CLOEXEC));
384 err = fcntl(fd, F_SETFD, flag);
385 } while((err < 0) && (errno == EINTR)) ;
386 350
387 if(err < 0) 351 if(err < 0)
388 return(-errno); 352 return -errno;
389 return(err); 353 return err;
390} 354}
391 355
392int os_pipe(int *fds, int stream, int close_on_exec) 356int os_pipe(int *fds, int stream, int close_on_exec)
@@ -395,16 +359,16 @@ int os_pipe(int *fds, int stream, int close_on_exec)
395 359
396 err = socketpair(AF_UNIX, type, 0, fds); 360 err = socketpair(AF_UNIX, type, 0, fds);
397 if(err < 0) 361 if(err < 0)
398 return(-errno); 362 return -errno;
399 363
400 if(!close_on_exec) 364 if(!close_on_exec)
401 return(0); 365 return 0;
402 366
403 err = os_set_exec_close(fds[0], 1); 367 err = os_set_exec_close(fds[0]);
404 if(err < 0) 368 if(err < 0)
405 goto error; 369 goto error;
406 370
407 err = os_set_exec_close(fds[1], 1); 371 err = os_set_exec_close(fds[1]);
408 if(err < 0) 372 if(err < 0)
409 goto error; 373 goto error;
410 374
@@ -412,9 +376,9 @@ int os_pipe(int *fds, int stream, int close_on_exec)
412 376
413 error: 377 error:
414 printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err); 378 printk("os_pipe : Setting FD_CLOEXEC failed, err = %d\n", -err);
415 os_close_file(fds[1]); 379 close(fds[1]);
416 os_close_file(fds[0]); 380 close(fds[0]);
417 return(err); 381 return err;
418} 382}
419 383
420int os_set_fd_async(int fd, int owner) 384int os_set_fd_async(int fd, int owner)
@@ -561,7 +525,7 @@ int os_create_unix_socket(char *file, int len, int close_on_exec)
561 return -errno; 525 return -errno;
562 526
563 if(close_on_exec) { 527 if(close_on_exec) {
564 err = os_set_exec_close(sock, 1); 528 err = os_set_exec_close(sock);
565 if(err < 0) 529 if(err < 0)
566 printk("create_unix_socket : close_on_exec failed, " 530 printk("create_unix_socket : close_on_exec failed, "
567 "err = %d", -err); 531 "err = %d", -err);
diff --git a/arch/um/os-Linux/helper.c b/arch/um/os-Linux/helper.c
index d81af7b8587a..7a72dbb61b0d 100644
--- a/arch/um/os-Linux/helper.c
+++ b/arch/um/os-Linux/helper.c
@@ -11,6 +11,7 @@
11#include <limits.h> 11#include <limits.h>
12#include <sys/signal.h> 12#include <sys/signal.h>
13#include <sys/wait.h> 13#include <sys/wait.h>
14#include <sys/socket.h>
14#include "user.h" 15#include "user.h"
15#include "kern_util.h" 16#include "kern_util.h"
16#include "os.h" 17#include "os.h"
@@ -54,13 +55,14 @@ int run_helper(void (*pre_exec)(void *), void *pre_data, char **argv)
54 if (stack == 0) 55 if (stack == 0)
55 return -ENOMEM; 56 return -ENOMEM;
56 57
57 ret = os_pipe(fds, 1, 0); 58 ret = socketpair(AF_UNIX, SOCK_STREAM, 0, fds);
58 if (ret < 0) { 59 if (ret < 0) {
59 printk("run_helper : pipe failed, ret = %d\n", -ret); 60 ret = -errno;
61 printk("run_helper : pipe failed, errno = %d\n", errno);
60 goto out_free; 62 goto out_free;
61 } 63 }
62 64
63 ret = os_set_exec_close(fds[1], 1); 65 ret = os_set_exec_close(fds[1]);
64 if (ret < 0) { 66 if (ret < 0) {
65 printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n", 67 printk("run_helper : setting FD_CLOEXEC failed, ret = %d\n",
66 -ret); 68 -ret);
diff --git a/arch/um/os-Linux/irq.c b/arch/um/os-Linux/irq.c
index a633fa8e0a94..6aa6f95d6524 100644
--- a/arch/um/os-Linux/irq.c
+++ b/arch/um/os-Linux/irq.c
@@ -145,11 +145,7 @@ void init_irq_signals(int on_sigstack)
145 145
146 flags = on_sigstack ? SA_ONSTACK : 0; 146 flags = on_sigstack ? SA_ONSTACK : 0;
147 147
148 set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
149 flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
150 set_handler(SIGALRM, (__sighandler_t) alarm_handler,
151 flags | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, -1);
152 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART, 148 set_handler(SIGIO, (__sighandler_t) sig_handler, flags | SA_RESTART,
153 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 149 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
154 signal(SIGWINCH, SIG_IGN); 150 signal(SIGWINCH, SIG_IGN);
155} 151}
diff --git a/arch/um/os-Linux/main.c b/arch/um/os-Linux/main.c
index e85f4995a011..82c3778627b8 100644
--- a/arch/um/os-Linux/main.c
+++ b/arch/um/os-Linux/main.c
@@ -1,33 +1,21 @@
1/* 1/*
2 * Copyright (C) 2000, 2001 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <unistd.h>
7#include <stdio.h> 6#include <stdio.h>
8#include <stdlib.h> 7#include <stdlib.h>
9#include <string.h> 8#include <unistd.h>
10#include <signal.h>
11#include <errno.h> 9#include <errno.h>
10#include <signal.h>
11#include <string.h>
12#include <sys/resource.h> 12#include <sys/resource.h>
13#include <sys/mman.h>
14#include <sys/user.h>
15#include <asm/page.h>
16#include "kern_util.h"
17#include "as-layout.h" 13#include "as-layout.h"
18#include "mem_user.h"
19#include "irq_user.h"
20#include "user.h"
21#include "init.h" 14#include "init.h"
22#include "mode.h" 15#include "kern_constants.h"
23#include "choose-mode.h" 16#include "kern_util.h"
24#include "uml-config.h"
25#include "os.h" 17#include "os.h"
26#include "um_malloc.h" 18#include "um_malloc.h"
27#include "kern_constants.h"
28
29/* Set in main, unchanged thereafter */
30char *linux_prog;
31 19
32#define PGD_BOUND (4 * 1024 * 1024) 20#define PGD_BOUND (4 * 1024 * 1024)
33#define STACKSIZE (8 * 1024 * 1024) 21#define STACKSIZE (8 * 1024 * 1024)
@@ -37,13 +25,13 @@ static void set_stklim(void)
37{ 25{
38 struct rlimit lim; 26 struct rlimit lim;
39 27
40 if(getrlimit(RLIMIT_STACK, &lim) < 0){ 28 if (getrlimit(RLIMIT_STACK, &lim) < 0) {
41 perror("getrlimit"); 29 perror("getrlimit");
42 exit(1); 30 exit(1);
43 } 31 }
44 if((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)){ 32 if ((lim.rlim_cur == RLIM_INFINITY) || (lim.rlim_cur > STACKSIZE)) {
45 lim.rlim_cur = STACKSIZE; 33 lim.rlim_cur = STACKSIZE;
46 if(setrlimit(RLIMIT_STACK, &lim) < 0){ 34 if (setrlimit(RLIMIT_STACK, &lim) < 0) {
47 perror("setrlimit"); 35 perror("setrlimit");
48 exit(1); 36 exit(1);
49 } 37 }
@@ -55,7 +43,7 @@ static __init void do_uml_initcalls(void)
55 initcall_t *call; 43 initcall_t *call;
56 44
57 call = &__uml_initcall_start; 45 call = &__uml_initcall_start;
58 while (call < &__uml_initcall_end){ 46 while (call < &__uml_initcall_end) {
59 (*call)(); 47 (*call)();
60 call++; 48 call++;
61 } 49 }
@@ -74,7 +62,8 @@ static void install_fatal_handler(int sig)
74 /* All signals are enabled in this handler ... */ 62 /* All signals are enabled in this handler ... */
75 sigemptyset(&action.sa_mask); 63 sigemptyset(&action.sa_mask);
76 64
77 /* ... including the signal being handled, plus we want the 65 /*
66 * ... including the signal being handled, plus we want the
78 * handler reset to the default behavior, so that if an exit 67 * handler reset to the default behavior, so that if an exit
79 * handler is hanging for some reason, the UML will just die 68 * handler is hanging for some reason, the UML will just die
80 * after this signal is sent a second time. 69 * after this signal is sent a second time.
@@ -82,7 +71,7 @@ static void install_fatal_handler(int sig)
82 action.sa_flags = SA_RESETHAND | SA_NODEFER; 71 action.sa_flags = SA_RESETHAND | SA_NODEFER;
83 action.sa_restorer = NULL; 72 action.sa_restorer = NULL;
84 action.sa_handler = last_ditch_exit; 73 action.sa_handler = last_ditch_exit;
85 if(sigaction(sig, &action, NULL) < 0){ 74 if (sigaction(sig, &action, NULL) < 0) {
86 printf("failed to install handler for signal %d - errno = %d\n", 75 printf("failed to install handler for signal %d - errno = %d\n",
87 errno); 76 errno);
88 exit(1); 77 exit(1);
@@ -98,7 +87,8 @@ static void setup_env_path(void)
98 int path_len = 0; 87 int path_len = 0;
99 88
100 old_path = getenv("PATH"); 89 old_path = getenv("PATH");
101 /* if no PATH variable is set or it has an empty value 90 /*
91 * if no PATH variable is set or it has an empty value
102 * just use the default + /usr/lib/uml 92 * just use the default + /usr/lib/uml
103 */ 93 */
104 if (!old_path || (path_len = strlen(old_path)) == 0) { 94 if (!old_path || (path_len = strlen(old_path)) == 0) {
@@ -126,93 +116,68 @@ int __init main(int argc, char **argv, char **envp)
126 char **new_argv; 116 char **new_argv;
127 int ret, i, err; 117 int ret, i, err;
128 118
129#ifdef UML_CONFIG_CMDLINE_ON_HOST
130 /* Allocate memory for thread command lines */
131 if(argc < 2 || strlen(argv[1]) < THREAD_NAME_LEN - 1){
132
133 char padding[THREAD_NAME_LEN] = {
134 [ 0 ... THREAD_NAME_LEN - 2] = ' ', '\0'
135 };
136
137 new_argv = malloc((argc + 2) * sizeof(char*));
138 if(!new_argv) {
139 perror("Allocating extended argv");
140 exit(1);
141 }
142
143 new_argv[0] = argv[0];
144 new_argv[1] = padding;
145
146 for(i = 2; i <= argc; i++)
147 new_argv[i] = argv[i - 1];
148 new_argv[argc + 1] = NULL;
149
150 execvp(new_argv[0], new_argv);
151 perror("execing with extended args");
152 exit(1);
153 }
154#endif
155
156 linux_prog = argv[0];
157
158 set_stklim(); 119 set_stklim();
159 120
160 setup_env_path(); 121 setup_env_path();
161 122
162 new_argv = malloc((argc + 1) * sizeof(char *)); 123 new_argv = malloc((argc + 1) * sizeof(char *));
163 if(new_argv == NULL){ 124 if (new_argv == NULL) {
164 perror("Mallocing argv"); 125 perror("Mallocing argv");
165 exit(1); 126 exit(1);
166 } 127 }
167 for(i=0;i<argc;i++){ 128 for (i = 0; i < argc; i++) {
168 new_argv[i] = strdup(argv[i]); 129 new_argv[i] = strdup(argv[i]);
169 if(new_argv[i] == NULL){ 130 if (new_argv[i] == NULL) {
170 perror("Mallocing an arg"); 131 perror("Mallocing an arg");
171 exit(1); 132 exit(1);
172 } 133 }
173 } 134 }
174 new_argv[argc] = NULL; 135 new_argv[argc] = NULL;
175 136
176 /* Allow these signals to bring down a UML if all other 137 /*
138 * Allow these signals to bring down a UML if all other
177 * methods of control fail. 139 * methods of control fail.
178 */ 140 */
179 install_fatal_handler(SIGINT); 141 install_fatal_handler(SIGINT);
180 install_fatal_handler(SIGTERM); 142 install_fatal_handler(SIGTERM);
181 install_fatal_handler(SIGHUP); 143 install_fatal_handler(SIGHUP);
182 144
183 scan_elf_aux( envp); 145 scan_elf_aux(envp);
184 146
185 do_uml_initcalls(); 147 do_uml_initcalls();
186 ret = linux_main(argc, argv); 148 ret = linux_main(argc, argv);
187 149
188 /* Disable SIGPROF - I have no idea why libc doesn't do this or turn 150 /*
151 * Disable SIGPROF - I have no idea why libc doesn't do this or turn
189 * off the profiling time, but UML dies with a SIGPROF just before 152 * off the profiling time, but UML dies with a SIGPROF just before
190 * exiting when profiling is active. 153 * exiting when profiling is active.
191 */ 154 */
192 change_sig(SIGPROF, 0); 155 change_sig(SIGPROF, 0);
193 156
194 /* This signal stuff used to be in the reboot case. However, 157 /*
158 * This signal stuff used to be in the reboot case. However,
195 * sometimes a SIGVTALRM can come in when we're halting (reproducably 159 * sometimes a SIGVTALRM can come in when we're halting (reproducably
196 * when writing out gcov information, presumably because that takes 160 * when writing out gcov information, presumably because that takes
197 * some time) and cause a segfault. 161 * some time) and cause a segfault.
198 */ 162 */
199 163
200 /* stop timers and set SIG*ALRM to be ignored */ 164 /* stop timers and set SIGVTALRM to be ignored */
201 disable_timer(); 165 disable_timer();
202 166
203 /* disable SIGIO for the fds and set SIGIO to be ignored */ 167 /* disable SIGIO for the fds and set SIGIO to be ignored */
204 err = deactivate_all_fds(); 168 err = deactivate_all_fds();
205 if(err) 169 if (err)
206 printf("deactivate_all_fds failed, errno = %d\n", -err); 170 printf("deactivate_all_fds failed, errno = %d\n", -err);
207 171
208 /* Let any pending signals fire now. This ensures 172 /*
173 * Let any pending signals fire now. This ensures
209 * that they won't be delivered after the exec, when 174 * that they won't be delivered after the exec, when
210 * they are definitely not expected. 175 * they are definitely not expected.
211 */ 176 */
212 unblock_signals(); 177 unblock_signals();
213 178
214 /* Reboot */ 179 /* Reboot */
215 if(ret){ 180 if (ret) {
216 printf("\n"); 181 printf("\n");
217 execvp(new_argv[0], new_argv); 182 execvp(new_argv[0], new_argv);
218 perror("Failed to exec kernel"); 183 perror("Failed to exec kernel");
@@ -222,26 +187,24 @@ int __init main(int argc, char **argv, char **envp)
222 return uml_exitcode; 187 return uml_exitcode;
223} 188}
224 189
225#define CAN_KMALLOC() \
226 (kmalloc_ok && CHOOSE_MODE((os_getpid() != tracing_pid), 1))
227
228extern void *__real_malloc(int); 190extern void *__real_malloc(int);
229 191
230void *__wrap_malloc(int size) 192void *__wrap_malloc(int size)
231{ 193{
232 void *ret; 194 void *ret;
233 195
234 if(!CAN_KMALLOC()) 196 if (!kmalloc_ok)
235 return __real_malloc(size); 197 return __real_malloc(size);
236 else if(size <= UM_KERN_PAGE_SIZE) 198 else if (size <= UM_KERN_PAGE_SIZE)
237 /* finding contiguous pages can be hard*/ 199 /* finding contiguous pages can be hard*/
238 ret = kmalloc(size, UM_GFP_KERNEL); 200 ret = kmalloc(size, UM_GFP_KERNEL);
239 else ret = vmalloc(size); 201 else ret = vmalloc(size);
240 202
241 /* glibc people insist that if malloc fails, errno should be 203 /*
204 * glibc people insist that if malloc fails, errno should be
242 * set by malloc as well. So we do. 205 * set by malloc as well. So we do.
243 */ 206 */
244 if(ret == NULL) 207 if (ret == NULL)
245 errno = ENOMEM; 208 errno = ENOMEM;
246 209
247 return ret; 210 return ret;
@@ -251,7 +214,7 @@ void *__wrap_calloc(int n, int size)
251{ 214{
252 void *ptr = __wrap_malloc(n * size); 215 void *ptr = __wrap_malloc(n * size);
253 216
254 if(ptr == NULL) 217 if (ptr == NULL)
255 return NULL; 218 return NULL;
256 memset(ptr, 0, n * size); 219 memset(ptr, 0, n * size);
257 return ptr; 220 return ptr;
@@ -265,7 +228,8 @@ void __wrap_free(void *ptr)
265{ 228{
266 unsigned long addr = (unsigned long) ptr; 229 unsigned long addr = (unsigned long) ptr;
267 230
268 /* We need to know how the allocation happened, so it can be correctly 231 /*
232 * We need to know how the allocation happened, so it can be correctly
269 * freed. This is done by seeing what region of memory the pointer is 233 * freed. This is done by seeing what region of memory the pointer is
270 * in - 234 * in -
271 * physical memory - kmalloc/kfree 235 * physical memory - kmalloc/kfree
@@ -283,12 +247,12 @@ void __wrap_free(void *ptr)
283 * there is a possibility for memory leaks. 247 * there is a possibility for memory leaks.
284 */ 248 */
285 249
286 if((addr >= uml_physmem) && (addr < high_physmem)){ 250 if ((addr >= uml_physmem) && (addr < high_physmem)) {
287 if(CAN_KMALLOC()) 251 if (kmalloc_ok)
288 kfree(ptr); 252 kfree(ptr);
289 } 253 }
290 else if((addr >= start_vm) && (addr < end_vm)){ 254 else if ((addr >= start_vm) && (addr < end_vm)) {
291 if(CAN_KMALLOC()) 255 if (kmalloc_ok)
292 vfree(ptr); 256 vfree(ptr);
293 } 257 }
294 else __real_free(ptr); 258 else __real_free(ptr);
diff --git a/arch/um/os-Linux/mem.c b/arch/um/os-Linux/mem.c
index c6378c6d10d2..436f8d20b20f 100644
--- a/arch/um/os-Linux/mem.c
+++ b/arch/um/os-Linux/mem.c
@@ -218,7 +218,7 @@ int __init create_tmp_file(unsigned long long len)
218 218
219 err = fchmod(fd, 0777); 219 err = fchmod(fd, 0777);
220 if(err < 0){ 220 if(err < 0){
221 perror("os_mode_fd"); 221 perror("fchmod");
222 exit(1); 222 exit(1);
223 } 223 }
224 224
@@ -226,7 +226,7 @@ int __init create_tmp_file(unsigned long long len)
226 * increase the file size by one byte, to the desired length. 226 * increase the file size by one byte, to the desired length.
227 */ 227 */
228 if (lseek64(fd, len - 1, SEEK_SET) < 0) { 228 if (lseek64(fd, len - 1, SEEK_SET) < 0) {
229 perror("os_seek_file"); 229 perror("lseek64");
230 exit(1); 230 exit(1);
231 } 231 }
232 232
@@ -247,7 +247,7 @@ int __init create_mem_file(unsigned long long len)
247 247
248 fd = create_tmp_file(len); 248 fd = create_tmp_file(len);
249 249
250 err = os_set_exec_close(fd, 1); 250 err = os_set_exec_close(fd);
251 if(err < 0){ 251 if(err < 0){
252 errno = -err; 252 errno = -err;
253 perror("exec_close"); 253 perror("exec_close");
diff --git a/arch/um/os-Linux/process.c b/arch/um/os-Linux/process.c
index e9c143297512..37781db4ceca 100644
--- a/arch/um/os-Linux/process.c
+++ b/arch/um/os-Linux/process.c
@@ -1,27 +1,24 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <unistd.h>
7#include <stdio.h> 6#include <stdio.h>
7#include <unistd.h>
8#include <errno.h> 8#include <errno.h>
9#include <signal.h> 9#include <signal.h>
10#include <fcntl.h>
10#include <sys/mman.h> 11#include <sys/mman.h>
12#include <sys/ptrace.h>
11#include <sys/wait.h> 13#include <sys/wait.h>
12#include <sys/mman.h> 14#include <asm/unistd.h>
13#include <sys/syscall.h> 15#include "init.h"
14#include "ptrace_user.h" 16#include "kern_constants.h"
17#include "longjmp.h"
15#include "os.h" 18#include "os.h"
16#include "user.h"
17#include "process.h" 19#include "process.h"
18#include "irq_user.h"
19#include "kern_util.h"
20#include "longjmp.h"
21#include "skas_ptrace.h" 20#include "skas_ptrace.h"
22#include "kern_constants.h" 21#include "user.h"
23#include "uml-config.h"
24#include "init.h"
25 22
26#define ARBITRARY_ADDR -1 23#define ARBITRARY_ADDR -1
27#define FAILURE_PID -1 24#define FAILURE_PID -1
@@ -32,30 +29,32 @@
32unsigned long os_process_pc(int pid) 29unsigned long os_process_pc(int pid)
33{ 30{
34 char proc_stat[STAT_PATH_LEN], buf[256]; 31 char proc_stat[STAT_PATH_LEN], buf[256];
35 unsigned long pc; 32 unsigned long pc = ARBITRARY_ADDR;
36 int fd, err; 33 int fd, err;
37 34
38 sprintf(proc_stat, "/proc/%d/stat", pid); 35 sprintf(proc_stat, "/proc/%d/stat", pid);
39 fd = os_open_file(proc_stat, of_read(OPENFLAGS()), 0); 36 fd = open(proc_stat, O_RDONLY, 0);
40 if(fd < 0){ 37 if (fd < 0) {
41 printk("os_process_pc - couldn't open '%s', err = %d\n", 38 printk(UM_KERN_ERR "os_process_pc - couldn't open '%s', "
42 proc_stat, -fd); 39 "errno = %d\n", proc_stat, errno);
43 return ARBITRARY_ADDR; 40 goto out;
44 } 41 }
45 CATCH_EINTR(err = read(fd, buf, sizeof(buf))); 42 CATCH_EINTR(err = read(fd, buf, sizeof(buf)));
46 if(err < 0){ 43 if (err < 0) {
47 printk("os_process_pc - couldn't read '%s', err = %d\n", 44 printk(UM_KERN_ERR "os_process_pc - couldn't read '%s', "
48 proc_stat, errno); 45 "err = %d\n", proc_stat, errno);
49 os_close_file(fd); 46 goto out_close;
50 return ARBITRARY_ADDR;
51 } 47 }
52 os_close_file(fd); 48 os_close_file(fd);
53 pc = ARBITRARY_ADDR; 49 pc = ARBITRARY_ADDR;
54 if(sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d " 50 if (sscanf(buf, "%*d " COMM_SCANF " %*c %*d %*d %*d %*d %*d %*d %*d "
55 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d " 51 "%*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d %*d "
56 "%*d %*d %*d %*d %*d %lu", &pc) != 1){ 52 "%*d %*d %*d %*d %*d %lu", &pc) != 1)
57 printk("os_process_pc - couldn't find pc in '%s'\n", buf); 53 printk(UM_KERN_ERR "os_process_pc - couldn't find pc in '%s'\n",
58 } 54 buf);
55 out_close:
56 close(fd);
57 out:
59 return pc; 58 return pc;
60} 59}
61 60
@@ -63,30 +62,32 @@ int os_process_parent(int pid)
63{ 62{
64 char stat[STAT_PATH_LEN]; 63 char stat[STAT_PATH_LEN];
65 char data[256]; 64 char data[256];
66 int parent, n, fd; 65 int parent = FAILURE_PID, n, fd;
67 66
68 if(pid == -1) 67 if (pid == -1)
69 return -1; 68 return parent;
70 69
71 snprintf(stat, sizeof(stat), "/proc/%d/stat", pid); 70 snprintf(stat, sizeof(stat), "/proc/%d/stat", pid);
72 fd = os_open_file(stat, of_read(OPENFLAGS()), 0); 71 fd = open(stat, O_RDONLY, 0);
73 if(fd < 0){ 72 if (fd < 0) {
74 printk("Couldn't open '%s', err = %d\n", stat, -fd); 73 printk(UM_KERN_ERR "Couldn't open '%s', errno = %d\n", stat,
75 return FAILURE_PID; 74 errno);
75 return parent;
76 } 76 }
77 77
78 CATCH_EINTR(n = read(fd, data, sizeof(data))); 78 CATCH_EINTR(n = read(fd, data, sizeof(data)));
79 os_close_file(fd); 79 close(fd);
80 80
81 if(n < 0){ 81 if (n < 0) {
82 printk("Couldn't read '%s', err = %d\n", stat, errno); 82 printk(UM_KERN_ERR "Couldn't read '%s', errno = %d\n", stat,
83 return FAILURE_PID; 83 errno);
84 return parent;
84 } 85 }
85 86
86 parent = FAILURE_PID; 87 parent = FAILURE_PID;
87 n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent); 88 n = sscanf(data, "%*d " COMM_SCANF " %*c %d", &parent);
88 if(n != 1) 89 if (n != 1)
89 printk("Failed to scan '%s'\n", data); 90 printk(UM_KERN_ERR "Failed to scan '%s'\n", data);
90 91
91 return parent; 92 return parent;
92} 93}
@@ -99,9 +100,8 @@ void os_stop_process(int pid)
99void os_kill_process(int pid, int reap_child) 100void os_kill_process(int pid, int reap_child)
100{ 101{
101 kill(pid, SIGKILL); 102 kill(pid, SIGKILL);
102 if(reap_child) 103 if (reap_child)
103 CATCH_EINTR(waitpid(pid, NULL, 0)); 104 CATCH_EINTR(waitpid(pid, NULL, 0));
104
105} 105}
106 106
107/* This is here uniquely to have access to the userspace errno, i.e. the one 107/* This is here uniquely to have access to the userspace errno, i.e. the one
@@ -129,17 +129,10 @@ void os_kill_ptraced_process(int pid, int reap_child)
129 kill(pid, SIGKILL); 129 kill(pid, SIGKILL);
130 ptrace(PTRACE_KILL, pid); 130 ptrace(PTRACE_KILL, pid);
131 ptrace(PTRACE_CONT, pid); 131 ptrace(PTRACE_CONT, pid);
132 if(reap_child) 132 if (reap_child)
133 CATCH_EINTR(waitpid(pid, NULL, 0)); 133 CATCH_EINTR(waitpid(pid, NULL, 0));
134} 134}
135 135
136#ifdef UML_CONFIG_MODE_TT
137void os_usr1_process(int pid)
138{
139 kill(pid, SIGUSR1);
140}
141#endif
142
143/* Don't use the glibc version, which caches the result in TLS. It misses some 136/* Don't use the glibc version, which caches the result in TLS. It misses some
144 * syscalls, and also breaks with clone(), which does not unshare the TLS. 137 * syscalls, and also breaks with clone(), which does not unshare the TLS.
145 */ 138 */
@@ -160,34 +153,35 @@ int os_map_memory(void *virt, int fd, unsigned long long off, unsigned long len,
160 void *loc; 153 void *loc;
161 int prot; 154 int prot;
162 155
163 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 156 prot = (r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
164 (x ? PROT_EXEC : 0); 157 (x ? PROT_EXEC : 0);
165 158
166 loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED, 159 loc = mmap64((void *) virt, len, prot, MAP_SHARED | MAP_FIXED,
167 fd, off); 160 fd, off);
168 if(loc == MAP_FAILED) 161 if (loc == MAP_FAILED)
169 return -errno; 162 return -errno;
170 return 0; 163 return 0;
171} 164}
172 165
173int os_protect_memory(void *addr, unsigned long len, int r, int w, int x) 166int os_protect_memory(void *addr, unsigned long len, int r, int w, int x)
174{ 167{
175 int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) | 168 int prot = ((r ? PROT_READ : 0) | (w ? PROT_WRITE : 0) |
176 (x ? PROT_EXEC : 0)); 169 (x ? PROT_EXEC : 0));
177 170
178 if(mprotect(addr, len, prot) < 0) 171 if (mprotect(addr, len, prot) < 0)
179 return -errno; 172 return -errno;
180 return 0; 173
174 return 0;
181} 175}
182 176
183int os_unmap_memory(void *addr, int len) 177int os_unmap_memory(void *addr, int len)
184{ 178{
185 int err; 179 int err;
186 180
187 err = munmap(addr, len); 181 err = munmap(addr, len);
188 if(err < 0) 182 if (err < 0)
189 return -errno; 183 return -errno;
190 return 0; 184 return 0;
191} 185}
192 186
193#ifndef MADV_REMOVE 187#ifndef MADV_REMOVE
@@ -199,7 +193,7 @@ int os_drop_memory(void *addr, int length)
199 int err; 193 int err;
200 194
201 err = madvise(addr, length, MADV_REMOVE); 195 err = madvise(addr, length, MADV_REMOVE);
202 if(err < 0) 196 if (err < 0)
203 err = -errno; 197 err = -errno;
204 return err; 198 return err;
205} 199}
@@ -209,22 +203,24 @@ int __init can_drop_memory(void)
209 void *addr; 203 void *addr;
210 int fd, ok = 0; 204 int fd, ok = 0;
211 205
212 printk("Checking host MADV_REMOVE support..."); 206 printk(UM_KERN_INFO "Checking host MADV_REMOVE support...");
213 fd = create_mem_file(UM_KERN_PAGE_SIZE); 207 fd = create_mem_file(UM_KERN_PAGE_SIZE);
214 if(fd < 0){ 208 if (fd < 0) {
215 printk("Creating test memory file failed, err = %d\n", -fd); 209 printk(UM_KERN_ERR "Creating test memory file failed, "
210 "err = %d\n", -fd);
216 goto out; 211 goto out;
217 } 212 }
218 213
219 addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, 214 addr = mmap64(NULL, UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
220 MAP_SHARED, fd, 0); 215 MAP_SHARED, fd, 0);
221 if(addr == MAP_FAILED){ 216 if (addr == MAP_FAILED) {
222 printk("Mapping test memory file failed, err = %d\n", -errno); 217 printk(UM_KERN_ERR "Mapping test memory file failed, "
218 "err = %d\n", -errno);
223 goto out_close; 219 goto out_close;
224 } 220 }
225 221
226 if(madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0){ 222 if (madvise(addr, UM_KERN_PAGE_SIZE, MADV_REMOVE) != 0) {
227 printk("MADV_REMOVE failed, err = %d\n", -errno); 223 printk(UM_KERN_ERR "MADV_REMOVE failed, err = %d\n", -errno);
228 goto out_unmap; 224 goto out_unmap;
229 } 225 }
230 226
@@ -239,58 +235,31 @@ out:
239 return ok; 235 return ok;
240} 236}
241 237
242#ifdef UML_CONFIG_MODE_TT
243void init_new_thread_stack(void *sig_stack, void (*usr1_handler)(int))
244{
245 int flags = 0, pages;
246
247 if(sig_stack != NULL){
248 pages = (1 << UML_CONFIG_KERNEL_STACK_ORDER);
249 set_sigstack(sig_stack, pages * UM_KERN_PAGE_SIZE);
250 flags = SA_ONSTACK;
251 }
252 if(usr1_handler){
253 struct sigaction sa;
254
255 sa.sa_handler = usr1_handler;
256 sigemptyset(&sa.sa_mask);
257 sa.sa_flags = flags;
258 sa.sa_restorer = NULL;
259 if(sigaction(SIGUSR1, &sa, NULL) < 0)
260 panic("init_new_thread_stack - sigaction failed - "
261 "errno = %d\n", errno);
262 }
263}
264#endif
265
266void init_new_thread_signals(void) 238void init_new_thread_signals(void)
267{ 239{
268 set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK, 240 set_handler(SIGSEGV, (__sighandler_t) sig_handler, SA_ONSTACK,
269 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 241 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
270 set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK, 242 set_handler(SIGTRAP, (__sighandler_t) sig_handler, SA_ONSTACK,
271 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 243 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
272 set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK, 244 set_handler(SIGFPE, (__sighandler_t) sig_handler, SA_ONSTACK,
273 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 245 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
274 set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK, 246 set_handler(SIGILL, (__sighandler_t) sig_handler, SA_ONSTACK,
275 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 247 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
276 set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK, 248 set_handler(SIGBUS, (__sighandler_t) sig_handler, SA_ONSTACK,
277 SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM, -1); 249 SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
278 set_handler(SIGUSR2, (__sighandler_t) sig_handler,
279 SA_ONSTACK, SIGUSR1, SIGIO, SIGWINCH, SIGALRM, SIGVTALRM,
280 -1);
281 signal(SIGHUP, SIG_IGN); 250 signal(SIGHUP, SIG_IGN);
282 251
283 init_irq_signals(1); 252 init_irq_signals(1);
284} 253}
285 254
286int run_kernel_thread(int (*fn)(void *), void *arg, void **jmp_ptr) 255int run_kernel_thread(int (*fn)(void *), void *arg, jmp_buf **jmp_ptr)
287{ 256{
288 jmp_buf buf; 257 jmp_buf buf;
289 int n; 258 int n;
290 259
291 *jmp_ptr = &buf; 260 *jmp_ptr = &buf;
292 n = UML_SETJMP(&buf); 261 n = UML_SETJMP(&buf);
293 if(n != 0) 262 if (n != 0)
294 return n; 263 return n;
295 (*fn)(arg); 264 (*fn)(arg);
296 return 0; 265 return 0;
diff --git a/arch/um/os-Linux/registers.c b/arch/um/os-Linux/registers.c
new file mode 100644
index 000000000000..a32ba6ab1211
--- /dev/null
+++ b/arch/um/os-Linux/registers.c
@@ -0,0 +1,57 @@
1/*
2 * Copyright (C) 2004 PathScale, Inc
3 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
4 * Licensed under the GPL
5 */
6
7#include <errno.h>
8#include <string.h>
9#include <sys/ptrace.h>
10#include "sysdep/ptrace.h"
11#include "user.h"
12
13/* This is set once at boot time and not changed thereafter */
14
15static unsigned long exec_regs[MAX_REG_NR];
16
17void init_thread_registers(struct uml_pt_regs *to)
18{
19 memcpy(to->gp, exec_regs, sizeof(to->gp));
20}
21
22void save_registers(int pid, struct uml_pt_regs *regs)
23{
24 int err;
25
26 err = ptrace(PTRACE_GETREGS, pid, 0, regs->gp);
27 if (err < 0)
28 panic("save_registers - saving registers failed, errno = %d\n",
29 errno);
30}
31
32void restore_registers(int pid, struct uml_pt_regs *regs)
33{
34 int err;
35
36 err = ptrace(PTRACE_SETREGS, pid, 0, regs->gp);
37 if (err < 0)
38 panic("restore_registers - saving registers failed, "
39 "errno = %d\n", errno);
40}
41
42void init_registers(int pid)
43{
44 int err;
45
46 err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
47 if (err)
48 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
49 errno);
50
51 arch_init_registers(pid);
52}
53
54void get_safe_registers(unsigned long *regs)
55{
56 memcpy(regs, exec_regs, sizeof(exec_regs));
57}
diff --git a/arch/um/os-Linux/signal.c b/arch/um/os-Linux/signal.c
index b98f7ea2d2f6..e9800b0b5689 100644
--- a/arch/um/os-Linux/signal.c
+++ b/arch/um/os-Linux/signal.c
@@ -1,26 +1,21 @@
1/* 1/*
2 * Copyright (C) 2004 PathScale, Inc 2 * Copyright (C) 2004 PathScale, Inc
3 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 4 * Licensed under the GPL
4 */ 5 */
5 6
6#include <signal.h>
7#include <stdio.h>
8#include <unistd.h>
9#include <stdlib.h> 7#include <stdlib.h>
10#include <errno.h>
11#include <stdarg.h> 8#include <stdarg.h>
12#include <string.h> 9#include <errno.h>
13#include <sys/mman.h> 10#include <signal.h>
14#include "user.h" 11#include <strings.h>
15#include "signal_kern.h"
16#include "sysdep/sigcontext.h"
17#include "sysdep/barrier.h"
18#include "sigcontext.h"
19#include "mode.h"
20#include "os.h" 12#include "os.h"
13#include "sysdep/barrier.h"
14#include "sysdep/sigcontext.h"
15#include "user.h"
21 16
22/* These are the asynchronous signals. SIGVTALRM and SIGARLM are handled 17/*
23 * together under SIGVTALRM_BIT. SIGPROF is excluded because we want to 18 * These are the asynchronous signals. SIGPROF is excluded because we want to
24 * be able to profile all of UML, not just the non-critical sections. If 19 * be able to profile all of UML, not just the non-critical sections. If
25 * profiling is not thread-safe, then that is not my problem. We can disable 20 * profiling is not thread-safe, then that is not my problem. We can disable
26 * profiling when SMP is enabled in that case. 21 * profiling when SMP is enabled in that case.
@@ -31,10 +26,8 @@
31#define SIGVTALRM_BIT 1 26#define SIGVTALRM_BIT 1
32#define SIGVTALRM_MASK (1 << SIGVTALRM_BIT) 27#define SIGVTALRM_MASK (1 << SIGVTALRM_BIT)
33 28
34#define SIGALRM_BIT 2 29/*
35#define SIGALRM_MASK (1 << SIGALRM_BIT) 30 * These are used by both the signal handlers and
36
37/* These are used by both the signal handlers and
38 * block/unblock_signals. I don't want modifications cached in a 31 * block/unblock_signals. I don't want modifications cached in a
39 * register - they must go straight to memory. 32 * register - they must go straight to memory.
40 */ 33 */
@@ -46,34 +39,27 @@ void sig_handler(int sig, struct sigcontext *sc)
46 int enabled; 39 int enabled;
47 40
48 enabled = signals_enabled; 41 enabled = signals_enabled;
49 if(!enabled && (sig == SIGIO)){ 42 if (!enabled && (sig == SIGIO)) {
50 pending |= SIGIO_MASK; 43 pending |= SIGIO_MASK;
51 return; 44 return;
52 } 45 }
53 46
54 block_signals(); 47 block_signals();
55 48
56 CHOOSE_MODE_PROC(sig_handler_common_tt, sig_handler_common_skas, 49 sig_handler_common_skas(sig, sc);
57 sig, sc);
58 50
59 set_signals(enabled); 51 set_signals(enabled);
60} 52}
61 53
62static void real_alarm_handler(int sig, struct sigcontext *sc) 54static void real_alarm_handler(struct sigcontext *sc)
63{ 55{
64 union uml_pt_regs regs; 56 struct uml_pt_regs regs;
65 57
66 if(sig == SIGALRM) 58 if (sc != NULL)
67 switch_timers(0);
68
69 if(sc != NULL)
70 copy_sc(&regs, sc); 59 copy_sc(&regs, sc);
71 regs.skas.is_user = 0; 60 regs.is_user = 0;
72 unblock_signals(); 61 unblock_signals();
73 timer_handler(sig, &regs); 62 timer_handler(SIGVTALRM, &regs);
74
75 if(sig == SIGALRM)
76 switch_timers(1);
77} 63}
78 64
79void alarm_handler(int sig, struct sigcontext *sc) 65void alarm_handler(int sig, struct sigcontext *sc)
@@ -81,27 +67,30 @@ void alarm_handler(int sig, struct sigcontext *sc)
81 int enabled; 67 int enabled;
82 68
83 enabled = signals_enabled; 69 enabled = signals_enabled;
84 if(!signals_enabled){ 70 if (!signals_enabled) {
85 if(sig == SIGVTALRM) 71 pending |= SIGVTALRM_MASK;
86 pending |= SIGVTALRM_MASK;
87 else pending |= SIGALRM_MASK;
88
89 return; 72 return;
90 } 73 }
91 74
92 block_signals(); 75 block_signals();
93 76
94 real_alarm_handler(sig, sc); 77 real_alarm_handler(sc);
95 set_signals(enabled); 78 set_signals(enabled);
96} 79}
97 80
81void timer_init(void)
82{
83 set_handler(SIGVTALRM, (__sighandler_t) alarm_handler,
84 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, -1);
85}
86
98void set_sigstack(void *sig_stack, int size) 87void set_sigstack(void *sig_stack, int size)
99{ 88{
100 stack_t stack = ((stack_t) { .ss_flags = 0, 89 stack_t stack = ((stack_t) { .ss_flags = 0,
101 .ss_sp = (__ptr_t) sig_stack, 90 .ss_sp = (__ptr_t) sig_stack,
102 .ss_size = size - sizeof(void *) }); 91 .ss_size = size - sizeof(void *) });
103 92
104 if(sigaltstack(&stack, NULL) != 0) 93 if (sigaltstack(&stack, NULL) != 0)
105 panic("enabling signal stack failed, errno = %d\n", errno); 94 panic("enabling signal stack failed, errno = %d\n", errno);
106} 95}
107 96
@@ -111,7 +100,7 @@ void remove_sigstack(void)
111 .ss_sp = NULL, 100 .ss_sp = NULL,
112 .ss_size = 0 }); 101 .ss_size = 0 });
113 102
114 if(sigaltstack(&stack, NULL) != 0) 103 if (sigaltstack(&stack, NULL) != 0)
115 panic("disabling signal stack failed, errno = %d\n", errno); 104 panic("disabling signal stack failed, errno = %d\n", errno);
116} 105}
117 106
@@ -135,26 +124,27 @@ void handle_signal(int sig, struct sigcontext *sc)
135 * with this interrupt. 124 * with this interrupt.
136 */ 125 */
137 bail = to_irq_stack(&pending); 126 bail = to_irq_stack(&pending);
138 if(bail) 127 if (bail)
139 return; 128 return;
140 129
141 nested = pending & 1; 130 nested = pending & 1;
142 pending &= ~1; 131 pending &= ~1;
143 132
144 while((sig = ffs(pending)) != 0){ 133 while ((sig = ffs(pending)) != 0){
145 sig--; 134 sig--;
146 pending &= ~(1 << sig); 135 pending &= ~(1 << sig);
147 (*handlers[sig])(sig, sc); 136 (*handlers[sig])(sig, sc);
148 } 137 }
149 138
150 /* Again, pending comes back with a mask of signals 139 /*
140 * Again, pending comes back with a mask of signals
151 * that arrived while tearing down the stack. If this 141 * that arrived while tearing down the stack. If this
152 * is non-zero, we just go back, set up the stack 142 * is non-zero, we just go back, set up the stack
153 * again, and handle the new interrupts. 143 * again, and handle the new interrupts.
154 */ 144 */
155 if(!nested) 145 if (!nested)
156 pending = from_irq_stack(nested); 146 pending = from_irq_stack(nested);
157 } while(pending); 147 } while (pending);
158} 148}
159 149
160extern void hard_handler(int sig); 150extern void hard_handler(int sig);
@@ -172,18 +162,18 @@ void set_handler(int sig, void (*handler)(int), int flags, ...)
172 sigemptyset(&action.sa_mask); 162 sigemptyset(&action.sa_mask);
173 163
174 va_start(ap, flags); 164 va_start(ap, flags);
175 while((mask = va_arg(ap, int)) != -1) 165 while ((mask = va_arg(ap, int)) != -1)
176 sigaddset(&action.sa_mask, mask); 166 sigaddset(&action.sa_mask, mask);
177 va_end(ap); 167 va_end(ap);
178 168
179 action.sa_flags = flags; 169 action.sa_flags = flags;
180 action.sa_restorer = NULL; 170 action.sa_restorer = NULL;
181 if(sigaction(sig, &action, NULL) < 0) 171 if (sigaction(sig, &action, NULL) < 0)
182 panic("sigaction failed - errno = %d\n", errno); 172 panic("sigaction failed - errno = %d\n", errno);
183 173
184 sigemptyset(&sig_mask); 174 sigemptyset(&sig_mask);
185 sigaddset(&sig_mask, sig); 175 sigaddset(&sig_mask, sig);
186 if(sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0) 176 if (sigprocmask(SIG_UNBLOCK, &sig_mask, NULL) < 0)
187 panic("sigprocmask failed - errno = %d\n", errno); 177 panic("sigprocmask failed - errno = %d\n", errno);
188} 178}
189 179
@@ -194,13 +184,14 @@ int change_sig(int signal, int on)
194 sigemptyset(&sigset); 184 sigemptyset(&sigset);
195 sigaddset(&sigset, signal); 185 sigaddset(&sigset, signal);
196 sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old); 186 sigprocmask(on ? SIG_UNBLOCK : SIG_BLOCK, &sigset, &old);
197 return(!sigismember(&old, signal)); 187 return !sigismember(&old, signal);
198} 188}
199 189
200void block_signals(void) 190void block_signals(void)
201{ 191{
202 signals_enabled = 0; 192 signals_enabled = 0;
203 /* This must return with signals disabled, so this barrier 193 /*
194 * This must return with signals disabled, so this barrier
204 * ensures that writes are flushed out before the return. 195 * ensures that writes are flushed out before the return.
205 * This might matter if gcc figures out how to inline this and 196 * This might matter if gcc figures out how to inline this and
206 * decides to shuffle this code into the caller. 197 * decides to shuffle this code into the caller.
@@ -212,27 +203,31 @@ void unblock_signals(void)
212{ 203{
213 int save_pending; 204 int save_pending;
214 205
215 if(signals_enabled == 1) 206 if (signals_enabled == 1)
216 return; 207 return;
217 208
218 /* We loop because the IRQ handler returns with interrupts off. So, 209 /*
210 * We loop because the IRQ handler returns with interrupts off. So,
219 * interrupts may have arrived and we need to re-enable them and 211 * interrupts may have arrived and we need to re-enable them and
220 * recheck pending. 212 * recheck pending.
221 */ 213 */
222 while(1){ 214 while(1) {
223 /* Save and reset save_pending after enabling signals. This 215 /*
216 * Save and reset save_pending after enabling signals. This
224 * way, pending won't be changed while we're reading it. 217 * way, pending won't be changed while we're reading it.
225 */ 218 */
226 signals_enabled = 1; 219 signals_enabled = 1;
227 220
228 /* Setting signals_enabled and reading pending must 221 /*
222 * Setting signals_enabled and reading pending must
229 * happen in this order. 223 * happen in this order.
230 */ 224 */
231 mb(); 225 mb();
232 226
233 save_pending = pending; 227 save_pending = pending;
234 if(save_pending == 0){ 228 if (save_pending == 0) {
235 /* This must return with signals enabled, so 229 /*
230 * This must return with signals enabled, so
236 * this barrier ensures that writes are 231 * this barrier ensures that writes are
237 * flushed out before the return. This might 232 * flushed out before the return. This might
238 * matter if gcc figures out how to inline 233 * matter if gcc figures out how to inline
@@ -245,26 +240,24 @@ void unblock_signals(void)
245 240
246 pending = 0; 241 pending = 0;
247 242
248 /* We have pending interrupts, so disable signals, as the 243 /*
244 * We have pending interrupts, so disable signals, as the
249 * handlers expect them off when they are called. They will 245 * handlers expect them off when they are called. They will
250 * be enabled again above. 246 * be enabled again above.
251 */ 247 */
252 248
253 signals_enabled = 0; 249 signals_enabled = 0;
254 250
255 /* Deal with SIGIO first because the alarm handler might 251 /*
252 * Deal with SIGIO first because the alarm handler might
256 * schedule, leaving the pending SIGIO stranded until we come 253 * schedule, leaving the pending SIGIO stranded until we come
257 * back here. 254 * back here.
258 */ 255 */
259 if(save_pending & SIGIO_MASK) 256 if (save_pending & SIGIO_MASK)
260 CHOOSE_MODE_PROC(sig_handler_common_tt, 257 sig_handler_common_skas(SIGIO, NULL);
261 sig_handler_common_skas, SIGIO, NULL);
262
263 if(save_pending & SIGALRM_MASK)
264 real_alarm_handler(SIGALRM, NULL);
265 258
266 if(save_pending & SIGVTALRM_MASK) 259 if (save_pending & SIGVTALRM_MASK)
267 real_alarm_handler(SIGVTALRM, NULL); 260 real_alarm_handler(NULL);
268 } 261 }
269} 262}
270 263
@@ -276,11 +269,11 @@ int get_signals(void)
276int set_signals(int enable) 269int set_signals(int enable)
277{ 270{
278 int ret; 271 int ret;
279 if(signals_enabled == enable) 272 if (signals_enabled == enable)
280 return enable; 273 return enable;
281 274
282 ret = signals_enabled; 275 ret = signals_enabled;
283 if(enable) 276 if (enable)
284 unblock_signals(); 277 unblock_signals();
285 else block_signals(); 278 else block_signals();
286 279
diff --git a/arch/um/os-Linux/skas/mem.c b/arch/um/os-Linux/skas/mem.c
index 0f7df4eb903f..484e68f9f7ae 100644
--- a/arch/um/os-Linux/skas/mem.c
+++ b/arch/um/os-Linux/skas/mem.c
@@ -1,31 +1,26 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <signal.h> 6#include <stddef.h>
7#include <unistd.h>
7#include <errno.h> 8#include <errno.h>
8#include <string.h> 9#include <string.h>
9#include <unistd.h>
10#include <sys/mman.h> 10#include <sys/mman.h>
11#include <sys/wait.h> 11#include "init.h"
12#include <asm/page.h> 12#include "kern_constants.h"
13#include <asm/unistd.h> 13#include "as-layout.h"
14#include "mem_user.h" 14#include "mm_id.h"
15#include "mem.h"
16#include "skas.h"
17#include "user.h"
18#include "os.h" 15#include "os.h"
19#include "proc_mm.h" 16#include "proc_mm.h"
20#include "ptrace_user.h" 17#include "ptrace_user.h"
21#include "kern_util.h"
22#include "task.h"
23#include "registers.h" 18#include "registers.h"
24#include "uml-config.h" 19#include "skas.h"
20#include "user.h"
25#include "sysdep/ptrace.h" 21#include "sysdep/ptrace.h"
26#include "sysdep/stub.h" 22#include "sysdep/stub.h"
27#include "init.h" 23#include "uml-config.h"
28#include "kern_constants.h"
29 24
30extern unsigned long batch_syscall_stub, __syscall_stub_start; 25extern unsigned long batch_syscall_stub, __syscall_stub_start;
31 26
@@ -34,7 +29,7 @@ extern void wait_stub_done(int pid);
34static inline unsigned long *check_init_stack(struct mm_id * mm_idp, 29static inline unsigned long *check_init_stack(struct mm_id * mm_idp,
35 unsigned long *stack) 30 unsigned long *stack)
36{ 31{
37 if(stack == NULL) { 32 if (stack == NULL) {
38 stack = (unsigned long *) mm_idp->stack + 2; 33 stack = (unsigned long *) mm_idp->stack + 2;
39 *stack = 0; 34 *stack = 0;
40 } 35 }
@@ -45,8 +40,8 @@ static unsigned long syscall_regs[MAX_REG_NR];
45 40
46static int __init init_syscall_regs(void) 41static int __init init_syscall_regs(void)
47{ 42{
48 get_safe_registers(syscall_regs, NULL); 43 get_safe_registers(syscall_regs);
49 syscall_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + 44 syscall_regs[REGS_IP_INDEX] = STUB_CODE +
50 ((unsigned long) &batch_syscall_stub - 45 ((unsigned long) &batch_syscall_stub -
51 (unsigned long) &__syscall_stub_start); 46 (unsigned long) &__syscall_stub_start);
52 return 0; 47 return 0;
@@ -68,29 +63,30 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
68 unsigned long * syscall; 63 unsigned long * syscall;
69 int err, pid = mm_idp->u.pid; 64 int err, pid = mm_idp->u.pid;
70 65
71 if(proc_mm) 66 if (proc_mm)
72 /* FIXME: Need to look up userspace_pid by cpu */ 67 /* FIXME: Need to look up userspace_pid by cpu */
73 pid = userspace_pid[0]; 68 pid = userspace_pid[0];
74 69
75 multi_count++; 70 multi_count++;
76 71
77 n = ptrace_setregs(pid, syscall_regs); 72 n = ptrace_setregs(pid, syscall_regs);
78 if(n < 0){ 73 if (n < 0) {
79 printk("Registers - \n"); 74 printk(UM_KERN_ERR "Registers - \n");
80 for(i = 0; i < MAX_REG_NR; i++) 75 for (i = 0; i < MAX_REG_NR; i++)
81 printk("\t%d\t0x%lx\n", i, syscall_regs[i]); 76 printk(UM_KERN_ERR "\t%d\t0x%lx\n", i, syscall_regs[i]);
82 panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n", 77 panic("do_syscall_stub : PTRACE_SETREGS failed, errno = %d\n",
83 -n); 78 -n);
84 } 79 }
85 80
86 err = ptrace(PTRACE_CONT, pid, 0, 0); 81 err = ptrace(PTRACE_CONT, pid, 0, 0);
87 if(err) 82 if (err)
88 panic("Failed to continue stub, pid = %d, errno = %d\n", pid, 83 panic("Failed to continue stub, pid = %d, errno = %d\n", pid,
89 errno); 84 errno);
90 85
91 wait_stub_done(pid); 86 wait_stub_done(pid);
92 87
93 /* When the stub stops, we find the following values on the 88 /*
89 * When the stub stops, we find the following values on the
94 * beginning of the stack: 90 * beginning of the stack:
95 * (long )return_value 91 * (long )return_value
96 * (long )offset to failed sycall-data (0, if no error) 92 * (long )offset to failed sycall-data (0, if no error)
@@ -98,26 +94,26 @@ static inline long do_syscall_stub(struct mm_id * mm_idp, void **addr)
98 ret = *((unsigned long *) mm_idp->stack); 94 ret = *((unsigned long *) mm_idp->stack);
99 offset = *((unsigned long *) mm_idp->stack + 1); 95 offset = *((unsigned long *) mm_idp->stack + 1);
100 if (offset) { 96 if (offset) {
101 data = (unsigned long *)(mm_idp->stack + 97 data = (unsigned long *)(mm_idp->stack + offset - STUB_DATA);
102 offset - UML_CONFIG_STUB_DATA); 98 printk(UM_KERN_ERR "do_syscall_stub : ret = %ld, offset = %ld, "
103 printk("do_syscall_stub : ret = %ld, offset = %ld, "
104 "data = %p\n", ret, offset, data); 99 "data = %p\n", ret, offset, data);
105 syscall = (unsigned long *)((unsigned long)data + data[0]); 100 syscall = (unsigned long *)((unsigned long)data + data[0]);
106 printk("do_syscall_stub: syscall %ld failed, return value = " 101 printk(UM_KERN_ERR "do_syscall_stub: syscall %ld failed, "
107 "0x%lx, expected return value = 0x%lx\n", 102 "return value = 0x%lx, expected return value = 0x%lx\n",
108 syscall[0], ret, syscall[7]); 103 syscall[0], ret, syscall[7]);
109 printk(" syscall parameters: " 104 printk(UM_KERN_ERR " syscall parameters: "
110 "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n", 105 "0x%lx 0x%lx 0x%lx 0x%lx 0x%lx 0x%lx\n",
111 syscall[1], syscall[2], syscall[3], 106 syscall[1], syscall[2], syscall[3],
112 syscall[4], syscall[5], syscall[6]); 107 syscall[4], syscall[5], syscall[6]);
113 for(n = 1; n < data[0]/sizeof(long); n++) { 108 for (n = 1; n < data[0]/sizeof(long); n++) {
114 if(n == 1) 109 if (n == 1)
115 printk(" additional syscall data:"); 110 printk(UM_KERN_ERR " additional syscall "
116 if(n % 4 == 1) 111 "data:");
117 printk("\n "); 112 if (n % 4 == 1)
113 printk("\n" UM_KERN_ERR " ");
118 printk(" 0x%lx", data[n]); 114 printk(" 0x%lx", data[n]);
119 } 115 }
120 if(n > 1) 116 if (n > 1)
121 printk("\n"); 117 printk("\n");
122 } 118 }
123 else ret = 0; 119 else ret = 0;
@@ -133,7 +129,7 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall,
133{ 129{
134 unsigned long *stack = check_init_stack(mm_idp, *addr); 130 unsigned long *stack = check_init_stack(mm_idp, *addr);
135 131
136 if(done && *addr == NULL) 132 if (done && *addr == NULL)
137 single_count++; 133 single_count++;
138 134
139 *stack += sizeof(long); 135 *stack += sizeof(long);
@@ -150,8 +146,8 @@ long run_syscall_stub(struct mm_id * mm_idp, int syscall,
150 *stack = 0; 146 *stack = 0;
151 multi_op_count++; 147 multi_op_count++;
152 148
153 if(!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) < 149 if (!done && ((((unsigned long) stack) & ~UM_KERN_PAGE_MASK) <
154 UM_KERN_PAGE_SIZE - 10 * sizeof(long))){ 150 UM_KERN_PAGE_SIZE - 10 * sizeof(long))) {
155 *addr = stack; 151 *addr = stack;
156 return 0; 152 return 0;
157 } 153 }
@@ -166,14 +162,15 @@ long syscall_stub_data(struct mm_id * mm_idp,
166 unsigned long *stack; 162 unsigned long *stack;
167 int ret = 0; 163 int ret = 0;
168 164
169 /* If *addr still is uninitialized, it *must* contain NULL. 165 /*
166 * If *addr still is uninitialized, it *must* contain NULL.
170 * Thus in this case do_syscall_stub correctly won't be called. 167 * Thus in this case do_syscall_stub correctly won't be called.
171 */ 168 */
172 if((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >= 169 if ((((unsigned long) *addr) & ~UM_KERN_PAGE_MASK) >=
173 UM_KERN_PAGE_SIZE - (10 + data_count) * sizeof(long)) { 170 UM_KERN_PAGE_SIZE - (10 + data_count) * sizeof(long)) {
174 ret = do_syscall_stub(mm_idp, addr); 171 ret = do_syscall_stub(mm_idp, addr);
175 /* in case of error, don't overwrite data on stack */ 172 /* in case of error, don't overwrite data on stack */
176 if(ret) 173 if (ret)
177 return ret; 174 return ret;
178 } 175 }
179 176
@@ -185,7 +182,7 @@ long syscall_stub_data(struct mm_id * mm_idp,
185 memcpy(stack + 1, data, data_count * sizeof(long)); 182 memcpy(stack + 1, data, data_count * sizeof(long));
186 183
187 *stub_addr = (void *)(((unsigned long)(stack + 1) & 184 *stub_addr = (void *)(((unsigned long)(stack + 1) &
188 ~UM_KERN_PAGE_MASK) + UML_CONFIG_STUB_DATA); 185 ~UM_KERN_PAGE_MASK) + STUB_DATA);
189 186
190 return 0; 187 return 0;
191} 188}
@@ -195,7 +192,7 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
195{ 192{
196 int ret; 193 int ret;
197 194
198 if(proc_mm){ 195 if (proc_mm) {
199 struct proc_mm_op map; 196 struct proc_mm_op map;
200 int fd = mm_idp->u.mm_fd; 197 int fd = mm_idp->u.mm_fd;
201 198
@@ -211,9 +208,10 @@ int map(struct mm_id * mm_idp, unsigned long virt, unsigned long len, int prot,
211 .offset= offset 208 .offset= offset
212 } } } ); 209 } } } );
213 CATCH_EINTR(ret = write(fd, &map, sizeof(map))); 210 CATCH_EINTR(ret = write(fd, &map, sizeof(map)));
214 if(ret != sizeof(map)){ 211 if (ret != sizeof(map)) {
215 ret = -errno; 212 ret = -errno;
216 printk("map : /proc/mm map failed, err = %d\n", -ret); 213 printk(UM_KERN_ERR "map : /proc/mm map failed, "
214 "err = %d\n", -ret);
217 } 215 }
218 else ret = 0; 216 else ret = 0;
219 } 217 }
@@ -234,7 +232,7 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
234{ 232{
235 int ret; 233 int ret;
236 234
237 if(proc_mm){ 235 if (proc_mm) {
238 struct proc_mm_op unmap; 236 struct proc_mm_op unmap;
239 int fd = mm_idp->u.mm_fd; 237 int fd = mm_idp->u.mm_fd;
240 238
@@ -245,9 +243,10 @@ int unmap(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
245 (unsigned long) addr, 243 (unsigned long) addr,
246 .len = len } } } ); 244 .len = len } } } );
247 CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap))); 245 CATCH_EINTR(ret = write(fd, &unmap, sizeof(unmap)));
248 if(ret != sizeof(unmap)){ 246 if (ret != sizeof(unmap)) {
249 ret = -errno; 247 ret = -errno;
250 printk("unmap - proc_mm write returned %d\n", ret); 248 printk(UM_KERN_ERR "unmap - proc_mm write returned "
249 "%d\n", ret);
251 } 250 }
252 else ret = 0; 251 else ret = 0;
253 } 252 }
@@ -268,7 +267,7 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
268 struct proc_mm_op protect; 267 struct proc_mm_op protect;
269 int ret; 268 int ret;
270 269
271 if(proc_mm){ 270 if (proc_mm) {
272 int fd = mm_idp->u.mm_fd; 271 int fd = mm_idp->u.mm_fd;
273 272
274 protect = ((struct proc_mm_op) { .op = MM_MPROTECT, 273 protect = ((struct proc_mm_op) { .op = MM_MPROTECT,
@@ -280,9 +279,9 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
280 .prot = prot } } } ); 279 .prot = prot } } } );
281 280
282 CATCH_EINTR(ret = write(fd, &protect, sizeof(protect))); 281 CATCH_EINTR(ret = write(fd, &protect, sizeof(protect)));
283 if(ret != sizeof(protect)){ 282 if (ret != sizeof(protect)) {
284 ret = -errno; 283 ret = -errno;
285 printk("protect failed, err = %d", -ret); 284 printk(UM_KERN_ERR "protect failed, err = %d", -ret);
286 } 285 }
287 else ret = 0; 286 else ret = 0;
288 } 287 }
@@ -295,7 +294,3 @@ int protect(struct mm_id * mm_idp, unsigned long addr, unsigned long len,
295 294
296 return ret; 295 return ret;
297} 296}
298
299void before_mem_skas(unsigned long unused)
300{
301}
diff --git a/arch/um/os-Linux/skas/process.c b/arch/um/os-Linux/skas/process.c
index ba9af8d62055..d77c81d7068a 100644
--- a/arch/um/os-Linux/skas/process.c
+++ b/arch/um/os-Linux/skas/process.c
@@ -1,48 +1,38 @@
1/* 1/*
2 * Copyright (C) 2002- 2004 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2002- 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdlib.h> 6#include <stdlib.h>
7#include <string.h>
8#include <unistd.h> 7#include <unistd.h>
9#include <errno.h>
10#include <signal.h>
11#include <sched.h> 8#include <sched.h>
12#include "ptrace_user.h" 9#include <errno.h>
13#include <sys/wait.h> 10#include <string.h>
14#include <sys/mman.h> 11#include <sys/mman.h>
15#include <sys/user.h> 12#include <sys/ptrace.h>
16#include <sys/time.h> 13#include <sys/wait.h>
17#include <sys/syscall.h> 14#include <asm/unistd.h>
18#include <asm/types.h> 15#include "as-layout.h"
19#include "user.h"
20#include "sysdep/ptrace.h"
21#include "kern_util.h"
22#include "skas.h"
23#include "stub-data.h"
24#include "mm_id.h"
25#include "sysdep/sigcontext.h"
26#include "sysdep/stub.h"
27#include "os.h"
28#include "proc_mm.h"
29#include "skas_ptrace.h"
30#include "chan_user.h" 16#include "chan_user.h"
31#include "registers.h" 17#include "kern_constants.h"
32#include "mem.h" 18#include "mem.h"
33#include "uml-config.h" 19#include "os.h"
34#include "process.h" 20#include "process.h"
35#include "longjmp.h" 21#include "proc_mm.h"
36#include "kern_constants.h" 22#include "ptrace_user.h"
37#include "as-layout.h" 23#include "registers.h"
24#include "skas.h"
25#include "skas_ptrace.h"
26#include "user.h"
27#include "sysdep/stub.h"
38 28
39int is_skas_winch(int pid, int fd, void *data) 29int is_skas_winch(int pid, int fd, void *data)
40{ 30{
41 if(pid != os_getpgrp()) 31 if (pid != getpgrp())
42 return(0); 32 return 0;
43 33
44 register_winch_irq(-1, fd, -1, data, 0); 34 register_winch_irq(-1, fd, -1, data, 0);
45 return(1); 35 return 1;
46} 36}
47 37
48static int ptrace_dump_regs(int pid) 38static int ptrace_dump_regs(int pid)
@@ -50,13 +40,12 @@ static int ptrace_dump_regs(int pid)
50 unsigned long regs[MAX_REG_NR]; 40 unsigned long regs[MAX_REG_NR];
51 int i; 41 int i;
52 42
53 if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) 43 if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
54 return -errno; 44 return -errno;
55 else { 45
56 printk("Stub registers -\n"); 46 printk(UM_KERN_ERR "Stub registers -\n");
57 for(i = 0; i < ARRAY_SIZE(regs); i++) 47 for (i = 0; i < ARRAY_SIZE(regs); i++)
58 printk("\t%d - %lx\n", i, regs[i]); 48 printk(UM_KERN_ERR "\t%d - %lx\n", i, regs[i]);
59 }
60 49
61 return 0; 50 return 0;
62} 51}
@@ -74,27 +63,28 @@ void wait_stub_done(int pid)
74{ 63{
75 int n, status, err; 64 int n, status, err;
76 65
77 while(1){ 66 while (1) {
78 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 67 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
79 if((n < 0) || !WIFSTOPPED(status)) 68 if ((n < 0) || !WIFSTOPPED(status))
80 goto bad_wait; 69 goto bad_wait;
81 70
82 if(((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0) 71 if (((1 << WSTOPSIG(status)) & STUB_SIG_MASK) == 0)
83 break; 72 break;
84 73
85 err = ptrace(PTRACE_CONT, pid, 0, 0); 74 err = ptrace(PTRACE_CONT, pid, 0, 0);
86 if(err) 75 if (err)
87 panic("wait_stub_done : continue failed, errno = %d\n", 76 panic("wait_stub_done : continue failed, errno = %d\n",
88 errno); 77 errno);
89 } 78 }
90 79
91 if(((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0) 80 if (((1 << WSTOPSIG(status)) & STUB_DONE_MASK) != 0)
92 return; 81 return;
93 82
94bad_wait: 83bad_wait:
95 err = ptrace_dump_regs(pid); 84 err = ptrace_dump_regs(pid);
96 if(err) 85 if (err)
97 printk("Failed to get registers from stub, errno = %d\n", -err); 86 printk(UM_KERN_ERR "Failed to get registers from stub, "
87 "errno = %d\n", -err);
98 panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, " 88 panic("wait_stub_done : failed to wait for SIGUSR1/SIGTRAP, pid = %d, "
99 "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status); 89 "n = %d, errno = %d, status = 0x%x\n", pid, n, errno, status);
100} 90}
@@ -105,9 +95,9 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
105{ 95{
106 int err; 96 int err;
107 97
108 if(ptrace_faultinfo){ 98 if (ptrace_faultinfo) {
109 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi); 99 err = ptrace(PTRACE_FAULTINFO, pid, 0, fi);
110 if(err) 100 if (err)
111 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, " 101 panic("get_skas_faultinfo - PTRACE_FAULTINFO failed, "
112 "errno = %d\n", errno); 102 "errno = %d\n", errno);
113 103
@@ -119,52 +109,57 @@ void get_skas_faultinfo(int pid, struct faultinfo * fi)
119 } 109 }
120 else { 110 else {
121 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV); 111 err = ptrace(PTRACE_CONT, pid, 0, SIGSEGV);
122 if(err) 112 if (err)
123 panic("Failed to continue stub, pid = %d, errno = %d\n", 113 panic("Failed to continue stub, pid = %d, errno = %d\n",
124 pid, errno); 114 pid, errno);
125 wait_stub_done(pid); 115 wait_stub_done(pid);
126 116
127 /* faultinfo is prepared by the stub-segv-handler at start of 117 /*
118 * faultinfo is prepared by the stub-segv-handler at start of
128 * the stub stack page. We just have to copy it. 119 * the stub stack page. We just have to copy it.
129 */ 120 */
130 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi)); 121 memcpy(fi, (void *)current_stub_stack(), sizeof(*fi));
131 } 122 }
132} 123}
133 124
134static void handle_segv(int pid, union uml_pt_regs * regs) 125static void handle_segv(int pid, struct uml_pt_regs * regs)
135{ 126{
136 get_skas_faultinfo(pid, &regs->skas.faultinfo); 127 get_skas_faultinfo(pid, &regs->faultinfo);
137 segv(regs->skas.faultinfo, 0, 1, NULL); 128 segv(regs->faultinfo, 0, 1, NULL);
138} 129}
139 130
140/*To use the same value of using_sysemu as the caller, ask it that value (in local_using_sysemu)*/ 131/*
141static void handle_trap(int pid, union uml_pt_regs *regs, int local_using_sysemu) 132 * To use the same value of using_sysemu as the caller, ask it that value
133 * (in local_using_sysemu
134 */
135static void handle_trap(int pid, struct uml_pt_regs *regs,
136 int local_using_sysemu)
142{ 137{
143 int err, status; 138 int err, status;
144 139
145 /* Mark this as a syscall */ 140 /* Mark this as a syscall */
146 UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->skas.regs); 141 UPT_SYSCALL_NR(regs) = PT_SYSCALL_NR(regs->gp);
147 142
148 if (!local_using_sysemu) 143 if (!local_using_sysemu)
149 { 144 {
150 err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, 145 err = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
151 __NR_getpid); 146 __NR_getpid);
152 if(err < 0) 147 if (err < 0)
153 panic("handle_trap - nullifying syscall failed errno = %d\n", 148 panic("handle_trap - nullifying syscall failed, "
154 errno); 149 "errno = %d\n", errno);
155 150
156 err = ptrace(PTRACE_SYSCALL, pid, 0, 0); 151 err = ptrace(PTRACE_SYSCALL, pid, 0, 0);
157 if(err < 0) 152 if (err < 0)
158 panic("handle_trap - continuing to end of syscall failed, " 153 panic("handle_trap - continuing to end of syscall "
159 "errno = %d\n", errno); 154 "failed, errno = %d\n", errno);
160 155
161 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); 156 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
162 if((err < 0) || !WIFSTOPPED(status) || 157 if ((err < 0) || !WIFSTOPPED(status) ||
163 (WSTOPSIG(status) != SIGTRAP + 0x80)){ 158 (WSTOPSIG(status) != SIGTRAP + 0x80)) {
164 err = ptrace_dump_regs(pid); 159 err = ptrace_dump_regs(pid);
165 if(err) 160 if (err)
166 printk("Failed to get registers from process, " 161 printk(UM_KERN_ERR "Failed to get registers "
167 "errno = %d\n", -err); 162 "from process, errno = %d\n", -err);
168 panic("handle_trap - failed to wait at end of syscall, " 163 panic("handle_trap - failed to wait at end of syscall, "
169 "errno = %d, status = %d\n", errno, status); 164 "errno = %d, status = %d\n", errno, status);
170 } 165 }
@@ -182,63 +177,64 @@ static int userspace_tramp(void *stack)
182 177
183 ptrace(PTRACE_TRACEME, 0, 0, 0); 178 ptrace(PTRACE_TRACEME, 0, 0, 0);
184 179
185 init_new_thread_signals(); 180 signal(SIGTERM, SIG_DFL);
186 err = set_interval(1); 181 err = set_interval();
187 if(err) 182 if (err)
188 panic("userspace_tramp - setting timer failed, errno = %d\n", 183 panic("userspace_tramp - setting timer failed, errno = %d\n",
189 err); 184 err);
190 185
191 if(!proc_mm){ 186 if (!proc_mm) {
192 /* This has a pte, but it can't be mapped in with the usual 187 /*
188 * This has a pte, but it can't be mapped in with the usual
193 * tlb_flush mechanism because this is part of that mechanism 189 * tlb_flush mechanism because this is part of that mechanism
194 */ 190 */
195 int fd; 191 int fd;
196 __u64 offset; 192 unsigned long long offset;
197 fd = phys_mapping(to_phys(&__syscall_stub_start), &offset); 193 fd = phys_mapping(to_phys(&__syscall_stub_start), &offset);
198 addr = mmap64((void *) UML_CONFIG_STUB_CODE, UM_KERN_PAGE_SIZE, 194 addr = mmap64((void *) STUB_CODE, UM_KERN_PAGE_SIZE,
199 PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset); 195 PROT_EXEC, MAP_FIXED | MAP_PRIVATE, fd, offset);
200 if(addr == MAP_FAILED){ 196 if (addr == MAP_FAILED) {
201 printk("mapping mmap stub failed, errno = %d\n", 197 printk(UM_KERN_ERR "mapping mmap stub at 0x%lx failed, "
202 errno); 198 "errno = %d\n", STUB_CODE, errno);
203 exit(1); 199 exit(1);
204 } 200 }
205 201
206 if(stack != NULL){ 202 if (stack != NULL) {
207 fd = phys_mapping(to_phys(stack), &offset); 203 fd = phys_mapping(to_phys(stack), &offset);
208 addr = mmap((void *) UML_CONFIG_STUB_DATA, 204 addr = mmap((void *) STUB_DATA,
209 UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE, 205 UM_KERN_PAGE_SIZE, PROT_READ | PROT_WRITE,
210 MAP_FIXED | MAP_SHARED, fd, offset); 206 MAP_FIXED | MAP_SHARED, fd, offset);
211 if(addr == MAP_FAILED){ 207 if (addr == MAP_FAILED) {
212 printk("mapping segfault stack failed, " 208 printk(UM_KERN_ERR "mapping segfault stack "
213 "errno = %d\n", errno); 209 "at 0x%lx failed, errno = %d\n",
210 STUB_DATA, errno);
214 exit(1); 211 exit(1);
215 } 212 }
216 } 213 }
217 } 214 }
218 if(!ptrace_faultinfo && (stack != NULL)){ 215 if (!ptrace_faultinfo && (stack != NULL)) {
219 struct sigaction sa; 216 struct sigaction sa;
220 217
221 unsigned long v = UML_CONFIG_STUB_CODE + 218 unsigned long v = STUB_CODE +
222 (unsigned long) stub_segv_handler - 219 (unsigned long) stub_segv_handler -
223 (unsigned long) &__syscall_stub_start; 220 (unsigned long) &__syscall_stub_start;
224 221
225 set_sigstack((void *) UML_CONFIG_STUB_DATA, UM_KERN_PAGE_SIZE); 222 set_sigstack((void *) STUB_DATA, UM_KERN_PAGE_SIZE);
226 sigemptyset(&sa.sa_mask); 223 sigemptyset(&sa.sa_mask);
227 sigaddset(&sa.sa_mask, SIGIO); 224 sigaddset(&sa.sa_mask, SIGIO);
228 sigaddset(&sa.sa_mask, SIGWINCH); 225 sigaddset(&sa.sa_mask, SIGWINCH);
229 sigaddset(&sa.sa_mask, SIGALRM);
230 sigaddset(&sa.sa_mask, SIGVTALRM); 226 sigaddset(&sa.sa_mask, SIGVTALRM);
231 sigaddset(&sa.sa_mask, SIGUSR1); 227 sigaddset(&sa.sa_mask, SIGUSR1);
232 sa.sa_flags = SA_ONSTACK; 228 sa.sa_flags = SA_ONSTACK;
233 sa.sa_handler = (void *) v; 229 sa.sa_handler = (void *) v;
234 sa.sa_restorer = NULL; 230 sa.sa_restorer = NULL;
235 if(sigaction(SIGSEGV, &sa, NULL) < 0) 231 if (sigaction(SIGSEGV, &sa, NULL) < 0)
236 panic("userspace_tramp - setting SIGSEGV handler " 232 panic("userspace_tramp - setting SIGSEGV handler "
237 "failed - errno = %d\n", errno); 233 "failed - errno = %d\n", errno);
238 } 234 }
239 235
240 os_stop_process(os_getpid()); 236 kill(os_getpid(), SIGSTOP);
241 return(0); 237 return 0;
242} 238}
243 239
244/* Each element set once, and only accessed by a single processor anyway */ 240/* Each element set once, and only accessed by a single processor anyway */
@@ -255,44 +251,55 @@ int start_userspace(unsigned long stub_stack)
255 stack = mmap(NULL, UM_KERN_PAGE_SIZE, 251 stack = mmap(NULL, UM_KERN_PAGE_SIZE,
256 PROT_READ | PROT_WRITE | PROT_EXEC, 252 PROT_READ | PROT_WRITE | PROT_EXEC,
257 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 253 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
258 if(stack == MAP_FAILED) 254 if (stack == MAP_FAILED)
259 panic("start_userspace : mmap failed, errno = %d", errno); 255 panic("start_userspace : mmap failed, errno = %d", errno);
260 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); 256 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *);
261 257
262 flags = CLONE_FILES | SIGCHLD; 258 flags = CLONE_FILES | SIGCHLD;
263 if(proc_mm) flags |= CLONE_VM; 259 if (proc_mm)
260 flags |= CLONE_VM;
261
264 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack); 262 pid = clone(userspace_tramp, (void *) sp, flags, (void *) stub_stack);
265 if(pid < 0) 263 if (pid < 0)
266 panic("start_userspace : clone failed, errno = %d", errno); 264 panic("start_userspace : clone failed, errno = %d", errno);
267 265
268 do { 266 do {
269 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 267 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
270 if(n < 0) 268 if (n < 0)
271 panic("start_userspace : wait failed, errno = %d", 269 panic("start_userspace : wait failed, errno = %d",
272 errno); 270 errno);
273 } while(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM)); 271 } while (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGVTALRM));
274 272
275 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) 273 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
276 panic("start_userspace : expected SIGSTOP, got status = %d", 274 panic("start_userspace : expected SIGSTOP, got status = %d",
277 status); 275 status);
278 276
279 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL, (void *)PTRACE_O_TRACESYSGOOD) < 0) 277 if (ptrace(PTRACE_OLDSETOPTIONS, pid, NULL,
280 panic("start_userspace : PTRACE_OLDSETOPTIONS failed, errno=%d\n", 278 (void *) PTRACE_O_TRACESYSGOOD) < 0)
281 errno); 279 panic("start_userspace : PTRACE_OLDSETOPTIONS failed, "
280 "errno = %d\n", errno);
282 281
283 if(munmap(stack, UM_KERN_PAGE_SIZE) < 0) 282 if (munmap(stack, UM_KERN_PAGE_SIZE) < 0)
284 panic("start_userspace : munmap failed, errno = %d\n", errno); 283 panic("start_userspace : munmap failed, errno = %d\n", errno);
285 284
286 return(pid); 285 return pid;
287} 286}
288 287
289void userspace(union uml_pt_regs *regs) 288void userspace(struct uml_pt_regs *regs)
290{ 289{
290 struct itimerval timer;
291 unsigned long long nsecs, now;
291 int err, status, op, pid = userspace_pid[0]; 292 int err, status, op, pid = userspace_pid[0];
292 /* To prevent races if using_sysemu changes under us.*/ 293 /* To prevent races if using_sysemu changes under us.*/
293 int local_using_sysemu; 294 int local_using_sysemu;
294 295
295 while(1){ 296 if (getitimer(ITIMER_VIRTUAL, &timer))
297 printk("Failed to get itimer, errno = %d\n", errno);
298 nsecs = timer.it_value.tv_sec * UM_NSEC_PER_SEC +
299 timer.it_value.tv_usec * UM_NSEC_PER_USEC;
300 nsecs += os_nsecs();
301
302 while (1) {
296 restore_registers(pid, regs); 303 restore_registers(pid, regs);
297 304
298 /* Now we set local_using_sysemu to be used for one loop */ 305 /* Now we set local_using_sysemu to be used for one loop */
@@ -302,26 +309,28 @@ void userspace(union uml_pt_regs *regs)
302 singlestepping(NULL)); 309 singlestepping(NULL));
303 310
304 err = ptrace(op, pid, 0, 0); 311 err = ptrace(op, pid, 0, 0);
305 if(err) 312 if (err)
306 panic("userspace - could not resume userspace process, " 313 panic("userspace - could not resume userspace process, "
307 "pid=%d, ptrace operation = %d, errno = %d\n", 314 "pid=%d, ptrace operation = %d, errno = %d\n",
308 pid, op, errno); 315 pid, op, errno);
309 316
310 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED)); 317 CATCH_EINTR(err = waitpid(pid, &status, WUNTRACED));
311 if(err < 0) 318 if (err < 0)
312 panic("userspace - waitpid failed, errno = %d\n", 319 panic("userspace - waitpid failed, errno = %d\n",
313 errno); 320 errno);
314 321
315 regs->skas.is_user = 1; 322 regs->is_user = 1;
316 save_registers(pid, regs); 323 save_registers(pid, regs);
317 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */ 324 UPT_SYSCALL_NR(regs) = -1; /* Assume: It's not a syscall */
318 325
319 if(WIFSTOPPED(status)){ 326 if (WIFSTOPPED(status)) {
320 int sig = WSTOPSIG(status); 327 int sig = WSTOPSIG(status);
321 switch(sig){ 328 switch(sig) {
322 case SIGSEGV: 329 case SIGSEGV:
323 if(PTRACE_FULL_FAULTINFO || !ptrace_faultinfo){ 330 if (PTRACE_FULL_FAULTINFO ||
324 get_skas_faultinfo(pid, &regs->skas.faultinfo); 331 !ptrace_faultinfo) {
332 get_skas_faultinfo(pid,
333 &regs->faultinfo);
325 (*sig_info[SIGSEGV])(SIGSEGV, regs); 334 (*sig_info[SIGSEGV])(SIGSEGV, regs);
326 } 335 }
327 else handle_segv(pid, regs); 336 else handle_segv(pid, regs);
@@ -332,8 +341,20 @@ void userspace(union uml_pt_regs *regs)
332 case SIGTRAP: 341 case SIGTRAP:
333 relay_signal(SIGTRAP, regs); 342 relay_signal(SIGTRAP, regs);
334 break; 343 break;
335 case SIGIO:
336 case SIGVTALRM: 344 case SIGVTALRM:
345 now = os_nsecs();
346 if(now < nsecs)
347 break;
348 block_signals();
349 (*sig_info[sig])(sig, regs);
350 unblock_signals();
351 nsecs = timer.it_value.tv_sec *
352 UM_NSEC_PER_SEC +
353 timer.it_value.tv_usec *
354 UM_NSEC_PER_USEC;
355 nsecs += os_nsecs();
356 break;
357 case SIGIO:
337 case SIGILL: 358 case SIGILL:
338 case SIGBUS: 359 case SIGBUS:
339 case SIGFPE: 360 case SIGFPE:
@@ -343,30 +364,29 @@ void userspace(union uml_pt_regs *regs)
343 unblock_signals(); 364 unblock_signals();
344 break; 365 break;
345 default: 366 default:
346 printk("userspace - child stopped with signal " 367 printk(UM_KERN_ERR "userspace - child stopped "
347 "%d\n", sig); 368 "with signal %d\n", sig);
348 } 369 }
349 pid = userspace_pid[0]; 370 pid = userspace_pid[0];
350 interrupt_end(); 371 interrupt_end();
351 372
352 /* Avoid -ERESTARTSYS handling in host */ 373 /* Avoid -ERESTARTSYS handling in host */
353 if(PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET) 374 if (PT_SYSCALL_NR_OFFSET != PT_SYSCALL_RET_OFFSET)
354 PT_SYSCALL_NR(regs->skas.regs) = -1; 375 PT_SYSCALL_NR(regs->gp) = -1;
355 } 376 }
356 } 377 }
357} 378}
358 379
359static unsigned long thread_regs[MAX_REG_NR]; 380static unsigned long thread_regs[MAX_REG_NR];
360static unsigned long thread_fp_regs[HOST_FP_SIZE];
361 381
362static int __init init_thread_regs(void) 382static int __init init_thread_regs(void)
363{ 383{
364 get_safe_registers(thread_regs, thread_fp_regs); 384 get_safe_registers(thread_regs);
365 /* Set parent's instruction pointer to start of clone-stub */ 385 /* Set parent's instruction pointer to start of clone-stub */
366 thread_regs[REGS_IP_INDEX] = UML_CONFIG_STUB_CODE + 386 thread_regs[REGS_IP_INDEX] = STUB_CODE +
367 (unsigned long) stub_clone_handler - 387 (unsigned long) stub_clone_handler -
368 (unsigned long) &__syscall_stub_start; 388 (unsigned long) &__syscall_stub_start;
369 thread_regs[REGS_SP_INDEX] = UML_CONFIG_STUB_DATA + UM_KERN_PAGE_SIZE - 389 thread_regs[REGS_SP_INDEX] = STUB_DATA + UM_KERN_PAGE_SIZE -
370 sizeof(void *); 390 sizeof(void *);
371#ifdef __SIGNAL_FRAMESIZE 391#ifdef __SIGNAL_FRAMESIZE
372 thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE; 392 thread_regs[REGS_SP_INDEX] -= __SIGNAL_FRAMESIZE;
@@ -378,53 +398,53 @@ __initcall(init_thread_regs);
378 398
379int copy_context_skas0(unsigned long new_stack, int pid) 399int copy_context_skas0(unsigned long new_stack, int pid)
380{ 400{
401 struct timeval tv = { .tv_sec = 0, .tv_usec = UM_USEC_PER_SEC / UM_HZ };
381 int err; 402 int err;
382 unsigned long current_stack = current_stub_stack(); 403 unsigned long current_stack = current_stub_stack();
383 struct stub_data *data = (struct stub_data *) current_stack; 404 struct stub_data *data = (struct stub_data *) current_stack;
384 struct stub_data *child_data = (struct stub_data *) new_stack; 405 struct stub_data *child_data = (struct stub_data *) new_stack;
385 __u64 new_offset; 406 unsigned long long new_offset;
386 int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset); 407 int new_fd = phys_mapping(to_phys((void *)new_stack), &new_offset);
387 408
388 /* prepare offset and fd of child's stack as argument for parent's 409 /*
410 * prepare offset and fd of child's stack as argument for parent's
389 * and child's mmap2 calls 411 * and child's mmap2 calls
390 */ 412 */
391 *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset), 413 *data = ((struct stub_data) { .offset = MMAP_OFFSET(new_offset),
392 .fd = new_fd, 414 .fd = new_fd,
393 .timer = ((struct itimerval) 415 .timer = ((struct itimerval)
394 { { 0, 1000000 / hz() }, 416 { .it_value = tv,
395 { 0, 1000000 / hz() }})}); 417 .it_interval = tv }) });
418
396 err = ptrace_setregs(pid, thread_regs); 419 err = ptrace_setregs(pid, thread_regs);
397 if(err < 0) 420 if (err < 0)
398 panic("copy_context_skas0 : PTRACE_SETREGS failed, " 421 panic("copy_context_skas0 : PTRACE_SETREGS failed, "
399 "pid = %d, errno = %d\n", pid, -err); 422 "pid = %d, errno = %d\n", pid, -err);
400 423
401 err = ptrace_setfpregs(pid, thread_fp_regs);
402 if(err < 0)
403 panic("copy_context_skas0 : PTRACE_SETFPREGS failed, "
404 "pid = %d, errno = %d\n", pid, -err);
405
406 /* set a well known return code for detection of child write failure */ 424 /* set a well known return code for detection of child write failure */
407 child_data->err = 12345678; 425 child_data->err = 12345678;
408 426
409 /* Wait, until parent has finished its work: read child's pid from 427 /*
428 * Wait, until parent has finished its work: read child's pid from
410 * parent's stack, and check, if bad result. 429 * parent's stack, and check, if bad result.
411 */ 430 */
412 err = ptrace(PTRACE_CONT, pid, 0, 0); 431 err = ptrace(PTRACE_CONT, pid, 0, 0);
413 if(err) 432 if (err)
414 panic("Failed to continue new process, pid = %d, " 433 panic("Failed to continue new process, pid = %d, "
415 "errno = %d\n", pid, errno); 434 "errno = %d\n", pid, errno);
416 wait_stub_done(pid); 435 wait_stub_done(pid);
417 436
418 pid = data->err; 437 pid = data->err;
419 if(pid < 0) 438 if (pid < 0)
420 panic("copy_context_skas0 - stub-parent reports error %d\n", 439 panic("copy_context_skas0 - stub-parent reports error %d\n",
421 -pid); 440 -pid);
422 441
423 /* Wait, until child has finished too: read child's result from 442 /*
443 * Wait, until child has finished too: read child's result from
424 * child's stack and check it. 444 * child's stack and check it.
425 */ 445 */
426 wait_stub_done(pid); 446 wait_stub_done(pid);
427 if (child_data->err != UML_CONFIG_STUB_DATA) 447 if (child_data->err != STUB_DATA)
428 panic("copy_context_skas0 - stub-child reports error %ld\n", 448 panic("copy_context_skas0 - stub-child reports error %ld\n",
429 child_data->err); 449 child_data->err);
430 450
@@ -446,7 +466,7 @@ void map_stub_pages(int fd, unsigned long code,
446{ 466{
447 struct proc_mm_op mmop; 467 struct proc_mm_op mmop;
448 int n; 468 int n;
449 __u64 code_offset; 469 unsigned long long code_offset;
450 int code_fd = phys_mapping(to_phys((void *) &__syscall_stub_start), 470 int code_fd = phys_mapping(to_phys((void *) &__syscall_stub_start),
451 &code_offset); 471 &code_offset);
452 472
@@ -461,16 +481,17 @@ void map_stub_pages(int fd, unsigned long code,
461 .offset = code_offset 481 .offset = code_offset
462 } } }); 482 } } });
463 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); 483 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
464 if(n != sizeof(mmop)){ 484 if (n != sizeof(mmop)) {
465 n = errno; 485 n = errno;
466 printk("mmap args - addr = 0x%lx, fd = %d, offset = %llx\n", 486 printk(UM_KERN_ERR "mmap args - addr = 0x%lx, fd = %d, "
467 code, code_fd, (unsigned long long) code_offset); 487 "offset = %llx\n", code, code_fd,
488 (unsigned long long) code_offset);
468 panic("map_stub_pages : /proc/mm map for code failed, " 489 panic("map_stub_pages : /proc/mm map for code failed, "
469 "err = %d\n", n); 490 "err = %d\n", n);
470 } 491 }
471 492
472 if ( stack ) { 493 if (stack) {
473 __u64 map_offset; 494 unsigned long long map_offset;
474 int map_fd = phys_mapping(to_phys((void *)stack), &map_offset); 495 int map_fd = phys_mapping(to_phys((void *)stack), &map_offset);
475 mmop = ((struct proc_mm_op) 496 mmop = ((struct proc_mm_op)
476 { .op = MM_MMAP, 497 { .op = MM_MMAP,
@@ -484,7 +505,7 @@ void map_stub_pages(int fd, unsigned long code,
484 .offset = map_offset 505 .offset = map_offset
485 } } }); 506 } } });
486 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop))); 507 CATCH_EINTR(n = write(fd, &mmop, sizeof(mmop)));
487 if(n != sizeof(mmop)) 508 if (n != sizeof(mmop))
488 panic("map_stub_pages : /proc/mm map for data failed, " 509 panic("map_stub_pages : /proc/mm map for data failed, "
489 "err = %d\n", errno); 510 "err = %d\n", errno);
490 } 511 }
@@ -504,7 +525,7 @@ void new_thread(void *stack, jmp_buf *buf, void (*handler)(void))
504 525
505void switch_threads(jmp_buf *me, jmp_buf *you) 526void switch_threads(jmp_buf *me, jmp_buf *you)
506{ 527{
507 if(UML_SETJMP(me) == 0) 528 if (UML_SETJMP(me) == 0)
508 UML_LONGJMP(you, 1); 529 UML_LONGJMP(you, 1);
509} 530}
510 531
@@ -520,8 +541,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
520 int n; 541 int n;
521 542
522 set_handler(SIGWINCH, (__sighandler_t) sig_handler, 543 set_handler(SIGWINCH, (__sighandler_t) sig_handler,
523 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGALRM, 544 SA_ONSTACK | SA_RESTART, SIGUSR1, SIGIO, SIGVTALRM, -1);
524 SIGVTALRM, -1);
525 545
526 /* 546 /*
527 * Can't use UML_SETJMP or UML_LONGJMP here because they save 547 * Can't use UML_SETJMP or UML_LONGJMP here because they save
@@ -532,7 +552,7 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
532 * after returning to the jumper. 552 * after returning to the jumper.
533 */ 553 */
534 n = setjmp(initial_jmpbuf); 554 n = setjmp(initial_jmpbuf);
535 switch(n){ 555 switch(n) {
536 case INIT_JMP_NEW_THREAD: 556 case INIT_JMP_NEW_THREAD:
537 (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler; 557 (*switch_buf)[0].JB_IP = (unsigned long) new_thread_handler;
538 (*switch_buf)[0].JB_SP = (unsigned long) stack + 558 (*switch_buf)[0].JB_SP = (unsigned long) stack +
@@ -544,10 +564,10 @@ int start_idle_thread(void *stack, jmp_buf *switch_buf)
544 break; 564 break;
545 case INIT_JMP_HALT: 565 case INIT_JMP_HALT:
546 kmalloc_ok = 0; 566 kmalloc_ok = 0;
547 return(0); 567 return 0;
548 case INIT_JMP_REBOOT: 568 case INIT_JMP_REBOOT:
549 kmalloc_ok = 0; 569 kmalloc_ok = 0;
550 return(1); 570 return 1;
551 default: 571 default:
552 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n); 572 panic("Bad sigsetjmp return in start_idle_thread - %d\n", n);
553 } 573 }
@@ -563,7 +583,7 @@ void initial_thread_cb_skas(void (*proc)(void *), void *arg)
563 cb_back = &here; 583 cb_back = &here;
564 584
565 block_signals(); 585 block_signals();
566 if(UML_SETJMP(&here) == 0) 586 if (UML_SETJMP(&here) == 0)
567 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK); 587 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_CALLBACK);
568 unblock_signals(); 588 unblock_signals();
569 589
@@ -584,16 +604,16 @@ void reboot_skas(void)
584 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT); 604 UML_LONGJMP(&initial_jmpbuf, INIT_JMP_REBOOT);
585} 605}
586 606
587void switch_mm_skas(struct mm_id *mm_idp) 607void __switch_mm(struct mm_id *mm_idp)
588{ 608{
589 int err; 609 int err;
590 610
591 /* FIXME: need cpu pid in switch_mm_skas */ 611 /* FIXME: need cpu pid in __switch_mm */
592 if(proc_mm){ 612 if (proc_mm) {
593 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0, 613 err = ptrace(PTRACE_SWITCH_MM, userspace_pid[0], 0,
594 mm_idp->u.mm_fd); 614 mm_idp->u.mm_fd);
595 if(err) 615 if (err)
596 panic("switch_mm_skas - PTRACE_SWITCH_MM failed, " 616 panic("__switch_mm - PTRACE_SWITCH_MM failed, "
597 "errno = %d\n", errno); 617 "errno = %d\n", errno);
598 } 618 }
599 else userspace_pid[0] = mm_idp->u.pid; 619 else userspace_pid[0] = mm_idp->u.pid;
diff --git a/arch/um/os-Linux/skas/trap.c b/arch/um/os-Linux/skas/trap.c
index 3b600c2e63b8..3b1b9244f468 100644
--- a/arch/um/os-Linux/skas/trap.c
+++ b/arch/um/os-Linux/skas/trap.c
@@ -1,37 +1,43 @@
1/* 1/*
2 * Copyright (C) 2002 - 2003 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <signal.h> 6#if 0
7#include <errno.h>
8#include "kern_util.h" 7#include "kern_util.h"
9#include "as-layout.h"
10#include "task.h"
11#include "sigcontext.h"
12#include "skas.h" 8#include "skas.h"
13#include "ptrace_user.h" 9#include "ptrace_user.h"
14#include "sysdep/ptrace.h"
15#include "sysdep/ptrace_user.h" 10#include "sysdep/ptrace_user.h"
11#endif
12
13#include <errno.h>
14#include <signal.h>
15#include "sysdep/ptrace.h"
16#include "kern_constants.h"
17#include "as-layout.h"
16#include "os.h" 18#include "os.h"
19#include "sigcontext.h"
20#include "task.h"
17 21
18static union uml_pt_regs ksig_regs[UM_NR_CPUS]; 22static struct uml_pt_regs ksig_regs[UM_NR_CPUS];
19 23
20void sig_handler_common_skas(int sig, void *sc_ptr) 24void sig_handler_common_skas(int sig, void *sc_ptr)
21{ 25{
22 struct sigcontext *sc = sc_ptr; 26 struct sigcontext *sc = sc_ptr;
23 union uml_pt_regs *r; 27 struct uml_pt_regs *r;
24 void (*handler)(int, union uml_pt_regs *); 28 void (*handler)(int, struct uml_pt_regs *);
25 int save_user, save_errno = errno; 29 int save_user, save_errno = errno;
26 30
27 /* This is done because to allow SIGSEGV to be delivered inside a SEGV 31 /*
32 * This is done because to allow SIGSEGV to be delivered inside a SEGV
28 * handler. This can happen in copy_user, and if SEGV is disabled, 33 * handler. This can happen in copy_user, and if SEGV is disabled,
29 * the process will die. 34 * the process will die.
30 * XXX Figure out why this is better than SA_NODEFER 35 * XXX Figure out why this is better than SA_NODEFER
31 */ 36 */
32 if(sig == SIGSEGV) { 37 if (sig == SIGSEGV) {
33 change_sig(SIGSEGV, 1); 38 change_sig(SIGSEGV, 1);
34 /* For segfaults, we want the data from the 39 /*
40 * For segfaults, we want the data from the
35 * sigcontext. In this case, we don't want to mangle 41 * sigcontext. In this case, we don't want to mangle
36 * the process registers, so use a static set of 42 * the process registers, so use a static set of
37 * registers. For other signals, the process 43 * registers. For other signals, the process
@@ -42,25 +48,22 @@ void sig_handler_common_skas(int sig, void *sc_ptr)
42 } 48 }
43 else r = TASK_REGS(get_current()); 49 else r = TASK_REGS(get_current());
44 50
45 save_user = r->skas.is_user; 51 save_user = r->is_user;
46 r->skas.is_user = 0; 52 r->is_user = 0;
47 if ( sig == SIGFPE || sig == SIGSEGV || 53 if ((sig == SIGFPE) || (sig == SIGSEGV) || (sig == SIGBUS) ||
48 sig == SIGBUS || sig == SIGILL || 54 (sig == SIGILL) || (sig == SIGTRAP))
49 sig == SIGTRAP ) { 55 GET_FAULTINFO_FROM_SC(r->faultinfo, sc);
50 GET_FAULTINFO_FROM_SC(r->skas.faultinfo, sc);
51 }
52 56
53 change_sig(SIGUSR1, 1); 57 change_sig(SIGUSR1, 1);
54 58
55 handler = sig_info[sig]; 59 handler = sig_info[sig];
56 60
57 /* unblock SIGALRM, SIGVTALRM, SIGIO if sig isn't IRQ signal */ 61 /* unblock SIGVTALRM, SIGIO if sig isn't IRQ signal */
58 if (sig != SIGIO && sig != SIGWINCH && 62 if ((sig != SIGIO) && (sig != SIGWINCH) && (sig != SIGVTALRM))
59 sig != SIGVTALRM && sig != SIGALRM)
60 unblock_signals(); 63 unblock_signals();
61 64
62 handler(sig, r); 65 handler(sig, r);
63 66
64 errno = save_errno; 67 errno = save_errno;
65 r->skas.is_user = save_user; 68 r->is_user = save_user;
66} 69}
diff --git a/arch/um/os-Linux/start_up.c b/arch/um/os-Linux/start_up.c
index 46f613975c19..7b81f6c08a5e 100644
--- a/arch/um/os-Linux/start_up.c
+++ b/arch/um/os-Linux/start_up.c
@@ -1,75 +1,65 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <pty.h>
7#include <stdio.h> 6#include <stdio.h>
8#include <stddef.h>
9#include <stdarg.h>
10#include <stdlib.h> 7#include <stdlib.h>
11#include <string.h> 8#include <stdarg.h>
12#include <unistd.h> 9#include <unistd.h>
13#include <signal.h>
14#include <sched.h>
15#include <fcntl.h>
16#include <errno.h> 10#include <errno.h>
17#include <sys/time.h> 11#include <fcntl.h>
18#include <sys/wait.h> 12#include <sched.h>
13#include <signal.h>
14#include <string.h>
19#include <sys/mman.h> 15#include <sys/mman.h>
20#include <sys/resource.h> 16#include <sys/ptrace.h>
17#include <sys/stat.h>
18#include <sys/wait.h>
21#include <asm/unistd.h> 19#include <asm/unistd.h>
22#include <asm/page.h>
23#include <sys/types.h>
24#include "kern_util.h"
25#include "user.h"
26#include "signal_kern.h"
27#include "sysdep/ptrace.h"
28#include "sysdep/sigcontext.h"
29#include "irq_user.h"
30#include "ptrace_user.h"
31#include "mem_user.h"
32#include "init.h" 20#include "init.h"
33#include "os.h"
34#include "uml-config.h"
35#include "choose-mode.h"
36#include "mode.h"
37#include "tempfile.h"
38#include "kern_constants.h" 21#include "kern_constants.h"
39 22#include "os.h"
40#ifdef UML_CONFIG_MODE_SKAS 23#include "mem_user.h"
41#include "skas.h" 24#include "ptrace_user.h"
42#include "skas_ptrace.h"
43#include "registers.h" 25#include "registers.h"
44#endif 26#include "skas_ptrace.h"
45 27
46static int ptrace_child(void *arg) 28static int ptrace_child(void)
47{ 29{
48 int ret; 30 int ret;
31 /* Calling os_getpid because some libcs cached getpid incorrectly */
49 int pid = os_getpid(), ppid = getppid(); 32 int pid = os_getpid(), ppid = getppid();
50 int sc_result; 33 int sc_result;
51 34
52 change_sig(SIGWINCH, 0); 35 change_sig(SIGWINCH, 0);
53 if(ptrace(PTRACE_TRACEME, 0, 0, 0) < 0){ 36 if (ptrace(PTRACE_TRACEME, 0, 0, 0) < 0) {
54 perror("ptrace"); 37 perror("ptrace");
55 os_kill_process(pid, 0); 38 kill(pid, SIGKILL);
56 } 39 }
57 kill(pid, SIGSTOP); 40 kill(pid, SIGSTOP);
58 41
59 /*This syscall will be intercepted by the parent. Don't call more than 42 /*
60 * once, please.*/ 43 * This syscall will be intercepted by the parent. Don't call more than
44 * once, please.
45 */
61 sc_result = os_getpid(); 46 sc_result = os_getpid();
62 47
63 if (sc_result == pid) 48 if (sc_result == pid)
64 ret = 1; /*Nothing modified by the parent, we are running 49 /* Nothing modified by the parent, we are running normally. */
65 normally.*/ 50 ret = 1;
66 else if (sc_result == ppid) 51 else if (sc_result == ppid)
67 ret = 0; /*Expected in check_ptrace and check_sysemu when they 52 /*
68 succeed in modifying the stack frame*/ 53 * Expected in check_ptrace and check_sysemu when they succeed
54 * in modifying the stack frame
55 */
56 ret = 0;
69 else 57 else
70 ret = 2; /*Serious trouble! This could be caused by a bug in 58 /* Serious trouble! This could be caused by a bug in host 2.6
71 host 2.6 SKAS3/2.6 patch before release -V6, together 59 * SKAS3/2.6 patch before release -V6, together with a bug in
72 with a bug in the UML code itself.*/ 60 * the UML code itself.
61 */
62 ret = 2;
73 _exit(ret); 63 _exit(ret);
74} 64}
75 65
@@ -101,29 +91,23 @@ static void non_fatal(char *fmt, ...)
101 fflush(stdout); 91 fflush(stdout);
102} 92}
103 93
104static int start_ptraced_child(void **stack_out) 94static int start_ptraced_child(void)
105{ 95{
106 void *stack;
107 unsigned long sp;
108 int pid, n, status; 96 int pid, n, status;
109 97
110 stack = mmap(NULL, UM_KERN_PAGE_SIZE, 98 pid = fork();
111 PROT_READ | PROT_WRITE | PROT_EXEC, 99 if (pid == 0)
112 MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); 100 ptrace_child();
113 if(stack == MAP_FAILED) 101 else if (pid < 0)
114 fatal_perror("check_ptrace : mmap failed"); 102 fatal_perror("start_ptraced_child : fork failed");
115 sp = (unsigned long) stack + UM_KERN_PAGE_SIZE - sizeof(void *); 103
116 pid = clone(ptrace_child, (void *) sp, SIGCHLD, NULL);
117 if(pid < 0)
118 fatal_perror("start_ptraced_child : clone failed");
119 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 104 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
120 if(n < 0) 105 if (n < 0)
121 fatal_perror("check_ptrace : clone failed"); 106 fatal_perror("check_ptrace : waitpid failed");
122 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP)) 107 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGSTOP))
123 fatal("check_ptrace : expected SIGSTOP, got status = %d", 108 fatal("check_ptrace : expected SIGSTOP, got status = %d",
124 status); 109 status);
125 110
126 *stack_out = stack;
127 return pid; 111 return pid;
128} 112}
129 113
@@ -133,15 +117,14 @@ static int start_ptraced_child(void **stack_out)
133 * So only for SYSEMU features we test mustpanic, while normal host features 117 * So only for SYSEMU features we test mustpanic, while normal host features
134 * must work anyway! 118 * must work anyway!
135 */ 119 */
136static int stop_ptraced_child(int pid, void *stack, int exitcode, 120static int stop_ptraced_child(int pid, int exitcode, int mustexit)
137 int mustexit)
138{ 121{
139 int status, n, ret = 0; 122 int status, n, ret = 0;
140 123
141 if(ptrace(PTRACE_CONT, pid, 0, 0) < 0) 124 if (ptrace(PTRACE_CONT, pid, 0, 0) < 0)
142 fatal_perror("stop_ptraced_child : ptrace failed"); 125 fatal_perror("stop_ptraced_child : ptrace failed");
143 CATCH_EINTR(n = waitpid(pid, &status, 0)); 126 CATCH_EINTR(n = waitpid(pid, &status, 0));
144 if(!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) { 127 if (!WIFEXITED(status) || (WEXITSTATUS(status) != exitcode)) {
145 int exit_with = WEXITSTATUS(status); 128 int exit_with = WEXITSTATUS(status);
146 if (exit_with == 2) 129 if (exit_with == 2)
147 non_fatal("check_ptrace : child exited with status 2. " 130 non_fatal("check_ptrace : child exited with status 2. "
@@ -154,8 +137,6 @@ static int stop_ptraced_child(int pid, void *stack, int exitcode,
154 ret = -1; 137 ret = -1;
155 } 138 }
156 139
157 if(munmap(stack, UM_KERN_PAGE_SIZE) < 0)
158 fatal_perror("check_ptrace : munmap failed");
159 return ret; 140 return ret;
160} 141}
161 142
@@ -207,40 +188,39 @@ __uml_setup("nosysemu", nosysemu_cmd_param,
207 188
208static void __init check_sysemu(void) 189static void __init check_sysemu(void)
209{ 190{
210 void *stack;
211 unsigned long regs[MAX_REG_NR]; 191 unsigned long regs[MAX_REG_NR];
212 int pid, n, status, count=0; 192 int pid, n, status, count=0;
213 193
214 non_fatal("Checking syscall emulation patch for ptrace..."); 194 non_fatal("Checking syscall emulation patch for ptrace...");
215 sysemu_supported = 0; 195 sysemu_supported = 0;
216 pid = start_ptraced_child(&stack); 196 pid = start_ptraced_child();
217 197
218 if(ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0) 198 if (ptrace(PTRACE_SYSEMU, pid, 0, 0) < 0)
219 goto fail; 199 goto fail;
220 200
221 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 201 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
222 if (n < 0) 202 if (n < 0)
223 fatal_perror("check_sysemu : wait failed"); 203 fatal_perror("check_sysemu : wait failed");
224 if(!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP)) 204 if (!WIFSTOPPED(status) || (WSTOPSIG(status) != SIGTRAP))
225 fatal("check_sysemu : expected SIGTRAP, got status = %d", 205 fatal("check_sysemu : expected SIGTRAP, got status = %d",
226 status); 206 status);
227 207
228 if(ptrace(PTRACE_GETREGS, pid, 0, regs) < 0) 208 if (ptrace(PTRACE_GETREGS, pid, 0, regs) < 0)
229 fatal_perror("check_sysemu : PTRACE_GETREGS failed"); 209 fatal_perror("check_sysemu : PTRACE_GETREGS failed");
230 if(PT_SYSCALL_NR(regs) != __NR_getpid){ 210 if (PT_SYSCALL_NR(regs) != __NR_getpid) {
231 non_fatal("check_sysemu got system call number %d, " 211 non_fatal("check_sysemu got system call number %d, "
232 "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid); 212 "expected %d...", PT_SYSCALL_NR(regs), __NR_getpid);
233 goto fail; 213 goto fail;
234 } 214 }
235 215
236 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid()); 216 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, os_getpid());
237 if(n < 0){ 217 if (n < 0) {
238 non_fatal("check_sysemu : failed to modify system call " 218 non_fatal("check_sysemu : failed to modify system call "
239 "return"); 219 "return");
240 goto fail; 220 goto fail;
241 } 221 }
242 222
243 if (stop_ptraced_child(pid, stack, 0, 0) < 0) 223 if (stop_ptraced_child(pid, 0, 0) < 0)
244 goto fail_stopped; 224 goto fail_stopped;
245 225
246 sysemu_supported = 1; 226 sysemu_supported = 1;
@@ -248,90 +228,90 @@ static void __init check_sysemu(void)
248 set_using_sysemu(!force_sysemu_disabled); 228 set_using_sysemu(!force_sysemu_disabled);
249 229
250 non_fatal("Checking advanced syscall emulation patch for ptrace..."); 230 non_fatal("Checking advanced syscall emulation patch for ptrace...");
251 pid = start_ptraced_child(&stack); 231 pid = start_ptraced_child();
252 232
253 if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, 233 if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
254 (void *) PTRACE_O_TRACESYSGOOD) < 0)) 234 (void *) PTRACE_O_TRACESYSGOOD) < 0))
255 fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed"); 235 fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
256 236
257 while(1){ 237 while (1) {
258 count++; 238 count++;
259 if(ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0) 239 if (ptrace(PTRACE_SYSEMU_SINGLESTEP, pid, 0, 0) < 0)
260 goto fail; 240 goto fail;
261 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 241 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
262 if(n < 0) 242 if (n < 0)
263 fatal_perror("check_ptrace : wait failed"); 243 fatal_perror("check_ptrace : wait failed");
264 244
265 if(WIFSTOPPED(status) && (WSTOPSIG(status) == (SIGTRAP|0x80))){ 245 if (WIFSTOPPED(status) &&
246 (WSTOPSIG(status) == (SIGTRAP|0x80))) {
266 if (!count) 247 if (!count)
267 fatal("check_ptrace : SYSEMU_SINGLESTEP " 248 fatal("check_ptrace : SYSEMU_SINGLESTEP "
268 "doesn't singlestep"); 249 "doesn't singlestep");
269 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET, 250 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_RET_OFFSET,
270 os_getpid()); 251 os_getpid());
271 if(n < 0) 252 if (n < 0)
272 fatal_perror("check_sysemu : failed to modify " 253 fatal_perror("check_sysemu : failed to modify "
273 "system call return"); 254 "system call return");
274 break; 255 break;
275 } 256 }
276 else if(WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP)) 257 else if (WIFSTOPPED(status) && (WSTOPSIG(status) == SIGTRAP))
277 count++; 258 count++;
278 else 259 else
279 fatal("check_ptrace : expected SIGTRAP or " 260 fatal("check_ptrace : expected SIGTRAP or "
280 "(SIGTRAP | 0x80), got status = %d", status); 261 "(SIGTRAP | 0x80), got status = %d", status);
281 } 262 }
282 if (stop_ptraced_child(pid, stack, 0, 0) < 0) 263 if (stop_ptraced_child(pid, 0, 0) < 0)
283 goto fail_stopped; 264 goto fail_stopped;
284 265
285 sysemu_supported = 2; 266 sysemu_supported = 2;
286 non_fatal("OK\n"); 267 non_fatal("OK\n");
287 268
288 if ( !force_sysemu_disabled ) 269 if (!force_sysemu_disabled)
289 set_using_sysemu(sysemu_supported); 270 set_using_sysemu(sysemu_supported);
290 return; 271 return;
291 272
292fail: 273fail:
293 stop_ptraced_child(pid, stack, 1, 0); 274 stop_ptraced_child(pid, 1, 0);
294fail_stopped: 275fail_stopped:
295 non_fatal("missing\n"); 276 non_fatal("missing\n");
296} 277}
297 278
298static void __init check_ptrace(void) 279static void __init check_ptrace(void)
299{ 280{
300 void *stack;
301 int pid, syscall, n, status; 281 int pid, syscall, n, status;
302 282
303 non_fatal("Checking that ptrace can change system call numbers..."); 283 non_fatal("Checking that ptrace can change system call numbers...");
304 pid = start_ptraced_child(&stack); 284 pid = start_ptraced_child();
305 285
306 if((ptrace(PTRACE_OLDSETOPTIONS, pid, 0, 286 if ((ptrace(PTRACE_OLDSETOPTIONS, pid, 0,
307 (void *) PTRACE_O_TRACESYSGOOD) < 0)) 287 (void *) PTRACE_O_TRACESYSGOOD) < 0))
308 fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed"); 288 fatal_perror("check_ptrace: PTRACE_OLDSETOPTIONS failed");
309 289
310 while(1){ 290 while (1) {
311 if(ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0) 291 if (ptrace(PTRACE_SYSCALL, pid, 0, 0) < 0)
312 fatal_perror("check_ptrace : ptrace failed"); 292 fatal_perror("check_ptrace : ptrace failed");
313 293
314 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED)); 294 CATCH_EINTR(n = waitpid(pid, &status, WUNTRACED));
315 if(n < 0) 295 if (n < 0)
316 fatal_perror("check_ptrace : wait failed"); 296 fatal_perror("check_ptrace : wait failed");
317 297
318 if(!WIFSTOPPED(status) || 298 if (!WIFSTOPPED(status) ||
319 (WSTOPSIG(status) != (SIGTRAP | 0x80))) 299 (WSTOPSIG(status) != (SIGTRAP | 0x80)))
320 fatal("check_ptrace : expected (SIGTRAP|0x80), " 300 fatal("check_ptrace : expected (SIGTRAP|0x80), "
321 "got status = %d", status); 301 "got status = %d", status);
322 302
323 syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET, 303 syscall = ptrace(PTRACE_PEEKUSR, pid, PT_SYSCALL_NR_OFFSET,
324 0); 304 0);
325 if(syscall == __NR_getpid){ 305 if (syscall == __NR_getpid) {
326 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET, 306 n = ptrace(PTRACE_POKEUSR, pid, PT_SYSCALL_NR_OFFSET,
327 __NR_getppid); 307 __NR_getppid);
328 if(n < 0) 308 if (n < 0)
329 fatal_perror("check_ptrace : failed to modify " 309 fatal_perror("check_ptrace : failed to modify "
330 "system call"); 310 "system call");
331 break; 311 break;
332 } 312 }
333 } 313 }
334 stop_ptraced_child(pid, stack, 0, 1); 314 stop_ptraced_child(pid, 0, 1);
335 non_fatal("OK\n"); 315 non_fatal("OK\n");
336 check_sysemu(); 316 check_sysemu();
337} 317}
@@ -343,18 +323,18 @@ static void __init check_coredump_limit(void)
343 struct rlimit lim; 323 struct rlimit lim;
344 int err = getrlimit(RLIMIT_CORE, &lim); 324 int err = getrlimit(RLIMIT_CORE, &lim);
345 325
346 if(err){ 326 if (err) {
347 perror("Getting core dump limit"); 327 perror("Getting core dump limit");
348 return; 328 return;
349 } 329 }
350 330
351 printf("Core dump limits :\n\tsoft - "); 331 printf("Core dump limits :\n\tsoft - ");
352 if(lim.rlim_cur == RLIM_INFINITY) 332 if (lim.rlim_cur == RLIM_INFINITY)
353 printf("NONE\n"); 333 printf("NONE\n");
354 else printf("%lu\n", lim.rlim_cur); 334 else printf("%lu\n", lim.rlim_cur);
355 335
356 printf("\thard - "); 336 printf("\thard - ");
357 if(lim.rlim_max == RLIM_INFINITY) 337 if (lim.rlim_max == RLIM_INFINITY)
358 printf("NONE\n"); 338 printf("NONE\n");
359 else printf("%lu\n", lim.rlim_max); 339 else printf("%lu\n", lim.rlim_max);
360} 340}
@@ -408,20 +388,18 @@ __uml_setup("noptraceldt", noptraceldt_cmd_param,
408" To support PTRACE_LDT, the host needs to be patched using\n" 388" To support PTRACE_LDT, the host needs to be patched using\n"
409" the current skas3 patch.\n\n"); 389" the current skas3 patch.\n\n");
410 390
411#ifdef UML_CONFIG_MODE_SKAS
412static inline void check_skas3_ptrace_faultinfo(void) 391static inline void check_skas3_ptrace_faultinfo(void)
413{ 392{
414 struct ptrace_faultinfo fi; 393 struct ptrace_faultinfo fi;
415 void *stack;
416 int pid, n; 394 int pid, n;
417 395
418 non_fatal(" - PTRACE_FAULTINFO..."); 396 non_fatal(" - PTRACE_FAULTINFO...");
419 pid = start_ptraced_child(&stack); 397 pid = start_ptraced_child();
420 398
421 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi); 399 n = ptrace(PTRACE_FAULTINFO, pid, 0, &fi);
422 if (n < 0) { 400 if (n < 0) {
423 ptrace_faultinfo = 0; 401 ptrace_faultinfo = 0;
424 if(errno == EIO) 402 if (errno == EIO)
425 non_fatal("not found\n"); 403 non_fatal("not found\n");
426 else 404 else
427 perror("not found"); 405 perror("not found");
@@ -434,13 +412,12 @@ static inline void check_skas3_ptrace_faultinfo(void)
434 } 412 }
435 413
436 init_registers(pid); 414 init_registers(pid);
437 stop_ptraced_child(pid, stack, 1, 1); 415 stop_ptraced_child(pid, 1, 1);
438} 416}
439 417
440static inline void check_skas3_ptrace_ldt(void) 418static inline void check_skas3_ptrace_ldt(void)
441{ 419{
442#ifdef PTRACE_LDT 420#ifdef PTRACE_LDT
443 void *stack;
444 int pid, n; 421 int pid, n;
445 unsigned char ldtbuf[40]; 422 unsigned char ldtbuf[40];
446 struct ptrace_ldt ldt_op = (struct ptrace_ldt) { 423 struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
@@ -449,11 +426,11 @@ static inline void check_skas3_ptrace_ldt(void)
449 .bytecount = sizeof(ldtbuf)}; 426 .bytecount = sizeof(ldtbuf)};
450 427
451 non_fatal(" - PTRACE_LDT..."); 428 non_fatal(" - PTRACE_LDT...");
452 pid = start_ptraced_child(&stack); 429 pid = start_ptraced_child();
453 430
454 n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op); 431 n = ptrace(PTRACE_LDT, pid, 0, (unsigned long) &ldt_op);
455 if (n < 0) { 432 if (n < 0) {
456 if(errno == EIO) 433 if (errno == EIO)
457 non_fatal("not found\n"); 434 non_fatal("not found\n");
458 else { 435 else {
459 perror("not found"); 436 perror("not found");
@@ -461,13 +438,13 @@ static inline void check_skas3_ptrace_ldt(void)
461 ptrace_ldt = 0; 438 ptrace_ldt = 0;
462 } 439 }
463 else { 440 else {
464 if(ptrace_ldt) 441 if (ptrace_ldt)
465 non_fatal("found\n"); 442 non_fatal("found\n");
466 else 443 else
467 non_fatal("found, but use is disabled\n"); 444 non_fatal("found, but use is disabled\n");
468 } 445 }
469 446
470 stop_ptraced_child(pid, stack, 1, 1); 447 stop_ptraced_child(pid, 1, 1);
471#else 448#else
472 /* PTRACE_LDT might be disabled via cmdline option. 449 /* PTRACE_LDT might be disabled via cmdline option.
473 * We want to override this, else we might use the stub 450 * We want to override this, else we might use the stub
@@ -484,12 +461,9 @@ static inline void check_skas3_proc_mm(void)
484 proc_mm = 0; 461 proc_mm = 0;
485 perror("not found"); 462 perror("not found");
486 } 463 }
487 else { 464 else if (!proc_mm)
488 if (!proc_mm) 465 non_fatal("found but disabled on command line\n");
489 non_fatal("found but disabled on command line\n"); 466 else non_fatal("found\n");
490 else
491 non_fatal("found\n");
492 }
493} 467}
494 468
495int can_do_skas(void) 469int can_do_skas(void)
@@ -500,17 +474,11 @@ int can_do_skas(void)
500 check_skas3_ptrace_faultinfo(); 474 check_skas3_ptrace_faultinfo();
501 check_skas3_ptrace_ldt(); 475 check_skas3_ptrace_ldt();
502 476
503 if(!proc_mm || !ptrace_faultinfo || !ptrace_ldt) 477 if (!proc_mm || !ptrace_faultinfo || !ptrace_ldt)
504 skas_needs_stub = 1; 478 skas_needs_stub = 1;
505 479
506 return 1; 480 return 1;
507} 481}
508#else
509int can_do_skas(void)
510{
511 return 0;
512}
513#endif
514 482
515int __init parse_iomem(char *str, int *add) 483int __init parse_iomem(char *str, int *add)
516{ 484{
@@ -521,25 +489,25 @@ int __init parse_iomem(char *str, int *add)
521 489
522 driver = str; 490 driver = str;
523 file = strchr(str,','); 491 file = strchr(str,',');
524 if(file == NULL){ 492 if (file == NULL) {
525 printf("parse_iomem : failed to parse iomem\n"); 493 printf("parse_iomem : failed to parse iomem\n");
526 goto out; 494 goto out;
527 } 495 }
528 *file = '\0'; 496 *file = '\0';
529 file++; 497 file++;
530 fd = open(file, O_RDWR, 0); 498 fd = open(file, O_RDWR, 0);
531 if(fd < 0){ 499 if (fd < 0) {
532 os_print_error(fd, "parse_iomem - Couldn't open io file"); 500 perror("parse_iomem - Couldn't open io file");
533 goto out; 501 goto out;
534 } 502 }
535 503
536 if(fstat64(fd, &buf) < 0){ 504 if (fstat64(fd, &buf) < 0) {
537 perror("parse_iomem - cannot stat_fd file"); 505 perror("parse_iomem - cannot stat_fd file");
538 goto out_close; 506 goto out_close;
539 } 507 }
540 508
541 new = malloc(sizeof(*new)); 509 new = malloc(sizeof(*new));
542 if(new == NULL){ 510 if (new == NULL) {
543 perror("Couldn't allocate iomem_region struct"); 511 perror("Couldn't allocate iomem_region struct");
544 goto out_close; 512 goto out_close;
545 } 513 }
diff --git a/arch/um/os-Linux/sys-i386/Makefile b/arch/um/os-Linux/sys-i386/Makefile
index 37806621b25d..a841262c594a 100644
--- a/arch/um/os-Linux/sys-i386/Makefile
+++ b/arch/um/os-Linux/sys-i386/Makefile
@@ -1,9 +1,9 @@
1# 1#
2# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-$(CONFIG_MODE_SKAS) = registers.o signal.o tls.o 6obj-y = registers.o signal.o tls.o
7 7
8USER_OBJS := $(obj-y) 8USER_OBJS := $(obj-y)
9 9
diff --git a/arch/um/os-Linux/sys-i386/registers.c b/arch/um/os-Linux/sys-i386/registers.c
index 84b44f9cd42a..d1997ca76e5c 100644
--- a/arch/um/os-Linux/sys-i386/registers.c
+++ b/arch/um/os-Linux/sys-i386/registers.c
@@ -1,144 +1,73 @@
1/* 1/*
2 * Copyright (C) 2004 PathScale, Inc 2 * Copyright (C) 2004 PathScale, Inc
3 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 4 * Licensed under the GPL
4 */ 5 */
5 6
6#include <errno.h> 7#include <errno.h>
7#include <string.h> 8#include "kern_constants.h"
8#include "sysdep/ptrace_user.h"
9#include "sysdep/ptrace.h"
10#include "uml-config.h"
11#include "skas_ptregs.h"
12#include "registers.h"
13#include "longjmp.h" 9#include "longjmp.h"
14#include "user.h" 10#include "user.h"
11#include "sysdep/ptrace_user.h"
15 12
16/* These are set once at boot time and not changed thereafter */
17
18static unsigned long exec_regs[MAX_REG_NR];
19static unsigned long exec_fp_regs[HOST_FP_SIZE];
20static unsigned long exec_fpx_regs[HOST_XFP_SIZE];
21static int have_fpx_regs = 1;
22
23void init_thread_registers(union uml_pt_regs *to)
24{
25 memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
26 memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp));
27 if(have_fpx_regs)
28 memcpy(to->skas.xfp, exec_fpx_regs, sizeof(to->skas.xfp));
29}
30
31/* XXX These need to use [GS]ETFPXREGS and copy_sc_{to,from}_user_skas needs
32 * to pass in a sufficiently large buffer
33 */
34int save_fp_registers(int pid, unsigned long *fp_regs) 13int save_fp_registers(int pid, unsigned long *fp_regs)
35{ 14{
36 if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) 15 if (ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
37 return -errno; 16 return -errno;
38 return 0; 17 return 0;
39} 18}
40 19
41int restore_fp_registers(int pid, unsigned long *fp_regs) 20int restore_fp_registers(int pid, unsigned long *fp_regs)
42{ 21{
43 if(ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0) 22 if (ptrace(PTRACE_SETFPREGS, pid, 0, fp_regs) < 0)
44 return -errno; 23 return -errno;
45 return 0; 24 return 0;
46} 25}
47 26
48static int move_registers(int pid, int int_op, union uml_pt_regs *regs, 27int save_fpx_registers(int pid, unsigned long *fp_regs)
49 int fp_op, unsigned long *fp_regs)
50{ 28{
51 if(ptrace(int_op, pid, 0, regs->skas.regs) < 0) 29 if (ptrace(PTRACE_GETFPXREGS, pid, 0, fp_regs) < 0)
52 return -errno;
53
54 if(ptrace(fp_op, pid, 0, fp_regs) < 0)
55 return -errno; 30 return -errno;
56
57 return 0; 31 return 0;
58} 32}
59 33
60void save_registers(int pid, union uml_pt_regs *regs) 34int restore_fpx_registers(int pid, unsigned long *fp_regs)
61{ 35{
62 unsigned long *fp_regs; 36 if (ptrace(PTRACE_SETFPXREGS, pid, 0, fp_regs) < 0)
63 int err, fp_op; 37 return -errno;
64 38 return 0;
65 if(have_fpx_regs){
66 fp_op = PTRACE_GETFPXREGS;
67 fp_regs = regs->skas.xfp;
68 }
69 else {
70 fp_op = PTRACE_GETFPREGS;
71 fp_regs = regs->skas.fp;
72 }
73
74 err = move_registers(pid, PTRACE_GETREGS, regs, fp_op, fp_regs);
75 if(err)
76 panic("save_registers - saving registers failed, errno = %d\n",
77 -err);
78} 39}
79 40
80void restore_registers(int pid, union uml_pt_regs *regs) 41unsigned long get_thread_reg(int reg, jmp_buf *buf)
81{ 42{
82 unsigned long *fp_regs; 43 switch (reg) {
83 int err, fp_op; 44 case EIP:
84 45 return buf[0]->__eip;
85 if(have_fpx_regs){ 46 case UESP:
86 fp_op = PTRACE_SETFPXREGS; 47 return buf[0]->__esp;
87 fp_regs = regs->skas.xfp; 48 case EBP:
88 } 49 return buf[0]->__ebp;
89 else { 50 default:
90 fp_op = PTRACE_SETFPREGS; 51 printk(UM_KERN_ERR "get_thread_regs - unknown register %d\n",
91 fp_regs = regs->skas.fp; 52 reg);
53 return 0;
92 } 54 }
93
94 err = move_registers(pid, PTRACE_SETREGS, regs, fp_op, fp_regs);
95 if(err)
96 panic("restore_registers - saving registers failed, "
97 "errno = %d\n", -err);
98} 55}
99 56
100void init_registers(int pid) 57int have_fpx_regs = 1;
58
59void arch_init_registers(int pid)
101{ 60{
61 unsigned long fpx_regs[HOST_XFP_SIZE];
102 int err; 62 int err;
103 63
104 memset(exec_regs, 0, sizeof(exec_regs)); 64 err = ptrace(PTRACE_GETFPXREGS, pid, 0, fpx_regs);
105 err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
106 if(err)
107 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
108 errno);
109
110 errno = 0;
111 err = ptrace(PTRACE_GETFPXREGS, pid, 0, exec_fpx_regs);
112 if(!err) 65 if(!err)
113 return; 66 return;
67
114 if(errno != EIO) 68 if(errno != EIO)
115 panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d", 69 panic("check_ptrace : PTRACE_GETFPXREGS failed, errno = %d",
116 errno); 70 errno);
117 71
118 have_fpx_regs = 0; 72 have_fpx_regs = 0;
119
120 err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
121 if(err)
122 panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
123 errno);
124}
125
126void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
127{
128 memcpy(regs, exec_regs, sizeof(exec_regs));
129 if(fp_regs != NULL)
130 memcpy(fp_regs, exec_fp_regs,
131 HOST_FP_SIZE * sizeof(unsigned long));
132}
133
134unsigned long get_thread_reg(int reg, jmp_buf *buf)
135{
136 switch(reg){
137 case EIP: return buf[0]->__eip;
138 case UESP: return buf[0]->__esp;
139 case EBP: return buf[0]->__ebp;
140 default:
141 printk("get_thread_regs - unknown register %d\n", reg);
142 return 0;
143 }
144} 73}
diff --git a/arch/um/os-Linux/sys-x86_64/Makefile b/arch/um/os-Linux/sys-x86_64/Makefile
index 7955e061a678..a42a4ef02e1e 100644
--- a/arch/um/os-Linux/sys-x86_64/Makefile
+++ b/arch/um/os-Linux/sys-x86_64/Makefile
@@ -1,9 +1,9 @@
1# 1#
2# Copyright (C) 2000 Jeff Dike (jdike@karaya.com) 2# Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3# Licensed under the GPL 3# Licensed under the GPL
4# 4#
5 5
6obj-$(CONFIG_MODE_SKAS) = registers.o prctl.o signal.o 6obj-y = registers.o prctl.o signal.o
7 7
8USER_OBJS := $(obj-y) 8USER_OBJS := $(obj-y)
9 9
diff --git a/arch/um/os-Linux/sys-x86_64/registers.c b/arch/um/os-Linux/sys-x86_64/registers.c
index 9467315b8059..9bfa789992de 100644
--- a/arch/um/os-Linux/sys-x86_64/registers.c
+++ b/arch/um/os-Linux/sys-x86_64/registers.c
@@ -1,23 +1,15 @@
1/* 1/*
2 * Copyright (C) 2004 PathScale, Inc 2 * Copyright (C) 2006-2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <errno.h> 6#include <errno.h>
7#include <sys/ptrace.h> 7#include <sys/ptrace.h>
8#include <string.h> 8#define __FRAME_OFFSETS
9#include "ptrace_user.h" 9#include <asm/ptrace.h>
10#include "uml-config.h"
11#include "skas_ptregs.h"
12#include "registers.h"
13#include "longjmp.h" 10#include "longjmp.h"
14#include "user.h" 11#include "user.h"
15 12
16/* These are set once at boot time and not changed thereafter */
17
18static unsigned long exec_regs[MAX_REG_NR];
19static unsigned long exec_fp_regs[HOST_FP_SIZE];
20
21int save_fp_registers(int pid, unsigned long *fp_regs) 13int save_fp_registers(int pid, unsigned long *fp_regs)
22{ 14{
23 if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0) 15 if(ptrace(PTRACE_GETFPREGS, pid, 0, fp_regs) < 0)
@@ -32,67 +24,6 @@ int restore_fp_registers(int pid, unsigned long *fp_regs)
32 return 0; 24 return 0;
33} 25}
34 26
35void init_thread_registers(union uml_pt_regs *to)
36{
37 memcpy(to->skas.regs, exec_regs, sizeof(to->skas.regs));
38 memcpy(to->skas.fp, exec_fp_regs, sizeof(to->skas.fp));
39}
40
41static int move_registers(int pid, int int_op, int fp_op,
42 union uml_pt_regs *regs)
43{
44 if(ptrace(int_op, pid, 0, regs->skas.regs) < 0)
45 return -errno;
46
47 if(ptrace(fp_op, pid, 0, regs->skas.fp) < 0)
48 return -errno;
49
50 return 0;
51}
52
53void save_registers(int pid, union uml_pt_regs *regs)
54{
55 int err;
56
57 err = move_registers(pid, PTRACE_GETREGS, PTRACE_GETFPREGS, regs);
58 if(err)
59 panic("save_registers - saving registers failed, errno = %d\n",
60 -err);
61}
62
63void restore_registers(int pid, union uml_pt_regs *regs)
64{
65 int err;
66
67 err = move_registers(pid, PTRACE_SETREGS, PTRACE_SETFPREGS, regs);
68 if(err)
69 panic("restore_registers - saving registers failed, "
70 "errno = %d\n", -err);
71}
72
73void init_registers(int pid)
74{
75 int err;
76
77 err = ptrace(PTRACE_GETREGS, pid, 0, exec_regs);
78 if(err)
79 panic("check_ptrace : PTRACE_GETREGS failed, errno = %d",
80 errno);
81
82 err = ptrace(PTRACE_GETFPREGS, pid, 0, exec_fp_regs);
83 if(err)
84 panic("check_ptrace : PTRACE_GETFPREGS failed, errno = %d",
85 errno);
86}
87
88void get_safe_registers(unsigned long *regs, unsigned long *fp_regs)
89{
90 memcpy(regs, exec_regs, sizeof(exec_regs));
91 if(fp_regs != NULL)
92 memcpy(fp_regs, exec_fp_regs,
93 HOST_FP_SIZE * sizeof(unsigned long));
94}
95
96unsigned long get_thread_reg(int reg, jmp_buf *buf) 27unsigned long get_thread_reg(int reg, jmp_buf *buf)
97{ 28{
98 switch(reg){ 29 switch(reg){
diff --git a/arch/um/os-Linux/time.c b/arch/um/os-Linux/time.c
index 5de169b168f6..e34e1effe0f5 100644
--- a/arch/um/os-Linux/time.c
+++ b/arch/um/os-Linux/time.c
@@ -1,101 +1,86 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h> 6#include <stddef.h>
7#include <stdlib.h> 7#include <errno.h>
8#include <unistd.h> 8#include <signal.h>
9#include <time.h> 9#include <time.h>
10#include <sys/time.h> 10#include <sys/time.h>
11#include <signal.h>
12#include <errno.h>
13#include "kern_util.h"
14#include "user.h"
15#include "process.h"
16#include "kern_constants.h" 11#include "kern_constants.h"
17#include "os.h" 12#include "os.h"
18#include "uml-config.h" 13#include "user.h"
19 14
20int set_interval(int is_virtual) 15int set_interval(void)
21{ 16{
22 int usec = 1000000/hz(); 17 int usec = UM_USEC_PER_SEC / UM_HZ;
23 int timer_type = is_virtual ? ITIMER_VIRTUAL : ITIMER_REAL;
24 struct itimerval interval = ((struct itimerval) { { 0, usec }, 18 struct itimerval interval = ((struct itimerval) { { 0, usec },
25 { 0, usec } }); 19 { 0, usec } });
26 20
27 if(setitimer(timer_type, &interval, NULL) == -1) 21 if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1)
28 return -errno; 22 return -errno;
29 23
30 return 0; 24 return 0;
31} 25}
32 26
33#ifdef UML_CONFIG_MODE_TT 27int timer_one_shot(int ticks)
34void enable_timer(void)
35{ 28{
36 set_interval(1); 29 unsigned long usec = ticks * UM_USEC_PER_SEC / UM_HZ;
37} 30 unsigned long sec = usec / UM_USEC_PER_SEC;
38#endif 31 struct itimerval interval;
39 32
40void disable_timer(void) 33 usec %= UM_USEC_PER_SEC;
41{ 34 interval = ((struct itimerval) { { 0, 0 }, { sec, usec } });
42 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); 35
43 if((setitimer(ITIMER_VIRTUAL, &disable, NULL) < 0) || 36 if (setitimer(ITIMER_VIRTUAL, &interval, NULL) == -1)
44 (setitimer(ITIMER_REAL, &disable, NULL) < 0)) 37 return -errno;
45 printk("disnable_timer - setitimer failed, errno = %d\n", 38
46 errno); 39 return 0;
47 /* If there are signals already queued, after unblocking ignore them */
48 signal(SIGALRM, SIG_IGN);
49 signal(SIGVTALRM, SIG_IGN);
50} 40}
51 41
52void switch_timers(int to_real) 42/**
43 * timeval_to_ns - Convert timeval to nanoseconds
44 * @ts: pointer to the timeval variable to be converted
45 *
46 * Returns the scalar nanosecond representation of the timeval
47 * parameter.
48 *
49 * Ripped from linux/time.h because it's a kernel header, and thus
50 * unusable from here.
51 */
52static inline long long timeval_to_ns(const struct timeval *tv)
53{ 53{
54 struct itimerval disable = ((struct itimerval) { { 0, 0 }, { 0, 0 }}); 54 return ((long long) tv->tv_sec * UM_NSEC_PER_SEC) +
55 struct itimerval enable = ((struct itimerval) { { 0, 1000000/hz() }, 55 tv->tv_usec * UM_NSEC_PER_USEC;
56 { 0, 1000000/hz() }});
57 int old, new;
58
59 if(to_real){
60 old = ITIMER_VIRTUAL;
61 new = ITIMER_REAL;
62 }
63 else {
64 old = ITIMER_REAL;
65 new = ITIMER_VIRTUAL;
66 }
67
68 if((setitimer(old, &disable, NULL) < 0) ||
69 (setitimer(new, &enable, NULL)))
70 printk("switch_timers - setitimer failed, errno = %d\n",
71 errno);
72} 56}
73 57
74#ifdef UML_CONFIG_MODE_TT 58long long disable_timer(void)
75void uml_idle_timer(void)
76{ 59{
77 if(signal(SIGVTALRM, SIG_IGN) == SIG_ERR) 60 struct itimerval time = ((struct itimerval) { { 0, 0 }, { 0, 0 } });
78 panic("Couldn't unset SIGVTALRM handler"); 61
62 if(setitimer(ITIMER_VIRTUAL, &time, &time) < 0)
63 printk(UM_KERN_ERR "disable_timer - setitimer failed, "
64 "errno = %d\n", errno);
79 65
80 set_handler(SIGALRM, (__sighandler_t) alarm_handler, 66 return timeval_to_ns(&time.it_value);
81 SA_RESTART, SIGUSR1, SIGIO, SIGWINCH, SIGVTALRM, -1);
82 set_interval(0);
83} 67}
84#endif
85 68
86unsigned long long os_nsecs(void) 69long long os_nsecs(void)
87{ 70{
88 struct timeval tv; 71 struct timeval tv;
89 72
90 gettimeofday(&tv, NULL); 73 gettimeofday(&tv, NULL);
91 return((unsigned long long) tv.tv_sec * BILLION + tv.tv_usec * 1000); 74 return timeval_to_ns(&tv);
92} 75}
93 76
94void idle_sleep(int secs) 77extern void alarm_handler(int sig, struct sigcontext *sc);
78
79void idle_sleep(unsigned long long nsecs)
95{ 80{
96 struct timespec ts; 81 struct timespec ts = { .tv_sec = nsecs / UM_NSEC_PER_SEC,
82 .tv_nsec = nsecs % UM_NSEC_PER_SEC };
97 83
98 ts.tv_sec = secs; 84 if (nanosleep(&ts, &ts) == 0)
99 ts.tv_nsec = 0; 85 alarm_handler(SIGVTALRM, NULL);
100 nanosleep(&ts, NULL);
101} 86}
diff --git a/arch/um/os-Linux/tls.c b/arch/um/os-Linux/tls.c
index 16215b990804..73277801ef14 100644
--- a/arch/um/os-Linux/tls.c
+++ b/arch/um/os-Linux/tls.c
@@ -1,18 +1,9 @@
1#include <errno.h> 1#include <errno.h>
2#include <unistd.h>
3#include <sys/ptrace.h> 2#include <sys/ptrace.h>
4#include <sys/syscall.h>
5#include <asm/ldt.h>
6#include "sysdep/tls.h" 3#include "sysdep/tls.h"
7#include "uml-config.h"
8 4
9/* TLS support - we basically rely on the host's one.*/ 5/* TLS support - we basically rely on the host's one.*/
10 6
11/* In TT mode, this should be called only by the tracing thread, and makes sense
12 * only for PTRACE_SET_THREAD_AREA. In SKAS mode, it's used normally.
13 *
14 */
15
16#ifndef PTRACE_GET_THREAD_AREA 7#ifndef PTRACE_GET_THREAD_AREA
17#define PTRACE_GET_THREAD_AREA 25 8#define PTRACE_GET_THREAD_AREA 25
18#endif 9#endif
@@ -32,8 +23,6 @@ int os_set_thread_area(user_desc_t *info, int pid)
32 return ret; 23 return ret;
33} 24}
34 25
35#ifdef UML_CONFIG_MODE_SKAS
36
37int os_get_thread_area(user_desc_t *info, int pid) 26int os_get_thread_area(user_desc_t *info, int pid)
38{ 27{
39 int ret; 28 int ret;
@@ -44,32 +33,3 @@ int os_get_thread_area(user_desc_t *info, int pid)
44 ret = -errno; 33 ret = -errno;
45 return ret; 34 return ret;
46} 35}
47
48#endif
49
50#ifdef UML_CONFIG_MODE_TT
51#include "linux/unistd.h"
52
53int do_set_thread_area_tt(user_desc_t *info)
54{
55 int ret;
56
57 ret = syscall(__NR_set_thread_area,info);
58 if (ret < 0) {
59 ret = -errno;
60 }
61 return ret;
62}
63
64int do_get_thread_area_tt(user_desc_t *info)
65{
66 int ret;
67
68 ret = syscall(__NR_get_thread_area,info);
69 if (ret < 0) {
70 ret = -errno;
71 }
72 return ret;
73}
74
75#endif /* UML_CONFIG_MODE_TT */
diff --git a/arch/um/os-Linux/trap.c b/arch/um/os-Linux/trap.c
index 295da657931a..2a1c9843e32e 100644
--- a/arch/um/os-Linux/trap.c
+++ b/arch/um/os-Linux/trap.c
@@ -1,22 +1,14 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdlib.h>
7#include <signal.h> 6#include <signal.h>
8#include "kern_util.h"
9#include "os.h" 7#include "os.h"
10#include "mode.h" 8#include "sysdep/ptrace.h"
11#include "longjmp.h"
12
13void usr2_handler(int sig, union uml_pt_regs *regs)
14{
15 CHOOSE_MODE(syscall_handler_tt(sig, regs), (void) 0);
16}
17 9
18/* Initialized from linux_main() */ 10/* Initialized from linux_main() */
19void (*sig_info[NSIG])(int, union uml_pt_regs *); 11void (*sig_info[NSIG])(int, struct uml_pt_regs *);
20 12
21void os_fill_handlinfo(struct kern_handlers h) 13void os_fill_handlinfo(struct kern_handlers h)
22{ 14{
@@ -28,13 +20,4 @@ void os_fill_handlinfo(struct kern_handlers h)
28 sig_info[SIGSEGV] = h.page_fault; 20 sig_info[SIGSEGV] = h.page_fault;
29 sig_info[SIGIO] = h.sigio_handler; 21 sig_info[SIGIO] = h.sigio_handler;
30 sig_info[SIGVTALRM] = h.timer_handler; 22 sig_info[SIGVTALRM] = h.timer_handler;
31 sig_info[SIGALRM] = h.timer_handler;
32 sig_info[SIGUSR2] = usr2_handler;
33}
34
35void do_longjmp(void *b, int val)
36{
37 jmp_buf *buf = b;
38
39 UML_LONGJMP(buf, val);
40} 23}
diff --git a/arch/um/os-Linux/tt.c b/arch/um/os-Linux/tt.c
deleted file mode 100644
index bcf9359c4e9f..000000000000
--- a/arch/um/os-Linux/tt.c
+++ /dev/null
@@ -1,196 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stdio.h>
7#include <unistd.h>
8#include <signal.h>
9#include <sched.h>
10#include <errno.h>
11#include <stdarg.h>
12#include <stdlib.h>
13#include <sys/time.h>
14#include <sys/ptrace.h>
15#include <linux/ptrace.h>
16#include <sys/wait.h>
17#include <sys/mman.h>
18#include <asm/ptrace.h>
19#include <asm/unistd.h>
20#include <asm/page.h>
21#include "kern_util.h"
22#include "user.h"
23#include "signal_kern.h"
24#include "sysdep/ptrace.h"
25#include "sysdep/sigcontext.h"
26#include "irq_user.h"
27#include "ptrace_user.h"
28#include "init.h"
29#include "os.h"
30#include "uml-config.h"
31#include "choose-mode.h"
32#include "mode.h"
33#include "tempfile.h"
34#include "kern_constants.h"
35
36int protect_memory(unsigned long addr, unsigned long len, int r, int w, int x,
37 int must_succeed)
38{
39 int err;
40
41 err = os_protect_memory((void *) addr, len, r, w, x);
42 if(err < 0){
43 if(must_succeed)
44 panic("protect failed, err = %d", -err);
45 else return(err);
46 }
47 return(0);
48}
49
50void kill_child_dead(int pid)
51{
52 kill(pid, SIGKILL);
53 kill(pid, SIGCONT);
54 do {
55 int n;
56 CATCH_EINTR(n = waitpid(pid, NULL, 0));
57 if (n > 0)
58 kill(pid, SIGCONT);
59 else
60 break;
61 } while(1);
62}
63
64void stop(void)
65{
66 while(1) sleep(1000000);
67}
68
69int wait_for_stop(int pid, int sig, int cont_type, void *relay)
70{
71 sigset_t *relay_signals = relay;
72 int status, ret;
73
74 while(1){
75 CATCH_EINTR(ret = waitpid(pid, &status, WUNTRACED));
76 if((ret < 0) ||
77 !WIFSTOPPED(status) || (WSTOPSIG(status) != sig)){
78 if(ret < 0){
79 printk("wait failed, errno = %d\n",
80 errno);
81 }
82 else if(WIFEXITED(status))
83 printk("process %d exited with status %d\n",
84 pid, WEXITSTATUS(status));
85 else if(WIFSIGNALED(status))
86 printk("process %d exited with signal %d\n",
87 pid, WTERMSIG(status));
88 else if((WSTOPSIG(status) == SIGVTALRM) ||
89 (WSTOPSIG(status) == SIGALRM) ||
90 (WSTOPSIG(status) == SIGIO) ||
91 (WSTOPSIG(status) == SIGPROF) ||
92 (WSTOPSIG(status) == SIGCHLD) ||
93 (WSTOPSIG(status) == SIGWINCH) ||
94 (WSTOPSIG(status) == SIGINT)){
95 ptrace(cont_type, pid, 0, WSTOPSIG(status));
96 continue;
97 }
98 else if((relay_signals != NULL) &&
99 sigismember(relay_signals, WSTOPSIG(status))){
100 ptrace(cont_type, pid, 0, WSTOPSIG(status));
101 continue;
102 }
103 else printk("process %d stopped with signal %d\n",
104 pid, WSTOPSIG(status));
105 panic("wait_for_stop failed to wait for %d to stop "
106 "with %d\n", pid, sig);
107 }
108 return(status);
109 }
110}
111
112void forward_ipi(int fd, int pid)
113{
114 int err;
115
116 err = os_set_owner(fd, pid);
117 if(err < 0)
118 printk("forward_ipi: set_owner failed, fd = %d, me = %d, "
119 "target = %d, err = %d\n", fd, os_getpid(), pid, -err);
120}
121
122/*
123 *-------------------------
124 * only for tt mode (will be deleted in future...)
125 *-------------------------
126 */
127
128struct tramp {
129 int (*tramp)(void *);
130 void *tramp_data;
131 unsigned long temp_stack;
132 int flags;
133 int pid;
134};
135
136/* See above for why sigkill is here */
137
138int sigkill = SIGKILL;
139
140int outer_tramp(void *arg)
141{
142 struct tramp *t;
143 int sig = sigkill;
144
145 t = arg;
146 t->pid = clone(t->tramp, (void *) t->temp_stack + UM_KERN_PAGE_SIZE/2,
147 t->flags, t->tramp_data);
148 if(t->pid > 0) wait_for_stop(t->pid, SIGSTOP, PTRACE_CONT, NULL);
149 kill(os_getpid(), sig);
150 _exit(0);
151}
152
153int start_fork_tramp(void *thread_arg, unsigned long temp_stack,
154 int clone_flags, int (*tramp)(void *))
155{
156 struct tramp arg;
157 unsigned long sp;
158 int new_pid, status, err;
159
160 /* The trampoline will run on the temporary stack */
161 sp = stack_sp(temp_stack);
162
163 clone_flags |= CLONE_FILES | SIGCHLD;
164
165 arg.tramp = tramp;
166 arg.tramp_data = thread_arg;
167 arg.temp_stack = temp_stack;
168 arg.flags = clone_flags;
169
170 /* Start the process and wait for it to kill itself */
171 new_pid = clone(outer_tramp, (void *) sp, clone_flags, &arg);
172 if(new_pid < 0)
173 return(new_pid);
174
175 CATCH_EINTR(err = waitpid(new_pid, &status, 0));
176 if(err < 0)
177 panic("Waiting for outer trampoline failed - errno = %d",
178 errno);
179
180 if(!WIFSIGNALED(status) || (WTERMSIG(status) != SIGKILL))
181 panic("outer trampoline didn't exit with SIGKILL, "
182 "status = %d", status);
183
184 return(arg.pid);
185}
186
187void forward_pending_sigio(int target)
188{
189 sigset_t sigs;
190
191 if(sigpending(&sigs))
192 panic("forward_pending_sigio : sigpending failed");
193 if(sigismember(&sigs, SIGIO))
194 kill(target, SIGIO);
195}
196
diff --git a/arch/um/os-Linux/uaccess.c b/arch/um/os-Linux/uaccess.c
index bbb73a650370..8d27b6d1df91 100644
--- a/arch/um/os-Linux/uaccess.c
+++ b/arch/um/os-Linux/uaccess.c
@@ -8,7 +8,7 @@
8#include "longjmp.h" 8#include "longjmp.h"
9 9
10unsigned long __do_user_copy(void *to, const void *from, int n, 10unsigned long __do_user_copy(void *to, const void *from, int n,
11 void **fault_addr, void **fault_catcher, 11 void **fault_addr, jmp_buf **fault_catcher,
12 void (*op)(void *to, const void *from, 12 void (*op)(void *to, const void *from,
13 int n), int *faulted_out) 13 int n), int *faulted_out)
14{ 14{
diff --git a/arch/um/os-Linux/umid.c b/arch/um/os-Linux/umid.c
index b462863f7172..106fa8641553 100644
--- a/arch/um/os-Linux/umid.c
+++ b/arch/um/os-Linux/umid.c
@@ -1,17 +1,21 @@
1/*
2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
1#include <stdio.h> 6#include <stdio.h>
2#include <unistd.h>
3#include <stdlib.h> 7#include <stdlib.h>
4#include <string.h> 8#include <dirent.h>
5#include <errno.h> 9#include <errno.h>
10#include <fcntl.h>
6#include <signal.h> 11#include <signal.h>
7#include <dirent.h> 12#include <string.h>
8#include <sys/fcntl.h> 13#include <unistd.h>
9#include <sys/stat.h> 14#include <sys/stat.h>
10#include <sys/param.h>
11#include "init.h" 15#include "init.h"
16#include "kern_constants.h"
12#include "os.h" 17#include "os.h"
13#include "user.h" 18#include "user.h"
14#include "mode.h"
15 19
16#define UML_DIR "~/.uml/" 20#define UML_DIR "~/.uml/"
17 21
@@ -28,13 +32,13 @@ static int __init make_uml_dir(void)
28 char dir[512] = { '\0' }; 32 char dir[512] = { '\0' };
29 int len, err; 33 int len, err;
30 34
31 if(*uml_dir == '~'){ 35 if (*uml_dir == '~') {
32 char *home = getenv("HOME"); 36 char *home = getenv("HOME");
33 37
34 err = -ENOENT; 38 err = -ENOENT;
35 if(home == NULL){ 39 if (home == NULL) {
36 printk("make_uml_dir : no value in environment for " 40 printk(UM_KERN_ERR "make_uml_dir : no value in "
37 "$HOME\n"); 41 "environment for $HOME\n");
38 goto err; 42 goto err;
39 } 43 }
40 strlcpy(dir, home, sizeof(dir)); 44 strlcpy(dir, home, sizeof(dir));
@@ -53,7 +57,7 @@ static int __init make_uml_dir(void)
53 } 57 }
54 strcpy(uml_dir, dir); 58 strcpy(uml_dir, dir);
55 59
56 if((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)){ 60 if ((mkdir(uml_dir, 0777) < 0) && (errno != EEXIST)) {
57 printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno)); 61 printf("Failed to mkdir '%s': %s\n", uml_dir, strerror(errno));
58 err = -errno; 62 err = -errno;
59 goto err_free; 63 goto err_free;
@@ -70,8 +74,8 @@ err:
70/* 74/*
71 * Unlinks the files contained in @dir and then removes @dir. 75 * Unlinks the files contained in @dir and then removes @dir.
72 * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We 76 * Doesn't handle directory trees, so it's not like rm -rf, but almost such. We
73 * ignore ENOENT errors for anything (they happen, strangely enough - possibly due 77 * ignore ENOENT errors for anything (they happen, strangely enough - possibly
74 * to races between multiple dying UML threads). 78 * due to races between multiple dying UML threads).
75 */ 79 */
76static int remove_files_and_dir(char *dir) 80static int remove_files_and_dir(char *dir)
77{ 81{
@@ -116,7 +120,8 @@ out:
116 return ret; 120 return ret;
117} 121}
118 122
119/* This says that there isn't already a user of the specified directory even if 123/*
124 * This says that there isn't already a user of the specified directory even if
120 * there are errors during the checking. This is because if these errors 125 * there are errors during the checking. This is because if these errors
121 * happen, the directory is unusable by the pre-existing UML, so we might as 126 * happen, the directory is unusable by the pre-existing UML, so we might as
122 * well take it over. This could happen either by 127 * well take it over. This could happen either by
@@ -134,44 +139,45 @@ static inline int is_umdir_used(char *dir)
134 int dead, fd, p, n, err; 139 int dead, fd, p, n, err;
135 140
136 n = snprintf(file, sizeof(file), "%s/pid", dir); 141 n = snprintf(file, sizeof(file), "%s/pid", dir);
137 if(n >= sizeof(file)){ 142 if (n >= sizeof(file)) {
138 printk("is_umdir_used - pid filename too long\n"); 143 printk(UM_KERN_ERR "is_umdir_used - pid filename too long\n");
139 err = -E2BIG; 144 err = -E2BIG;
140 goto out; 145 goto out;
141 } 146 }
142 147
143 dead = 0; 148 dead = 0;
144 fd = open(file, O_RDONLY); 149 fd = open(file, O_RDONLY);
145 if(fd < 0) { 150 if (fd < 0) {
146 fd = -errno; 151 fd = -errno;
147 if(fd != -ENOENT){ 152 if (fd != -ENOENT) {
148 printk("is_umdir_used : couldn't open pid file '%s', " 153 printk(UM_KERN_ERR "is_umdir_used : couldn't open pid "
149 "err = %d\n", file, -fd); 154 "file '%s', err = %d\n", file, -fd);
150 } 155 }
151 goto out; 156 goto out;
152 } 157 }
153 158
154 err = 0; 159 err = 0;
155 n = read(fd, pid, sizeof(pid)); 160 n = read(fd, pid, sizeof(pid));
156 if(n < 0){ 161 if (n < 0) {
157 printk("is_umdir_used : couldn't read pid file '%s', " 162 printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
158 "err = %d\n", file, errno); 163 "'%s', err = %d\n", file, errno);
159 goto out_close; 164 goto out_close;
160 } else if(n == 0){ 165 } else if (n == 0) {
161 printk("is_umdir_used : couldn't read pid file '%s', " 166 printk(UM_KERN_ERR "is_umdir_used : couldn't read pid file "
162 "0-byte read\n", file); 167 "'%s', 0-byte read\n", file);
163 goto out_close; 168 goto out_close;
164 } 169 }
165 170
166 p = strtoul(pid, &end, 0); 171 p = strtoul(pid, &end, 0);
167 if(end == pid){ 172 if (end == pid) {
168 printk("is_umdir_used : couldn't parse pid file '%s', " 173 printk(UM_KERN_ERR "is_umdir_used : couldn't parse pid file "
169 "errno = %d\n", file, errno); 174 "'%s', errno = %d\n", file, errno);
170 goto out_close; 175 goto out_close;
171 } 176 }
172 177
173 if((kill(p, 0) == 0) || (errno != ESRCH)){ 178 if ((kill(p, 0) == 0) || (errno != ESRCH)) {
174 printk("umid \"%s\" is already in use by pid %d\n", umid, p); 179 printk(UM_KERN_ERR "umid \"%s\" is already in use by pid %d\n",
180 umid, p);
175 return 1; 181 return 1;
176 } 182 }
177 183
@@ -195,8 +201,8 @@ static int umdir_take_if_dead(char *dir)
195 201
196 ret = remove_files_and_dir(dir); 202 ret = remove_files_and_dir(dir);
197 if (ret) { 203 if (ret) {
198 printk("is_umdir_used - remove_files_and_dir failed with " 204 printk(UM_KERN_ERR "is_umdir_used - remove_files_and_dir "
199 "err = %d\n", ret); 205 "failed with err = %d\n", ret);
200 } 206 }
201 return ret; 207 return ret;
202} 208}
@@ -207,27 +213,28 @@ static void __init create_pid_file(void)
207 char pid[sizeof("nnnnn\0")]; 213 char pid[sizeof("nnnnn\0")];
208 int fd, n; 214 int fd, n;
209 215
210 if(umid_file_name("pid", file, sizeof(file))) 216 if (umid_file_name("pid", file, sizeof(file)))
211 return; 217 return;
212 218
213 fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644); 219 fd = open(file, O_RDWR | O_CREAT | O_EXCL, 0644);
214 if(fd < 0){ 220 if (fd < 0) {
215 printk("Open of machine pid file \"%s\" failed: %s\n", 221 printk(UM_KERN_ERR "Open of machine pid file \"%s\" failed: "
216 file, strerror(errno)); 222 "%s\n", file, strerror(errno));
217 return; 223 return;
218 } 224 }
219 225
220 snprintf(pid, sizeof(pid), "%d\n", getpid()); 226 snprintf(pid, sizeof(pid), "%d\n", getpid());
221 n = write(fd, pid, strlen(pid)); 227 n = write(fd, pid, strlen(pid));
222 if(n != strlen(pid)) 228 if (n != strlen(pid))
223 printk("Write of pid file failed - err = %d\n", errno); 229 printk(UM_KERN_ERR "Write of pid file failed - err = %d\n",
230 errno);
224 231
225 close(fd); 232 close(fd);
226} 233}
227 234
228int __init set_umid(char *name) 235int __init set_umid(char *name)
229{ 236{
230 if(strlen(name) > UMID_LEN - 1) 237 if (strlen(name) > UMID_LEN - 1)
231 return -E2BIG; 238 return -E2BIG;
232 239
233 strlcpy(umid, name, sizeof(umid)); 240 strlcpy(umid, name, sizeof(umid));
@@ -243,18 +250,18 @@ int __init make_umid(void)
243 int fd, err; 250 int fd, err;
244 char tmp[256]; 251 char tmp[256];
245 252
246 if(umid_setup) 253 if (umid_setup)
247 return 0; 254 return 0;
248 255
249 make_uml_dir(); 256 make_uml_dir();
250 257
251 if(*umid == '\0'){ 258 if (*umid == '\0') {
252 strlcpy(tmp, uml_dir, sizeof(tmp)); 259 strlcpy(tmp, uml_dir, sizeof(tmp));
253 strlcat(tmp, "XXXXXX", sizeof(tmp)); 260 strlcat(tmp, "XXXXXX", sizeof(tmp));
254 fd = mkstemp(tmp); 261 fd = mkstemp(tmp);
255 if(fd < 0){ 262 if (fd < 0) {
256 printk("make_umid - mkstemp(%s) failed: %s\n", 263 printk(UM_KERN_ERR "make_umid - mkstemp(%s) failed: "
257 tmp, strerror(errno)); 264 "%s\n", tmp, strerror(errno));
258 err = -errno; 265 err = -errno;
259 goto err; 266 goto err;
260 } 267 }
@@ -263,11 +270,12 @@ int __init make_umid(void)
263 270
264 set_umid(&tmp[strlen(uml_dir)]); 271 set_umid(&tmp[strlen(uml_dir)]);
265 272
266 /* There's a nice tiny little race between this unlink and 273 /*
274 * There's a nice tiny little race between this unlink and
267 * the mkdir below. It'd be nice if there were a mkstemp 275 * the mkdir below. It'd be nice if there were a mkstemp
268 * for directories. 276 * for directories.
269 */ 277 */
270 if(unlink(tmp)){ 278 if (unlink(tmp)) {
271 err = -errno; 279 err = -errno;
272 goto err; 280 goto err;
273 } 281 }
@@ -275,9 +283,9 @@ int __init make_umid(void)
275 283
276 snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid); 284 snprintf(tmp, sizeof(tmp), "%s%s", uml_dir, umid);
277 err = mkdir(tmp, 0777); 285 err = mkdir(tmp, 0777);
278 if(err < 0){ 286 if (err < 0) {
279 err = -errno; 287 err = -errno;
280 if(err != -EEXIST) 288 if (err != -EEXIST)
281 goto err; 289 goto err;
282 290
283 if (umdir_take_if_dead(tmp) < 0) 291 if (umdir_take_if_dead(tmp) < 0)
@@ -285,9 +293,10 @@ int __init make_umid(void)
285 293
286 err = mkdir(tmp, 0777); 294 err = mkdir(tmp, 0777);
287 } 295 }
288 if(err){ 296 if (err) {
289 err = -errno; 297 err = -errno;
290 printk("Failed to create '%s' - err = %d\n", umid, -errno); 298 printk(UM_KERN_ERR "Failed to create '%s' - err = %d\n", umid,
299 errno);
291 goto err; 300 goto err;
292 } 301 }
293 302
@@ -302,14 +311,15 @@ int __init make_umid(void)
302 311
303static int __init make_umid_init(void) 312static int __init make_umid_init(void)
304{ 313{
305 if(!make_umid()) 314 if (!make_umid())
306 return 0; 315 return 0;
307 316
308 /* If initializing with the given umid failed, then try again with 317 /*
318 * If initializing with the given umid failed, then try again with
309 * a random one. 319 * a random one.
310 */ 320 */
311 printk("Failed to initialize umid \"%s\", trying with a random umid\n", 321 printk(UM_KERN_ERR "Failed to initialize umid \"%s\", trying with a "
312 umid); 322 "random umid\n", umid);
313 *umid = '\0'; 323 *umid = '\0';
314 make_umid(); 324 make_umid();
315 325
@@ -323,12 +333,12 @@ int __init umid_file_name(char *name, char *buf, int len)
323 int n, err; 333 int n, err;
324 334
325 err = make_umid(); 335 err = make_umid();
326 if(err) 336 if (err)
327 return err; 337 return err;
328 338
329 n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name); 339 n = snprintf(buf, len, "%s%s/%s", uml_dir, umid, name);
330 if(n >= len){ 340 if (n >= len) {
331 printk("umid_file_name : buffer too short\n"); 341 printk(UM_KERN_ERR "umid_file_name : buffer too short\n");
332 return -E2BIG; 342 return -E2BIG;
333 } 343 }
334 344
@@ -342,21 +352,22 @@ char *get_umid(void)
342 352
343static int __init set_uml_dir(char *name, int *add) 353static int __init set_uml_dir(char *name, int *add)
344{ 354{
345 if(*name == '\0'){ 355 if (*name == '\0') {
346 printf("uml_dir can't be an empty string\n"); 356 printf("uml_dir can't be an empty string\n");
347 return 0; 357 return 0;
348 } 358 }
349 359
350 if(name[strlen(name) - 1] == '/'){ 360 if (name[strlen(name) - 1] == '/') {
351 uml_dir = name; 361 uml_dir = name;
352 return 0; 362 return 0;
353 } 363 }
354 364
355 uml_dir = malloc(strlen(name) + 2); 365 uml_dir = malloc(strlen(name) + 2);
356 if(uml_dir == NULL){ 366 if (uml_dir == NULL) {
357 printf("Failed to malloc uml_dir - error = %d\n", errno); 367 printf("Failed to malloc uml_dir - error = %d\n", errno);
358 368
359 /* Return 0 here because do_initcalls doesn't look at 369 /*
370 * Return 0 here because do_initcalls doesn't look at
360 * the return value. 371 * the return value.
361 */ 372 */
362 return 0; 373 return 0;
@@ -377,7 +388,7 @@ static void remove_umid_dir(void)
377 388
378 sprintf(dir, "%s%s", uml_dir, umid); 389 sprintf(dir, "%s%s", uml_dir, umid);
379 err = remove_files_and_dir(dir); 390 err = remove_files_and_dir(dir);
380 if(err) 391 if (err)
381 printf("remove_umid_dir - remove_files_and_dir failed with " 392 printf("remove_umid_dir - remove_files_and_dir failed with "
382 "err = %d\n", err); 393 "err = %d\n", err);
383} 394}
diff --git a/arch/um/os-Linux/util.c b/arch/um/os-Linux/util.c
index 7cbcf484e13d..ef095436a78c 100644
--- a/arch/um/os-Linux/util.c
+++ b/arch/um/os-Linux/util.c
@@ -105,6 +105,44 @@ int setjmp_wrapper(void (*proc)(void *, void *), ...)
105 105
106void os_dump_core(void) 106void os_dump_core(void)
107{ 107{
108 int pid;
109
108 signal(SIGSEGV, SIG_DFL); 110 signal(SIGSEGV, SIG_DFL);
111
112 /*
113 * We are about to SIGTERM this entire process group to ensure that
114 * nothing is around to run after the kernel exits. The
115 * kernel wants to abort, not die through SIGTERM, so we
116 * ignore it here.
117 */
118
119 signal(SIGTERM, SIG_IGN);
120 kill(0, SIGTERM);
121 /*
122 * Most of the other processes associated with this UML are
123 * likely sTopped, so give them a SIGCONT so they see the
124 * SIGTERM.
125 */
126 kill(0, SIGCONT);
127
128 /*
129 * Now, having sent signals to everyone but us, make sure they
130 * die by ptrace. Processes can survive what's been done to
131 * them so far - the mechanism I understand is receiving a
132 * SIGSEGV and segfaulting immediately upon return. There is
133 * always a SIGSEGV pending, and (I'm guessing) signals are
134 * processed in numeric order so the SIGTERM (signal 15 vs
135 * SIGSEGV being signal 11) is never handled.
136 *
137 * Run a waitpid loop until we get some kind of error.
138 * Hopefully, it's ECHILD, but there's not a lot we can do if
139 * it's something else. Tell os_kill_ptraced_process not to
140 * wait for the child to report its death because there's
141 * nothing reasonable to do if that fails.
142 */
143
144 while ((pid = waitpid(-1, NULL, WNOHANG)) > 0)
145 os_kill_ptraced_process(pid, 0);
146
109 abort(); 147 abort();
110} 148}
diff --git a/arch/um/scripts/Makefile.rules b/arch/um/scripts/Makefile.rules
index bf23dd3e24d0..61107b68e05b 100644
--- a/arch/um/scripts/Makefile.rules
+++ b/arch/um/scripts/Makefile.rules
@@ -21,7 +21,7 @@ $(UNPROFILE_OBJS:.o=.%): \
21$(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \ 21$(UNPROFILE_OBJS) : CHECKFLAGS := -D__linux__ -Dlinux -D__STDC__ \
22 -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF) 22 -Dunix -D__unix__ -D__$(SUBARCH)__ $(CF)
23 23
24# The stubs and unmap.o can't try to call mcount or update basic block data 24# The stubs can't try to call mcount or update basic block data
25define unprofile 25define unprofile
26 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1))) 26 $(patsubst -pg,,$(patsubst -fprofile-arcs -ftest-coverage,,$(1)))
27endef 27endef
diff --git a/arch/um/sys-i386/Makefile b/arch/um/sys-i386/Makefile
index a4618b6b85b9..964dc1a04c37 100644
--- a/arch/um/sys-i386/Makefile
+++ b/arch/um/sys-i386/Makefile
@@ -1,23 +1,21 @@
1#
2# Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3#
4
1obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \ 5obj-y = bug.o bugs.o checksum.o delay.o fault.o ksyms.o ldt.o ptrace.o \
2 ptrace_user.o setjmp.o signal.o sigcontext.o syscalls.o sysrq.o \ 6 ptrace_user.o setjmp.o signal.o stub.o stub_segv.o syscalls.o sysrq.o \
3 sys_call_table.o tls.o 7 sys_call_table.o tls.o
4 8
5obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
6
7subarch-obj-y = lib/bitops_32.o lib/semaphore_32.o lib/string_32.o 9subarch-obj-y = lib/bitops_32.o lib/semaphore_32.o lib/string_32.o
8subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o 10subarch-obj-$(CONFIG_HIGHMEM) += mm/highmem_32.o
9subarch-obj-$(CONFIG_MODULES) += kernel/module_32.o 11subarch-obj-$(CONFIG_MODULES) += kernel/module_32.o
10 12
11USER_OBJS := bugs.o ptrace_user.o sigcontext.o fault.o 13USER_OBJS := bugs.o ptrace_user.o fault.o
12 14
13USER_OBJS += user-offsets.s 15USER_OBJS += user-offsets.s
14extra-y += user-offsets.s 16extra-y += user-offsets.s
15 17
16extra-$(CONFIG_MODE_TT) += unmap.o
17
18UNPROFILE_OBJS := stub_segv.o 18UNPROFILE_OBJS := stub_segv.o
19CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) 19CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING)
20 20
21include arch/um/scripts/Makefile.rules 21include arch/um/scripts/Makefile.rules
22
23$(obj)/unmap.%: _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/um/sys-i386/bugs.c b/arch/um/sys-i386/bugs.c
index 0393e44813e7..806895d73bcc 100644
--- a/arch/um/sys-i386/bugs.c
+++ b/arch/um/sys-i386/bugs.c
@@ -1,18 +1,15 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <unistd.h>
7#include <errno.h> 6#include <errno.h>
7#include <signal.h>
8#include <string.h> 8#include <string.h>
9#include <sys/signal.h> 9#include "kern_constants.h"
10#include <asm/ldt.h>
11#include "kern_util.h"
12#include "user.h"
13#include "sysdep/ptrace.h"
14#include "task.h"
15#include "os.h" 10#include "os.h"
11#include "task.h"
12#include "user.h"
16 13
17#define MAXTOKEN 64 14#define MAXTOKEN 64
18 15
@@ -30,18 +27,20 @@ static char token(int fd, char *buf, int len, char stop)
30 do { 27 do {
31 n = os_read_file(fd, ptr, sizeof(*ptr)); 28 n = os_read_file(fd, ptr, sizeof(*ptr));
32 c = *ptr++; 29 c = *ptr++;
33 if(n != sizeof(*ptr)){ 30 if (n != sizeof(*ptr)) {
34 if(n == 0) 31 if (n == 0)
35 return 0; 32 return 0;
36 printk("Reading /proc/cpuinfo failed, err = %d\n", -n); 33 printk(UM_KERN_ERR "Reading /proc/cpuinfo failed, "
37 if(n < 0) 34 "err = %d\n", -n);
35 if (n < 0)
38 return n; 36 return n;
39 else return -EIO; 37 else return -EIO;
40 } 38 }
41 } while((c != '\n') && (c != stop) && (ptr < end)); 39 } while ((c != '\n') && (c != stop) && (ptr < end));
42 40
43 if(ptr == end){ 41 if (ptr == end) {
44 printk("Failed to find '%c' in /proc/cpuinfo\n", stop); 42 printk(UM_KERN_ERR "Failed to find '%c' in /proc/cpuinfo\n",
43 stop);
45 return -1; 44 return -1;
46 } 45 }
47 *(ptr - 1) = '\0'; 46 *(ptr - 1) = '\0';
@@ -54,26 +53,27 @@ static int find_cpuinfo_line(int fd, char *key, char *scratch, int len)
54 char c; 53 char c;
55 54
56 scratch[len - 1] = '\0'; 55 scratch[len - 1] = '\0';
57 while(1){ 56 while (1) {
58 c = token(fd, scratch, len - 1, ':'); 57 c = token(fd, scratch, len - 1, ':');
59 if(c <= 0) 58 if (c <= 0)
60 return 0; 59 return 0;
61 else if(c != ':'){ 60 else if (c != ':') {
62 printk("Failed to find ':' in /proc/cpuinfo\n"); 61 printk(UM_KERN_ERR "Failed to find ':' in "
62 "/proc/cpuinfo\n");
63 return 0; 63 return 0;
64 } 64 }
65 65
66 if(!strncmp(scratch, key, strlen(key))) 66 if (!strncmp(scratch, key, strlen(key)))
67 return 1; 67 return 1;
68 68
69 do { 69 do {
70 n = os_read_file(fd, &c, sizeof(c)); 70 n = os_read_file(fd, &c, sizeof(c));
71 if(n != sizeof(c)){ 71 if (n != sizeof(c)) {
72 printk("Failed to find newline in " 72 printk(UM_KERN_ERR "Failed to find newline in "
73 "/proc/cpuinfo, err = %d\n", -n); 73 "/proc/cpuinfo, err = %d\n", -n);
74 return 0; 74 return 0;
75 } 75 }
76 } while(c != '\n'); 76 } while (c != '\n');
77 } 77 }
78 return 0; 78 return 0;
79} 79}
@@ -83,46 +83,50 @@ static int check_cpu_flag(char *feature, int *have_it)
83 char buf[MAXTOKEN], c; 83 char buf[MAXTOKEN], c;
84 int fd, len = ARRAY_SIZE(buf); 84 int fd, len = ARRAY_SIZE(buf);
85 85
86 printk("Checking for host processor %s support...", feature); 86 printk(UM_KERN_INFO "Checking for host processor %s support...",
87 feature);
87 fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0); 88 fd = os_open_file("/proc/cpuinfo", of_read(OPENFLAGS()), 0);
88 if(fd < 0){ 89 if (fd < 0) {
89 printk("Couldn't open /proc/cpuinfo, err = %d\n", -fd); 90 printk(UM_KERN_ERR "Couldn't open /proc/cpuinfo, err = %d\n",
91 -fd);
90 return 0; 92 return 0;
91 } 93 }
92 94
93 *have_it = 0; 95 *have_it = 0;
94 if(!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf))) 96 if (!find_cpuinfo_line(fd, "flags", buf, ARRAY_SIZE(buf)))
95 goto out; 97 goto out;
96 98
97 c = token(fd, buf, len - 1, ' '); 99 c = token(fd, buf, len - 1, ' ');
98 if(c < 0) 100 if (c < 0)
99 goto out; 101 goto out;
100 else if(c != ' '){ 102 else if (c != ' ') {
101 printk("Failed to find ' ' in /proc/cpuinfo\n"); 103 printk(UM_KERN_ERR "Failed to find ' ' in /proc/cpuinfo\n");
102 goto out; 104 goto out;
103 } 105 }
104 106
105 while(1){ 107 while (1) {
106 c = token(fd, buf, len - 1, ' '); 108 c = token(fd, buf, len - 1, ' ');
107 if(c < 0) 109 if (c < 0)
108 goto out; 110 goto out;
109 else if(c == '\n') break; 111 else if (c == '\n')
112 break;
110 113
111 if(!strcmp(buf, feature)){ 114 if (!strcmp(buf, feature)) {
112 *have_it = 1; 115 *have_it = 1;
113 goto out; 116 goto out;
114 } 117 }
115 } 118 }
116 out: 119 out:
117 if(*have_it == 0) 120 if (*have_it == 0)
118 printk("No\n"); 121 printk("No\n");
119 else if(*have_it == 1) 122 else if (*have_it == 1)
120 printk("Yes\n"); 123 printk("Yes\n");
121 os_close_file(fd); 124 os_close_file(fd);
122 return 1; 125 return 1;
123} 126}
124 127
125#if 0 /* This doesn't work in tt mode, plus it's causing compilation problems 128#if 0 /*
129 * This doesn't work in tt mode, plus it's causing compilation problems
126 * for some people. 130 * for some people.
127 */ 131 */
128static void disable_lcall(void) 132static void disable_lcall(void)
@@ -135,8 +139,9 @@ static void disable_lcall(void)
135 ldt.base_addr = 0; 139 ldt.base_addr = 0;
136 ldt.limit = 0; 140 ldt.limit = 0;
137 err = modify_ldt(1, &ldt, sizeof(ldt)); 141 err = modify_ldt(1, &ldt, sizeof(ldt));
138 if(err) 142 if (err)
139 printk("Failed to disable lcall7 - errno = %d\n", errno); 143 printk(UM_KERN_ERR "Failed to disable lcall7 - errno = %d\n",
144 errno);
140} 145}
141#endif 146#endif
142 147
@@ -151,40 +156,41 @@ void arch_check_bugs(void)
151{ 156{
152 int have_it; 157 int have_it;
153 158
154 if(os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0){ 159 if (os_access("/proc/cpuinfo", OS_ACC_R_OK) < 0) {
155 printk("/proc/cpuinfo not available - skipping CPU capability " 160 printk(UM_KERN_ERR "/proc/cpuinfo not available - skipping CPU "
156 "checks\n"); 161 "capability checks\n");
157 return; 162 return;
158 } 163 }
159 if(check_cpu_flag("cmov", &have_it)) 164 if (check_cpu_flag("cmov", &have_it))
160 host_has_cmov = have_it; 165 host_has_cmov = have_it;
161 if(check_cpu_flag("xmm", &have_it)) 166 if (check_cpu_flag("xmm", &have_it))
162 host_has_xmm = have_it; 167 host_has_xmm = have_it;
163} 168}
164 169
165int arch_handle_signal(int sig, union uml_pt_regs *regs) 170int arch_handle_signal(int sig, struct uml_pt_regs *regs)
166{ 171{
167 unsigned char tmp[2]; 172 unsigned char tmp[2];
168 173
169 /* This is testing for a cmov (0x0f 0x4x) instruction causing a 174 /*
175 * This is testing for a cmov (0x0f 0x4x) instruction causing a
170 * SIGILL in init. 176 * SIGILL in init.
171 */ 177 */
172 if((sig != SIGILL) || (TASK_PID(get_current()) != 1)) 178 if ((sig != SIGILL) || (TASK_PID(get_current()) != 1))
173 return 0; 179 return 0;
174 180
175 if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2)) 181 if (copy_from_user_proc(tmp, (void *) UPT_IP(regs), 2))
176 panic("SIGILL in init, could not read instructions!\n"); 182 panic("SIGILL in init, could not read instructions!\n");
177 if((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40)) 183 if ((tmp[0] != 0x0f) || ((tmp[1] & 0xf0) != 0x40))
178 return 0; 184 return 0;
179 185
180 if(host_has_cmov == 0) 186 if (host_has_cmov == 0)
181 panic("SIGILL caused by cmov, which this processor doesn't " 187 panic("SIGILL caused by cmov, which this processor doesn't "
182 "implement, boot a filesystem compiled for older " 188 "implement, boot a filesystem compiled for older "
183 "processors"); 189 "processors");
184 else if(host_has_cmov == 1) 190 else if (host_has_cmov == 1)
185 panic("SIGILL caused by cmov, which this processor claims to " 191 panic("SIGILL caused by cmov, which this processor claims to "
186 "implement"); 192 "implement");
187 else if(host_has_cmov == -1) 193 else if (host_has_cmov == -1)
188 panic("SIGILL caused by cmov, couldn't tell if this processor " 194 panic("SIGILL caused by cmov, couldn't tell if this processor "
189 "implements it, boot a filesystem compiled for older " 195 "implements it, boot a filesystem compiled for older "
190 "processors"); 196 "processors");
diff --git a/arch/um/sys-i386/fault.c b/arch/um/sys-i386/fault.c
index 745b4fd49e9f..d670f68532f4 100644
--- a/arch/um/sys-i386/fault.c
+++ b/arch/um/sys-i386/fault.c
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 - 2004 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -15,14 +15,14 @@ struct exception_table_entry
15const struct exception_table_entry *search_exception_tables(unsigned long add); 15const struct exception_table_entry *search_exception_tables(unsigned long add);
16 16
17/* Compare this to arch/i386/mm/extable.c:fixup_exception() */ 17/* Compare this to arch/i386/mm/extable.c:fixup_exception() */
18int arch_fixup(unsigned long address, union uml_pt_regs *regs) 18int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
19{ 19{
20 const struct exception_table_entry *fixup; 20 const struct exception_table_entry *fixup;
21 21
22 fixup = search_exception_tables(address); 22 fixup = search_exception_tables(address);
23 if(fixup != 0){ 23 if (fixup != 0) {
24 UPT_IP(regs) = fixup->fixup; 24 UPT_IP(regs) = fixup->fixup;
25 return(1); 25 return 1;
26 } 26 }
27 return(0); 27 return 0;
28} 28}
diff --git a/arch/um/sys-i386/ldt.c b/arch/um/sys-i386/ldt.c
index a939a7ef0227..67c0958eb984 100644
--- a/arch/um/sys-i386/ldt.c
+++ b/arch/um/sys-i386/ldt.c
@@ -1,106 +1,30 @@
1/* 1/*
2 * Copyright (C) 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2001 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/sched.h" 6#include "linux/mm.h"
7#include "linux/slab.h"
8#include "linux/types.h"
9#include "linux/errno.h"
10#include "linux/spinlock.h"
11#include "asm/uaccess.h"
12#include "asm/smp.h"
13#include "asm/ldt.h"
14#include "asm/unistd.h" 7#include "asm/unistd.h"
15#include "choose-mode.h"
16#include "kern.h"
17#include "mode_kern.h"
18#include "os.h" 8#include "os.h"
19 9#include "proc_mm.h"
20extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
21
22#ifdef CONFIG_MODE_TT
23
24static long do_modify_ldt_tt(int func, void __user *ptr,
25 unsigned long bytecount)
26{
27 struct user_desc info;
28 int res = 0;
29 void *buf = NULL;
30 void *p = NULL; /* What we pass to host. */
31
32 switch(func){
33 case 1:
34 case 0x11: /* write_ldt */
35 /* Do this check now to avoid overflows. */
36 if (bytecount != sizeof(struct user_desc)) {
37 res = -EINVAL;
38 goto out;
39 }
40
41 if(copy_from_user(&info, ptr, sizeof(info))) {
42 res = -EFAULT;
43 goto out;
44 }
45
46 p = &info;
47 break;
48 case 0:
49 case 2: /* read_ldt */
50
51 /* The use of info avoids kmalloc on the write case, not on the
52 * read one. */
53 buf = kmalloc(bytecount, GFP_KERNEL);
54 if (!buf) {
55 res = -ENOMEM;
56 goto out;
57 }
58 p = buf;
59 break;
60 default:
61 res = -ENOSYS;
62 goto out;
63 }
64
65 res = modify_ldt(func, p, bytecount);
66 if(res < 0)
67 goto out;
68
69 switch(func){
70 case 0:
71 case 2:
72 /* Modify_ldt was for reading and returned the number of read
73 * bytes.*/
74 if(copy_to_user(ptr, p, res))
75 res = -EFAULT;
76 break;
77 }
78
79out:
80 kfree(buf);
81 return res;
82}
83
84#endif
85
86#ifdef CONFIG_MODE_SKAS
87
88#include "skas.h" 10#include "skas.h"
89#include "skas_ptrace.h" 11#include "skas_ptrace.h"
90#include "asm/mmu_context.h" 12#include "sysdep/tls.h"
91#include "proc_mm.h" 13
14extern int modify_ldt(int func, void *ptr, unsigned long bytecount);
92 15
93long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc, 16long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
94 void **addr, int done) 17 void **addr, int done)
95{ 18{
96 long res; 19 long res;
97 20
98 if(proc_mm){ 21 if (proc_mm) {
99 /* This is a special handling for the case, that the mm to 22 /*
23 * This is a special handling for the case, that the mm to
100 * modify isn't current->active_mm. 24 * modify isn't current->active_mm.
101 * If this is called directly by modify_ldt, 25 * If this is called directly by modify_ldt,
102 * (current->active_mm->context.skas.u == mm_idp) 26 * (current->active_mm->context.skas.u == mm_idp)
103 * will be true. So no call to switch_mm_skas(mm_idp) is done. 27 * will be true. So no call to __switch_mm(mm_idp) is done.
104 * If this is called in case of init_new_ldt or PTRACE_LDT, 28 * If this is called in case of init_new_ldt or PTRACE_LDT,
105 * mm_idp won't belong to current->active_mm, but child->mm. 29 * mm_idp won't belong to current->active_mm, but child->mm.
106 * So we need to switch child's mm into our userspace, then 30 * So we need to switch child's mm into our userspace, then
@@ -108,12 +32,12 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
108 * 32 *
109 * Note: I'm unsure: should interrupts be disabled here? 33 * Note: I'm unsure: should interrupts be disabled here?
110 */ 34 */
111 if(!current->active_mm || current->active_mm == &init_mm || 35 if (!current->active_mm || current->active_mm == &init_mm ||
112 mm_idp != &current->active_mm->context.skas.id) 36 mm_idp != &current->active_mm->context.id)
113 switch_mm_skas(mm_idp); 37 __switch_mm(mm_idp);
114 } 38 }
115 39
116 if(ptrace_ldt) { 40 if (ptrace_ldt) {
117 struct ptrace_ldt ldt_op = (struct ptrace_ldt) { 41 struct ptrace_ldt ldt_op = (struct ptrace_ldt) {
118 .func = func, 42 .func = func,
119 .ptr = desc, 43 .ptr = desc,
@@ -121,7 +45,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
121 u32 cpu; 45 u32 cpu;
122 int pid; 46 int pid;
123 47
124 if(!proc_mm) 48 if (!proc_mm)
125 pid = mm_idp->u.pid; 49 pid = mm_idp->u.pid;
126 else { 50 else {
127 cpu = get_cpu(); 51 cpu = get_cpu();
@@ -130,7 +54,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
130 54
131 res = os_ptrace_ldt(pid, 0, (unsigned long) &ldt_op); 55 res = os_ptrace_ldt(pid, 0, (unsigned long) &ldt_op);
132 56
133 if(proc_mm) 57 if (proc_mm)
134 put_cpu(); 58 put_cpu();
135 } 59 }
136 else { 60 else {
@@ -139,7 +63,7 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
139 (sizeof(*desc) + sizeof(long) - 1) & 63 (sizeof(*desc) + sizeof(long) - 1) &
140 ~(sizeof(long) - 1), 64 ~(sizeof(long) - 1),
141 addr, &stub_addr); 65 addr, &stub_addr);
142 if(!res){ 66 if (!res) {
143 unsigned long args[] = { func, 67 unsigned long args[] = { func,
144 (unsigned long)stub_addr, 68 (unsigned long)stub_addr,
145 sizeof(*desc), 69 sizeof(*desc),
@@ -149,13 +73,14 @@ long write_ldt_entry(struct mm_id * mm_idp, int func, struct user_desc * desc,
149 } 73 }
150 } 74 }
151 75
152 if(proc_mm){ 76 if (proc_mm) {
153 /* This is the second part of special handling, that makes 77 /*
78 * This is the second part of special handling, that makes
154 * PTRACE_LDT possible to implement. 79 * PTRACE_LDT possible to implement.
155 */ 80 */
156 if(current->active_mm && current->active_mm != &init_mm && 81 if (current->active_mm && current->active_mm != &init_mm &&
157 mm_idp != &current->active_mm->context.skas.id) 82 mm_idp != &current->active_mm->context.id)
158 switch_mm_skas(&current->active_mm->context.skas.id); 83 __switch_mm(&current->active_mm->context.id);
159 } 84 }
160 85
161 return res; 86 return res;
@@ -170,21 +95,22 @@ static long read_ldt_from_host(void __user * ptr, unsigned long bytecount)
170 .ptr = kmalloc(bytecount, GFP_KERNEL)}; 95 .ptr = kmalloc(bytecount, GFP_KERNEL)};
171 u32 cpu; 96 u32 cpu;
172 97
173 if(ptrace_ldt.ptr == NULL) 98 if (ptrace_ldt.ptr == NULL)
174 return -ENOMEM; 99 return -ENOMEM;
175 100
176 /* This is called from sys_modify_ldt only, so userspace_pid gives 101 /*
102 * This is called from sys_modify_ldt only, so userspace_pid gives
177 * us the right number 103 * us the right number
178 */ 104 */
179 105
180 cpu = get_cpu(); 106 cpu = get_cpu();
181 res = os_ptrace_ldt(userspace_pid[cpu], 0, (unsigned long) &ptrace_ldt); 107 res = os_ptrace_ldt(userspace_pid[cpu], 0, (unsigned long) &ptrace_ldt);
182 put_cpu(); 108 put_cpu();
183 if(res < 0) 109 if (res < 0)
184 goto out; 110 goto out;
185 111
186 n = copy_to_user(ptr, ptrace_ldt.ptr, res); 112 n = copy_to_user(ptr, ptrace_ldt.ptr, res);
187 if(n != 0) 113 if (n != 0)
188 res = -EFAULT; 114 res = -EFAULT;
189 115
190 out: 116 out:
@@ -209,35 +135,34 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
209{ 135{
210 int i, err = 0; 136 int i, err = 0;
211 unsigned long size; 137 unsigned long size;
212 uml_ldt_t * ldt = &current->mm->context.skas.ldt; 138 uml_ldt_t * ldt = &current->mm->context.ldt;
213 139
214 if(!ldt->entry_count) 140 if (!ldt->entry_count)
215 goto out; 141 goto out;
216 if(bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES) 142 if (bytecount > LDT_ENTRY_SIZE*LDT_ENTRIES)
217 bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES; 143 bytecount = LDT_ENTRY_SIZE*LDT_ENTRIES;
218 err = bytecount; 144 err = bytecount;
219 145
220 if(ptrace_ldt){ 146 if (ptrace_ldt)
221 return read_ldt_from_host(ptr, bytecount); 147 return read_ldt_from_host(ptr, bytecount);
222 }
223 148
224 down(&ldt->semaphore); 149 down(&ldt->semaphore);
225 if(ldt->entry_count <= LDT_DIRECT_ENTRIES){ 150 if (ldt->entry_count <= LDT_DIRECT_ENTRIES) {
226 size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES; 151 size = LDT_ENTRY_SIZE*LDT_DIRECT_ENTRIES;
227 if(size > bytecount) 152 if (size > bytecount)
228 size = bytecount; 153 size = bytecount;
229 if(copy_to_user(ptr, ldt->u.entries, size)) 154 if (copy_to_user(ptr, ldt->u.entries, size))
230 err = -EFAULT; 155 err = -EFAULT;
231 bytecount -= size; 156 bytecount -= size;
232 ptr += size; 157 ptr += size;
233 } 158 }
234 else { 159 else {
235 for(i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount; 160 for (i=0; i<ldt->entry_count/LDT_ENTRIES_PER_PAGE && bytecount;
236 i++){ 161 i++) {
237 size = PAGE_SIZE; 162 size = PAGE_SIZE;
238 if(size > bytecount) 163 if (size > bytecount)
239 size = bytecount; 164 size = bytecount;
240 if(copy_to_user(ptr, ldt->u.pages[i], size)){ 165 if (copy_to_user(ptr, ldt->u.pages[i], size)) {
241 err = -EFAULT; 166 err = -EFAULT;
242 break; 167 break;
243 } 168 }
@@ -247,10 +172,10 @@ static int read_ldt(void __user * ptr, unsigned long bytecount)
247 } 172 }
248 up(&ldt->semaphore); 173 up(&ldt->semaphore);
249 174
250 if(bytecount == 0 || err == -EFAULT) 175 if (bytecount == 0 || err == -EFAULT)
251 goto out; 176 goto out;
252 177
253 if(clear_user(ptr, bytecount)) 178 if (clear_user(ptr, bytecount))
254 err = -EFAULT; 179 err = -EFAULT;
255 180
256out: 181out:
@@ -261,15 +186,16 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount)
261{ 186{
262 int err; 187 int err;
263 188
264 if(bytecount > 5*LDT_ENTRY_SIZE) 189 if (bytecount > 5*LDT_ENTRY_SIZE)
265 bytecount = 5*LDT_ENTRY_SIZE; 190 bytecount = 5*LDT_ENTRY_SIZE;
266 191
267 err = bytecount; 192 err = bytecount;
268 /* UML doesn't support lcall7 and lcall27. 193 /*
194 * UML doesn't support lcall7 and lcall27.
269 * So, we don't really have a default ldt, but emulate 195 * So, we don't really have a default ldt, but emulate
270 * an empty ldt of common host default ldt size. 196 * an empty ldt of common host default ldt size.
271 */ 197 */
272 if(clear_user(ptr, bytecount)) 198 if (clear_user(ptr, bytecount))
273 err = -EFAULT; 199 err = -EFAULT;
274 200
275 return err; 201 return err;
@@ -277,60 +203,60 @@ static int read_default_ldt(void __user * ptr, unsigned long bytecount)
277 203
278static int write_ldt(void __user * ptr, unsigned long bytecount, int func) 204static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
279{ 205{
280 uml_ldt_t * ldt = &current->mm->context.skas.ldt; 206 uml_ldt_t * ldt = &current->mm->context.ldt;
281 struct mm_id * mm_idp = &current->mm->context.skas.id; 207 struct mm_id * mm_idp = &current->mm->context.id;
282 int i, err; 208 int i, err;
283 struct user_desc ldt_info; 209 struct user_desc ldt_info;
284 struct ldt_entry entry0, *ldt_p; 210 struct ldt_entry entry0, *ldt_p;
285 void *addr = NULL; 211 void *addr = NULL;
286 212
287 err = -EINVAL; 213 err = -EINVAL;
288 if(bytecount != sizeof(ldt_info)) 214 if (bytecount != sizeof(ldt_info))
289 goto out; 215 goto out;
290 err = -EFAULT; 216 err = -EFAULT;
291 if(copy_from_user(&ldt_info, ptr, sizeof(ldt_info))) 217 if (copy_from_user(&ldt_info, ptr, sizeof(ldt_info)))
292 goto out; 218 goto out;
293 219
294 err = -EINVAL; 220 err = -EINVAL;
295 if(ldt_info.entry_number >= LDT_ENTRIES) 221 if (ldt_info.entry_number >= LDT_ENTRIES)
296 goto out; 222 goto out;
297 if(ldt_info.contents == 3){ 223 if (ldt_info.contents == 3) {
298 if (func == 1) 224 if (func == 1)
299 goto out; 225 goto out;
300 if (ldt_info.seg_not_present == 0) 226 if (ldt_info.seg_not_present == 0)
301 goto out; 227 goto out;
302 } 228 }
303 229
304 if(!ptrace_ldt) 230 if (!ptrace_ldt)
305 down(&ldt->semaphore); 231 down(&ldt->semaphore);
306 232
307 err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1); 233 err = write_ldt_entry(mm_idp, func, &ldt_info, &addr, 1);
308 if(err) 234 if (err)
309 goto out_unlock; 235 goto out_unlock;
310 else if(ptrace_ldt) { 236 else if (ptrace_ldt) {
311 /* With PTRACE_LDT available, this is used as a flag only */ 237 /* With PTRACE_LDT available, this is used as a flag only */
312 ldt->entry_count = 1; 238 ldt->entry_count = 1;
313 goto out; 239 goto out;
314 } 240 }
315 241
316 if(ldt_info.entry_number >= ldt->entry_count && 242 if (ldt_info.entry_number >= ldt->entry_count &&
317 ldt_info.entry_number >= LDT_DIRECT_ENTRIES){ 243 ldt_info.entry_number >= LDT_DIRECT_ENTRIES) {
318 for(i=ldt->entry_count/LDT_ENTRIES_PER_PAGE; 244 for (i=ldt->entry_count/LDT_ENTRIES_PER_PAGE;
319 i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number; 245 i*LDT_ENTRIES_PER_PAGE <= ldt_info.entry_number;
320 i++){ 246 i++) {
321 if(i == 0) 247 if (i == 0)
322 memcpy(&entry0, ldt->u.entries, 248 memcpy(&entry0, ldt->u.entries,
323 sizeof(entry0)); 249 sizeof(entry0));
324 ldt->u.pages[i] = (struct ldt_entry *) 250 ldt->u.pages[i] = (struct ldt_entry *)
325 __get_free_page(GFP_KERNEL|__GFP_ZERO); 251 __get_free_page(GFP_KERNEL|__GFP_ZERO);
326 if(!ldt->u.pages[i]){ 252 if (!ldt->u.pages[i]) {
327 err = -ENOMEM; 253 err = -ENOMEM;
328 /* Undo the change in host */ 254 /* Undo the change in host */
329 memset(&ldt_info, 0, sizeof(ldt_info)); 255 memset(&ldt_info, 0, sizeof(ldt_info));
330 write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1); 256 write_ldt_entry(mm_idp, 1, &ldt_info, &addr, 1);
331 goto out_unlock; 257 goto out_unlock;
332 } 258 }
333 if(i == 0) { 259 if (i == 0) {
334 memcpy(ldt->u.pages[0], &entry0, 260 memcpy(ldt->u.pages[0], &entry0,
335 sizeof(entry0)); 261 sizeof(entry0));
336 memcpy(ldt->u.pages[0]+1, ldt->u.entries+1, 262 memcpy(ldt->u.pages[0]+1, ldt->u.entries+1,
@@ -339,17 +265,17 @@ static int write_ldt(void __user * ptr, unsigned long bytecount, int func)
339 ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE; 265 ldt->entry_count = (i + 1) * LDT_ENTRIES_PER_PAGE;
340 } 266 }
341 } 267 }
342 if(ldt->entry_count <= ldt_info.entry_number) 268 if (ldt->entry_count <= ldt_info.entry_number)
343 ldt->entry_count = ldt_info.entry_number + 1; 269 ldt->entry_count = ldt_info.entry_number + 1;
344 270
345 if(ldt->entry_count <= LDT_DIRECT_ENTRIES) 271 if (ldt->entry_count <= LDT_DIRECT_ENTRIES)
346 ldt_p = ldt->u.entries + ldt_info.entry_number; 272 ldt_p = ldt->u.entries + ldt_info.entry_number;
347 else 273 else
348 ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] + 274 ldt_p = ldt->u.pages[ldt_info.entry_number/LDT_ENTRIES_PER_PAGE] +
349 ldt_info.entry_number%LDT_ENTRIES_PER_PAGE; 275 ldt_info.entry_number%LDT_ENTRIES_PER_PAGE;
350 276
351 if(ldt_info.base_addr == 0 && ldt_info.limit == 0 && 277 if (ldt_info.base_addr == 0 && ldt_info.limit == 0 &&
352 (func == 1 || LDT_empty(&ldt_info))){ 278 (func == 1 || LDT_empty(&ldt_info))) {
353 ldt_p->a = 0; 279 ldt_p->a = 0;
354 ldt_p->b = 0; 280 ldt_p->b = 0;
355 } 281 }
@@ -400,7 +326,7 @@ static void ldt_get_host_info(void)
400 326
401 spin_lock(&host_ldt_lock); 327 spin_lock(&host_ldt_lock);
402 328
403 if(host_ldt_entries != NULL){ 329 if (host_ldt_entries != NULL) {
404 spin_unlock(&host_ldt_lock); 330 spin_unlock(&host_ldt_lock);
405 return; 331 return;
406 } 332 }
@@ -408,49 +334,49 @@ static void ldt_get_host_info(void)
408 334
409 spin_unlock(&host_ldt_lock); 335 spin_unlock(&host_ldt_lock);
410 336
411 for(i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++); 337 for (i = LDT_PAGES_MAX-1, order=0; i; i>>=1, order++)
338 ;
412 339
413 ldt = (struct ldt_entry *) 340 ldt = (struct ldt_entry *)
414 __get_free_pages(GFP_KERNEL|__GFP_ZERO, order); 341 __get_free_pages(GFP_KERNEL|__GFP_ZERO, order);
415 if(ldt == NULL) { 342 if (ldt == NULL) {
416 printk("ldt_get_host_info: couldn't allocate buffer for host " 343 printk(KERN_ERR "ldt_get_host_info: couldn't allocate buffer "
417 "ldt\n"); 344 "for host ldt\n");
418 return; 345 return;
419 } 346 }
420 347
421 ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE); 348 ret = modify_ldt(0, ldt, (1<<order)*PAGE_SIZE);
422 if(ret < 0) { 349 if (ret < 0) {
423 printk("ldt_get_host_info: couldn't read host ldt\n"); 350 printk(KERN_ERR "ldt_get_host_info: couldn't read host ldt\n");
424 goto out_free; 351 goto out_free;
425 } 352 }
426 if(ret == 0) { 353 if (ret == 0) {
427 /* default_ldt is active, simply write an empty entry 0 */ 354 /* default_ldt is active, simply write an empty entry 0 */
428 host_ldt_entries = dummy_list; 355 host_ldt_entries = dummy_list;
429 goto out_free; 356 goto out_free;
430 } 357 }
431 358
432 for(i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++){ 359 for (i=0, size=0; i<ret/LDT_ENTRY_SIZE; i++) {
433 if(ldt[i].a != 0 || ldt[i].b != 0) 360 if (ldt[i].a != 0 || ldt[i].b != 0)
434 size++; 361 size++;
435 } 362 }
436 363
437 if(size < ARRAY_SIZE(dummy_list)) 364 if (size < ARRAY_SIZE(dummy_list))
438 host_ldt_entries = dummy_list; 365 host_ldt_entries = dummy_list;
439 else { 366 else {
440 size = (size + 1) * sizeof(dummy_list[0]); 367 size = (size + 1) * sizeof(dummy_list[0]);
441 tmp = kmalloc(size, GFP_KERNEL); 368 tmp = kmalloc(size, GFP_KERNEL);
442 if(tmp == NULL) { 369 if (tmp == NULL) {
443 printk("ldt_get_host_info: couldn't allocate host ldt " 370 printk(KERN_ERR "ldt_get_host_info: couldn't allocate "
444 "list\n"); 371 "host ldt list\n");
445 goto out_free; 372 goto out_free;
446 } 373 }
447 host_ldt_entries = tmp; 374 host_ldt_entries = tmp;
448 } 375 }
449 376
450 for(i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++){ 377 for (i=0, k=0; i<ret/LDT_ENTRY_SIZE; i++) {
451 if(ldt[i].a != 0 || ldt[i].b != 0) { 378 if (ldt[i].a != 0 || ldt[i].b != 0)
452 host_ldt_entries[k++] = i; 379 host_ldt_entries[k++] = i;
453 }
454 } 380 }
455 host_ldt_entries[k] = -1; 381 host_ldt_entries[k] = -1;
456 382
@@ -458,8 +384,7 @@ out_free:
458 free_pages((unsigned long)ldt, order); 384 free_pages((unsigned long)ldt, order);
459} 385}
460 386
461long init_new_ldt(struct mmu_context_skas * new_mm, 387long init_new_ldt(struct mm_context *new_mm, struct mm_context *from_mm)
462 struct mmu_context_skas * from_mm)
463{ 388{
464 struct user_desc desc; 389 struct user_desc desc;
465 short * num_p; 390 short * num_p;
@@ -469,15 +394,15 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
469 struct proc_mm_op copy; 394 struct proc_mm_op copy;
470 395
471 396
472 if(!ptrace_ldt) 397 if (!ptrace_ldt)
473 init_MUTEX(&new_mm->ldt.semaphore); 398 init_MUTEX(&new_mm->ldt.semaphore);
474 399
475 if(!from_mm){ 400 if (!from_mm) {
476 memset(&desc, 0, sizeof(desc)); 401 memset(&desc, 0, sizeof(desc));
477 /* 402 /*
478 * We have to initialize a clean ldt. 403 * We have to initialize a clean ldt.
479 */ 404 */
480 if(proc_mm) { 405 if (proc_mm) {
481 /* 406 /*
482 * If the new mm was created using proc_mm, host's 407 * If the new mm was created using proc_mm, host's
483 * default-ldt currently is assigned, which normally 408 * default-ldt currently is assigned, which normally
@@ -485,8 +410,7 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
485 * To remove these gates, we simply write an empty 410 * To remove these gates, we simply write an empty
486 * entry as number 0 to the host. 411 * entry as number 0 to the host.
487 */ 412 */
488 err = write_ldt_entry(&new_mm->id, 1, &desc, 413 err = write_ldt_entry(&new_mm->id, 1, &desc, &addr, 1);
489 &addr, 1);
490 } 414 }
491 else{ 415 else{
492 /* 416 /*
@@ -495,11 +419,11 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
495 * will be reset in the following loop 419 * will be reset in the following loop
496 */ 420 */
497 ldt_get_host_info(); 421 ldt_get_host_info();
498 for(num_p=host_ldt_entries; *num_p != -1; num_p++){ 422 for (num_p=host_ldt_entries; *num_p != -1; num_p++) {
499 desc.entry_number = *num_p; 423 desc.entry_number = *num_p;
500 err = write_ldt_entry(&new_mm->id, 1, &desc, 424 err = write_ldt_entry(&new_mm->id, 1, &desc,
501 &addr, *(num_p + 1) == -1); 425 &addr, *(num_p + 1) == -1);
502 if(err) 426 if (err)
503 break; 427 break;
504 } 428 }
505 } 429 }
@@ -508,8 +432,9 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
508 goto out; 432 goto out;
509 } 433 }
510 434
511 if(proc_mm){ 435 if (proc_mm) {
512 /* We have a valid from_mm, so we now have to copy the LDT of 436 /*
437 * We have a valid from_mm, so we now have to copy the LDT of
513 * from_mm to new_mm, because using proc_mm an new mm with 438 * from_mm to new_mm, because using proc_mm an new mm with
514 * an empty/default LDT was created in new_mm() 439 * an empty/default LDT was created in new_mm()
515 */ 440 */
@@ -518,27 +443,27 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
518 { .copy_segments = 443 { .copy_segments =
519 from_mm->id.u.mm_fd } } ); 444 from_mm->id.u.mm_fd } } );
520 i = os_write_file(new_mm->id.u.mm_fd, &copy, sizeof(copy)); 445 i = os_write_file(new_mm->id.u.mm_fd, &copy, sizeof(copy));
521 if(i != sizeof(copy)) 446 if (i != sizeof(copy))
522 printk("new_mm : /proc/mm copy_segments failed, " 447 printk(KERN_ERR "new_mm : /proc/mm copy_segments "
523 "err = %d\n", -i); 448 "failed, err = %d\n", -i);
524 } 449 }
525 450
526 if(!ptrace_ldt) { 451 if (!ptrace_ldt) {
527 /* Our local LDT is used to supply the data for 452 /*
453 * Our local LDT is used to supply the data for
528 * modify_ldt(READLDT), if PTRACE_LDT isn't available, 454 * modify_ldt(READLDT), if PTRACE_LDT isn't available,
529 * i.e., we have to use the stub for modify_ldt, which 455 * i.e., we have to use the stub for modify_ldt, which
530 * can't handle the big read buffer of up to 64kB. 456 * can't handle the big read buffer of up to 64kB.
531 */ 457 */
532 down(&from_mm->ldt.semaphore); 458 down(&from_mm->ldt.semaphore);
533 if(from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES){ 459 if (from_mm->ldt.entry_count <= LDT_DIRECT_ENTRIES)
534 memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries, 460 memcpy(new_mm->ldt.u.entries, from_mm->ldt.u.entries,
535 sizeof(new_mm->ldt.u.entries)); 461 sizeof(new_mm->ldt.u.entries));
536 } 462 else {
537 else{
538 i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; 463 i = from_mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
539 while(i-->0){ 464 while (i-->0) {
540 page = __get_free_page(GFP_KERNEL|__GFP_ZERO); 465 page = __get_free_page(GFP_KERNEL|__GFP_ZERO);
541 if (!page){ 466 if (!page) {
542 err = -ENOMEM; 467 err = -ENOMEM;
543 break; 468 break;
544 } 469 }
@@ -557,22 +482,19 @@ long init_new_ldt(struct mmu_context_skas * new_mm,
557} 482}
558 483
559 484
560void free_ldt(struct mmu_context_skas * mm) 485void free_ldt(struct mm_context *mm)
561{ 486{
562 int i; 487 int i;
563 488
564 if(!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES){ 489 if (!ptrace_ldt && mm->ldt.entry_count > LDT_DIRECT_ENTRIES) {
565 i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE; 490 i = mm->ldt.entry_count / LDT_ENTRIES_PER_PAGE;
566 while(i-- > 0){ 491 while (i-- > 0)
567 free_page((long )mm->ldt.u.pages[i]); 492 free_page((long) mm->ldt.u.pages[i]);
568 }
569 } 493 }
570 mm->ldt.entry_count = 0; 494 mm->ldt.entry_count = 0;
571} 495}
572#endif
573 496
574int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount) 497int sys_modify_ldt(int func, void __user *ptr, unsigned long bytecount)
575{ 498{
576 return CHOOSE_MODE_PROC(do_modify_ldt_tt, do_modify_ldt_skas, func, 499 return do_modify_ldt_skas(func, ptr, bytecount);
577 ptr, bytecount);
578} 500}
diff --git a/arch/um/sys-i386/ptrace.c b/arch/um/sys-i386/ptrace.c
index 28bf01150323..9657c89fdf31 100644
--- a/arch/um/sys-i386/ptrace.c
+++ b/arch/um/sys-i386/ptrace.c
@@ -1,35 +1,26 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <linux/compiler.h>
7#include "linux/sched.h"
8#include "linux/mm.h" 6#include "linux/mm.h"
9#include "asm/elf.h" 7#include "linux/sched.h"
10#include "asm/ptrace.h"
11#include "asm/uaccess.h" 8#include "asm/uaccess.h"
12#include "asm/unistd.h" 9#include "skas.h"
13#include "sysdep/ptrace.h"
14#include "sysdep/sigcontext.h"
15#include "sysdep/sc.h"
16 10
17void arch_switch_to_tt(struct task_struct *from, struct task_struct *to) 11extern int arch_switch_tls(struct task_struct *from, struct task_struct *to);
18{
19 update_debugregs(to->thread.arch.debugregs_seq);
20 arch_switch_tls_tt(from, to);
21}
22 12
23void arch_switch_to_skas(struct task_struct *from, struct task_struct *to) 13void arch_switch_to(struct task_struct *from, struct task_struct *to)
24{ 14{
25 int err = arch_switch_tls_skas(from, to); 15 int err = arch_switch_tls(from, to);
26 if (!err) 16 if (!err)
27 return; 17 return;
28 18
29 if (err != -EINVAL) 19 if (err != -EINVAL)
30 printk(KERN_WARNING "arch_switch_tls_skas failed, errno %d, not EINVAL\n", -err); 20 printk(KERN_WARNING "arch_switch_tls failed, errno %d, "
21 "not EINVAL\n", -err);
31 else 22 else
32 printk(KERN_WARNING "arch_switch_tls_skas failed, errno = EINVAL\n"); 23 printk(KERN_WARNING "arch_switch_tls failed, errno = EINVAL\n");
33} 24}
34 25
35int is_syscall(unsigned long addr) 26int is_syscall(unsigned long addr)
@@ -38,21 +29,21 @@ int is_syscall(unsigned long addr)
38 int n; 29 int n;
39 30
40 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); 31 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
41 if(n){ 32 if (n) {
42 /* access_process_vm() grants access to vsyscall and stub, 33 /* access_process_vm() grants access to vsyscall and stub,
43 * while copy_from_user doesn't. Maybe access_process_vm is 34 * while copy_from_user doesn't. Maybe access_process_vm is
44 * slow, but that doesn't matter, since it will be called only 35 * slow, but that doesn't matter, since it will be called only
45 * in case of singlestepping, if copy_from_user failed. 36 * in case of singlestepping, if copy_from_user failed.
46 */ 37 */
47 n = access_process_vm(current, addr, &instr, sizeof(instr), 0); 38 n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
48 if(n != sizeof(instr)) { 39 if (n != sizeof(instr)) {
49 printk("is_syscall : failed to read instruction from " 40 printk(KERN_ERR "is_syscall : failed to read "
50 "0x%lx\n", addr); 41 "instruction from 0x%lx\n", addr);
51 return(1); 42 return 1;
52 } 43 }
53 } 44 }
54 /* int 0x80 or sysenter */ 45 /* int 0x80 or sysenter */
55 return((instr == 0x80cd) || (instr == 0x340f)); 46 return (instr == 0x80cd) || (instr == 0x340f);
56} 47}
57 48
58/* determines which flags the user has access to. */ 49/* determines which flags the user has access to. */
@@ -96,21 +87,21 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
96 87
97int poke_user(struct task_struct *child, long addr, long data) 88int poke_user(struct task_struct *child, long addr, long data)
98{ 89{
99 if ((addr & 3) || addr < 0) 90 if ((addr & 3) || addr < 0)
100 return -EIO; 91 return -EIO;
101
102 if (addr < MAX_REG_OFFSET)
103 return putreg(child, addr, data);
104 92
105 else if((addr >= offsetof(struct user, u_debugreg[0])) && 93 if (addr < MAX_REG_OFFSET)
106 (addr <= offsetof(struct user, u_debugreg[7]))){ 94 return putreg(child, addr, data);
107 addr -= offsetof(struct user, u_debugreg[0]); 95 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
108 addr = addr >> 2; 96 (addr <= offsetof(struct user, u_debugreg[7]))) {
109 if((addr == 4) || (addr == 5)) return -EIO; 97 addr -= offsetof(struct user, u_debugreg[0]);
110 child->thread.arch.debugregs[addr] = data; 98 addr = addr >> 2;
111 return 0; 99 if ((addr == 4) || (addr == 5))
112 } 100 return -EIO;
113 return -EIO; 101 child->thread.arch.debugregs[addr] = data;
102 return 0;
103 }
104 return -EIO;
114} 105}
115 106
116unsigned long getreg(struct task_struct *child, int regno) 107unsigned long getreg(struct task_struct *child, int regno)
@@ -133,20 +124,20 @@ unsigned long getreg(struct task_struct *child, int regno)
133 return retval; 124 return retval;
134} 125}
135 126
127/* read the word at location addr in the USER area. */
136int peek_user(struct task_struct *child, long addr, long data) 128int peek_user(struct task_struct *child, long addr, long data)
137{ 129{
138/* read the word at location addr in the USER area. */
139 unsigned long tmp; 130 unsigned long tmp;
140 131
141 if ((addr & 3) || addr < 0) 132 if ((addr & 3) || addr < 0)
142 return -EIO; 133 return -EIO;
143 134
144 tmp = 0; /* Default return condition */ 135 tmp = 0; /* Default return condition */
145 if(addr < MAX_REG_OFFSET){ 136 if (addr < MAX_REG_OFFSET) {
146 tmp = getreg(child, addr); 137 tmp = getreg(child, addr);
147 } 138 }
148 else if((addr >= offsetof(struct user, u_debugreg[0])) && 139 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
149 (addr <= offsetof(struct user, u_debugreg[7]))){ 140 (addr <= offsetof(struct user, u_debugreg[7]))) {
150 addr -= offsetof(struct user, u_debugreg[0]); 141 addr -= offsetof(struct user, u_debugreg[0]);
151 addr = addr >> 2; 142 addr = addr >> 2;
152 tmp = child->thread.arch.debugregs[addr]; 143 tmp = child->thread.arch.debugregs[addr];
@@ -154,277 +145,68 @@ int peek_user(struct task_struct *child, long addr, long data)
154 return put_user(tmp, (unsigned long __user *) data); 145 return put_user(tmp, (unsigned long __user *) data);
155} 146}
156 147
157struct i387_fxsave_struct { 148int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
158 unsigned short cwd;
159 unsigned short swd;
160 unsigned short twd;
161 unsigned short fop;
162 long fip;
163 long fcs;
164 long foo;
165 long fos;
166 long mxcsr;
167 long reserved;
168 long st_space[32]; /* 8*16 bytes for each FP-reg = 128 bytes */
169 long xmm_space[32]; /* 8*16 bytes for each XMM-reg = 128 bytes */
170 long padding[56];
171};
172
173/*
174 * FPU tag word conversions.
175 */
176
177static inline unsigned short twd_i387_to_fxsr( unsigned short twd )
178{ 149{
179 unsigned int tmp; /* to avoid 16 bit prefixes in the code */ 150 int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
180 151 long fpregs[HOST_FP_SIZE];
181 /* Transform each pair of bits into 01 (valid) or 00 (empty) */
182 tmp = ~twd;
183 tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
184 /* and move the valid bits to the lower byte. */
185 tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
186 tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
187 tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
188 return tmp;
189}
190 152
191static inline unsigned long twd_fxsr_to_i387( struct i387_fxsave_struct *fxsave ) 153 BUG_ON(sizeof(*buf) != sizeof(fpregs));
192{ 154 err = save_fp_registers(userspace_pid[cpu], fpregs);
193 struct _fpxreg *st = NULL; 155 if (err)
194 unsigned long twd = (unsigned long) fxsave->twd; 156 return err;
195 unsigned long tag;
196 unsigned long ret = 0xffff0000;
197 int i;
198 157
199#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16); 158 n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
159 if(n > 0)
160 return -EFAULT;
200 161
201 for ( i = 0 ; i < 8 ; i++ ) { 162 return n;
202 if ( twd & 0x1 ) {
203 st = (struct _fpxreg *) FPREG_ADDR( fxsave, i );
204
205 switch ( st->exponent & 0x7fff ) {
206 case 0x7fff:
207 tag = 2; /* Special */
208 break;
209 case 0x0000:
210 if ( !st->significand[0] &&
211 !st->significand[1] &&
212 !st->significand[2] &&
213 !st->significand[3] ) {
214 tag = 1; /* Zero */
215 } else {
216 tag = 2; /* Special */
217 }
218 break;
219 default:
220 if ( st->significand[3] & 0x8000 ) {
221 tag = 0; /* Valid */
222 } else {
223 tag = 2; /* Special */
224 }
225 break;
226 }
227 } else {
228 tag = 3; /* Empty */
229 }
230 ret |= (tag << (2 * i));
231 twd = twd >> 1;
232 }
233 return ret;
234} 163}
235 164
236/* 165int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
237 * FXSR floating point environment conversions.
238 */
239
240#ifdef CONFIG_MODE_TT
241static inline int convert_fxsr_to_user_tt(struct _fpstate __user *buf,
242 struct pt_regs *regs)
243{ 166{
244 struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs)); 167 int n, cpu = ((struct thread_info *) child->stack)->cpu;
245 unsigned long env[7]; 168 long fpregs[HOST_FP_SIZE];
246 struct _fpreg __user *to;
247 struct _fpxreg *from;
248 int i;
249 169
250 env[0] = (unsigned long)fxsave->cwd | 0xffff0000; 170 BUG_ON(sizeof(*buf) != sizeof(fpregs));
251 env[1] = (unsigned long)fxsave->swd | 0xffff0000; 171 n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
252 env[2] = twd_fxsr_to_i387(fxsave); 172 if (n > 0)
253 env[3] = fxsave->fip; 173 return -EFAULT;
254 env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
255 env[5] = fxsave->foo;
256 env[6] = fxsave->fos;
257 174
258 if ( __copy_to_user( buf, env, 7 * sizeof(unsigned long) ) ) 175 return restore_fp_registers(userspace_pid[cpu], fpregs);
259 return 1;
260
261 to = &buf->_st[0];
262 from = (struct _fpxreg *) &fxsave->st_space[0];
263 for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
264 if ( __copy_to_user( to, from, sizeof(*to) ) )
265 return 1;
266 }
267 return 0;
268} 176}
269#endif
270 177
271static inline int convert_fxsr_to_user(struct _fpstate __user *buf, 178int get_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
272 struct pt_regs *regs)
273{ 179{
274 return(CHOOSE_MODE(convert_fxsr_to_user_tt(buf, regs), 0)); 180 int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
275} 181 long fpregs[HOST_XFP_SIZE];
276 182
277#ifdef CONFIG_MODE_TT 183 BUG_ON(sizeof(*buf) != sizeof(fpregs));
278static inline int convert_fxsr_from_user_tt(struct pt_regs *regs, 184 err = save_fpx_registers(userspace_pid[cpu], fpregs);
279 struct _fpstate __user *buf) 185 if (err)
280{ 186 return err;
281 struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
282 unsigned long env[7];
283 struct _fpxreg *to;
284 struct _fpreg __user *from;
285 int i;
286
287 if ( __copy_from_user( env, buf, 7 * sizeof(long) ) )
288 return 1;
289 187
290 fxsave->cwd = (unsigned short)(env[0] & 0xffff); 188 n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
291 fxsave->swd = (unsigned short)(env[1] & 0xffff); 189 if(n > 0)
292 fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff)); 190 return -EFAULT;
293 fxsave->fip = env[3];
294 fxsave->fop = (unsigned short)((env[4] & 0xffff0000) >> 16);
295 fxsave->fcs = (env[4] & 0xffff);
296 fxsave->foo = env[5];
297 fxsave->fos = env[6];
298 191
299 to = (struct _fpxreg *) &fxsave->st_space[0]; 192 return n;
300 from = &buf->_st[0];
301 for ( i = 0 ; i < 8 ; i++, to++, from++ ) {
302 if ( __copy_from_user( to, from, sizeof(*from) ) )
303 return 1;
304 }
305 return 0;
306}
307#endif
308
309static inline int convert_fxsr_from_user(struct pt_regs *regs,
310 struct _fpstate __user *buf)
311{
312 return(CHOOSE_MODE(convert_fxsr_from_user_tt(regs, buf), 0));
313}
314
315int get_fpregs(unsigned long buf, struct task_struct *child)
316{
317 int err;
318
319 err = convert_fxsr_to_user((struct _fpstate __user *) buf,
320 &child->thread.regs);
321 if(err) return(-EFAULT);
322 else return(0);
323}
324
325int set_fpregs(unsigned long buf, struct task_struct *child)
326{
327 int err;
328
329 err = convert_fxsr_from_user(&child->thread.regs,
330 (struct _fpstate __user *) buf);
331 if(err) return(-EFAULT);
332 else return(0);
333}
334
335#ifdef CONFIG_MODE_TT
336int get_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
337{
338 struct pt_regs *regs = &tsk->thread.regs;
339 struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
340 int err;
341
342 err = __copy_to_user((void __user *) buf, fxsave,
343 sizeof(struct user_fxsr_struct));
344 if(err) return -EFAULT;
345 else return 0;
346}
347#endif
348
349int get_fpxregs(unsigned long buf, struct task_struct *tsk)
350{
351 return(CHOOSE_MODE(get_fpxregs_tt(buf, tsk), 0));
352}
353
354#ifdef CONFIG_MODE_TT
355int set_fpxregs_tt(unsigned long buf, struct task_struct *tsk)
356{
357 struct pt_regs *regs = &tsk->thread.regs;
358 struct i387_fxsave_struct *fxsave = SC_FXSR_ENV(PT_REGS_SC(regs));
359 int err;
360
361 err = __copy_from_user(fxsave, (void __user *) buf,
362 sizeof(struct user_fxsr_struct) );
363 if(err) return -EFAULT;
364 else return 0;
365}
366#endif
367
368int set_fpxregs(unsigned long buf, struct task_struct *tsk)
369{
370 return(CHOOSE_MODE(set_fpxregs_tt(buf, tsk), 0));
371}
372
373#ifdef notdef
374int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu)
375{
376 fpu->cwd = (((SC_FP_CW(PT_REGS_SC(regs)) & 0xffff) << 16) |
377 (SC_FP_SW(PT_REGS_SC(regs)) & 0xffff));
378 fpu->swd = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
379 fpu->twd = SC_FP_IPOFF(PT_REGS_SC(regs));
380 fpu->fip = SC_FP_CSSEL(PT_REGS_SC(regs)) & 0xffff;
381 fpu->fcs = SC_FP_DATAOFF(PT_REGS_SC(regs));
382 fpu->foo = SC_FP_DATASEL(PT_REGS_SC(regs));
383 fpu->fos = 0;
384 memcpy(fpu->st_space, (void *) SC_FP_ST(PT_REGS_SC(regs)),
385 sizeof(fpu->st_space));
386 return(1);
387} 193}
388#endif
389 194
390#ifdef CONFIG_MODE_TT 195int set_fpxregs(struct user_fxsr_struct __user *buf, struct task_struct *child)
391static inline void copy_fpu_fxsave_tt(struct pt_regs *regs,
392 struct user_i387_struct *buf)
393{ 196{
394 struct i387_fxsave_struct *fpu = SC_FXSR_ENV(PT_REGS_SC(regs)); 197 int n, cpu = ((struct thread_info *) child->stack)->cpu;
395 unsigned short *to; 198 long fpregs[HOST_XFP_SIZE];
396 unsigned short *from;
397 int i;
398 199
399 memcpy( buf, fpu, 7 * sizeof(long) ); 200 BUG_ON(sizeof(*buf) != sizeof(fpregs));
201 n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
202 if (n > 0)
203 return -EFAULT;
400 204
401 to = (unsigned short *) &buf->st_space[0]; 205 return restore_fpx_registers(userspace_pid[cpu], fpregs);
402 from = (unsigned short *) &fpu->st_space[0];
403 for ( i = 0 ; i < 8 ; i++, to += 5, from += 8 ) {
404 memcpy( to, from, 5 * sizeof(unsigned short) );
405 }
406} 206}
407#endif
408 207
409static inline void copy_fpu_fxsave(struct pt_regs *regs, 208long subarch_ptrace(struct task_struct *child, long request, long addr,
410 struct user_i387_struct *buf) 209 long data)
411{ 210{
412 (void) CHOOSE_MODE(copy_fpu_fxsave_tt(regs, buf), 0); 211 return -EIO;
413} 212}
414
415int dump_fpu(struct pt_regs *regs, elf_fpregset_t *fpu )
416{
417 copy_fpu_fxsave(regs, (struct user_i387_struct *) fpu);
418 return(1);
419}
420
421/*
422 * Overrides for Emacs so that we follow Linus's tabbing style.
423 * Emacs will notice this stuff at the end of the file and automatically
424 * adjust the settings for this buffer only. This must remain at the end
425 * of the file.
426 * ---------------------------------------------------------------------------
427 * Local variables:
428 * c-file-style: "linux"
429 * End:
430 */
diff --git a/arch/um/sys-i386/ptrace_user.c b/arch/um/sys-i386/ptrace_user.c
index 40ff0c831bd0..5cf97bc229b9 100644
--- a/arch/um/sys-i386/ptrace_user.c
+++ b/arch/um/sys-i386/ptrace_user.c
@@ -1,20 +1,10 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <stdio.h>
7#include <stddef.h>
8#include <errno.h> 6#include <errno.h>
9#include <unistd.h> 7#include <sys/ptrace.h>
10#include "ptrace_user.h"
11/* Grr, asm/user.h includes asm/ptrace.h, so has to follow ptrace_user.h */
12#include <asm/user.h>
13#include "kern_util.h"
14#include "sysdep/thread.h"
15#include "user.h"
16#include "os.h"
17#include "uml-config.h"
18 8
19int ptrace_getregs(long pid, unsigned long *regs_out) 9int ptrace_getregs(long pid, unsigned long *regs_out)
20{ 10{
@@ -43,89 +33,3 @@ int ptrace_setfpregs(long pid, unsigned long *regs)
43 return -errno; 33 return -errno;
44 return 0; 34 return 0;
45} 35}
46
47#ifdef UML_CONFIG_MODE_TT
48
49static void write_debugregs(int pid, unsigned long *regs)
50{
51 struct user *dummy;
52 int nregs, i;
53
54 dummy = NULL;
55 nregs = ARRAY_SIZE(dummy->u_debugreg);
56 for(i = 0; i < nregs; i++){
57 if((i == 4) || (i == 5)) continue;
58 if(ptrace(PTRACE_POKEUSR, pid, &dummy->u_debugreg[i],
59 regs[i]) < 0)
60 printk("write_debugregs - ptrace failed on "
61 "register %d, value = 0x%lx, errno = %d\n", i,
62 regs[i], errno);
63 }
64}
65
66static void read_debugregs(int pid, unsigned long *regs)
67{
68 struct user *dummy;
69 int nregs, i;
70
71 dummy = NULL;
72 nregs = ARRAY_SIZE(dummy->u_debugreg);
73 for(i = 0; i < nregs; i++){
74 regs[i] = ptrace(PTRACE_PEEKUSR, pid,
75 &dummy->u_debugreg[i], 0);
76 }
77}
78
79/* Accessed only by the tracing thread */
80static unsigned long kernel_debugregs[8] = { [ 0 ... 7 ] = 0 };
81
82void arch_enter_kernel(void *task, int pid)
83{
84 read_debugregs(pid, TASK_DEBUGREGS(task));
85 write_debugregs(pid, kernel_debugregs);
86}
87
88void arch_leave_kernel(void *task, int pid)
89{
90 read_debugregs(pid, kernel_debugregs);
91 write_debugregs(pid, TASK_DEBUGREGS(task));
92}
93
94#ifdef UML_CONFIG_PT_PROXY
95/* Accessed only by the tracing thread */
96static int debugregs_seq;
97
98/* Only called by the ptrace proxy */
99void ptrace_pokeuser(unsigned long addr, unsigned long data)
100{
101 if((addr < offsetof(struct user, u_debugreg[0])) ||
102 (addr > offsetof(struct user, u_debugreg[7])))
103 return;
104 addr -= offsetof(struct user, u_debugreg[0]);
105 addr = addr >> 2;
106 if(kernel_debugregs[addr] == data) return;
107
108 kernel_debugregs[addr] = data;
109 debugregs_seq++;
110}
111
112static void update_debugregs_cb(void *arg)
113{
114 int pid = *((int *) arg);
115
116 write_debugregs(pid, kernel_debugregs);
117}
118
119/* Optimized out in its header when not defined */
120void update_debugregs(int seq)
121{
122 int me;
123
124 if(seq == debugregs_seq) return;
125
126 me = os_getpid();
127 initial_thread_cb(update_debugregs_cb, &me);
128}
129#endif
130
131#endif
diff --git a/arch/um/sys-i386/sigcontext.c b/arch/um/sys-i386/sigcontext.c
deleted file mode 100644
index 467d489c31cd..000000000000
--- a/arch/um/sys-i386/sigcontext.c
+++ /dev/null
@@ -1,71 +0,0 @@
1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <stddef.h>
7#include <string.h>
8#include <asm/ptrace.h>
9#include <asm/sigcontext.h>
10#include "sysdep/ptrace.h"
11#include "kern_util.h"
12
13void sc_to_sc(void *to_ptr, void *from_ptr)
14{
15 struct sigcontext *to = to_ptr, *from = from_ptr;
16
17 memcpy(to, from, sizeof(*to) + sizeof(struct _fpstate));
18 if(from->fpstate != NULL)
19 to->fpstate = (struct _fpstate *) (to + 1);
20}
21
22unsigned long *sc_sigmask(void *sc_ptr)
23{
24 struct sigcontext *sc = sc_ptr;
25 return &sc->oldmask;
26}
27
28int sc_get_fpregs(unsigned long buf, void *sc_ptr)
29{
30 struct sigcontext *sc = sc_ptr;
31 struct _fpstate *from = sc->fpstate, *to = (struct _fpstate *) buf;
32 int err = 0;
33
34 if(from == NULL){
35 err |= clear_user_proc(&to->cw, sizeof(to->cw));
36 err |= clear_user_proc(&to->sw, sizeof(to->sw));
37 err |= clear_user_proc(&to->tag, sizeof(to->tag));
38 err |= clear_user_proc(&to->ipoff, sizeof(to->ipoff));
39 err |= clear_user_proc(&to->cssel, sizeof(to->cssel));
40 err |= clear_user_proc(&to->dataoff, sizeof(to->dataoff));
41 err |= clear_user_proc(&to->datasel, sizeof(to->datasel));
42 err |= clear_user_proc(&to->_st, sizeof(to->_st));
43 }
44 else {
45 err |= copy_to_user_proc(&to->cw, &from->cw, sizeof(to->cw));
46 err |= copy_to_user_proc(&to->sw, &from->sw, sizeof(to->sw));
47 err |= copy_to_user_proc(&to->tag, &from->tag,
48 sizeof(to->tag));
49 err |= copy_to_user_proc(&to->ipoff, &from->ipoff,
50 sizeof(to->ipoff));
51 err |= copy_to_user_proc(&to->cssel,& from->cssel,
52 sizeof(to->cssel));
53 err |= copy_to_user_proc(&to->dataoff, &from->dataoff,
54 sizeof(to->dataoff));
55 err |= copy_to_user_proc(&to->datasel, &from->datasel,
56 sizeof(to->datasel));
57 err |= copy_to_user_proc(to->_st, from->_st, sizeof(to->_st));
58 }
59 return(err);
60}
61
62/*
63 * Overrides for Emacs so that we follow Linus's tabbing style.
64 * Emacs will notice this stuff at the end of the file and automatically
65 * adjust the settings for this buffer only. This must remain at the end
66 * of the file.
67 * ---------------------------------------------------------------------------
68 * Local variables:
69 * c-file-style: "linux"
70 * End:
71 */
diff --git a/arch/um/sys-i386/signal.c b/arch/um/sys-i386/signal.c
index 1cbf95f6858a..0147227ce18d 100644
--- a/arch/um/sys-i386/signal.c
+++ b/arch/um/sys-i386/signal.c
@@ -1,189 +1,293 @@
1/* 1/*
2 * Copyright (C) 2004 Jeff Dike (jdike@addtoit.com) 2 * Copyright (C) 2004 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/signal.h"
7#include "linux/ptrace.h" 6#include "linux/ptrace.h"
8#include "asm/current.h"
9#include "asm/ucontext.h"
10#include "asm/uaccess.h"
11#include "asm/unistd.h" 7#include "asm/unistd.h"
8#include "asm/uaccess.h"
9#include "asm/ucontext.h"
12#include "frame_kern.h" 10#include "frame_kern.h"
13#include "sigcontext.h"
14#include "registers.h"
15#include "mode.h"
16
17#ifdef CONFIG_MODE_SKAS
18
19#include "skas.h" 11#include "skas.h"
20 12
21void copy_sc(union uml_pt_regs *regs, void *from) 13void copy_sc(struct uml_pt_regs *regs, void *from)
22{ 14{
23 struct sigcontext *sc = from; 15 struct sigcontext *sc = from;
24 16
25 REGS_GS(regs->skas.regs) = sc->gs; 17 REGS_GS(regs->gp) = sc->gs;
26 REGS_FS(regs->skas.regs) = sc->fs; 18 REGS_FS(regs->gp) = sc->fs;
27 REGS_ES(regs->skas.regs) = sc->es; 19 REGS_ES(regs->gp) = sc->es;
28 REGS_DS(regs->skas.regs) = sc->ds; 20 REGS_DS(regs->gp) = sc->ds;
29 REGS_EDI(regs->skas.regs) = sc->edi; 21 REGS_EDI(regs->gp) = sc->edi;
30 REGS_ESI(regs->skas.regs) = sc->esi; 22 REGS_ESI(regs->gp) = sc->esi;
31 REGS_EBP(regs->skas.regs) = sc->ebp; 23 REGS_EBP(regs->gp) = sc->ebp;
32 REGS_SP(regs->skas.regs) = sc->esp; 24 REGS_SP(regs->gp) = sc->esp;
33 REGS_EBX(regs->skas.regs) = sc->ebx; 25 REGS_EBX(regs->gp) = sc->ebx;
34 REGS_EDX(regs->skas.regs) = sc->edx; 26 REGS_EDX(regs->gp) = sc->edx;
35 REGS_ECX(regs->skas.regs) = sc->ecx; 27 REGS_ECX(regs->gp) = sc->ecx;
36 REGS_EAX(regs->skas.regs) = sc->eax; 28 REGS_EAX(regs->gp) = sc->eax;
37 REGS_IP(regs->skas.regs) = sc->eip; 29 REGS_IP(regs->gp) = sc->eip;
38 REGS_CS(regs->skas.regs) = sc->cs; 30 REGS_CS(regs->gp) = sc->cs;
39 REGS_EFLAGS(regs->skas.regs) = sc->eflags; 31 REGS_EFLAGS(regs->gp) = sc->eflags;
40 REGS_SS(regs->skas.regs) = sc->ss; 32 REGS_SS(regs->gp) = sc->ss;
41} 33}
42 34
43static int copy_sc_from_user_skas(struct pt_regs *regs, 35/*
44 struct sigcontext __user *from) 36 * FPU tag word conversions.
37 */
38
39static inline unsigned short twd_i387_to_fxsr(unsigned short twd)
45{ 40{
46 struct sigcontext sc; 41 unsigned int tmp; /* to avoid 16 bit prefixes in the code */
47 unsigned long fpregs[HOST_FP_SIZE]; 42
48 int err; 43 /* Transform each pair of bits into 01 (valid) or 00 (empty) */
44 tmp = ~twd;
45 tmp = (tmp | (tmp>>1)) & 0x5555; /* 0V0V0V0V0V0V0V0V */
46 /* and move the valid bits to the lower byte. */
47 tmp = (tmp | (tmp >> 1)) & 0x3333; /* 00VV00VV00VV00VV */
48 tmp = (tmp | (tmp >> 2)) & 0x0f0f; /* 0000VVVV0000VVVV */
49 tmp = (tmp | (tmp >> 4)) & 0x00ff; /* 00000000VVVVVVVV */
50 return tmp;
51}
49 52
50 err = copy_from_user(&sc, from, sizeof(sc)); 53static inline unsigned long twd_fxsr_to_i387(struct user_fxsr_struct *fxsave)
51 err |= copy_from_user(fpregs, sc.fpstate, sizeof(fpregs)); 54{
52 if(err) 55 struct _fpxreg *st = NULL;
53 return err; 56 unsigned long twd = (unsigned long) fxsave->twd;
57 unsigned long tag;
58 unsigned long ret = 0xffff0000;
59 int i;
60
61#define FPREG_ADDR(f, n) ((char *)&(f)->st_space + (n) * 16);
62
63 for (i = 0; i < 8; i++) {
64 if (twd & 0x1) {
65 st = (struct _fpxreg *) FPREG_ADDR(fxsave, i);
66
67 switch (st->exponent & 0x7fff) {
68 case 0x7fff:
69 tag = 2; /* Special */
70 break;
71 case 0x0000:
72 if ( !st->significand[0] &&
73 !st->significand[1] &&
74 !st->significand[2] &&
75 !st->significand[3] ) {
76 tag = 1; /* Zero */
77 } else {
78 tag = 2; /* Special */
79 }
80 break;
81 default:
82 if (st->significand[3] & 0x8000) {
83 tag = 0; /* Valid */
84 } else {
85 tag = 2; /* Special */
86 }
87 break;
88 }
89 } else {
90 tag = 3; /* Empty */
91 }
92 ret |= (tag << (2 * i));
93 twd = twd >> 1;
94 }
95 return ret;
96}
54 97
55 copy_sc(&regs->regs, &sc); 98static int convert_fxsr_to_user(struct _fpstate __user *buf,
99 struct user_fxsr_struct *fxsave)
100{
101 unsigned long env[7];
102 struct _fpreg __user *to;
103 struct _fpxreg *from;
104 int i;
105
106 env[0] = (unsigned long)fxsave->cwd | 0xffff0000ul;
107 env[1] = (unsigned long)fxsave->swd | 0xffff0000ul;
108 env[2] = twd_fxsr_to_i387(fxsave);
109 env[3] = fxsave->fip;
110 env[4] = fxsave->fcs | ((unsigned long)fxsave->fop << 16);
111 env[5] = fxsave->foo;
112 env[6] = fxsave->fos;
113
114 if (__copy_to_user(buf, env, 7 * sizeof(unsigned long)))
115 return 1;
56 116
57 err = restore_fp_registers(userspace_pid[0], fpregs); 117 to = &buf->_st[0];
58 if(err < 0) { 118 from = (struct _fpxreg *) &fxsave->st_space[0];
59 printk("copy_sc_from_user_skas - PTRACE_SETFPREGS failed, " 119 for (i = 0; i < 8; i++, to++, from++) {
60 "errno = %d\n", -err); 120 unsigned long __user *t = (unsigned long __user *)to;
61 return err; 121 unsigned long *f = (unsigned long *)from;
62 }
63 122
123 if (__put_user(*f, t) ||
124 __put_user(*(f + 1), t + 1) ||
125 __put_user(from->exponent, &to->exponent))
126 return 1;
127 }
64 return 0; 128 return 0;
65} 129}
66 130
67int copy_sc_to_user_skas(struct sigcontext __user *to, struct _fpstate __user *to_fp, 131static int convert_fxsr_from_user(struct user_fxsr_struct *fxsave,
68 struct pt_regs *regs, unsigned long sp) 132 struct _fpstate __user *buf)
69{ 133{
70 struct sigcontext sc; 134 unsigned long env[7];
71 unsigned long fpregs[HOST_FP_SIZE]; 135 struct _fpxreg *to;
72 struct faultinfo * fi = &current->thread.arch.faultinfo; 136 struct _fpreg __user *from;
73 int err; 137 int i;
74 138
75 sc.gs = REGS_GS(regs->regs.skas.regs); 139 if (copy_from_user( env, buf, 7 * sizeof(long)))
76 sc.fs = REGS_FS(regs->regs.skas.regs);
77 sc.es = REGS_ES(regs->regs.skas.regs);
78 sc.ds = REGS_DS(regs->regs.skas.regs);
79 sc.edi = REGS_EDI(regs->regs.skas.regs);
80 sc.esi = REGS_ESI(regs->regs.skas.regs);
81 sc.ebp = REGS_EBP(regs->regs.skas.regs);
82 sc.esp = sp;
83 sc.ebx = REGS_EBX(regs->regs.skas.regs);
84 sc.edx = REGS_EDX(regs->regs.skas.regs);
85 sc.ecx = REGS_ECX(regs->regs.skas.regs);
86 sc.eax = REGS_EAX(regs->regs.skas.regs);
87 sc.eip = REGS_IP(regs->regs.skas.regs);
88 sc.cs = REGS_CS(regs->regs.skas.regs);
89 sc.eflags = REGS_EFLAGS(regs->regs.skas.regs);
90 sc.esp_at_signal = regs->regs.skas.regs[UESP];
91 sc.ss = regs->regs.skas.regs[SS];
92 sc.cr2 = fi->cr2;
93 sc.err = fi->error_code;
94 sc.trapno = fi->trap_no;
95
96 err = save_fp_registers(userspace_pid[0], fpregs);
97 if(err < 0){
98 printk("copy_sc_to_user_skas - PTRACE_GETFPREGS failed, "
99 "errno = %d\n", err);
100 return 1; 140 return 1;
101 }
102 to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
103 sc.fpstate = to_fp;
104 141
105 if(err) 142 fxsave->cwd = (unsigned short)(env[0] & 0xffff);
106 return err; 143 fxsave->swd = (unsigned short)(env[1] & 0xffff);
107 144 fxsave->twd = twd_i387_to_fxsr((unsigned short)(env[2] & 0xffff));
108 return copy_to_user(to, &sc, sizeof(sc)) || 145 fxsave->fip = env[3];
109 copy_to_user(to_fp, fpregs, sizeof(fpregs)); 146 fxsave->fop = (unsigned short)((env[4] & 0xffff0000ul) >> 16);
147 fxsave->fcs = (env[4] & 0xffff);
148 fxsave->foo = env[5];
149 fxsave->fos = env[6];
150
151 to = (struct _fpxreg *) &fxsave->st_space[0];
152 from = &buf->_st[0];
153 for (i = 0; i < 8; i++, to++, from++) {
154 unsigned long *t = (unsigned long *)to;
155 unsigned long __user *f = (unsigned long __user *)from;
156
157 if (__get_user(*t, f) ||
158 __get_user(*(t + 1), f + 1) ||
159 __get_user(to->exponent, &from->exponent))
160 return 1;
161 }
162 return 0;
110} 163}
111#endif
112 164
113#ifdef CONFIG_MODE_TT 165extern int have_fpx_regs;
114 166
115/* These copy a sigcontext to/from userspace. They copy the fpstate pointer, 167static int copy_sc_from_user(struct pt_regs *regs,
116 * blowing away the old, good one. So, that value is saved, and then restored 168 struct sigcontext __user *from)
117 * after the sigcontext copy. In copy_from, the variable holding the saved
118 * fpstate pointer, and the sigcontext that it should be restored to are both
119 * in the kernel, so we can just restore using an assignment. In copy_to, the
120 * saved pointer is in the kernel, but the sigcontext is in userspace, so we
121 * copy_to_user it.
122 */
123int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from,
124 int fpsize)
125{ 169{
126 struct _fpstate *to_fp; 170 struct sigcontext sc;
127 struct _fpstate __user *from_fp;
128 unsigned long sigs;
129 int err; 171 int err;
130 172
131 to_fp = to->fpstate; 173 err = copy_from_user(&sc, from, sizeof(sc));
132 sigs = to->oldmask; 174 if (err)
133 err = copy_from_user(to, from, sizeof(*to)); 175 return err;
134 from_fp = to->fpstate; 176
135 to->oldmask = sigs; 177 copy_sc(&regs->regs, &sc);
136 to->fpstate = to_fp; 178 if (have_fpx_regs) {
137 if(to_fp != NULL) 179 struct user_fxsr_struct fpx;
138 err |= copy_from_user(to_fp, from_fp, fpsize); 180
139 return err; 181 err = copy_from_user(&fpx, &sc.fpstate->_fxsr_env[0],
182 sizeof(struct user_fxsr_struct));
183 if (err)
184 return 1;
185
186 err = convert_fxsr_from_user(&fpx, sc.fpstate);
187 if (err)
188 return 1;
189
190 err = restore_fpx_registers(userspace_pid[current_thread->cpu],
191 (unsigned long *) &fpx);
192 if (err < 0) {
193 printk(KERN_ERR "copy_sc_from_user - "
194 "restore_fpx_registers failed, errno = %d\n",
195 -err);
196 return 1;
197 }
198 }
199 else {
200 struct user_i387_struct fp;
201
202 err = copy_from_user(&fp, sc.fpstate,
203 sizeof(struct user_i387_struct));
204 if (err)
205 return 1;
206
207 err = restore_fp_registers(userspace_pid[current_thread->cpu],
208 (unsigned long *) &fp);
209 if (err < 0) {
210 printk(KERN_ERR "copy_sc_from_user - "
211 "restore_fp_registers failed, errno = %d\n",
212 -err);
213 return 1;
214 }
215 }
216
217 return 0;
140} 218}
141 219
142int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp, 220static int copy_sc_to_user(struct sigcontext __user *to,
143 struct sigcontext *from, int fpsize, unsigned long sp) 221 struct _fpstate __user *to_fp, struct pt_regs *regs,
222 unsigned long sp)
144{ 223{
145 struct _fpstate __user *to_fp; 224 struct sigcontext sc;
146 struct _fpstate *from_fp; 225 struct faultinfo * fi = &current->thread.arch.faultinfo;
147 int err; 226 int err;
148 227
149 to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1)); 228 sc.gs = REGS_GS(regs->regs.gp);
150 from_fp = from->fpstate; 229 sc.fs = REGS_FS(regs->regs.gp);
151 err = copy_to_user(to, from, sizeof(*to)); 230 sc.es = REGS_ES(regs->regs.gp);
231 sc.ds = REGS_DS(regs->regs.gp);
232 sc.edi = REGS_EDI(regs->regs.gp);
233 sc.esi = REGS_ESI(regs->regs.gp);
234 sc.ebp = REGS_EBP(regs->regs.gp);
235 sc.esp = sp;
236 sc.ebx = REGS_EBX(regs->regs.gp);
237 sc.edx = REGS_EDX(regs->regs.gp);
238 sc.ecx = REGS_ECX(regs->regs.gp);
239 sc.eax = REGS_EAX(regs->regs.gp);
240 sc.eip = REGS_IP(regs->regs.gp);
241 sc.cs = REGS_CS(regs->regs.gp);
242 sc.eflags = REGS_EFLAGS(regs->regs.gp);
243 sc.esp_at_signal = regs->regs.gp[UESP];
244 sc.ss = regs->regs.gp[SS];
245 sc.cr2 = fi->cr2;
246 sc.err = fi->error_code;
247 sc.trapno = fi->trap_no;
152 248
153 /* The SP in the sigcontext is the updated one for the signal 249 to_fp = (to_fp ? to_fp : (struct _fpstate __user *) (to + 1));
154 * delivery. The sp passed in is the original, and this needs 250 sc.fpstate = to_fp;
155 * to be restored, so we stick it in separately.
156 */
157 err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp));
158 251
159 if(from_fp != NULL){ 252 if (have_fpx_regs) {
160 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate)); 253 struct user_fxsr_struct fpx;
161 err |= copy_to_user(to_fp, from_fp, fpsize); 254
255 err = save_fpx_registers(userspace_pid[current_thread->cpu],
256 (unsigned long *) &fpx);
257 if (err < 0){
258 printk(KERN_ERR "copy_sc_to_user - save_fpx_registers "
259 "failed, errno = %d\n", err);
260 return 1;
261 }
262
263 err = convert_fxsr_to_user(to_fp, &fpx);
264 if (err)
265 return 1;
266
267 err |= __put_user(fpx.swd, &to_fp->status);
268 err |= __put_user(X86_FXSR_MAGIC, &to_fp->magic);
269 if (err)
270 return 1;
271
272 if (copy_to_user(&to_fp->_fxsr_env[0], &fpx,
273 sizeof(struct user_fxsr_struct)))
274 return 1;
162 } 275 }
163 return err; 276 else {
164} 277 struct user_i387_struct fp;
165#endif
166
167static int copy_sc_from_user(struct pt_regs *to, void __user *from)
168{
169 int ret;
170 278
171 ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from, 279 err = save_fp_registers(userspace_pid[current_thread->cpu],
172 sizeof(struct _fpstate)), 280 (unsigned long *) &fp);
173 copy_sc_from_user_skas(to, from)); 281 if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct)))
174 return ret; 282 return 1;
175} 283 }
176 284
177static int copy_sc_to_user(struct sigcontext __user *to, struct _fpstate __user *fp, 285 return copy_to_user(to, &sc, sizeof(sc));
178 struct pt_regs *from, unsigned long sp)
179{
180 return CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
181 sizeof(*fp), sp),
182 copy_sc_to_user_skas(to, fp, from, sp));
183} 286}
184 287
185static int copy_ucontext_to_user(struct ucontext __user *uc, struct _fpstate __user *fp, 288static int copy_ucontext_to_user(struct ucontext __user *uc,
186 sigset_t *set, unsigned long sp) 289 struct _fpstate __user *fp, sigset_t *set,
290 unsigned long sp)
187{ 291{
188 int err = 0; 292 int err = 0;
189 293
@@ -233,7 +337,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
233 return 1; 337 return 1;
234 338
235 restorer = frame->retcode; 339 restorer = frame->retcode;
236 if(ka->sa.sa_flags & SA_RESTORER) 340 if (ka->sa.sa_flags & SA_RESTORER)
237 restorer = ka->sa.sa_restorer; 341 restorer = ka->sa.sa_restorer;
238 342
239 /* Update SP now because the page fault handler refuses to extend 343 /* Update SP now because the page fault handler refuses to extend
@@ -265,7 +369,7 @@ int setup_signal_stack_sc(unsigned long stack_top, int sig,
265 err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2)); 369 err |= __put_user(__NR_sigreturn, (int __user *)(frame->retcode+2));
266 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6)); 370 err |= __put_user(0x80cd, (short __user *)(frame->retcode+6));
267 371
268 if(err) 372 if (err)
269 goto err; 373 goto err;
270 374
271 PT_REGS_SP(regs) = (unsigned long) frame; 375 PT_REGS_SP(regs) = (unsigned long) frame;
@@ -298,7 +402,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
298 return 1; 402 return 1;
299 403
300 restorer = frame->retcode; 404 restorer = frame->retcode;
301 if(ka->sa.sa_flags & SA_RESTORER) 405 if (ka->sa.sa_flags & SA_RESTORER)
302 restorer = ka->sa.sa_restorer; 406 restorer = ka->sa.sa_restorer;
303 407
304 /* See comment above about why this is here */ 408 /* See comment above about why this is here */
@@ -323,7 +427,7 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
323 err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1)); 427 err |= __put_user(__NR_rt_sigreturn, (int __user *)(frame->retcode+1));
324 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5)); 428 err |= __put_user(0x80cd, (short __user *)(frame->retcode+5));
325 429
326 if(err) 430 if (err)
327 goto err; 431 goto err;
328 432
329 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler; 433 PT_REGS_IP(regs) = (unsigned long) ka->sa.sa_handler;
@@ -350,8 +454,8 @@ long sys_sigreturn(struct pt_regs regs)
350 unsigned long __user *extramask = frame->extramask; 454 unsigned long __user *extramask = frame->extramask;
351 int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long); 455 int sig_size = (_NSIG_WORDS - 1) * sizeof(unsigned long);
352 456
353 if(copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) || 457 if (copy_from_user(&set.sig[0], oldmask, sizeof(set.sig[0])) ||
354 copy_from_user(&set.sig[1], extramask, sig_size)) 458 copy_from_user(&set.sig[1], extramask, sig_size))
355 goto segfault; 459 goto segfault;
356 460
357 sigdelsetmask(&set, ~_BLOCKABLE); 461 sigdelsetmask(&set, ~_BLOCKABLE);
@@ -361,7 +465,7 @@ long sys_sigreturn(struct pt_regs regs)
361 recalc_sigpending(); 465 recalc_sigpending();
362 spin_unlock_irq(&current->sighand->siglock); 466 spin_unlock_irq(&current->sighand->siglock);
363 467
364 if(copy_sc_from_user(&current->thread.regs, sc)) 468 if (copy_sc_from_user(&current->thread.regs, sc))
365 goto segfault; 469 goto segfault;
366 470
367 /* Avoid ERESTART handling */ 471 /* Avoid ERESTART handling */
@@ -376,12 +480,13 @@ long sys_sigreturn(struct pt_regs regs)
376long sys_rt_sigreturn(struct pt_regs regs) 480long sys_rt_sigreturn(struct pt_regs regs)
377{ 481{
378 unsigned long sp = PT_REGS_SP(&current->thread.regs); 482 unsigned long sp = PT_REGS_SP(&current->thread.regs);
379 struct rt_sigframe __user *frame = (struct rt_sigframe __user *) (sp - 4); 483 struct rt_sigframe __user *frame =
484 (struct rt_sigframe __user *) (sp - 4);
380 sigset_t set; 485 sigset_t set;
381 struct ucontext __user *uc = &frame->uc; 486 struct ucontext __user *uc = &frame->uc;
382 int sig_size = _NSIG_WORDS * sizeof(unsigned long); 487 int sig_size = _NSIG_WORDS * sizeof(unsigned long);
383 488
384 if(copy_from_user(&set, &uc->uc_sigmask, sig_size)) 489 if (copy_from_user(&set, &uc->uc_sigmask, sig_size))
385 goto segfault; 490 goto segfault;
386 491
387 sigdelsetmask(&set, ~_BLOCKABLE); 492 sigdelsetmask(&set, ~_BLOCKABLE);
@@ -391,7 +496,7 @@ long sys_rt_sigreturn(struct pt_regs regs)
391 recalc_sigpending(); 496 recalc_sigpending();
392 spin_unlock_irq(&current->sighand->siglock); 497 spin_unlock_irq(&current->sighand->siglock);
393 498
394 if(copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext)) 499 if (copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext))
395 goto segfault; 500 goto segfault;
396 501
397 /* Avoid ERESTART handling */ 502 /* Avoid ERESTART handling */
diff --git a/arch/um/sys-i386/stub.S b/arch/um/sys-i386/stub.S
index 6a70d9ab5c29..e730772c401b 100644
--- a/arch/um/sys-i386/stub.S
+++ b/arch/um/sys-i386/stub.S
@@ -1,4 +1,5 @@
1#include "uml-config.h" 1#include "uml-config.h"
2#include "as-layout.h"
2 3
3 .globl syscall_stub 4 .globl syscall_stub
4.section .__syscall_stub, "x" 5.section .__syscall_stub, "x"
@@ -6,7 +7,7 @@
6 .globl batch_syscall_stub 7 .globl batch_syscall_stub
7batch_syscall_stub: 8batch_syscall_stub:
8 /* load pointer to first operation */ 9 /* load pointer to first operation */
9 mov $(UML_CONFIG_STUB_DATA+8), %esp 10 mov $(ASM_STUB_DATA+8), %esp
10 11
11again: 12again:
12 /* load length of additional data */ 13 /* load length of additional data */
@@ -14,12 +15,12 @@ again:
14 15
15 /* if(length == 0) : end of list */ 16 /* if(length == 0) : end of list */
16 /* write possible 0 to header */ 17 /* write possible 0 to header */
17 mov %eax, UML_CONFIG_STUB_DATA+4 18 mov %eax, ASM_STUB_DATA+4
18 cmpl $0, %eax 19 cmpl $0, %eax
19 jz done 20 jz done
20 21
21 /* save current pointer */ 22 /* save current pointer */
22 mov %esp, UML_CONFIG_STUB_DATA+4 23 mov %esp, ASM_STUB_DATA+4
23 24
24 /* skip additional data */ 25 /* skip additional data */
25 add %eax, %esp 26 add %eax, %esp
@@ -45,7 +46,7 @@ again:
45 46
46done: 47done:
47 /* save return value */ 48 /* save return value */
48 mov %eax, UML_CONFIG_STUB_DATA 49 mov %eax, ASM_STUB_DATA
49 50
50 /* stop */ 51 /* stop */
51 int3 52 int3
diff --git a/arch/um/sys-i386/stub_segv.c b/arch/um/sys-i386/stub_segv.c
index 2355dc19c46c..b3999cb76bfd 100644
--- a/arch/um/sys-i386/stub_segv.c
+++ b/arch/um/sys-i386/stub_segv.c
@@ -6,6 +6,7 @@
6#include <signal.h> 6#include <signal.h>
7#include <sys/select.h> /* The only way I can see to get sigset_t */ 7#include <sys/select.h> /* The only way I can see to get sigset_t */
8#include <asm/unistd.h> 8#include <asm/unistd.h>
9#include "as-layout.h"
9#include "uml-config.h" 10#include "uml-config.h"
10#include "sysdep/stub.h" 11#include "sysdep/stub.h"
11#include "sysdep/sigcontext.h" 12#include "sysdep/sigcontext.h"
@@ -17,8 +18,7 @@ stub_segv_handler(int sig)
17 struct sigcontext *sc = (struct sigcontext *) (&sig + 1); 18 struct sigcontext *sc = (struct sigcontext *) (&sig + 1);
18 int pid; 19 int pid;
19 20
20 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), 21 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA), sc);
21 sc);
22 22
23 pid = stub_syscall0(__NR_getpid); 23 pid = stub_syscall0(__NR_getpid);
24 stub_syscall2(__NR_kill, pid, SIGUSR1); 24 stub_syscall2(__NR_kill, pid, SIGUSR1);
diff --git a/arch/um/sys-i386/tls.c b/arch/um/sys-i386/tls.c
index fea8e5e15cc4..b02266ab5c55 100644
--- a/arch/um/sys-i386/tls.c
+++ b/arch/um/sys-i386/tls.c
@@ -3,25 +3,12 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include "linux/kernel.h" 6#include "linux/percpu.h"
7#include "linux/sched.h" 7#include "linux/sched.h"
8#include "linux/slab.h"
9#include "linux/types.h"
10#include "asm/uaccess.h" 8#include "asm/uaccess.h"
11#include "asm/ptrace.h"
12#include "asm/segment.h"
13#include "asm/smp.h"
14#include "asm/desc.h"
15#include "choose-mode.h"
16#include "kern.h"
17#include "kern_util.h"
18#include "mode_kern.h"
19#include "os.h" 9#include "os.h"
20#include "mode.h"
21
22#ifdef CONFIG_MODE_SKAS
23#include "skas.h" 10#include "skas.h"
24#endif 11#include "sysdep/tls.h"
25 12
26/* 13/*
27 * If needed we can detect when it's uninitialized. 14 * If needed we can detect when it's uninitialized.
@@ -31,8 +18,7 @@
31static int host_supports_tls = -1; 18static int host_supports_tls = -1;
32int host_gdt_entry_tls_min; 19int host_gdt_entry_tls_min;
33 20
34#ifdef CONFIG_MODE_SKAS 21int do_set_thread_area(struct user_desc *info)
35int do_set_thread_area_skas(struct user_desc *info)
36{ 22{
37 int ret; 23 int ret;
38 u32 cpu; 24 u32 cpu;
@@ -43,7 +29,7 @@ int do_set_thread_area_skas(struct user_desc *info)
43 return ret; 29 return ret;
44} 30}
45 31
46int do_get_thread_area_skas(struct user_desc *info) 32int do_get_thread_area(struct user_desc *info)
47{ 33{
48 int ret; 34 int ret;
49 u32 cpu; 35 u32 cpu;
@@ -53,7 +39,6 @@ int do_get_thread_area_skas(struct user_desc *info)
53 put_cpu(); 39 put_cpu();
54 return ret; 40 return ret;
55} 41}
56#endif
57 42
58/* 43/*
59 * sys_get_thread_area: get a yet unused TLS descriptor index. 44 * sys_get_thread_area: get a yet unused TLS descriptor index.
@@ -82,7 +67,8 @@ static inline void clear_user_desc(struct user_desc* info)
82 /* Postcondition: LDT_empty(info) returns true. */ 67 /* Postcondition: LDT_empty(info) returns true. */
83 memset(info, 0, sizeof(*info)); 68 memset(info, 0, sizeof(*info));
84 69
85 /* Check the LDT_empty or the i386 sys_get_thread_area code - we obtain 70 /*
71 * Check the LDT_empty or the i386 sys_get_thread_area code - we obtain
86 * indeed an empty user_desc. 72 * indeed an empty user_desc.
87 */ 73 */
88 info->read_exec_only = 1; 74 info->read_exec_only = 1;
@@ -97,10 +83,13 @@ static int load_TLS(int flags, struct task_struct *to)
97 int idx; 83 int idx;
98 84
99 for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) { 85 for (idx = GDT_ENTRY_TLS_MIN; idx < GDT_ENTRY_TLS_MAX; idx++) {
100 struct uml_tls_struct* curr = &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN]; 86 struct uml_tls_struct* curr =
87 &to->thread.arch.tls_array[idx - GDT_ENTRY_TLS_MIN];
101 88
102 /* Actually, now if it wasn't flushed it gets cleared and 89 /*
103 * flushed to the host, which will clear it.*/ 90 * Actually, now if it wasn't flushed it gets cleared and
91 * flushed to the host, which will clear it.
92 */
104 if (!curr->present) { 93 if (!curr->present) {
105 if (!curr->flushed) { 94 if (!curr->flushed) {
106 clear_user_desc(&curr->tls); 95 clear_user_desc(&curr->tls);
@@ -124,7 +113,8 @@ out:
124 return ret; 113 return ret;
125} 114}
126 115
127/* Verify if we need to do a flush for the new process, i.e. if there are any 116/*
117 * Verify if we need to do a flush for the new process, i.e. if there are any
128 * present desc's, only if they haven't been flushed. 118 * present desc's, only if they haven't been flushed.
129 */ 119 */
130static inline int needs_TLS_update(struct task_struct *task) 120static inline int needs_TLS_update(struct task_struct *task)
@@ -133,10 +123,13 @@ static inline int needs_TLS_update(struct task_struct *task)
133 int ret = 0; 123 int ret = 0;
134 124
135 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { 125 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
136 struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; 126 struct uml_tls_struct* curr =
127 &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
137 128
138 /* Can't test curr->present, we may need to clear a descriptor 129 /*
139 * which had a value. */ 130 * Can't test curr->present, we may need to clear a descriptor
131 * which had a value.
132 */
140 if (curr->flushed) 133 if (curr->flushed)
141 continue; 134 continue;
142 ret = 1; 135 ret = 1;
@@ -145,7 +138,8 @@ static inline int needs_TLS_update(struct task_struct *task)
145 return ret; 138 return ret;
146} 139}
147 140
148/* On a newly forked process, the TLS descriptors haven't yet been flushed. So 141/*
142 * On a newly forked process, the TLS descriptors haven't yet been flushed. So
149 * we mark them as such and the first switch_to will do the job. 143 * we mark them as such and the first switch_to will do the job.
150 */ 144 */
151void clear_flushed_tls(struct task_struct *task) 145void clear_flushed_tls(struct task_struct *task)
@@ -153,10 +147,13 @@ void clear_flushed_tls(struct task_struct *task)
153 int i; 147 int i;
154 148
155 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) { 149 for (i = GDT_ENTRY_TLS_MIN; i < GDT_ENTRY_TLS_MAX; i++) {
156 struct uml_tls_struct* curr = &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN]; 150 struct uml_tls_struct* curr =
151 &task->thread.arch.tls_array[i - GDT_ENTRY_TLS_MIN];
157 152
158 /* Still correct to do this, if it wasn't present on the host it 153 /*
159 * will remain as flushed as it was. */ 154 * Still correct to do this, if it wasn't present on the host it
155 * will remain as flushed as it was.
156 */
160 if (!curr->present) 157 if (!curr->present)
161 continue; 158 continue;
162 159
@@ -164,40 +161,33 @@ void clear_flushed_tls(struct task_struct *task)
164 } 161 }
165} 162}
166 163
167/* In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a 164/*
165 * In SKAS0 mode, currently, multiple guest threads sharing the same ->mm have a
168 * common host process. So this is needed in SKAS0 too. 166 * common host process. So this is needed in SKAS0 too.
169 * 167 *
170 * However, if each thread had a different host process (and this was discussed 168 * However, if each thread had a different host process (and this was discussed
171 * for SMP support) this won't be needed. 169 * for SMP support) this won't be needed.
172 * 170 *
173 * And this will not need be used when (and if) we'll add support to the host 171 * And this will not need be used when (and if) we'll add support to the host
174 * SKAS patch. */ 172 * SKAS patch.
173 */
175 174
176int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to) 175int arch_switch_tls(struct task_struct *from, struct task_struct *to)
177{ 176{
178 if (!host_supports_tls) 177 if (!host_supports_tls)
179 return 0; 178 return 0;
180 179
181 /* We have no need whatsoever to switch TLS for kernel threads; beyond 180 /*
181 * We have no need whatsoever to switch TLS for kernel threads; beyond
182 * that, that would also result in us calling os_set_thread_area with 182 * that, that would also result in us calling os_set_thread_area with
183 * userspace_pid[cpu] == 0, which gives an error. */ 183 * userspace_pid[cpu] == 0, which gives an error.
184 */
184 if (likely(to->mm)) 185 if (likely(to->mm))
185 return load_TLS(O_FORCE, to); 186 return load_TLS(O_FORCE, to);
186 187
187 return 0; 188 return 0;
188} 189}
189 190
190int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to)
191{
192 if (!host_supports_tls)
193 return 0;
194
195 if (needs_TLS_update(to))
196 return load_TLS(0, to);
197
198 return 0;
199}
200
201static int set_tls_entry(struct task_struct* task, struct user_desc *info, 191static int set_tls_entry(struct task_struct* task, struct user_desc *info,
202 int idx, int flushed) 192 int idx, int flushed)
203{ 193{
@@ -251,17 +241,20 @@ static int get_tls_entry(struct task_struct* task, struct user_desc *info, int i
251 *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls; 241 *info = t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].tls;
252 242
253out: 243out:
254 /* Temporary debugging check, to make sure that things have been 244 /*
245 * Temporary debugging check, to make sure that things have been
255 * flushed. This could be triggered if load_TLS() failed. 246 * flushed. This could be triggered if load_TLS() failed.
256 */ 247 */
257 if (unlikely(task == current && !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) { 248 if (unlikely(task == current &&
249 !t->arch.tls_array[idx - GDT_ENTRY_TLS_MIN].flushed)) {
258 printk(KERN_ERR "get_tls_entry: task with pid %d got here " 250 printk(KERN_ERR "get_tls_entry: task with pid %d got here "
259 "without flushed TLS.", current->pid); 251 "without flushed TLS.", current->pid);
260 } 252 }
261 253
262 return 0; 254 return 0;
263clear: 255clear:
264 /* When the TLS entry has not been set, the values read to user in the 256 /*
257 * When the TLS entry has not been set, the values read to user in the
265 * tls_array are 0 (because it's cleared at boot, see 258 * tls_array are 0 (because it's cleared at boot, see
266 * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that. 259 * arch/i386/kernel/head.S:cpu_gdt_table). Emulate that.
267 */ 260 */
@@ -293,7 +286,7 @@ asmlinkage int sys_set_thread_area(struct user_desc __user *user_desc)
293 return -EFAULT; 286 return -EFAULT;
294 } 287 }
295 288
296 ret = CHOOSE_MODE_PROC(do_set_thread_area_tt, do_set_thread_area_skas, &info); 289 ret = do_set_thread_area(&info);
297 if (ret) 290 if (ret)
298 return ret; 291 return ret;
299 return set_tls_entry(current, &info, idx, 1); 292 return set_tls_entry(current, &info, idx, 1);
@@ -363,8 +356,10 @@ out:
363} 356}
364 357
365 358
366/* XXX: This part is probably common to i386 and x86-64. Don't create a common 359/*
367 * file for now, do that when implementing x86-64 support.*/ 360 * XXX: This part is probably common to i386 and x86-64. Don't create a common
361 * file for now, do that when implementing x86-64 support.
362 */
368static int __init __setup_host_supports_tls(void) 363static int __init __setup_host_supports_tls(void)
369{ 364{
370 check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min); 365 check_host_supports_tls(&host_supports_tls, &host_gdt_entry_tls_min);
diff --git a/arch/um/sys-i386/unmap.c b/arch/um/sys-i386/unmap.c
deleted file mode 100644
index 1b0ad0e4adcd..000000000000
--- a/arch/um/sys-i386/unmap.c
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <linux/mman.h>
7#include <asm/unistd.h>
8
9static int errno;
10
11static inline _syscall2(int,munmap,void *,start,size_t,len)
12static inline _syscall6(void *,mmap2,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
13int switcheroo(int fd, int prot, void *from, void *to, int size)
14{
15 if(munmap(to, size) < 0){
16 return(-1);
17 }
18 if(mmap2(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1 ){
19 return(-1);
20 }
21 if(munmap(from, size) < 0){
22 return(-1);
23 }
24 return(0);
25}
diff --git a/arch/um/sys-i386/user-offsets.c b/arch/um/sys-i386/user-offsets.c
index 29118cf5ff25..514241526a1b 100644
--- a/arch/um/sys-i386/user-offsets.c
+++ b/arch/um/sys-i386/user-offsets.c
@@ -2,9 +2,9 @@
2#include <stddef.h> 2#include <stddef.h>
3#include <signal.h> 3#include <signal.h>
4#include <sys/poll.h> 4#include <sys/poll.h>
5#include <sys/user.h>
5#include <sys/mman.h> 6#include <sys/mman.h>
6#include <asm/ptrace.h> 7#include <asm/ptrace.h>
7#include <asm/user.h>
8 8
9#define DEFINE(sym, val) \ 9#define DEFINE(sym, val) \
10 asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 10 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
@@ -48,8 +48,8 @@ void foo(void)
48 OFFSET(HOST_SC_FP_ST, _fpstate, _st); 48 OFFSET(HOST_SC_FP_ST, _fpstate, _st);
49 OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env); 49 OFFSET(HOST_SC_FXSR_ENV, _fpstate, _fxsr_env);
50 50
51 DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_i387_struct)); 51 DEFINE_LONGS(HOST_FP_SIZE, sizeof(struct user_fpregs_struct));
52 DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fxsr_struct)); 52 DEFINE_LONGS(HOST_XFP_SIZE, sizeof(struct user_fpxregs_struct));
53 53
54 DEFINE(HOST_IP, EIP); 54 DEFINE(HOST_IP, EIP);
55 DEFINE(HOST_SP, UESP); 55 DEFINE(HOST_SP, UESP);
diff --git a/arch/um/sys-x86_64/Makefile b/arch/um/sys-x86_64/Makefile
index ea8185d85404..3c22de532088 100644
--- a/arch/um/sys-x86_64/Makefile
+++ b/arch/um/sys-x86_64/Makefile
@@ -5,10 +5,9 @@
5# 5#
6 6
7obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \ 7obj-y = bug.o bugs.o delay.o fault.o ldt.o mem.o ptrace.o ptrace_user.o \
8 setjmp.o sigcontext.o signal.o syscalls.o syscall_table.o sysrq.o \ 8 setjmp.o signal.o stub.o stub_segv.o syscalls.o syscall_table.o \
9 ksyms.o tls.o 9 sysrq.o ksyms.o tls.o
10 10
11obj-$(CONFIG_MODE_SKAS) += stub.o stub_segv.o
12obj-$(CONFIG_MODULES) += um_module.o 11obj-$(CONFIG_MODULES) += um_module.o
13 12
14subarch-obj-y = lib/bitops_64.o lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o 13subarch-obj-y = lib/bitops_64.o lib/csum-partial_64.o lib/memcpy_64.o lib/thunk_64.o
@@ -16,16 +15,12 @@ subarch-obj-$(CONFIG_MODULES) += kernel/module_64.o
16 15
17ldt-y = ../sys-i386/ldt.o 16ldt-y = ../sys-i386/ldt.o
18 17
19USER_OBJS := ptrace_user.o sigcontext.o 18USER_OBJS := ptrace_user.o
20 19
21USER_OBJS += user-offsets.s 20USER_OBJS += user-offsets.s
22extra-y += user-offsets.s 21extra-y += user-offsets.s
23 22
24extra-$(CONFIG_MODE_TT) += unmap.o
25
26UNPROFILE_OBJS := stub_segv.o 23UNPROFILE_OBJS := stub_segv.o
27CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING) 24CFLAGS_stub_segv.o := $(CFLAGS_NO_HARDENING)
28 25
29include arch/um/scripts/Makefile.rules 26include arch/um/scripts/Makefile.rules
30
31$(obj)/unmap.%: _c_flags = $(call unprofile,$(CFLAGS))
diff --git a/arch/um/sys-x86_64/bugs.c b/arch/um/sys-x86_64/bugs.c
index 095478890371..506b6765bbcb 100644
--- a/arch/um/sys-x86_64/bugs.c
+++ b/arch/um/sys-x86_64/bugs.c
@@ -14,7 +14,7 @@ void arch_check_bugs(void)
14{ 14{
15} 15}
16 16
17int arch_handle_signal(int sig, union uml_pt_regs *regs) 17int arch_handle_signal(int sig, struct uml_pt_regs *regs)
18{ 18{
19 return 0; 19 return 0;
20} 20}
diff --git a/arch/um/sys-x86_64/fault.c b/arch/um/sys-x86_64/fault.c
index 4636b1465b6c..ce85117fc64e 100644
--- a/arch/um/sys-x86_64/fault.c
+++ b/arch/um/sys-x86_64/fault.c
@@ -14,14 +14,15 @@ struct exception_table_entry
14}; 14};
15 15
16const struct exception_table_entry *search_exception_tables(unsigned long add); 16const struct exception_table_entry *search_exception_tables(unsigned long add);
17int arch_fixup(unsigned long address, union uml_pt_regs *regs) 17
18int arch_fixup(unsigned long address, struct uml_pt_regs *regs)
18{ 19{
19 const struct exception_table_entry *fixup; 20 const struct exception_table_entry *fixup;
20 21
21 fixup = search_exception_tables(address); 22 fixup = search_exception_tables(address);
22 if(fixup != 0){ 23 if (fixup != 0) {
23 UPT_IP(regs) = fixup->fixup; 24 UPT_IP(regs) = fixup->fixup;
24 return(1); 25 return 1;
25 } 26 }
26 return(0); 27 return 0;
27} 28}
diff --git a/arch/um/sys-x86_64/ptrace.c b/arch/um/sys-x86_64/ptrace.c
index 1970d78aa528..a3cfeed17af4 100644
--- a/arch/um/sys-x86_64/ptrace.c
+++ b/arch/um/sys-x86_64/ptrace.c
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright 2003 PathScale, Inc. 2 * Copyright 2003 PathScale, Inc.
3 * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * 4 *
4 * Licensed under the GPL 5 * Licensed under the GPL
5 */ 6 */
@@ -12,17 +13,10 @@
12#include <asm/uaccess.h> 13#include <asm/uaccess.h>
13#include <asm/elf.h> 14#include <asm/elf.h>
14 15
15/* XXX x86_64 */ 16/*
16unsigned long not_ss; 17 * determines which flags the user has access to.
17unsigned long not_ds; 18 * 1 = access 0 = no access
18unsigned long not_es; 19 */
19
20#define SC_SS(r) (not_ss)
21#define SC_DS(r) (not_ds)
22#define SC_ES(r) (not_es)
23
24/* determines which flags the user has access to. */
25/* 1 = access 0 = no access */
26#define FLAG_MASK 0x44dd5UL 20#define FLAG_MASK 0x44dd5UL
27 21
28int putreg(struct task_struct *child, int regno, unsigned long value) 22int putreg(struct task_struct *child, int regno, unsigned long value)
@@ -66,20 +60,21 @@ int putreg(struct task_struct *child, int regno, unsigned long value)
66 60
67int poke_user(struct task_struct *child, long addr, long data) 61int poke_user(struct task_struct *child, long addr, long data)
68{ 62{
69 if ((addr & 3) || addr < 0) 63 if ((addr & 3) || addr < 0)
70 return -EIO; 64 return -EIO;
71 65
72 if (addr < MAX_REG_OFFSET) 66 if (addr < MAX_REG_OFFSET)
73 return putreg(child, addr, data); 67 return putreg(child, addr, data);
74 else if((addr >= offsetof(struct user, u_debugreg[0])) && 68 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
75 (addr <= offsetof(struct user, u_debugreg[7]))){ 69 (addr <= offsetof(struct user, u_debugreg[7]))){
76 addr -= offsetof(struct user, u_debugreg[0]); 70 addr -= offsetof(struct user, u_debugreg[0]);
77 addr = addr >> 2; 71 addr = addr >> 2;
78 if((addr == 4) || (addr == 5)) return -EIO; 72 if ((addr == 4) || (addr == 5))
79 child->thread.arch.debugregs[addr] = data; 73 return -EIO;
80 return 0; 74 child->thread.arch.debugregs[addr] = data;
81 } 75 return 0;
82 return -EIO; 76 }
77 return -EIO;
83} 78}
84 79
85unsigned long getreg(struct task_struct *child, int regno) 80unsigned long getreg(struct task_struct *child, int regno)
@@ -107,29 +102,22 @@ unsigned long getreg(struct task_struct *child, int regno)
107int peek_user(struct task_struct *child, long addr, long data) 102int peek_user(struct task_struct *child, long addr, long data)
108{ 103{
109 /* read the word at location addr in the USER area. */ 104 /* read the word at location addr in the USER area. */
110 unsigned long tmp; 105 unsigned long tmp;
111
112 if ((addr & 3) || addr < 0)
113 return -EIO;
114
115 tmp = 0; /* Default return condition */
116 if(addr < MAX_REG_OFFSET){
117 tmp = getreg(child, addr);
118 }
119 else if((addr >= offsetof(struct user, u_debugreg[0])) &&
120 (addr <= offsetof(struct user, u_debugreg[7]))){
121 addr -= offsetof(struct user, u_debugreg[0]);
122 addr = addr >> 2;
123 tmp = child->thread.arch.debugregs[addr];
124 }
125 return put_user(tmp, (unsigned long *) data);
126}
127 106
128void arch_switch(void) 107 if ((addr & 3) || addr < 0)
129{ 108 return -EIO;
130/* XXX 109
131 printk("arch_switch\n"); 110 tmp = 0; /* Default return condition */
132*/ 111 if (addr < MAX_REG_OFFSET){
112 tmp = getreg(child, addr);
113 }
114 else if ((addr >= offsetof(struct user, u_debugreg[0])) &&
115 (addr <= offsetof(struct user, u_debugreg[7]))){
116 addr -= offsetof(struct user, u_debugreg[0]);
117 addr = addr >> 2;
118 tmp = child->thread.arch.debugregs[addr];
119 }
120 return put_user(tmp, (unsigned long *) data);
133} 121}
134 122
135/* XXX Mostly copied from sys-i386 */ 123/* XXX Mostly copied from sys-i386 */
@@ -139,54 +127,68 @@ int is_syscall(unsigned long addr)
139 int n; 127 int n;
140 128
141 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr)); 129 n = copy_from_user(&instr, (void __user *) addr, sizeof(instr));
142 if(n){ 130 if (n){
143 /* access_process_vm() grants access to vsyscall and stub, 131 /* access_process_vm() grants access to vsyscall and stub,
144 * while copy_from_user doesn't. Maybe access_process_vm is 132 * while copy_from_user doesn't. Maybe access_process_vm is
145 * slow, but that doesn't matter, since it will be called only 133 * slow, but that doesn't matter, since it will be called only
146 * in case of singlestepping, if copy_from_user failed. 134 * in case of singlestepping, if copy_from_user failed.
147 */ 135 */
148 n = access_process_vm(current, addr, &instr, sizeof(instr), 0); 136 n = access_process_vm(current, addr, &instr, sizeof(instr), 0);
149 if(n != sizeof(instr)) { 137 if (n != sizeof(instr)) {
150 printk("is_syscall : failed to read instruction from " 138 printk("is_syscall : failed to read instruction from "
151 "0x%lx\n", addr); 139 "0x%lx\n", addr);
152 return(1); 140 return 1;
153 } 141 }
154 } 142 }
155 /* sysenter */ 143 /* sysenter */
156 return(instr == 0x050f); 144 return instr == 0x050f;
157} 145}
158 146
159int get_fpregs(unsigned long buf, struct task_struct *child) 147int get_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
160{ 148{
161 panic("get_fpregs"); 149 int err, n, cpu = ((struct thread_info *) child->stack)->cpu;
162 return(0); 150 long fpregs[HOST_FP_SIZE];
163}
164 151
165int set_fpregs(unsigned long buf, struct task_struct *child) 152 BUG_ON(sizeof(*buf) != sizeof(fpregs));
166{ 153 err = save_fp_registers(userspace_pid[cpu], fpregs);
167 panic("set_fpregs"); 154 if (err)
168 return(0); 155 return err;
156
157 n = copy_to_user((void *) buf, fpregs, sizeof(fpregs));
158 if(n > 0)
159 return -EFAULT;
160
161 return n;
169} 162}
170 163
171int get_fpxregs(unsigned long buf, struct task_struct *tsk) 164int set_fpregs(struct user_i387_struct __user *buf, struct task_struct *child)
172{ 165{
173 panic("get_fpxregs"); 166 int n, cpu = ((struct thread_info *) child->stack)->cpu;
174 return(0); 167 long fpregs[HOST_FP_SIZE];
168
169 BUG_ON(sizeof(*buf) != sizeof(fpregs));
170 n = copy_from_user(fpregs, (void *) buf, sizeof(fpregs));
171 if (n > 0)
172 return -EFAULT;
173
174 return restore_fp_registers(userspace_pid[cpu], fpregs);
175} 175}
176 176
177int set_fpxregs(unsigned long buf, struct task_struct *tsk) 177long subarch_ptrace(struct task_struct *child, long request, long addr,
178 long data)
178{ 179{
179 panic("set_fxpregs"); 180 int ret = -EIO;
180 return(0);
181}
182 181
183/* 182 switch (request) {
184 * Overrides for Emacs so that we follow Linus's tabbing style. 183 case PTRACE_GETFPXREGS: /* Get the child FPU state. */
185 * Emacs will notice this stuff at the end of the file and automatically 184 ret = get_fpregs((struct user_i387_struct __user *) data,
186 * adjust the settings for this buffer only. This must remain at the end 185 child);
187 * of the file. 186 break;
188 * --------------------------------------------------------------------------- 187 case PTRACE_SETFPXREGS: /* Set the child FPU state. */
189 * Local variables: 188 ret = set_fpregs((struct user_i387_struct __user *) data,
190 * c-file-style: "linux" 189 child);
191 * End: 190 break;
192 */ 191 }
192
193 return ret;
194}
diff --git a/arch/um/sys-x86_64/sigcontext.c b/arch/um/sys-x86_64/sigcontext.c
deleted file mode 100644
index c88e64def6f2..000000000000
--- a/arch/um/sys-x86_64/sigcontext.c
+++ /dev/null
@@ -1,39 +0,0 @@
1/*
2 * Copyright 2003 PathScale, Inc.
3 *
4 * Licensed under the GPL
5 */
6
7#include <stdio.h>
8#include <string.h>
9#include <signal.h>
10#include "user.h"
11
12void sc_to_sc(void *to_ptr, void *from_ptr)
13{
14 struct sigcontext *to = to_ptr, *from = from_ptr;
15 int size = sizeof(*to); /* + sizeof(struct _fpstate); */
16
17 memcpy(to, from, size);
18 if(from->fpstate != NULL)
19 to->fpstate = (struct _fpstate *) (to + 1);
20
21 to->fpstate = NULL;
22}
23
24unsigned long *sc_sigmask(void *sc_ptr)
25{
26 struct sigcontext *sc = sc_ptr;
27
28 return(&sc->oldmask);
29}
30
31/* Overrides for Emacs so that we follow Linus's tabbing style.
32 * Emacs will notice this stuff at the end of the file and automatically
33 * adjust the settings for this buffer only. This must remain at the end
34 * of the file.
35 * ---------------------------------------------------------------------------
36 * Local variables:
37 * c-file-style: "linux"
38 * End:
39 */
diff --git a/arch/um/sys-x86_64/signal.c b/arch/um/sys-x86_64/signal.c
index fe8ec04d35bb..1778d33808f4 100644
--- a/arch/um/sys-x86_64/signal.c
+++ b/arch/um/sys-x86_64/signal.c
@@ -1,111 +1,121 @@
1/* 1/*
2 * Copyright (C) 2003 PathScale, Inc. 2 * Copyright (C) 2003 PathScale, Inc.
3 * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 4 * Licensed under the GPL
4 */ 5 */
5 6
6#include "linux/stddef.h"
7#include "linux/errno.h"
8#include "linux/personality.h" 7#include "linux/personality.h"
9#include "linux/ptrace.h" 8#include "linux/ptrace.h"
10#include "asm/current.h" 9#include "asm/unistd.h"
11#include "asm/uaccess.h" 10#include "asm/uaccess.h"
12#include "asm/sigcontext.h" 11#include "asm/ucontext.h"
13#include "asm/ptrace.h"
14#include "asm/arch/ucontext.h"
15#include "choose-mode.h"
16#include "sysdep/ptrace.h"
17#include "frame_kern.h" 12#include "frame_kern.h"
18
19#ifdef CONFIG_MODE_SKAS
20
21#include "skas.h" 13#include "skas.h"
22 14
23void copy_sc(union uml_pt_regs *regs, void *from) 15void copy_sc(struct uml_pt_regs *regs, void *from)
24{ 16{
25 struct sigcontext *sc = from; 17 struct sigcontext *sc = from;
26 18
27#define GETREG(regs, regno, sc, regname) \ 19#define GETREG(regs, regno, sc, regname) \
28 (regs)->skas.regs[(regno) / sizeof(unsigned long)] = (sc)->regname 20 (regs)->gp[(regno) / sizeof(unsigned long)] = (sc)->regname
29 21
30 GETREG(regs, R8, sc, r8); 22 GETREG(regs, R8, sc, r8);
31 GETREG(regs, R9, sc, r9); 23 GETREG(regs, R9, sc, r9);
32 GETREG(regs, R10, sc, r10); 24 GETREG(regs, R10, sc, r10);
33 GETREG(regs, R11, sc, r11); 25 GETREG(regs, R11, sc, r11);
34 GETREG(regs, R12, sc, r12); 26 GETREG(regs, R12, sc, r12);
35 GETREG(regs, R13, sc, r13); 27 GETREG(regs, R13, sc, r13);
36 GETREG(regs, R14, sc, r14); 28 GETREG(regs, R14, sc, r14);
37 GETREG(regs, R15, sc, r15); 29 GETREG(regs, R15, sc, r15);
38 GETREG(regs, RDI, sc, rdi); 30 GETREG(regs, RDI, sc, rdi);
39 GETREG(regs, RSI, sc, rsi); 31 GETREG(regs, RSI, sc, rsi);
40 GETREG(regs, RBP, sc, rbp); 32 GETREG(regs, RBP, sc, rbp);
41 GETREG(regs, RBX, sc, rbx); 33 GETREG(regs, RBX, sc, rbx);
42 GETREG(regs, RDX, sc, rdx); 34 GETREG(regs, RDX, sc, rdx);
43 GETREG(regs, RAX, sc, rax); 35 GETREG(regs, RAX, sc, rax);
44 GETREG(regs, RCX, sc, rcx); 36 GETREG(regs, RCX, sc, rcx);
45 GETREG(regs, RSP, sc, rsp); 37 GETREG(regs, RSP, sc, rsp);
46 GETREG(regs, RIP, sc, rip); 38 GETREG(regs, RIP, sc, rip);
47 GETREG(regs, EFLAGS, sc, eflags); 39 GETREG(regs, EFLAGS, sc, eflags);
48 GETREG(regs, CS, sc, cs); 40 GETREG(regs, CS, sc, cs);
49 41
50#undef GETREG 42#undef GETREG
51} 43}
52 44
53static int copy_sc_from_user_skas(struct pt_regs *regs, 45static int copy_sc_from_user(struct pt_regs *regs,
54 struct sigcontext __user *from) 46 struct sigcontext __user *from,
47 struct _fpstate __user *fpp)
55{ 48{
56 int err = 0; 49 struct user_i387_struct fp;
57 50 int err = 0;
58#define GETREG(regs, regno, sc, regname) \ 51
59 __get_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \ 52#define GETREG(regs, regno, sc, regname) \
60 &(sc)->regname) 53 __get_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \
61 54 &(sc)->regname)
62 err |= GETREG(regs, R8, from, r8); 55
63 err |= GETREG(regs, R9, from, r9); 56 err |= GETREG(regs, R8, from, r8);
64 err |= GETREG(regs, R10, from, r10); 57 err |= GETREG(regs, R9, from, r9);
65 err |= GETREG(regs, R11, from, r11); 58 err |= GETREG(regs, R10, from, r10);
66 err |= GETREG(regs, R12, from, r12); 59 err |= GETREG(regs, R11, from, r11);
67 err |= GETREG(regs, R13, from, r13); 60 err |= GETREG(regs, R12, from, r12);
68 err |= GETREG(regs, R14, from, r14); 61 err |= GETREG(regs, R13, from, r13);
69 err |= GETREG(regs, R15, from, r15); 62 err |= GETREG(regs, R14, from, r14);
70 err |= GETREG(regs, RDI, from, rdi); 63 err |= GETREG(regs, R15, from, r15);
71 err |= GETREG(regs, RSI, from, rsi); 64 err |= GETREG(regs, RDI, from, rdi);
72 err |= GETREG(regs, RBP, from, rbp); 65 err |= GETREG(regs, RSI, from, rsi);
73 err |= GETREG(regs, RBX, from, rbx); 66 err |= GETREG(regs, RBP, from, rbp);
74 err |= GETREG(regs, RDX, from, rdx); 67 err |= GETREG(regs, RBX, from, rbx);
75 err |= GETREG(regs, RAX, from, rax); 68 err |= GETREG(regs, RDX, from, rdx);
76 err |= GETREG(regs, RCX, from, rcx); 69 err |= GETREG(regs, RAX, from, rax);
77 err |= GETREG(regs, RSP, from, rsp); 70 err |= GETREG(regs, RCX, from, rcx);
78 err |= GETREG(regs, RIP, from, rip); 71 err |= GETREG(regs, RSP, from, rsp);
79 err |= GETREG(regs, EFLAGS, from, eflags); 72 err |= GETREG(regs, RIP, from, rip);
80 err |= GETREG(regs, CS, from, cs); 73 err |= GETREG(regs, EFLAGS, from, eflags);
74 err |= GETREG(regs, CS, from, cs);
75 if (err)
76 return 1;
81 77
82#undef GETREG 78#undef GETREG
83 79
84 return err; 80 err = copy_from_user(&fp, fpp, sizeof(struct user_i387_struct));
81 if (err)
82 return 1;
83
84 err = restore_fp_registers(userspace_pid[current_thread->cpu],
85 (unsigned long *) &fp);
86 if (err < 0) {
87 printk(KERN_ERR "copy_sc_from_user - "
88 "restore_fp_registers failed, errno = %d\n",
89 -err);
90 return 1;
91 }
92
93 return 0;
85} 94}
86 95
87int copy_sc_to_user_skas(struct sigcontext __user *to, 96static int copy_sc_to_user(struct sigcontext __user *to,
88 struct _fpstate __user *to_fp, 97 struct _fpstate __user *to_fp, struct pt_regs *regs,
89 struct pt_regs *regs, unsigned long mask, 98 unsigned long mask, unsigned long sp)
90 unsigned long sp)
91{ 99{
92 struct faultinfo * fi = &current->thread.arch.faultinfo; 100 struct faultinfo * fi = &current->thread.arch.faultinfo;
101 struct user_i387_struct fp;
93 int err = 0; 102 int err = 0;
94 103
95 err |= __put_user(0, &to->gs); 104 err |= __put_user(0, &to->gs);
96 err |= __put_user(0, &to->fs); 105 err |= __put_user(0, &to->fs);
97 106
98#define PUTREG(regs, regno, sc, regname) \ 107#define PUTREG(regs, regno, sc, regname) \
99 __put_user((regs)->regs.skas.regs[(regno) / sizeof(unsigned long)], \ 108 __put_user((regs)->regs.gp[(regno) / sizeof(unsigned long)], \
100 &(sc)->regname) 109 &(sc)->regname)
101 110
102 err |= PUTREG(regs, RDI, to, rdi); 111 err |= PUTREG(regs, RDI, to, rdi);
103 err |= PUTREG(regs, RSI, to, rsi); 112 err |= PUTREG(regs, RSI, to, rsi);
104 err |= PUTREG(regs, RBP, to, rbp); 113 err |= PUTREG(regs, RBP, to, rbp);
105 /* Must use orignal RSP, which is passed in, rather than what's in 114 /*
106 * the pt_regs, because that's already been updated to point at the 115 * Must use orignal RSP, which is passed in, rather than what's in
107 * signal frame. 116 * the pt_regs, because that's already been updated to point at the
108 */ 117 * signal frame.
118 */
109 err |= __put_user(sp, &to->rsp); 119 err |= __put_user(sp, &to->rsp);
110 err |= PUTREG(regs, RBX, to, rbx); 120 err |= PUTREG(regs, RBX, to, rbx);
111 err |= PUTREG(regs, RDX, to, rdx); 121 err |= PUTREG(regs, RDX, to, rdx);
@@ -121,91 +131,38 @@ int copy_sc_to_user_skas(struct sigcontext __user *to,
121 err |= PUTREG(regs, R15, to, r15); 131 err |= PUTREG(regs, R15, to, r15);
122 err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */ 132 err |= PUTREG(regs, CS, to, cs); /* XXX x86_64 doesn't do this */
123 133
124 err |= __put_user(fi->cr2, &to->cr2); 134 err |= __put_user(fi->cr2, &to->cr2);
125 err |= __put_user(fi->error_code, &to->err); 135 err |= __put_user(fi->error_code, &to->err);
126 err |= __put_user(fi->trap_no, &to->trapno); 136 err |= __put_user(fi->trap_no, &to->trapno);
127 137
128 err |= PUTREG(regs, RIP, to, rip); 138 err |= PUTREG(regs, RIP, to, rip);
129 err |= PUTREG(regs, EFLAGS, to, eflags); 139 err |= PUTREG(regs, EFLAGS, to, eflags);
130#undef PUTREG 140#undef PUTREG
131 141
132 err |= __put_user(mask, &to->oldmask); 142 err |= __put_user(mask, &to->oldmask);
133 143 if (err)
134 return(err); 144 return 1;
135} 145
136 146 err = save_fp_registers(userspace_pid[current_thread->cpu],
137#endif 147 (unsigned long *) &fp);
138 148 if (err < 0) {
139#ifdef CONFIG_MODE_TT 149 printk(KERN_ERR "copy_sc_from_user - restore_fp_registers "
140int copy_sc_from_user_tt(struct sigcontext *to, struct sigcontext __user *from, 150 "failed, errno = %d\n", -err);
141 int fpsize) 151 return 1;
142{
143 struct _fpstate *to_fp;
144 struct _fpstate __user *from_fp;
145 unsigned long sigs;
146 int err;
147
148 to_fp = to->fpstate;
149 sigs = to->oldmask;
150 err = copy_from_user(to, from, sizeof(*to));
151 from_fp = to->fpstate;
152 to->fpstate = to_fp;
153 to->oldmask = sigs;
154 if(to_fp != NULL)
155 err |= copy_from_user(to_fp, from_fp, fpsize);
156 return(err);
157}
158
159int copy_sc_to_user_tt(struct sigcontext __user *to, struct _fpstate __user *fp,
160 struct sigcontext *from, int fpsize, unsigned long sp)
161{
162 struct _fpstate __user *to_fp;
163 struct _fpstate *from_fp;
164 int err;
165
166 to_fp = (fp ? fp : (struct _fpstate __user *) (to + 1));
167 from_fp = from->fpstate;
168 err = copy_to_user(to, from, sizeof(*to));
169 /* The SP in the sigcontext is the updated one for the signal
170 * delivery. The sp passed in is the original, and this needs
171 * to be restored, so we stick it in separately.
172 */
173 err |= copy_to_user(&SC_SP(to), &sp, sizeof(sp));
174
175 if(from_fp != NULL){
176 err |= copy_to_user(&to->fpstate, &to_fp, sizeof(to->fpstate));
177 err |= copy_to_user(to_fp, from_fp, fpsize);
178 } 152 }
179 return err;
180}
181 153
182#endif 154 if (copy_to_user(to_fp, &fp, sizeof(struct user_i387_struct)))
183 155 return 1;
184static int copy_sc_from_user(struct pt_regs *to, void __user *from)
185{
186 int ret;
187
188 ret = CHOOSE_MODE(copy_sc_from_user_tt(UPT_SC(&to->regs), from,
189 sizeof(struct _fpstate)),
190 copy_sc_from_user_skas(to, from));
191 return(ret);
192}
193 156
194static int copy_sc_to_user(struct sigcontext __user *to, 157 return err;
195 struct _fpstate __user *fp,
196 struct pt_regs *from, unsigned long mask,
197 unsigned long sp)
198{
199 return(CHOOSE_MODE(copy_sc_to_user_tt(to, fp, UPT_SC(&from->regs),
200 sizeof(*fp), sp),
201 copy_sc_to_user_skas(to, fp, from, mask, sp)));
202} 158}
203 159
204struct rt_sigframe 160struct rt_sigframe
205{ 161{
206 char __user *pretcode; 162 char __user *pretcode;
207 struct ucontext uc; 163 struct ucontext uc;
208 struct siginfo info; 164 struct siginfo info;
165 struct _fpstate fpstate;
209}; 166};
210 167
211#define round_down(m, n) (((m) / (n)) * (n)) 168#define round_down(m, n) (((m) / (n)) * (n))
@@ -215,7 +172,6 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
215 siginfo_t *info, sigset_t *set) 172 siginfo_t *info, sigset_t *set)
216{ 173{
217 struct rt_sigframe __user *frame; 174 struct rt_sigframe __user *frame;
218 struct _fpstate __user *fp = NULL;
219 unsigned long save_sp = PT_REGS_RSP(regs); 175 unsigned long save_sp = PT_REGS_RSP(regs);
220 int err = 0; 176 int err = 0;
221 struct task_struct *me = current; 177 struct task_struct *me = current;
@@ -223,15 +179,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
223 frame = (struct rt_sigframe __user *) 179 frame = (struct rt_sigframe __user *)
224 round_down(stack_top - sizeof(struct rt_sigframe), 16); 180 round_down(stack_top - sizeof(struct rt_sigframe), 16);
225 /* Subtract 128 for a red zone and 8 for proper alignment */ 181 /* Subtract 128 for a red zone and 8 for proper alignment */
226 frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8); 182 frame = (struct rt_sigframe __user *) ((unsigned long) frame - 128 - 8);
227
228 if (!access_ok(VERIFY_WRITE, fp, sizeof(struct _fpstate)))
229 goto out;
230 183
231#if 0 /* XXX */
232 if (save_i387(fp) < 0)
233 err |= -1;
234#endif
235 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame))) 184 if (!access_ok(VERIFY_WRITE, frame, sizeof(*frame)))
236 goto out; 185 goto out;
237 186
@@ -241,7 +190,8 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
241 goto out; 190 goto out;
242 } 191 }
243 192
244 /* Update SP now because the page fault handler refuses to extend 193 /*
194 * Update SP now because the page fault handler refuses to extend
245 * the stack if the faulting address is too far below the current 195 * the stack if the faulting address is too far below the current
246 * SP, which frame now certainly is. If there's an error, the original 196 * SP, which frame now certainly is. If there's an error, the original
247 * value is restored on the way out. 197 * value is restored on the way out.
@@ -258,9 +208,9 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
258 err |= __put_user(sas_ss_flags(save_sp), 208 err |= __put_user(sas_ss_flags(save_sp),
259 &frame->uc.uc_stack.ss_flags); 209 &frame->uc.uc_stack.ss_flags);
260 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size); 210 err |= __put_user(me->sas_ss_size, &frame->uc.uc_stack.ss_size);
261 err |= copy_sc_to_user(&frame->uc.uc_mcontext, fp, regs, set->sig[0], 211 err |= copy_sc_to_user(&frame->uc.uc_mcontext, &frame->fpstate, regs,
262 save_sp); 212 set->sig[0], save_sp);
263 err |= __put_user(fp, &frame->uc.uc_mcontext.fpstate); 213 err |= __put_user(&frame->fpstate, &frame->uc.uc_mcontext.fpstate);
264 if (sizeof(*set) == 16) { 214 if (sizeof(*set) == 16) {
265 __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]); 215 __put_user(set->sig[0], &frame->uc.uc_sigmask.sig[0]);
266 __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]); 216 __put_user(set->sig[1], &frame->uc.uc_sigmask.sig[1]);
@@ -269,8 +219,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
269 err |= __copy_to_user(&frame->uc.uc_sigmask, set, 219 err |= __copy_to_user(&frame->uc.uc_sigmask, set,
270 sizeof(*set)); 220 sizeof(*set));
271 221
272 /* Set up to return from userspace. If provided, use a stub 222 /*
273 already in userspace. */ 223 * Set up to return from userspace. If provided, use a stub
224 * already in userspace.
225 */
274 /* x86-64 should always use SA_RESTORER. */ 226 /* x86-64 should always use SA_RESTORER. */
275 if (ka->sa.sa_flags & SA_RESTORER) 227 if (ka->sa.sa_flags & SA_RESTORER)
276 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode); 228 err |= __put_user(ka->sa.sa_restorer, &frame->pretcode);
@@ -292,8 +244,10 @@ int setup_signal_stack_si(unsigned long stack_top, int sig,
292 /* In case the signal handler was declared without prototypes */ 244 /* In case the signal handler was declared without prototypes */
293 PT_REGS_RAX(regs) = 0; 245 PT_REGS_RAX(regs) = 0;
294 246
295 /* This also works for non SA_SIGINFO handlers because they expect the 247 /*
296 next argument after the signal number on the stack. */ 248 * This also works for non SA_SIGINFO handlers because they expect the
249 * next argument after the signal number on the stack.
250 */
297 PT_REGS_RSI(regs) = (unsigned long) &frame->info; 251 PT_REGS_RSI(regs) = (unsigned long) &frame->info;
298 PT_REGS_RDX(regs) = (unsigned long) &frame->uc; 252 PT_REGS_RDX(regs) = (unsigned long) &frame->uc;
299 PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler; 253 PT_REGS_RIP(regs) = (unsigned long) ka->sa.sa_handler;
@@ -313,7 +267,7 @@ long sys_rt_sigreturn(struct pt_regs *regs)
313 struct ucontext __user *uc = &frame->uc; 267 struct ucontext __user *uc = &frame->uc;
314 sigset_t set; 268 sigset_t set;
315 269
316 if(copy_from_user(&set, &uc->uc_sigmask, sizeof(set))) 270 if (copy_from_user(&set, &uc->uc_sigmask, sizeof(set)))
317 goto segfault; 271 goto segfault;
318 272
319 sigdelsetmask(&set, ~_BLOCKABLE); 273 sigdelsetmask(&set, ~_BLOCKABLE);
@@ -323,24 +277,15 @@ long sys_rt_sigreturn(struct pt_regs *regs)
323 recalc_sigpending(); 277 recalc_sigpending();
324 spin_unlock_irq(&current->sighand->siglock); 278 spin_unlock_irq(&current->sighand->siglock);
325 279
326 if(copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext)) 280 if (copy_sc_from_user(&current->thread.regs, &uc->uc_mcontext,
281 &frame->fpstate))
327 goto segfault; 282 goto segfault;
328 283
329 /* Avoid ERESTART handling */ 284 /* Avoid ERESTART handling */
330 PT_REGS_SYSCALL_NR(&current->thread.regs) = -1; 285 PT_REGS_SYSCALL_NR(&current->thread.regs) = -1;
331 return(PT_REGS_SYSCALL_RET(&current->thread.regs)); 286 return PT_REGS_SYSCALL_RET(&current->thread.regs);
332 287
333 segfault: 288 segfault:
334 force_sig(SIGSEGV, current); 289 force_sig(SIGSEGV, current);
335 return 0; 290 return 0;
336} 291}
337/*
338 * Overrides for Emacs so that we follow Linus's tabbing style.
339 * Emacs will notice this stuff at the end of the file and automatically
340 * adjust the settings for this buffer only. This must remain at the end
341 * of the file.
342 * ---------------------------------------------------------------------------
343 * Local variables:
344 * c-file-style: "linux"
345 * End:
346 */
diff --git a/arch/um/sys-x86_64/stub.S b/arch/um/sys-x86_64/stub.S
index 03c279735784..4afe204a6af7 100644
--- a/arch/um/sys-x86_64/stub.S
+++ b/arch/um/sys-x86_64/stub.S
@@ -1,4 +1,5 @@
1#include "uml-config.h" 1#include "uml-config.h"
2#include "as-layout.h"
2 3
3 .globl syscall_stub 4 .globl syscall_stub
4.section .__syscall_stub, "x" 5.section .__syscall_stub, "x"
@@ -7,18 +8,18 @@ syscall_stub:
7 /* We don't have 64-bit constants, so this constructs the address 8 /* We don't have 64-bit constants, so this constructs the address
8 * we need. 9 * we need.
9 */ 10 */
10 movq $(UML_CONFIG_STUB_DATA >> 32), %rbx 11 movq $(ASM_STUB_DATA >> 32), %rbx
11 salq $32, %rbx 12 salq $32, %rbx
12 movq $(UML_CONFIG_STUB_DATA & 0xffffffff), %rcx 13 movq $(ASM_STUB_DATA & 0xffffffff), %rcx
13 or %rcx, %rbx 14 or %rcx, %rbx
14 movq %rax, (%rbx) 15 movq %rax, (%rbx)
15 int3 16 int3
16 17
17 .globl batch_syscall_stub 18 .globl batch_syscall_stub
18batch_syscall_stub: 19batch_syscall_stub:
19 mov $(UML_CONFIG_STUB_DATA >> 32), %rbx 20 mov $(ASM_STUB_DATA >> 32), %rbx
20 sal $32, %rbx 21 sal $32, %rbx
21 mov $(UML_CONFIG_STUB_DATA & 0xffffffff), %rax 22 mov $(ASM_STUB_DATA & 0xffffffff), %rax
22 or %rax, %rbx 23 or %rax, %rbx
23 /* load pointer to first operation */ 24 /* load pointer to first operation */
24 mov %rbx, %rsp 25 mov %rbx, %rsp
diff --git a/arch/um/sys-x86_64/stub_segv.c b/arch/um/sys-x86_64/stub_segv.c
index 652fa34c2cd3..3afb590f0072 100644
--- a/arch/um/sys-x86_64/stub_segv.c
+++ b/arch/um/sys-x86_64/stub_segv.c
@@ -6,6 +6,7 @@
6#include <stddef.h> 6#include <stddef.h>
7#include <signal.h> 7#include <signal.h>
8#include <asm/unistd.h> 8#include <asm/unistd.h>
9#include "as-layout.h"
9#include "uml-config.h" 10#include "uml-config.h"
10#include "sysdep/sigcontext.h" 11#include "sysdep/sigcontext.h"
11#include "sysdep/faultinfo.h" 12#include "sysdep/faultinfo.h"
@@ -33,7 +34,7 @@ stub_segv_handler(int sig)
33 int pid; 34 int pid;
34 35
35 __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :); 36 __asm__ __volatile__("movq %%rdx, %0" : "=g" (uc) :);
36 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) UML_CONFIG_STUB_DATA), 37 GET_FAULTINFO_FROM_SC(*((struct faultinfo *) STUB_DATA),
37 &uc->uc_mcontext); 38 &uc->uc_mcontext);
38 39
39 pid = stub_syscall0(__NR_getpid); 40 pid = stub_syscall0(__NR_getpid);
diff --git a/arch/um/sys-x86_64/syscalls.c b/arch/um/sys-x86_64/syscalls.c
index b3f6350cac44..86f6b18410ee 100644
--- a/arch/um/sys-x86_64/syscalls.c
+++ b/arch/um/sys-x86_64/syscalls.c
@@ -1,70 +1,36 @@
1/* 1/*
2 * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
2 * Copyright 2003 PathScale, Inc. 3 * Copyright 2003 PathScale, Inc.
3 * 4 *
4 * Licensed under the GPL 5 * Licensed under the GPL
5 */ 6 */
6 7
7#include "linux/linkage.h" 8#include "linux/linkage.h"
8#include "linux/slab.h"
9#include "linux/shm.h"
10#include "linux/utsname.h"
11#include "linux/personality.h" 9#include "linux/personality.h"
12#include "asm/uaccess.h" 10#include "linux/utsname.h"
13#define __FRAME_OFFSETS
14#include "asm/ptrace.h"
15#include "asm/unistd.h"
16#include "asm/prctl.h" /* XXX This should get the constants from libc */ 11#include "asm/prctl.h" /* XXX This should get the constants from libc */
17#include "choose-mode.h" 12#include "asm/uaccess.h"
18#include "kern.h"
19#include "os.h" 13#include "os.h"
20 14
21asmlinkage long sys_uname64(struct new_utsname __user * name) 15asmlinkage long sys_uname64(struct new_utsname __user * name)
22{ 16{
23 int err; 17 int err;
18
24 down_read(&uts_sem); 19 down_read(&uts_sem);
25 err = copy_to_user(name, utsname(), sizeof (*name)); 20 err = copy_to_user(name, utsname(), sizeof (*name));
26 up_read(&uts_sem); 21 up_read(&uts_sem);
22
27 if (personality(current->personality) == PER_LINUX32) 23 if (personality(current->personality) == PER_LINUX32)
28 err |= copy_to_user(&name->machine, "i686", 5); 24 err |= copy_to_user(&name->machine, "i686", 5);
29 return err ? -EFAULT : 0;
30}
31
32#ifdef CONFIG_MODE_TT
33extern long arch_prctl(int code, unsigned long addr);
34
35static long arch_prctl_tt(int code, unsigned long addr)
36{
37 unsigned long tmp;
38 long ret;
39
40 switch(code){
41 case ARCH_SET_GS:
42 case ARCH_SET_FS:
43 ret = arch_prctl(code, addr);
44 break;
45 case ARCH_GET_FS:
46 case ARCH_GET_GS:
47 ret = arch_prctl(code, (unsigned long) &tmp);
48 if(!ret)
49 ret = put_user(tmp, (long __user *)addr);
50 break;
51 default:
52 ret = -EINVAL;
53 break;
54 }
55 25
56 return(ret); 26 return err ? -EFAULT : 0;
57} 27}
58#endif
59
60#ifdef CONFIG_MODE_SKAS
61 28
62long arch_prctl_skas(struct task_struct *task, int code, 29long arch_prctl(struct task_struct *task, int code, unsigned long __user *addr)
63 unsigned long __user *addr)
64{ 30{
65 unsigned long *ptr = addr, tmp; 31 unsigned long *ptr = addr, tmp;
66 long ret; 32 long ret;
67 int pid = task->mm->context.skas.id.u.pid; 33 int pid = task->mm->context.id.u.pid;
68 34
69 /* 35 /*
70 * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to 36 * With ARCH_SET_FS (and ARCH_SET_GS is treated similarly to
@@ -79,52 +45,50 @@ long arch_prctl_skas(struct task_struct *task, int code,
79 * arch_prctl is run on the host, then the registers are read 45 * arch_prctl is run on the host, then the registers are read
80 * back. 46 * back.
81 */ 47 */
82 switch(code){ 48 switch (code) {
83 case ARCH_SET_FS: 49 case ARCH_SET_FS:
84 case ARCH_SET_GS: 50 case ARCH_SET_GS:
85 restore_registers(pid, &current->thread.regs.regs); 51 restore_registers(pid, &current->thread.regs.regs);
86 break; 52 break;
87 case ARCH_GET_FS: 53 case ARCH_GET_FS:
88 case ARCH_GET_GS: 54 case ARCH_GET_GS:
89 /* 55 /*
90 * With these two, we read to a local pointer and 56 * With these two, we read to a local pointer and
91 * put_user it to the userspace pointer that we were 57 * put_user it to the userspace pointer that we were
92 * given. If addr isn't valid (because it hasn't been 58 * given. If addr isn't valid (because it hasn't been
93 * faulted in or is just bogus), we want put_user to 59 * faulted in or is just bogus), we want put_user to
94 * fault it in (or return -EFAULT) instead of having 60 * fault it in (or return -EFAULT) instead of having
95 * the host return -EFAULT. 61 * the host return -EFAULT.
96 */ 62 */
97 ptr = &tmp; 63 ptr = &tmp;
98 } 64 }
99 65
100 ret = os_arch_prctl(pid, code, ptr); 66 ret = os_arch_prctl(pid, code, ptr);
101 if(ret) 67 if (ret)
102 return ret; 68 return ret;
103 69
104 switch(code){ 70 switch (code) {
105 case ARCH_SET_FS: 71 case ARCH_SET_FS:
106 current->thread.arch.fs = (unsigned long) ptr; 72 current->thread.arch.fs = (unsigned long) ptr;
107 save_registers(pid, &current->thread.regs.regs); 73 save_registers(pid, &current->thread.regs.regs);
108 break; 74 break;
109 case ARCH_SET_GS: 75 case ARCH_SET_GS:
110 save_registers(pid, &current->thread.regs.regs); 76 save_registers(pid, &current->thread.regs.regs);
111 break; 77 break;
112 case ARCH_GET_FS: 78 case ARCH_GET_FS:
113 ret = put_user(tmp, addr); 79 ret = put_user(tmp, addr);
114 break; 80 break;
115 case ARCH_GET_GS: 81 case ARCH_GET_GS:
116 ret = put_user(tmp, addr); 82 ret = put_user(tmp, addr);
117 break; 83 break;
118 } 84 }
119 85
120 return ret; 86 return ret;
121} 87}
122#endif
123 88
124long sys_arch_prctl(int code, unsigned long addr) 89long sys_arch_prctl(int code, unsigned long addr)
125{ 90{
126 return CHOOSE_MODE_PROC(arch_prctl_tt, arch_prctl_skas, current, code, 91 return arch_prctl(current, code, (unsigned long __user *) addr);
127 (unsigned long __user *) addr);
128} 92}
129 93
130long sys_clone(unsigned long clone_flags, unsigned long newsp, 94long sys_clone(unsigned long clone_flags, unsigned long newsp,
@@ -141,10 +105,10 @@ long sys_clone(unsigned long clone_flags, unsigned long newsp,
141 return ret; 105 return ret;
142} 106}
143 107
144void arch_switch_to_skas(struct task_struct *from, struct task_struct *to) 108void arch_switch_to(struct task_struct *from, struct task_struct *to)
145{ 109{
146 if((to->thread.arch.fs == 0) || (to->mm == NULL)) 110 if ((to->thread.arch.fs == 0) || (to->mm == NULL))
147 return; 111 return;
148 112
149 arch_prctl_skas(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs); 113 arch_prctl(to, ARCH_SET_FS, (void __user *) to->thread.arch.fs);
150} 114}
diff --git a/arch/um/sys-x86_64/tls.c b/arch/um/sys-x86_64/tls.c
index febbc94be25f..f7ba46200ecd 100644
--- a/arch/um/sys-x86_64/tls.c
+++ b/arch/um/sys-x86_64/tls.c
@@ -11,7 +11,7 @@ int arch_copy_tls(struct task_struct *t)
11 * (which is argument 5, child_tid, of clone) so it can be set 11 * (which is argument 5, child_tid, of clone) so it can be set
12 * during context switches. 12 * during context switches.
13 */ 13 */
14 t->thread.arch.fs = t->thread.regs.regs.skas.regs[R8 / sizeof(long)]; 14 t->thread.arch.fs = t->thread.regs.regs.gp[R8 / sizeof(long)];
15 15
16 return 0; 16 return 0;
17} 17}
diff --git a/arch/um/sys-x86_64/unmap.c b/arch/um/sys-x86_64/unmap.c
deleted file mode 100644
index f4a4bffd8a18..000000000000
--- a/arch/um/sys-x86_64/unmap.c
+++ /dev/null
@@ -1,25 +0,0 @@
1/*
2 * Copyright (C) 2000 Jeff Dike (jdike@karaya.com)
3 * Licensed under the GPL
4 */
5
6#include <linux/mman.h>
7#include <asm/unistd.h>
8
9static int errno;
10
11static inline _syscall2(int,munmap,void *,start,size_t,len)
12static inline _syscall6(void *,mmap,void *,addr,size_t,len,int,prot,int,flags,int,fd,off_t,offset)
13int switcheroo(int fd, int prot, void *from, void *to, int size)
14{
15 if(munmap(to, size) < 0){
16 return(-1);
17 }
18 if(mmap(to, size, prot, MAP_SHARED | MAP_FIXED, fd, 0) == (void*) -1){
19 return(-1);
20 }
21 if(munmap(from, size) < 0){
22 return(-1);
23 }
24 return(0);
25}
diff --git a/arch/um/sys-x86_64/user-offsets.c b/arch/um/sys-x86_64/user-offsets.c
index 0d5fd764c21f..f1ef2a8dfbc6 100644
--- a/arch/um/sys-x86_64/user-offsets.c
+++ b/arch/um/sys-x86_64/user-offsets.c
@@ -3,17 +3,10 @@
3#include <signal.h> 3#include <signal.h>
4#include <sys/poll.h> 4#include <sys/poll.h>
5#include <sys/mman.h> 5#include <sys/mman.h>
6#include <sys/user.h>
6#define __FRAME_OFFSETS 7#define __FRAME_OFFSETS
7#include <asm/ptrace.h> 8#include <asm/ptrace.h>
8#include <asm/types.h> 9#include <asm/types.h>
9/* For some reason, x86_64 defines u64 and u32 only in <pci/types.h>, which I
10 * refuse to include here, even though they're used throughout the headers.
11 * These are used in asm/user.h, and that include can't be avoided because of
12 * the sizeof(struct user_regs_struct) below.
13 */
14typedef __u64 u64;
15typedef __u32 u32;
16#include <asm/user.h>
17 10
18#define DEFINE(sym, val) \ 11#define DEFINE(sym, val) \
19 asm volatile("\n->" #sym " %0 " #val : : "i" (val)) 12 asm volatile("\n->" #sym " %0 " #val : : "i" (val))
diff --git a/arch/v850/kernel/fpga85e2c.c b/arch/v850/kernel/fpga85e2c.c
index 5c4923558a75..ab9cf16a85c8 100644
--- a/arch/v850/kernel/fpga85e2c.c
+++ b/arch/v850/kernel/fpga85e2c.c
@@ -160,5 +160,8 @@ static void make_reg_snap (int irq, void *dummy, struct pt_regs *regs)
160 160
161static int reg_snap_dev_id; 161static int reg_snap_dev_id;
162static struct irqaction reg_snap_action = { 162static struct irqaction reg_snap_action = {
163 make_reg_snap, 0, CPU_MASK_NONE, "reg_snap", &reg_snap_dev_id, 0 163 .handler = make_reg_snap,
164 .mask = CPU_MASK_NONE,
165 .name = "reg_snap",
166 .dev_id = &reg_snap_dev_id,
164}; 167};
diff --git a/arch/v850/kernel/time.c b/arch/v850/kernel/time.c
index f0905b03523b..d810c93fe665 100644
--- a/arch/v850/kernel/time.c
+++ b/arch/v850/kernel/time.c
@@ -92,12 +92,11 @@ static irqreturn_t timer_interrupt (int irq, void *dummy, struct pt_regs *regs)
92 92
93static int timer_dev_id; 93static int timer_dev_id;
94static struct irqaction timer_irqaction = { 94static struct irqaction timer_irqaction = {
95 timer_interrupt, 95 .handler = timer_interrupt,
96 IRQF_DISABLED, 96 .flags = IRQF_DISABLED,
97 CPU_MASK_NONE, 97 .mask = CPU_MASK_NONE,
98 "timer", 98 .name = "timer",
99 &timer_dev_id, 99 .dev_id = &timer_dev_id,
100 NULL
101}; 100};
102 101
103void time_init (void) 102void time_init (void)
diff --git a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
index ffd01e5dcb52..2ca43ba32bc0 100644
--- a/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
+++ b/arch/x86/kernel/cpu/cpufreq/acpi-cpufreq.c
@@ -595,7 +595,7 @@ static int acpi_cpufreq_cpu_init(struct cpufreq_policy *policy)
595 dmi_check_system(sw_any_bug_dmi_table); 595 dmi_check_system(sw_any_bug_dmi_table);
596 if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) { 596 if (bios_with_sw_any_bug && cpus_weight(policy->cpus) == 1) {
597 policy->shared_type = CPUFREQ_SHARED_TYPE_ALL; 597 policy->shared_type = CPUFREQ_SHARED_TYPE_ALL;
598 policy->cpus = cpu_core_map[cpu]; 598 policy->cpus = per_cpu(cpu_core_map, cpu);
599 } 599 }
600#endif 600#endif
601 601
diff --git a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
index 8eb414b906d2..793eae854f4f 100644
--- a/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
+++ b/arch/x86/kernel/cpu/cpufreq/p4-clockmod.c
@@ -200,7 +200,7 @@ static int cpufreq_p4_cpu_init(struct cpufreq_policy *policy)
200 unsigned int i; 200 unsigned int i;
201 201
202#ifdef CONFIG_SMP 202#ifdef CONFIG_SMP
203 policy->cpus = cpu_sibling_map[policy->cpu]; 203 policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
204#endif 204#endif
205 205
206 /* Errata workaround */ 206 /* Errata workaround */
diff --git a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
index b273b69cfddf..c06ac680c9ca 100644
--- a/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
+++ b/arch/x86/kernel/cpu/cpufreq/powernow-k8.c
@@ -57,7 +57,7 @@ static struct powernow_k8_data *powernow_data[NR_CPUS];
57static int cpu_family = CPU_OPTERON; 57static int cpu_family = CPU_OPTERON;
58 58
59#ifndef CONFIG_SMP 59#ifndef CONFIG_SMP
60static cpumask_t cpu_core_map[1]; 60DEFINE_PER_CPU(cpumask_t, cpu_core_map);
61#endif 61#endif
62 62
63/* Return a frequency in MHz, given an input fid */ 63/* Return a frequency in MHz, given an input fid */
@@ -667,7 +667,7 @@ static int fill_powernow_table(struct powernow_k8_data *data, struct pst_s *pst,
667 667
668 dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid); 668 dprintk("cfid 0x%x, cvid 0x%x\n", data->currfid, data->currvid);
669 data->powernow_table = powernow_table; 669 data->powernow_table = powernow_table;
670 if (first_cpu(cpu_core_map[data->cpu]) == data->cpu) 670 if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
671 print_basics(data); 671 print_basics(data);
672 672
673 for (j = 0; j < data->numps; j++) 673 for (j = 0; j < data->numps; j++)
@@ -821,7 +821,7 @@ static int powernow_k8_cpu_init_acpi(struct powernow_k8_data *data)
821 821
822 /* fill in data */ 822 /* fill in data */
823 data->numps = data->acpi_data.state_count; 823 data->numps = data->acpi_data.state_count;
824 if (first_cpu(cpu_core_map[data->cpu]) == data->cpu) 824 if (first_cpu(per_cpu(cpu_core_map, data->cpu)) == data->cpu)
825 print_basics(data); 825 print_basics(data);
826 powernow_k8_acpi_pst_values(data, 0); 826 powernow_k8_acpi_pst_values(data, 0);
827 827
@@ -1214,7 +1214,7 @@ static int __cpuinit powernowk8_cpu_init(struct cpufreq_policy *pol)
1214 if (cpu_family == CPU_HW_PSTATE) 1214 if (cpu_family == CPU_HW_PSTATE)
1215 pol->cpus = cpumask_of_cpu(pol->cpu); 1215 pol->cpus = cpumask_of_cpu(pol->cpu);
1216 else 1216 else
1217 pol->cpus = cpu_core_map[pol->cpu]; 1217 pol->cpus = per_cpu(cpu_core_map, pol->cpu);
1218 data->available_cores = &(pol->cpus); 1218 data->available_cores = &(pol->cpus);
1219 1219
1220 /* Take a crude guess here. 1220 /* Take a crude guess here.
@@ -1281,7 +1281,7 @@ static unsigned int powernowk8_get (unsigned int cpu)
1281 cpumask_t oldmask = current->cpus_allowed; 1281 cpumask_t oldmask = current->cpus_allowed;
1282 unsigned int khz = 0; 1282 unsigned int khz = 0;
1283 1283
1284 data = powernow_data[first_cpu(cpu_core_map[cpu])]; 1284 data = powernow_data[first_cpu(per_cpu(cpu_core_map, cpu))];
1285 1285
1286 if (!data) 1286 if (!data)
1287 return -EINVAL; 1287 return -EINVAL;
diff --git a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
index 36685e8f7be1..14d68aa301ee 100644
--- a/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
+++ b/arch/x86/kernel/cpu/cpufreq/speedstep-ich.c
@@ -322,7 +322,7 @@ static int speedstep_cpu_init(struct cpufreq_policy *policy)
322 322
323 /* only run on CPU to be set, or on its sibling */ 323 /* only run on CPU to be set, or on its sibling */
324#ifdef CONFIG_SMP 324#ifdef CONFIG_SMP
325 policy->cpus = cpu_sibling_map[policy->cpu]; 325 policy->cpus = per_cpu(cpu_sibling_map, policy->cpu);
326#endif 326#endif
327 327
328 cpus_allowed = current->cpus_allowed; 328 cpus_allowed = current->cpus_allowed;
diff --git a/arch/x86/kernel/cpu/proc.c b/arch/x86/kernel/cpu/proc.c
index 1e31b6caffb1..879a0f789b1e 100644
--- a/arch/x86/kernel/cpu/proc.c
+++ b/arch/x86/kernel/cpu/proc.c
@@ -122,7 +122,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
122#ifdef CONFIG_X86_HT 122#ifdef CONFIG_X86_HT
123 if (c->x86_max_cores * smp_num_siblings > 1) { 123 if (c->x86_max_cores * smp_num_siblings > 1) {
124 seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); 124 seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
125 seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[n])); 125 seq_printf(m, "siblings\t: %d\n",
126 cpus_weight(per_cpu(cpu_core_map, n)));
126 seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); 127 seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
127 seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); 128 seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
128 } 129 }
diff --git a/arch/x86/kernel/io_apic_32.c b/arch/x86/kernel/io_apic_32.c
index e2f4a1c68547..4ee1e5ee9b57 100644
--- a/arch/x86/kernel/io_apic_32.c
+++ b/arch/x86/kernel/io_apic_32.c
@@ -378,7 +378,7 @@ static struct irq_cpu_info {
378 378
379#define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask) 379#define IRQ_ALLOWED(cpu, allowed_mask) cpu_isset(cpu, allowed_mask)
380 380
381#define CPU_TO_PACKAGEINDEX(i) (first_cpu(cpu_sibling_map[i])) 381#define CPU_TO_PACKAGEINDEX(i) (first_cpu(per_cpu(cpu_sibling_map, i)))
382 382
383static cpumask_t balance_irq_affinity[NR_IRQS] = { 383static cpumask_t balance_irq_affinity[NR_IRQS] = {
384 [0 ... NR_IRQS-1] = CPU_MASK_ALL 384 [0 ... NR_IRQS-1] = CPU_MASK_ALL
@@ -598,7 +598,7 @@ tryanotherirq:
598 * (A+B)/2 vs B 598 * (A+B)/2 vs B
599 */ 599 */
600 load = CPU_IRQ(min_loaded) >> 1; 600 load = CPU_IRQ(min_loaded) >> 1;
601 for_each_cpu_mask(j, cpu_sibling_map[min_loaded]) { 601 for_each_cpu_mask(j, per_cpu(cpu_sibling_map, min_loaded)) {
602 if (load > CPU_IRQ(j)) { 602 if (load > CPU_IRQ(j)) {
603 /* This won't change cpu_sibling_map[min_loaded] */ 603 /* This won't change cpu_sibling_map[min_loaded] */
604 load = CPU_IRQ(j); 604 load = CPU_IRQ(j);
diff --git a/arch/x86/kernel/kprobes_32.c b/arch/x86/kernel/kprobes_32.c
index e7d0d3c2ef64..90f778c04b3f 100644
--- a/arch/x86/kernel/kprobes_32.c
+++ b/arch/x86/kernel/kprobes_32.c
@@ -41,6 +41,13 @@ void jprobe_return_end(void);
41DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 41DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
42DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 42DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
43 43
44struct kretprobe_blackpoint kretprobe_blacklist[] = {
45 {"__switch_to", }, /* This function switches only current task, but
46 doesn't switch kernel stack.*/
47 {NULL, NULL} /* Terminator */
48};
49const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
50
44/* insert a jmp code */ 51/* insert a jmp code */
45static __always_inline void set_jmp_op(void *from, void *to) 52static __always_inline void set_jmp_op(void *from, void *to)
46{ 53{
@@ -584,7 +591,7 @@ out:
584 return 1; 591 return 1;
585} 592}
586 593
587static int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr) 594int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
588{ 595{
589 struct kprobe *cur = kprobe_running(); 596 struct kprobe *cur = kprobe_running();
590 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk(); 597 struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
@@ -666,7 +673,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
666 ret = NOTIFY_STOP; 673 ret = NOTIFY_STOP;
667 break; 674 break;
668 case DIE_GPF: 675 case DIE_GPF:
669 case DIE_PAGE_FAULT:
670 /* kprobe_running() needs smp_processor_id() */ 676 /* kprobe_running() needs smp_processor_id() */
671 preempt_disable(); 677 preempt_disable();
672 if (kprobe_running() && 678 if (kprobe_running() &&
diff --git a/arch/x86/kernel/kprobes_64.c b/arch/x86/kernel/kprobes_64.c
index 62e28e52d784..681b801c5e26 100644
--- a/arch/x86/kernel/kprobes_64.c
+++ b/arch/x86/kernel/kprobes_64.c
@@ -48,6 +48,13 @@ static void __kprobes arch_copy_kprobe(struct kprobe *p);
48DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL; 48DEFINE_PER_CPU(struct kprobe *, current_kprobe) = NULL;
49DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk); 49DEFINE_PER_CPU(struct kprobe_ctlblk, kprobe_ctlblk);
50 50
51struct kretprobe_blackpoint kretprobe_blacklist[] = {
52 {"__switch_to", }, /* This function switches only current task, but
53 doesn't switch kernel stack.*/
54 {NULL, NULL} /* Terminator */
55};
56const int kretprobe_blacklist_size = ARRAY_SIZE(kretprobe_blacklist);
57
51/* 58/*
52 * returns non-zero if opcode modifies the interrupt flag. 59 * returns non-zero if opcode modifies the interrupt flag.
53 */ 60 */
@@ -657,7 +664,6 @@ int __kprobes kprobe_exceptions_notify(struct notifier_block *self,
657 ret = NOTIFY_STOP; 664 ret = NOTIFY_STOP;
658 break; 665 break;
659 case DIE_GPF: 666 case DIE_GPF:
660 case DIE_PAGE_FAULT:
661 /* kprobe_running() needs smp_processor_id() */ 667 /* kprobe_running() needs smp_processor_id() */
662 preempt_disable(); 668 preempt_disable();
663 if (kprobe_running() && 669 if (kprobe_running() &&
diff --git a/arch/x86/kernel/mce_amd_64.c b/arch/x86/kernel/mce_amd_64.c
index 2f8a7f18b0fe..805b62b1e0df 100644
--- a/arch/x86/kernel/mce_amd_64.c
+++ b/arch/x86/kernel/mce_amd_64.c
@@ -472,7 +472,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
472 472
473#ifdef CONFIG_SMP 473#ifdef CONFIG_SMP
474 if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) { /* symlink */ 474 if (cpu_data[cpu].cpu_core_id && shared_bank[bank]) { /* symlink */
475 i = first_cpu(cpu_core_map[cpu]); 475 i = first_cpu(per_cpu(cpu_core_map, cpu));
476 476
477 /* first core not up yet */ 477 /* first core not up yet */
478 if (cpu_data[i].cpu_core_id) 478 if (cpu_data[i].cpu_core_id)
@@ -492,7 +492,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
492 if (err) 492 if (err)
493 goto out; 493 goto out;
494 494
495 b->cpus = cpu_core_map[cpu]; 495 b->cpus = per_cpu(cpu_core_map, cpu);
496 per_cpu(threshold_banks, cpu)[bank] = b; 496 per_cpu(threshold_banks, cpu)[bank] = b;
497 goto out; 497 goto out;
498 } 498 }
@@ -509,7 +509,7 @@ static __cpuinit int threshold_create_bank(unsigned int cpu, unsigned int bank)
509#ifndef CONFIG_SMP 509#ifndef CONFIG_SMP
510 b->cpus = CPU_MASK_ALL; 510 b->cpus = CPU_MASK_ALL;
511#else 511#else
512 b->cpus = cpu_core_map[cpu]; 512 b->cpus = per_cpu(cpu_core_map, cpu);
513#endif 513#endif
514 err = kobject_register(&b->kobj); 514 err = kobject_register(&b->kobj);
515 if (err) 515 if (err)
diff --git a/arch/x86/kernel/pci-calgary_64.c b/arch/x86/kernel/pci-calgary_64.c
index 71da01e73f03..a50b787b3bfa 100644
--- a/arch/x86/kernel/pci-calgary_64.c
+++ b/arch/x86/kernel/pci-calgary_64.c
@@ -35,6 +35,7 @@
35#include <linux/pci_ids.h> 35#include <linux/pci_ids.h>
36#include <linux/pci.h> 36#include <linux/pci.h>
37#include <linux/delay.h> 37#include <linux/delay.h>
38#include <linux/scatterlist.h>
38#include <asm/iommu.h> 39#include <asm/iommu.h>
39#include <asm/calgary.h> 40#include <asm/calgary.h>
40#include <asm/tce.h> 41#include <asm/tce.h>
@@ -384,31 +385,32 @@ static void calgary_unmap_sg(struct device *dev,
384 struct scatterlist *sglist, int nelems, int direction) 385 struct scatterlist *sglist, int nelems, int direction)
385{ 386{
386 struct iommu_table *tbl = find_iommu_table(dev); 387 struct iommu_table *tbl = find_iommu_table(dev);
388 struct scatterlist *s;
389 int i;
387 390
388 if (!translate_phb(to_pci_dev(dev))) 391 if (!translate_phb(to_pci_dev(dev)))
389 return; 392 return;
390 393
391 while (nelems--) { 394 for_each_sg(sglist, s, nelems, i) {
392 unsigned int npages; 395 unsigned int npages;
393 dma_addr_t dma = sglist->dma_address; 396 dma_addr_t dma = s->dma_address;
394 unsigned int dmalen = sglist->dma_length; 397 unsigned int dmalen = s->dma_length;
395 398
396 if (dmalen == 0) 399 if (dmalen == 0)
397 break; 400 break;
398 401
399 npages = num_dma_pages(dma, dmalen); 402 npages = num_dma_pages(dma, dmalen);
400 iommu_free(tbl, dma, npages); 403 iommu_free(tbl, dma, npages);
401 sglist++;
402 } 404 }
403} 405}
404 406
405static int calgary_nontranslate_map_sg(struct device* dev, 407static int calgary_nontranslate_map_sg(struct device* dev,
406 struct scatterlist *sg, int nelems, int direction) 408 struct scatterlist *sg, int nelems, int direction)
407{ 409{
410 struct scatterlist *s;
408 int i; 411 int i;
409 412
410 for (i = 0; i < nelems; i++ ) { 413 for_each_sg(sg, s, nelems, i) {
411 struct scatterlist *s = &sg[i];
412 BUG_ON(!s->page); 414 BUG_ON(!s->page);
413 s->dma_address = virt_to_bus(page_address(s->page) +s->offset); 415 s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
414 s->dma_length = s->length; 416 s->dma_length = s->length;
@@ -420,6 +422,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
420 int nelems, int direction) 422 int nelems, int direction)
421{ 423{
422 struct iommu_table *tbl = find_iommu_table(dev); 424 struct iommu_table *tbl = find_iommu_table(dev);
425 struct scatterlist *s;
423 unsigned long vaddr; 426 unsigned long vaddr;
424 unsigned int npages; 427 unsigned int npages;
425 unsigned long entry; 428 unsigned long entry;
@@ -428,8 +431,7 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
428 if (!translate_phb(to_pci_dev(dev))) 431 if (!translate_phb(to_pci_dev(dev)))
429 return calgary_nontranslate_map_sg(dev, sg, nelems, direction); 432 return calgary_nontranslate_map_sg(dev, sg, nelems, direction);
430 433
431 for (i = 0; i < nelems; i++ ) { 434 for_each_sg(sg, s, nelems, i) {
432 struct scatterlist *s = &sg[i];
433 BUG_ON(!s->page); 435 BUG_ON(!s->page);
434 436
435 vaddr = (unsigned long)page_address(s->page) + s->offset; 437 vaddr = (unsigned long)page_address(s->page) + s->offset;
@@ -454,9 +456,9 @@ static int calgary_map_sg(struct device *dev, struct scatterlist *sg,
454 return nelems; 456 return nelems;
455error: 457error:
456 calgary_unmap_sg(dev, sg, nelems, direction); 458 calgary_unmap_sg(dev, sg, nelems, direction);
457 for (i = 0; i < nelems; i++) { 459 for_each_sg(sg, s, nelems, i) {
458 sg[i].dma_address = bad_dma_address; 460 sg->dma_address = bad_dma_address;
459 sg[i].dma_length = 0; 461 sg->dma_length = 0;
460 } 462 }
461 return 0; 463 return 0;
462} 464}
diff --git a/arch/x86/kernel/pci-gart_64.c b/arch/x86/kernel/pci-gart_64.c
index 4918c575d582..cfcc84e6c350 100644
--- a/arch/x86/kernel/pci-gart_64.c
+++ b/arch/x86/kernel/pci-gart_64.c
@@ -23,6 +23,7 @@
23#include <linux/interrupt.h> 23#include <linux/interrupt.h>
24#include <linux/bitops.h> 24#include <linux/bitops.h>
25#include <linux/kdebug.h> 25#include <linux/kdebug.h>
26#include <linux/scatterlist.h>
26#include <asm/atomic.h> 27#include <asm/atomic.h>
27#include <asm/io.h> 28#include <asm/io.h>
28#include <asm/mtrr.h> 29#include <asm/mtrr.h>
@@ -278,10 +279,10 @@ static void gart_unmap_single(struct device *dev, dma_addr_t dma_addr,
278 */ 279 */
279static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir) 280static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
280{ 281{
282 struct scatterlist *s;
281 int i; 283 int i;
282 284
283 for (i = 0; i < nents; i++) { 285 for_each_sg(sg, s, nents, i) {
284 struct scatterlist *s = &sg[i];
285 if (!s->dma_length || !s->length) 286 if (!s->dma_length || !s->length)
286 break; 287 break;
287 gart_unmap_single(dev, s->dma_address, s->dma_length, dir); 288 gart_unmap_single(dev, s->dma_address, s->dma_length, dir);
@@ -292,14 +293,14 @@ static void gart_unmap_sg(struct device *dev, struct scatterlist *sg, int nents,
292static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg, 293static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
293 int nents, int dir) 294 int nents, int dir)
294{ 295{
296 struct scatterlist *s;
295 int i; 297 int i;
296 298
297#ifdef CONFIG_IOMMU_DEBUG 299#ifdef CONFIG_IOMMU_DEBUG
298 printk(KERN_DEBUG "dma_map_sg overflow\n"); 300 printk(KERN_DEBUG "dma_map_sg overflow\n");
299#endif 301#endif
300 302
301 for (i = 0; i < nents; i++ ) { 303 for_each_sg(sg, s, nents, i) {
302 struct scatterlist *s = &sg[i];
303 unsigned long addr = page_to_phys(s->page) + s->offset; 304 unsigned long addr = page_to_phys(s->page) + s->offset;
304 if (nonforced_iommu(dev, addr, s->length)) { 305 if (nonforced_iommu(dev, addr, s->length)) {
305 addr = dma_map_area(dev, addr, s->length, dir); 306 addr = dma_map_area(dev, addr, s->length, dir);
@@ -319,23 +320,23 @@ static int dma_map_sg_nonforce(struct device *dev, struct scatterlist *sg,
319} 320}
320 321
321/* Map multiple scatterlist entries continuous into the first. */ 322/* Map multiple scatterlist entries continuous into the first. */
322static int __dma_map_cont(struct scatterlist *sg, int start, int stopat, 323static int __dma_map_cont(struct scatterlist *start, int nelems,
323 struct scatterlist *sout, unsigned long pages) 324 struct scatterlist *sout, unsigned long pages)
324{ 325{
325 unsigned long iommu_start = alloc_iommu(pages); 326 unsigned long iommu_start = alloc_iommu(pages);
326 unsigned long iommu_page = iommu_start; 327 unsigned long iommu_page = iommu_start;
328 struct scatterlist *s;
327 int i; 329 int i;
328 330
329 if (iommu_start == -1) 331 if (iommu_start == -1)
330 return -1; 332 return -1;
331 333
332 for (i = start; i < stopat; i++) { 334 for_each_sg(start, s, nelems, i) {
333 struct scatterlist *s = &sg[i];
334 unsigned long pages, addr; 335 unsigned long pages, addr;
335 unsigned long phys_addr = s->dma_address; 336 unsigned long phys_addr = s->dma_address;
336 337
337 BUG_ON(i > start && s->offset); 338 BUG_ON(s != start && s->offset);
338 if (i == start) { 339 if (s == start) {
339 *sout = *s; 340 *sout = *s;
340 sout->dma_address = iommu_bus_base; 341 sout->dma_address = iommu_bus_base;
341 sout->dma_address += iommu_page*PAGE_SIZE + s->offset; 342 sout->dma_address += iommu_page*PAGE_SIZE + s->offset;
@@ -357,17 +358,17 @@ static int __dma_map_cont(struct scatterlist *sg, int start, int stopat,
357 return 0; 358 return 0;
358} 359}
359 360
360static inline int dma_map_cont(struct scatterlist *sg, int start, int stopat, 361static inline int dma_map_cont(struct scatterlist *start, int nelems,
361 struct scatterlist *sout, 362 struct scatterlist *sout,
362 unsigned long pages, int need) 363 unsigned long pages, int need)
363{ 364{
364 if (!need) { 365 if (!need) {
365 BUG_ON(stopat - start != 1); 366 BUG_ON(nelems != 1);
366 *sout = sg[start]; 367 *sout = *start;
367 sout->dma_length = sg[start].length; 368 sout->dma_length = start->length;
368 return 0; 369 return 0;
369 } 370 }
370 return __dma_map_cont(sg, start, stopat, sout, pages); 371 return __dma_map_cont(start, nelems, sout, pages);
371} 372}
372 373
373/* 374/*
@@ -381,6 +382,7 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
381 int start; 382 int start;
382 unsigned long pages = 0; 383 unsigned long pages = 0;
383 int need = 0, nextneed; 384 int need = 0, nextneed;
385 struct scatterlist *s, *ps, *start_sg, *sgmap;
384 386
385 if (nents == 0) 387 if (nents == 0)
386 return 0; 388 return 0;
@@ -390,8 +392,9 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
390 392
391 out = 0; 393 out = 0;
392 start = 0; 394 start = 0;
393 for (i = 0; i < nents; i++) { 395 start_sg = sgmap = sg;
394 struct scatterlist *s = &sg[i]; 396 ps = NULL; /* shut up gcc */
397 for_each_sg(sg, s, nents, i) {
395 dma_addr_t addr = page_to_phys(s->page) + s->offset; 398 dma_addr_t addr = page_to_phys(s->page) + s->offset;
396 s->dma_address = addr; 399 s->dma_address = addr;
397 BUG_ON(s->length == 0); 400 BUG_ON(s->length == 0);
@@ -400,29 +403,33 @@ int gart_map_sg(struct device *dev, struct scatterlist *sg, int nents, int dir)
400 403
401 /* Handle the previous not yet processed entries */ 404 /* Handle the previous not yet processed entries */
402 if (i > start) { 405 if (i > start) {
403 struct scatterlist *ps = &sg[i-1];
404 /* Can only merge when the last chunk ends on a page 406 /* Can only merge when the last chunk ends on a page
405 boundary and the new one doesn't have an offset. */ 407 boundary and the new one doesn't have an offset. */
406 if (!iommu_merge || !nextneed || !need || s->offset || 408 if (!iommu_merge || !nextneed || !need || s->offset ||
407 (ps->offset + ps->length) % PAGE_SIZE) { 409 (ps->offset + ps->length) % PAGE_SIZE) {
408 if (dma_map_cont(sg, start, i, sg+out, pages, 410 if (dma_map_cont(start_sg, i - start, sgmap,
409 need) < 0) 411 pages, need) < 0)
410 goto error; 412 goto error;
411 out++; 413 out++;
414 sgmap = sg_next(sgmap);
412 pages = 0; 415 pages = 0;
413 start = i; 416 start = i;
417 start_sg = s;
414 } 418 }
415 } 419 }
416 420
417 need = nextneed; 421 need = nextneed;
418 pages += to_pages(s->offset, s->length); 422 pages += to_pages(s->offset, s->length);
423 ps = s;
419 } 424 }
420 if (dma_map_cont(sg, start, i, sg+out, pages, need) < 0) 425 if (dma_map_cont(start_sg, i - start, sgmap, pages, need) < 0)
421 goto error; 426 goto error;
422 out++; 427 out++;
423 flush_gart(); 428 flush_gart();
424 if (out < nents) 429 if (out < nents) {
425 sg[out].dma_length = 0; 430 sgmap = sg_next(sgmap);
431 sgmap->dma_length = 0;
432 }
426 return out; 433 return out;
427 434
428error: 435error:
@@ -437,8 +444,8 @@ error:
437 if (panic_on_overflow) 444 if (panic_on_overflow)
438 panic("dma_map_sg: overflow on %lu pages\n", pages); 445 panic("dma_map_sg: overflow on %lu pages\n", pages);
439 iommu_full(dev, pages << PAGE_SHIFT, dir); 446 iommu_full(dev, pages << PAGE_SHIFT, dir);
440 for (i = 0; i < nents; i++) 447 for_each_sg(sg, s, nents, i)
441 sg[i].dma_address = bad_dma_address; 448 s->dma_address = bad_dma_address;
442 return 0; 449 return 0;
443} 450}
444 451
diff --git a/arch/x86/kernel/pci-nommu_64.c b/arch/x86/kernel/pci-nommu_64.c
index 2a34c6c025a9..e85d4360360c 100644
--- a/arch/x86/kernel/pci-nommu_64.c
+++ b/arch/x86/kernel/pci-nommu_64.c
@@ -5,6 +5,7 @@
5#include <linux/pci.h> 5#include <linux/pci.h>
6#include <linux/string.h> 6#include <linux/string.h>
7#include <linux/dma-mapping.h> 7#include <linux/dma-mapping.h>
8#include <linux/scatterlist.h>
8 9
9#include <asm/iommu.h> 10#include <asm/iommu.h>
10#include <asm/processor.h> 11#include <asm/processor.h>
@@ -57,10 +58,10 @@ static void nommu_unmap_single(struct device *dev, dma_addr_t addr,size_t size,
57static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg, 58static int nommu_map_sg(struct device *hwdev, struct scatterlist *sg,
58 int nents, int direction) 59 int nents, int direction)
59{ 60{
61 struct scatterlist *s;
60 int i; 62 int i;
61 63
62 for (i = 0; i < nents; i++ ) { 64 for_each_sg(sg, s, nents, i) {
63 struct scatterlist *s = &sg[i];
64 BUG_ON(!s->page); 65 BUG_ON(!s->page);
65 s->dma_address = virt_to_bus(page_address(s->page) +s->offset); 66 s->dma_address = virt_to_bus(page_address(s->page) +s->offset);
66 if (!check_addr("map_sg", hwdev, s->dma_address, s->length)) 67 if (!check_addr("map_sg", hwdev, s->dma_address, s->length))
diff --git a/arch/x86/kernel/process_64.c b/arch/x86/kernel/process_64.c
index 7352d4b377e6..6309b275cb9c 100644
--- a/arch/x86/kernel/process_64.c
+++ b/arch/x86/kernel/process_64.c
@@ -581,7 +581,7 @@ static inline void __switch_to_xtra(struct task_struct *prev_p,
581 * 581 *
582 * Kprobes not supported here. Set the probe on schedule instead. 582 * Kprobes not supported here. Set the probe on schedule instead.
583 */ 583 */
584__kprobes struct task_struct * 584struct task_struct *
585__switch_to(struct task_struct *prev_p, struct task_struct *next_p) 585__switch_to(struct task_struct *prev_p, struct task_struct *next_p)
586{ 586{
587 struct thread_struct *prev = &prev_p->thread, 587 struct thread_struct *prev = &prev_p->thread,
diff --git a/arch/x86/kernel/ptrace_32.c b/arch/x86/kernel/ptrace_32.c
index 0cecd7513c97..8622b9cd3e38 100644
--- a/arch/x86/kernel/ptrace_32.c
+++ b/arch/x86/kernel/ptrace_32.c
@@ -524,11 +524,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
524 ret = 0; 524 ret = 0;
525 break; 525 break;
526 526
527 case PTRACE_DETACH:
528 /* detach a process that was attached. */
529 ret = ptrace_detach(child, data);
530 break;
531
532 case PTRACE_GETREGS: { /* Get all gp regs from the child. */ 527 case PTRACE_GETREGS: { /* Get all gp regs from the child. */
533 if (!access_ok(VERIFY_WRITE, datap, FRAME_SIZE*sizeof(long))) { 528 if (!access_ok(VERIFY_WRITE, datap, FRAME_SIZE*sizeof(long))) {
534 ret = -EIO; 529 ret = -EIO;
diff --git a/arch/x86/kernel/ptrace_64.c b/arch/x86/kernel/ptrace_64.c
index c0cac42df3b6..86321ee6da93 100644
--- a/arch/x86/kernel/ptrace_64.c
+++ b/arch/x86/kernel/ptrace_64.c
@@ -500,11 +500,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
500 ret = 0; 500 ret = 0;
501 break; 501 break;
502 502
503 case PTRACE_DETACH:
504 /* detach a process that was attached. */
505 ret = ptrace_detach(child, data);
506 break;
507
508 case PTRACE_GETREGS: { /* Get all gp regs from the child. */ 503 case PTRACE_GETREGS: { /* Get all gp regs from the child. */
509 if (!access_ok(VERIFY_WRITE, (unsigned __user *)data, 504 if (!access_ok(VERIFY_WRITE, (unsigned __user *)data,
510 sizeof(struct user_regs_struct))) { 505 sizeof(struct user_regs_struct))) {
diff --git a/arch/x86/kernel/setup_64.c b/arch/x86/kernel/setup_64.c
index b7da90e79c78..85b5b6310acc 100644
--- a/arch/x86/kernel/setup_64.c
+++ b/arch/x86/kernel/setup_64.c
@@ -1070,7 +1070,8 @@ static int show_cpuinfo(struct seq_file *m, void *v)
1070 if (smp_num_siblings * c->x86_max_cores > 1) { 1070 if (smp_num_siblings * c->x86_max_cores > 1) {
1071 int cpu = c - cpu_data; 1071 int cpu = c - cpu_data;
1072 seq_printf(m, "physical id\t: %d\n", c->phys_proc_id); 1072 seq_printf(m, "physical id\t: %d\n", c->phys_proc_id);
1073 seq_printf(m, "siblings\t: %d\n", cpus_weight(cpu_core_map[cpu])); 1073 seq_printf(m, "siblings\t: %d\n",
1074 cpus_weight(per_cpu(cpu_core_map, cpu)));
1074 seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id); 1075 seq_printf(m, "core id\t\t: %d\n", c->cpu_core_id);
1075 seq_printf(m, "cpu cores\t: %d\n", c->booted_cores); 1076 seq_printf(m, "cpu cores\t: %d\n", c->booted_cores);
1076 } 1077 }
diff --git a/arch/x86/kernel/smpboot_32.c b/arch/x86/kernel/smpboot_32.c
index e4f61d1c6248..31fc08bd15ef 100644
--- a/arch/x86/kernel/smpboot_32.c
+++ b/arch/x86/kernel/smpboot_32.c
@@ -70,12 +70,12 @@ EXPORT_SYMBOL(smp_num_siblings);
70int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID}; 70int cpu_llc_id[NR_CPUS] __cpuinitdata = {[0 ... NR_CPUS-1] = BAD_APICID};
71 71
72/* representing HT siblings of each logical CPU */ 72/* representing HT siblings of each logical CPU */
73cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; 73DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
74EXPORT_SYMBOL(cpu_sibling_map); 74EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
75 75
76/* representing HT and core siblings of each logical CPU */ 76/* representing HT and core siblings of each logical CPU */
77cpumask_t cpu_core_map[NR_CPUS] __read_mostly; 77DEFINE_PER_CPU(cpumask_t, cpu_core_map);
78EXPORT_SYMBOL(cpu_core_map); 78EXPORT_PER_CPU_SYMBOL(cpu_core_map);
79 79
80/* bitmap of online cpus */ 80/* bitmap of online cpus */
81cpumask_t cpu_online_map __read_mostly; 81cpumask_t cpu_online_map __read_mostly;
@@ -300,7 +300,7 @@ cpumask_t cpu_coregroup_map(int cpu)
300 * And for power savings, we return cpu_core_map 300 * And for power savings, we return cpu_core_map
301 */ 301 */
302 if (sched_mc_power_savings || sched_smt_power_savings) 302 if (sched_mc_power_savings || sched_smt_power_savings)
303 return cpu_core_map[cpu]; 303 return per_cpu(cpu_core_map, cpu);
304 else 304 else
305 return c->llc_shared_map; 305 return c->llc_shared_map;
306} 306}
@@ -319,22 +319,22 @@ void __cpuinit set_cpu_sibling_map(int cpu)
319 for_each_cpu_mask(i, cpu_sibling_setup_map) { 319 for_each_cpu_mask(i, cpu_sibling_setup_map) {
320 if (c[cpu].phys_proc_id == c[i].phys_proc_id && 320 if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
321 c[cpu].cpu_core_id == c[i].cpu_core_id) { 321 c[cpu].cpu_core_id == c[i].cpu_core_id) {
322 cpu_set(i, cpu_sibling_map[cpu]); 322 cpu_set(i, per_cpu(cpu_sibling_map, cpu));
323 cpu_set(cpu, cpu_sibling_map[i]); 323 cpu_set(cpu, per_cpu(cpu_sibling_map, i));
324 cpu_set(i, cpu_core_map[cpu]); 324 cpu_set(i, per_cpu(cpu_core_map, cpu));
325 cpu_set(cpu, cpu_core_map[i]); 325 cpu_set(cpu, per_cpu(cpu_core_map, i));
326 cpu_set(i, c[cpu].llc_shared_map); 326 cpu_set(i, c[cpu].llc_shared_map);
327 cpu_set(cpu, c[i].llc_shared_map); 327 cpu_set(cpu, c[i].llc_shared_map);
328 } 328 }
329 } 329 }
330 } else { 330 } else {
331 cpu_set(cpu, cpu_sibling_map[cpu]); 331 cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
332 } 332 }
333 333
334 cpu_set(cpu, c[cpu].llc_shared_map); 334 cpu_set(cpu, c[cpu].llc_shared_map);
335 335
336 if (current_cpu_data.x86_max_cores == 1) { 336 if (current_cpu_data.x86_max_cores == 1) {
337 cpu_core_map[cpu] = cpu_sibling_map[cpu]; 337 per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
338 c[cpu].booted_cores = 1; 338 c[cpu].booted_cores = 1;
339 return; 339 return;
340 } 340 }
@@ -346,17 +346,17 @@ void __cpuinit set_cpu_sibling_map(int cpu)
346 cpu_set(cpu, c[i].llc_shared_map); 346 cpu_set(cpu, c[i].llc_shared_map);
347 } 347 }
348 if (c[cpu].phys_proc_id == c[i].phys_proc_id) { 348 if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
349 cpu_set(i, cpu_core_map[cpu]); 349 cpu_set(i, per_cpu(cpu_core_map, cpu));
350 cpu_set(cpu, cpu_core_map[i]); 350 cpu_set(cpu, per_cpu(cpu_core_map, i));
351 /* 351 /*
352 * Does this new cpu bringup a new core? 352 * Does this new cpu bringup a new core?
353 */ 353 */
354 if (cpus_weight(cpu_sibling_map[cpu]) == 1) { 354 if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) {
355 /* 355 /*
356 * for each core in package, increment 356 * for each core in package, increment
357 * the booted_cores for this new cpu 357 * the booted_cores for this new cpu
358 */ 358 */
359 if (first_cpu(cpu_sibling_map[i]) == i) 359 if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
360 c[cpu].booted_cores++; 360 c[cpu].booted_cores++;
361 /* 361 /*
362 * increment the core count for all 362 * increment the core count for all
@@ -983,8 +983,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
983 printk(KERN_NOTICE "Local APIC not detected." 983 printk(KERN_NOTICE "Local APIC not detected."
984 " Using dummy APIC emulation.\n"); 984 " Using dummy APIC emulation.\n");
985 map_cpu_to_logical_apicid(); 985 map_cpu_to_logical_apicid();
986 cpu_set(0, cpu_sibling_map[0]); 986 cpu_set(0, per_cpu(cpu_sibling_map, 0));
987 cpu_set(0, cpu_core_map[0]); 987 cpu_set(0, per_cpu(cpu_core_map, 0));
988 return; 988 return;
989 } 989 }
990 990
@@ -1008,8 +1008,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1008 printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n"); 1008 printk(KERN_ERR "... forcing use of dummy APIC emulation. (tell your hw vendor)\n");
1009 smpboot_clear_io_apic_irqs(); 1009 smpboot_clear_io_apic_irqs();
1010 phys_cpu_present_map = physid_mask_of_physid(0); 1010 phys_cpu_present_map = physid_mask_of_physid(0);
1011 cpu_set(0, cpu_sibling_map[0]); 1011 cpu_set(0, per_cpu(cpu_sibling_map, 0));
1012 cpu_set(0, cpu_core_map[0]); 1012 cpu_set(0, per_cpu(cpu_core_map, 0));
1013 return; 1013 return;
1014 } 1014 }
1015 1015
@@ -1023,8 +1023,8 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1023 printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n"); 1023 printk(KERN_INFO "SMP mode deactivated, forcing use of dummy APIC emulation.\n");
1024 smpboot_clear_io_apic_irqs(); 1024 smpboot_clear_io_apic_irqs();
1025 phys_cpu_present_map = physid_mask_of_physid(0); 1025 phys_cpu_present_map = physid_mask_of_physid(0);
1026 cpu_set(0, cpu_sibling_map[0]); 1026 cpu_set(0, per_cpu(cpu_sibling_map, 0));
1027 cpu_set(0, cpu_core_map[0]); 1027 cpu_set(0, per_cpu(cpu_core_map, 0));
1028 return; 1028 return;
1029 } 1029 }
1030 1030
@@ -1102,16 +1102,16 @@ static void __init smp_boot_cpus(unsigned int max_cpus)
1102 Dprintk("Boot done.\n"); 1102 Dprintk("Boot done.\n");
1103 1103
1104 /* 1104 /*
1105 * construct cpu_sibling_map[], so that we can tell sibling CPUs 1105 * construct cpu_sibling_map, so that we can tell sibling CPUs
1106 * efficiently. 1106 * efficiently.
1107 */ 1107 */
1108 for (cpu = 0; cpu < NR_CPUS; cpu++) { 1108 for (cpu = 0; cpu < NR_CPUS; cpu++) {
1109 cpus_clear(cpu_sibling_map[cpu]); 1109 cpus_clear(per_cpu(cpu_sibling_map, cpu));
1110 cpus_clear(cpu_core_map[cpu]); 1110 cpus_clear(per_cpu(cpu_core_map, cpu));
1111 } 1111 }
1112 1112
1113 cpu_set(0, cpu_sibling_map[0]); 1113 cpu_set(0, per_cpu(cpu_sibling_map, 0));
1114 cpu_set(0, cpu_core_map[0]); 1114 cpu_set(0, per_cpu(cpu_core_map, 0));
1115 1115
1116 smpboot_setup_io_apic(); 1116 smpboot_setup_io_apic();
1117 1117
@@ -1148,19 +1148,19 @@ void remove_siblinginfo(int cpu)
1148 int sibling; 1148 int sibling;
1149 struct cpuinfo_x86 *c = cpu_data; 1149 struct cpuinfo_x86 *c = cpu_data;
1150 1150
1151 for_each_cpu_mask(sibling, cpu_core_map[cpu]) { 1151 for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
1152 cpu_clear(cpu, cpu_core_map[sibling]); 1152 cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
1153 /* 1153 /*/
1154 * last thread sibling in this cpu core going down 1154 * last thread sibling in this cpu core going down
1155 */ 1155 */
1156 if (cpus_weight(cpu_sibling_map[cpu]) == 1) 1156 if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
1157 c[sibling].booted_cores--; 1157 c[sibling].booted_cores--;
1158 } 1158 }
1159 1159
1160 for_each_cpu_mask(sibling, cpu_sibling_map[cpu]) 1160 for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
1161 cpu_clear(cpu, cpu_sibling_map[sibling]); 1161 cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
1162 cpus_clear(cpu_sibling_map[cpu]); 1162 cpus_clear(per_cpu(cpu_sibling_map, cpu));
1163 cpus_clear(cpu_core_map[cpu]); 1163 cpus_clear(per_cpu(cpu_core_map, cpu));
1164 c[cpu].phys_proc_id = 0; 1164 c[cpu].phys_proc_id = 0;
1165 c[cpu].cpu_core_id = 0; 1165 c[cpu].cpu_core_id = 0;
1166 cpu_clear(cpu, cpu_sibling_setup_map); 1166 cpu_clear(cpu, cpu_sibling_setup_map);
diff --git a/arch/x86/kernel/smpboot_64.c b/arch/x86/kernel/smpboot_64.c
index 720a7d1f8862..0faa0a0af272 100644
--- a/arch/x86/kernel/smpboot_64.c
+++ b/arch/x86/kernel/smpboot_64.c
@@ -91,12 +91,12 @@ EXPORT_SYMBOL(cpu_data);
91int smp_threads_ready; 91int smp_threads_ready;
92 92
93/* representing HT siblings of each logical CPU */ 93/* representing HT siblings of each logical CPU */
94cpumask_t cpu_sibling_map[NR_CPUS] __read_mostly; 94DEFINE_PER_CPU(cpumask_t, cpu_sibling_map);
95EXPORT_SYMBOL(cpu_sibling_map); 95EXPORT_PER_CPU_SYMBOL(cpu_sibling_map);
96 96
97/* representing HT and core siblings of each logical CPU */ 97/* representing HT and core siblings of each logical CPU */
98cpumask_t cpu_core_map[NR_CPUS] __read_mostly; 98DEFINE_PER_CPU(cpumask_t, cpu_core_map);
99EXPORT_SYMBOL(cpu_core_map); 99EXPORT_PER_CPU_SYMBOL(cpu_core_map);
100 100
101/* 101/*
102 * Trampoline 80x86 program as an array. 102 * Trampoline 80x86 program as an array.
@@ -243,7 +243,7 @@ cpumask_t cpu_coregroup_map(int cpu)
243 * And for power savings, we return cpu_core_map 243 * And for power savings, we return cpu_core_map
244 */ 244 */
245 if (sched_mc_power_savings || sched_smt_power_savings) 245 if (sched_mc_power_savings || sched_smt_power_savings)
246 return cpu_core_map[cpu]; 246 return per_cpu(cpu_core_map, cpu);
247 else 247 else
248 return c->llc_shared_map; 248 return c->llc_shared_map;
249} 249}
@@ -262,22 +262,22 @@ static inline void set_cpu_sibling_map(int cpu)
262 for_each_cpu_mask(i, cpu_sibling_setup_map) { 262 for_each_cpu_mask(i, cpu_sibling_setup_map) {
263 if (c[cpu].phys_proc_id == c[i].phys_proc_id && 263 if (c[cpu].phys_proc_id == c[i].phys_proc_id &&
264 c[cpu].cpu_core_id == c[i].cpu_core_id) { 264 c[cpu].cpu_core_id == c[i].cpu_core_id) {
265 cpu_set(i, cpu_sibling_map[cpu]); 265 cpu_set(i, per_cpu(cpu_sibling_map, cpu));
266 cpu_set(cpu, cpu_sibling_map[i]); 266 cpu_set(cpu, per_cpu(cpu_sibling_map, i));
267 cpu_set(i, cpu_core_map[cpu]); 267 cpu_set(i, per_cpu(cpu_core_map, cpu));
268 cpu_set(cpu, cpu_core_map[i]); 268 cpu_set(cpu, per_cpu(cpu_core_map, i));
269 cpu_set(i, c[cpu].llc_shared_map); 269 cpu_set(i, c[cpu].llc_shared_map);
270 cpu_set(cpu, c[i].llc_shared_map); 270 cpu_set(cpu, c[i].llc_shared_map);
271 } 271 }
272 } 272 }
273 } else { 273 } else {
274 cpu_set(cpu, cpu_sibling_map[cpu]); 274 cpu_set(cpu, per_cpu(cpu_sibling_map, cpu));
275 } 275 }
276 276
277 cpu_set(cpu, c[cpu].llc_shared_map); 277 cpu_set(cpu, c[cpu].llc_shared_map);
278 278
279 if (current_cpu_data.x86_max_cores == 1) { 279 if (current_cpu_data.x86_max_cores == 1) {
280 cpu_core_map[cpu] = cpu_sibling_map[cpu]; 280 per_cpu(cpu_core_map, cpu) = per_cpu(cpu_sibling_map, cpu);
281 c[cpu].booted_cores = 1; 281 c[cpu].booted_cores = 1;
282 return; 282 return;
283 } 283 }
@@ -289,17 +289,17 @@ static inline void set_cpu_sibling_map(int cpu)
289 cpu_set(cpu, c[i].llc_shared_map); 289 cpu_set(cpu, c[i].llc_shared_map);
290 } 290 }
291 if (c[cpu].phys_proc_id == c[i].phys_proc_id) { 291 if (c[cpu].phys_proc_id == c[i].phys_proc_id) {
292 cpu_set(i, cpu_core_map[cpu]); 292 cpu_set(i, per_cpu(cpu_core_map, cpu));
293 cpu_set(cpu, cpu_core_map[i]); 293 cpu_set(cpu, per_cpu(cpu_core_map, i));
294 /* 294 /*
295 * Does this new cpu bringup a new core? 295 * Does this new cpu bringup a new core?
296 */ 296 */
297 if (cpus_weight(cpu_sibling_map[cpu]) == 1) { 297 if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1) {
298 /* 298 /*
299 * for each core in package, increment 299 * for each core in package, increment
300 * the booted_cores for this new cpu 300 * the booted_cores for this new cpu
301 */ 301 */
302 if (first_cpu(cpu_sibling_map[i]) == i) 302 if (first_cpu(per_cpu(cpu_sibling_map, i)) == i)
303 c[cpu].booted_cores++; 303 c[cpu].booted_cores++;
304 /* 304 /*
305 * increment the core count for all 305 * increment the core count for all
@@ -735,8 +735,8 @@ static __init void disable_smp(void)
735 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id); 735 phys_cpu_present_map = physid_mask_of_physid(boot_cpu_id);
736 else 736 else
737 phys_cpu_present_map = physid_mask_of_physid(0); 737 phys_cpu_present_map = physid_mask_of_physid(0);
738 cpu_set(0, cpu_sibling_map[0]); 738 cpu_set(0, per_cpu(cpu_sibling_map, 0));
739 cpu_set(0, cpu_core_map[0]); 739 cpu_set(0, per_cpu(cpu_core_map, 0));
740} 740}
741 741
742#ifdef CONFIG_HOTPLUG_CPU 742#ifdef CONFIG_HOTPLUG_CPU
@@ -971,19 +971,19 @@ static void remove_siblinginfo(int cpu)
971 int sibling; 971 int sibling;
972 struct cpuinfo_x86 *c = cpu_data; 972 struct cpuinfo_x86 *c = cpu_data;
973 973
974 for_each_cpu_mask(sibling, cpu_core_map[cpu]) { 974 for_each_cpu_mask(sibling, per_cpu(cpu_core_map, cpu)) {
975 cpu_clear(cpu, cpu_core_map[sibling]); 975 cpu_clear(cpu, per_cpu(cpu_core_map, sibling));
976 /* 976 /*
977 * last thread sibling in this cpu core going down 977 * last thread sibling in this cpu core going down
978 */ 978 */
979 if (cpus_weight(cpu_sibling_map[cpu]) == 1) 979 if (cpus_weight(per_cpu(cpu_sibling_map, cpu)) == 1)
980 c[sibling].booted_cores--; 980 c[sibling].booted_cores--;
981 } 981 }
982 982
983 for_each_cpu_mask(sibling, cpu_sibling_map[cpu]) 983 for_each_cpu_mask(sibling, per_cpu(cpu_sibling_map, cpu))
984 cpu_clear(cpu, cpu_sibling_map[sibling]); 984 cpu_clear(cpu, per_cpu(cpu_sibling_map, sibling));
985 cpus_clear(cpu_sibling_map[cpu]); 985 cpus_clear(per_cpu(cpu_sibling_map, cpu));
986 cpus_clear(cpu_core_map[cpu]); 986 cpus_clear(per_cpu(cpu_core_map, cpu));
987 c[cpu].phys_proc_id = 0; 987 c[cpu].phys_proc_id = 0;
988 c[cpu].cpu_core_id = 0; 988 c[cpu].cpu_core_id = 0;
989 cpu_clear(cpu, cpu_sibling_setup_map); 989 cpu_clear(cpu, cpu_sibling_setup_map);
diff --git a/arch/x86/mm/fault_32.c b/arch/x86/mm/fault_32.c
index fcb38e7f3543..c686ae20fd6b 100644
--- a/arch/x86/mm/fault_32.c
+++ b/arch/x86/mm/fault_32.c
@@ -25,6 +25,7 @@
25#include <linux/kprobes.h> 25#include <linux/kprobes.h>
26#include <linux/uaccess.h> 26#include <linux/uaccess.h>
27#include <linux/kdebug.h> 27#include <linux/kdebug.h>
28#include <linux/kprobes.h>
28 29
29#include <asm/system.h> 30#include <asm/system.h>
30#include <asm/desc.h> 31#include <asm/desc.h>
@@ -32,33 +33,27 @@
32 33
33extern void die(const char *,struct pt_regs *,long); 34extern void die(const char *,struct pt_regs *,long);
34 35
35static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); 36#ifdef CONFIG_KPROBES
36 37static inline int notify_page_fault(struct pt_regs *regs)
37int register_page_fault_notifier(struct notifier_block *nb)
38{ 38{
39 vmalloc_sync_all(); 39 int ret = 0;
40 return atomic_notifier_chain_register(&notify_page_fault_chain, nb); 40
41} 41 /* kprobe_running() needs smp_processor_id() */
42EXPORT_SYMBOL_GPL(register_page_fault_notifier); 42 if (!user_mode_vm(regs)) {
43 preempt_disable();
44 if (kprobe_running() && kprobe_fault_handler(regs, 14))
45 ret = 1;
46 preempt_enable();
47 }
43 48
44int unregister_page_fault_notifier(struct notifier_block *nb) 49 return ret;
45{
46 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
47} 50}
48EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); 51#else
49 52static inline int notify_page_fault(struct pt_regs *regs)
50static inline int notify_page_fault(struct pt_regs *regs, long err)
51{ 53{
52 struct die_args args = { 54 return 0;
53 .regs = regs,
54 .str = "page fault",
55 .err = err,
56 .trapnr = 14,
57 .signr = SIGSEGV
58 };
59 return atomic_notifier_call_chain(&notify_page_fault_chain,
60 DIE_PAGE_FAULT, &args);
61} 55}
56#endif
62 57
63/* 58/*
64 * Return EIP plus the CS segment base. The segment limit is also 59 * Return EIP plus the CS segment base. The segment limit is also
@@ -331,7 +326,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
331 if (unlikely(address >= TASK_SIZE)) { 326 if (unlikely(address >= TASK_SIZE)) {
332 if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0) 327 if (!(error_code & 0x0000000d) && vmalloc_fault(address) >= 0)
333 return; 328 return;
334 if (notify_page_fault(regs, error_code) == NOTIFY_STOP) 329 if (notify_page_fault(regs))
335 return; 330 return;
336 /* 331 /*
337 * Don't take the mm semaphore here. If we fixup a prefetch 332 * Don't take the mm semaphore here. If we fixup a prefetch
@@ -340,7 +335,7 @@ fastcall void __kprobes do_page_fault(struct pt_regs *regs,
340 goto bad_area_nosemaphore; 335 goto bad_area_nosemaphore;
341 } 336 }
342 337
343 if (notify_page_fault(regs, error_code) == NOTIFY_STOP) 338 if (notify_page_fault(regs))
344 return; 339 return;
345 340
346 /* It's safe to allow irq's after cr2 has been saved and the vmalloc 341 /* It's safe to allow irq's after cr2 has been saved and the vmalloc
@@ -598,7 +593,7 @@ out_of_memory:
598 } 593 }
599 printk("VM: killing process %s\n", tsk->comm); 594 printk("VM: killing process %s\n", tsk->comm);
600 if (error_code & 4) 595 if (error_code & 4)
601 do_exit(SIGKILL); 596 do_group_exit(SIGKILL);
602 goto no_context; 597 goto no_context;
603 598
604do_sigbus: 599do_sigbus:
diff --git a/arch/x86/mm/fault_64.c b/arch/x86/mm/fault_64.c
index 54816adb8e93..5e0e54906c48 100644
--- a/arch/x86/mm/fault_64.c
+++ b/arch/x86/mm/fault_64.c
@@ -25,6 +25,7 @@
25#include <linux/kprobes.h> 25#include <linux/kprobes.h>
26#include <linux/uaccess.h> 26#include <linux/uaccess.h>
27#include <linux/kdebug.h> 27#include <linux/kdebug.h>
28#include <linux/kprobes.h>
28 29
29#include <asm/system.h> 30#include <asm/system.h>
30#include <asm/pgalloc.h> 31#include <asm/pgalloc.h>
@@ -40,34 +41,27 @@
40#define PF_RSVD (1<<3) 41#define PF_RSVD (1<<3)
41#define PF_INSTR (1<<4) 42#define PF_INSTR (1<<4)
42 43
43static ATOMIC_NOTIFIER_HEAD(notify_page_fault_chain); 44#ifdef CONFIG_KPROBES
44 45static inline int notify_page_fault(struct pt_regs *regs)
45/* Hook to register for page fault notifications */
46int register_page_fault_notifier(struct notifier_block *nb)
47{ 46{
48 vmalloc_sync_all(); 47 int ret = 0;
49 return atomic_notifier_chain_register(&notify_page_fault_chain, nb); 48
50} 49 /* kprobe_running() needs smp_processor_id() */
51EXPORT_SYMBOL_GPL(register_page_fault_notifier); 50 if (!user_mode(regs)) {
51 preempt_disable();
52 if (kprobe_running() && kprobe_fault_handler(regs, 14))
53 ret = 1;
54 preempt_enable();
55 }
52 56
53int unregister_page_fault_notifier(struct notifier_block *nb) 57 return ret;
54{
55 return atomic_notifier_chain_unregister(&notify_page_fault_chain, nb);
56} 58}
57EXPORT_SYMBOL_GPL(unregister_page_fault_notifier); 59#else
58 60static inline int notify_page_fault(struct pt_regs *regs)
59static inline int notify_page_fault(struct pt_regs *regs, long err)
60{ 61{
61 struct die_args args = { 62 return 0;
62 .regs = regs,
63 .str = "page fault",
64 .err = err,
65 .trapnr = 14,
66 .signr = SIGSEGV
67 };
68 return atomic_notifier_call_chain(&notify_page_fault_chain,
69 DIE_PAGE_FAULT, &args);
70} 63}
64#endif
71 65
72/* Sometimes the CPU reports invalid exceptions on prefetch. 66/* Sometimes the CPU reports invalid exceptions on prefetch.
73 Check that here and ignore. 67 Check that here and ignore.
@@ -345,7 +339,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
345 if (vmalloc_fault(address) >= 0) 339 if (vmalloc_fault(address) >= 0)
346 return; 340 return;
347 } 341 }
348 if (notify_page_fault(regs, error_code) == NOTIFY_STOP) 342 if (notify_page_fault(regs))
349 return; 343 return;
350 /* 344 /*
351 * Don't take the mm semaphore here. If we fixup a prefetch 345 * Don't take the mm semaphore here. If we fixup a prefetch
@@ -354,7 +348,7 @@ asmlinkage void __kprobes do_page_fault(struct pt_regs *regs,
354 goto bad_area_nosemaphore; 348 goto bad_area_nosemaphore;
355 } 349 }
356 350
357 if (notify_page_fault(regs, error_code) == NOTIFY_STOP) 351 if (notify_page_fault(regs))
358 return; 352 return;
359 353
360 if (likely(regs->eflags & X86_EFLAGS_IF)) 354 if (likely(regs->eflags & X86_EFLAGS_IF))
diff --git a/arch/x86/mm/init_32.c b/arch/x86/mm/init_32.c
index 730a5b177b1f..dda4e83649a0 100644
--- a/arch/x86/mm/init_32.c
+++ b/arch/x86/mm/init_32.c
@@ -735,11 +735,6 @@ int arch_add_memory(int nid, u64 start, u64 size)
735 return __add_pages(zone, start_pfn, nr_pages); 735 return __add_pages(zone, start_pfn, nr_pages);
736} 736}
737 737
738int remove_memory(u64 start, u64 size)
739{
740 return -EINVAL;
741}
742EXPORT_SYMBOL_GPL(remove_memory);
743#endif 738#endif
744 739
745struct kmem_cache *pmd_cache; 740struct kmem_cache *pmd_cache;
diff --git a/arch/x86/mm/init_64.c b/arch/x86/mm/init_64.c
index 458893b376f8..1e3862e41065 100644
--- a/arch/x86/mm/init_64.c
+++ b/arch/x86/mm/init_64.c
@@ -474,12 +474,6 @@ error:
474} 474}
475EXPORT_SYMBOL_GPL(arch_add_memory); 475EXPORT_SYMBOL_GPL(arch_add_memory);
476 476
477int remove_memory(u64 start, u64 size)
478{
479 return -EINVAL;
480}
481EXPORT_SYMBOL_GPL(remove_memory);
482
483#if !defined(CONFIG_ACPI_NUMA) && defined(CONFIG_NUMA) 477#if !defined(CONFIG_ACPI_NUMA) && defined(CONFIG_NUMA)
484int memory_add_physaddr_to_nid(u64 start) 478int memory_add_physaddr_to_nid(u64 start)
485{ 479{
@@ -748,3 +742,48 @@ const char *arch_vma_name(struct vm_area_struct *vma)
748 return "[vsyscall]"; 742 return "[vsyscall]";
749 return NULL; 743 return NULL;
750} 744}
745
746#ifdef CONFIG_SPARSEMEM_VMEMMAP
747/*
748 * Initialise the sparsemem vmemmap using huge-pages at the PMD level.
749 */
750int __meminit vmemmap_populate(struct page *start_page,
751 unsigned long size, int node)
752{
753 unsigned long addr = (unsigned long)start_page;
754 unsigned long end = (unsigned long)(start_page + size);
755 unsigned long next;
756 pgd_t *pgd;
757 pud_t *pud;
758 pmd_t *pmd;
759
760 for (; addr < end; addr = next) {
761 next = pmd_addr_end(addr, end);
762
763 pgd = vmemmap_pgd_populate(addr, node);
764 if (!pgd)
765 return -ENOMEM;
766 pud = vmemmap_pud_populate(pgd, addr, node);
767 if (!pud)
768 return -ENOMEM;
769
770 pmd = pmd_offset(pud, addr);
771 if (pmd_none(*pmd)) {
772 pte_t entry;
773 void *p = vmemmap_alloc_block(PMD_SIZE, node);
774 if (!p)
775 return -ENOMEM;
776
777 entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL);
778 mk_pte_huge(entry);
779 set_pmd(pmd, __pmd(pte_val(entry)));
780
781 printk(KERN_DEBUG " [%lx-%lx] PMD ->%p on node %d\n",
782 addr, addr + PMD_SIZE - 1, p, node);
783 } else
784 vmemmap_verify((pte_t *)pmd, node, addr, next);
785 }
786
787 return 0;
788}
789#endif
diff --git a/arch/x86/oprofile/op_model_p4.c b/arch/x86/oprofile/op_model_p4.c
index 47925927b12f..56b4757a1f47 100644
--- a/arch/x86/oprofile/op_model_p4.c
+++ b/arch/x86/oprofile/op_model_p4.c
@@ -379,7 +379,7 @@ static unsigned int get_stagger(void)
379{ 379{
380#ifdef CONFIG_SMP 380#ifdef CONFIG_SMP
381 int cpu = smp_processor_id(); 381 int cpu = smp_processor_id();
382 return (cpu != first_cpu(cpu_sibling_map[cpu])); 382 return (cpu != first_cpu(per_cpu(cpu_sibling_map, cpu)));
383#endif 383#endif
384 return 0; 384 return 0;
385} 385}
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index 557b8e24706a..4fa33c27ccb6 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -147,8 +147,13 @@ void __init xen_smp_prepare_boot_cpu(void)
147 make_lowmem_page_readwrite(&per_cpu__gdt_page); 147 make_lowmem_page_readwrite(&per_cpu__gdt_page);
148 148
149 for (cpu = 0; cpu < NR_CPUS; cpu++) { 149 for (cpu = 0; cpu < NR_CPUS; cpu++) {
150 cpus_clear(cpu_sibling_map[cpu]); 150 cpus_clear(per_cpu(cpu_sibling_map, cpu));
151 cpus_clear(cpu_core_map[cpu]); 151 /*
152 * cpu_core_map lives in a per cpu area that is cleared
153 * when the per cpu array is allocated.
154 *
155 * cpus_clear(per_cpu(cpu_core_map, cpu));
156 */
152 } 157 }
153 158
154 xen_setup_vcpu_info_placement(); 159 xen_setup_vcpu_info_placement();
@@ -159,8 +164,13 @@ void __init xen_smp_prepare_cpus(unsigned int max_cpus)
159 unsigned cpu; 164 unsigned cpu;
160 165
161 for (cpu = 0; cpu < NR_CPUS; cpu++) { 166 for (cpu = 0; cpu < NR_CPUS; cpu++) {
162 cpus_clear(cpu_sibling_map[cpu]); 167 cpus_clear(per_cpu(cpu_sibling_map, cpu));
163 cpus_clear(cpu_core_map[cpu]); 168 /*
169 * cpu_core_ map will be zeroed when the per
170 * cpu area is allocated.
171 *
172 * cpus_clear(per_cpu(cpu_core_map, cpu));
173 */
164 } 174 }
165 175
166 smp_store_cpu_info(0); 176 smp_store_cpu_info(0);
diff --git a/arch/x86_64/Kconfig b/arch/x86_64/Kconfig
index cf013cb85ea4..8c83dbe4c4d0 100644
--- a/arch/x86_64/Kconfig
+++ b/arch/x86_64/Kconfig
@@ -409,6 +409,7 @@ config ARCH_DISCONTIGMEM_DEFAULT
409config ARCH_SPARSEMEM_ENABLE 409config ARCH_SPARSEMEM_ENABLE
410 def_bool y 410 def_bool y
411 depends on (NUMA || EXPERIMENTAL) 411 depends on (NUMA || EXPERIMENTAL)
412 select SPARSEMEM_VMEMMAP_ENABLE
412 413
413config ARCH_MEMORY_PROBE 414config ARCH_MEMORY_PROBE
414 def_bool y 415 def_bool y
diff --git a/arch/xtensa/kernel/ptrace.c b/arch/xtensa/kernel/ptrace.c
index 06a13d9b69db..5533c7850d53 100644
--- a/arch/xtensa/kernel/ptrace.c
+++ b/arch/xtensa/kernel/ptrace.c
@@ -304,10 +304,6 @@ long arch_ptrace(struct task_struct *child, long request, long addr, long data)
304 ret = put_user(sizeof(elf_fpregset_t), (unsigned long *) data); 304 ret = put_user(sizeof(elf_fpregset_t), (unsigned long *) data);
305 break; 305 break;
306 306
307 case PTRACE_DETACH: /* detach a process that was attached. */
308 ret = ptrace_detach(child, data);
309 break;
310
311 default: 307 default:
312 ret = ptrace_request(child, request, addr, data); 308 ret = ptrace_request(child, request, addr, data);
313 goto out; 309 goto out;
diff --git a/arch/xtensa/mm/fault.c b/arch/xtensa/mm/fault.c
index 45d28f217c03..2f842859948f 100644
--- a/arch/xtensa/mm/fault.c
+++ b/arch/xtensa/mm/fault.c
@@ -152,7 +152,7 @@ out_of_memory:
152 } 152 }
153 printk("VM: killing process %s\n", current->comm); 153 printk("VM: killing process %s\n", current->comm);
154 if (user_mode(regs)) 154 if (user_mode(regs))
155 do_exit(SIGKILL); 155 do_group_exit(SIGKILL);
156 bad_page_fault(regs, address, SIGKILL); 156 bad_page_fault(regs, address, SIGKILL);
157 return; 157 return;
158 158
diff --git a/block/blktrace.c b/block/blktrace.c
index 775471ef84a5..d00ac3993c18 100644
--- a/block/blktrace.c
+++ b/block/blktrace.c
@@ -550,7 +550,7 @@ static void blk_trace_set_ht_offsets(void)
550 for_each_online_cpu(cpu) { 550 for_each_online_cpu(cpu) {
551 unsigned long long *cpu_off, *sibling_off; 551 unsigned long long *cpu_off, *sibling_off;
552 552
553 for_each_cpu_mask(i, cpu_sibling_map[cpu]) { 553 for_each_cpu_mask(i, per_cpu(cpu_sibling_map, cpu)) {
554 if (i == cpu) 554 if (i == cpu)
555 continue; 555 continue;
556 556
diff --git a/block/bsg.c b/block/bsg.c
index b8ddfc66f210..8e181ab3afb9 100644
--- a/block/bsg.c
+++ b/block/bsg.c
@@ -908,7 +908,7 @@ static long bsg_ioctl(struct file *file, unsigned int cmd, unsigned long arg)
908 } 908 }
909} 909}
910 910
911static struct file_operations bsg_fops = { 911static const struct file_operations bsg_fops = {
912 .read = bsg_read, 912 .read = bsg_read,
913 .write = bsg_write, 913 .write = bsg_write,
914 .poll = bsg_poll, 914 .poll = bsg_poll,
diff --git a/block/elevator.c b/block/elevator.c
index b9c518afe1f8..952aee04a68a 100644
--- a/block/elevator.c
+++ b/block/elevator.c
@@ -712,6 +712,14 @@ struct request *elv_next_request(struct request_queue *q)
712 int ret; 712 int ret;
713 713
714 while ((rq = __elv_next_request(q)) != NULL) { 714 while ((rq = __elv_next_request(q)) != NULL) {
715 /*
716 * Kill the empty barrier place holder, the driver must
717 * not ever see it.
718 */
719 if (blk_empty_barrier(rq)) {
720 end_queued_request(rq, 1);
721 continue;
722 }
715 if (!(rq->cmd_flags & REQ_STARTED)) { 723 if (!(rq->cmd_flags & REQ_STARTED)) {
716 /* 724 /*
717 * This is the first time the device driver 725 * This is the first time the device driver
@@ -751,15 +759,8 @@ struct request *elv_next_request(struct request_queue *q)
751 rq = NULL; 759 rq = NULL;
752 break; 760 break;
753 } else if (ret == BLKPREP_KILL) { 761 } else if (ret == BLKPREP_KILL) {
754 int nr_bytes = rq->hard_nr_sectors << 9;
755
756 if (!nr_bytes)
757 nr_bytes = rq->data_len;
758
759 blkdev_dequeue_request(rq);
760 rq->cmd_flags |= REQ_QUIET; 762 rq->cmd_flags |= REQ_QUIET;
761 end_that_request_chunk(rq, 0, nr_bytes); 763 end_queued_request(rq, 0);
762 end_that_request_last(rq, 0);
763 } else { 764 } else {
764 printk(KERN_ERR "%s: bad return=%d\n", __FUNCTION__, 765 printk(KERN_ERR "%s: bad return=%d\n", __FUNCTION__,
765 ret); 766 ret);
diff --git a/block/ll_rw_blk.c b/block/ll_rw_blk.c
index d875673e76cd..9eabac95fbe0 100644
--- a/block/ll_rw_blk.c
+++ b/block/ll_rw_blk.c
@@ -30,6 +30,7 @@
30#include <linux/cpu.h> 30#include <linux/cpu.h>
31#include <linux/blktrace_api.h> 31#include <linux/blktrace_api.h>
32#include <linux/fault-inject.h> 32#include <linux/fault-inject.h>
33#include <linux/scatterlist.h>
33 34
34/* 35/*
35 * for max sense size 36 * for max sense size
@@ -304,23 +305,6 @@ int blk_queue_ordered(struct request_queue *q, unsigned ordered,
304 305
305EXPORT_SYMBOL(blk_queue_ordered); 306EXPORT_SYMBOL(blk_queue_ordered);
306 307
307/**
308 * blk_queue_issue_flush_fn - set function for issuing a flush
309 * @q: the request queue
310 * @iff: the function to be called issuing the flush
311 *
312 * Description:
313 * If a driver supports issuing a flush command, the support is notified
314 * to the block layer by defining it through this call.
315 *
316 **/
317void blk_queue_issue_flush_fn(struct request_queue *q, issue_flush_fn *iff)
318{
319 q->issue_flush_fn = iff;
320}
321
322EXPORT_SYMBOL(blk_queue_issue_flush_fn);
323
324/* 308/*
325 * Cache flushing for ordered writes handling 309 * Cache flushing for ordered writes handling
326 */ 310 */
@@ -377,10 +361,12 @@ void blk_ordered_complete_seq(struct request_queue *q, unsigned seq, int error)
377 /* 361 /*
378 * Okay, sequence complete. 362 * Okay, sequence complete.
379 */ 363 */
380 rq = q->orig_bar_rq; 364 uptodate = 1;
381 uptodate = q->orderr ? q->orderr : 1; 365 if (q->orderr)
366 uptodate = q->orderr;
382 367
383 q->ordseq = 0; 368 q->ordseq = 0;
369 rq = q->orig_bar_rq;
384 370
385 end_that_request_first(rq, uptodate, rq->hard_nr_sectors); 371 end_that_request_first(rq, uptodate, rq->hard_nr_sectors);
386 end_that_request_last(rq, uptodate); 372 end_that_request_last(rq, uptodate);
@@ -445,7 +431,8 @@ static inline struct request *start_ordered(struct request_queue *q,
445 rq_init(q, rq); 431 rq_init(q, rq);
446 if (bio_data_dir(q->orig_bar_rq->bio) == WRITE) 432 if (bio_data_dir(q->orig_bar_rq->bio) == WRITE)
447 rq->cmd_flags |= REQ_RW; 433 rq->cmd_flags |= REQ_RW;
448 rq->cmd_flags |= q->ordered & QUEUE_ORDERED_FUA ? REQ_FUA : 0; 434 if (q->ordered & QUEUE_ORDERED_FUA)
435 rq->cmd_flags |= REQ_FUA;
449 rq->elevator_private = NULL; 436 rq->elevator_private = NULL;
450 rq->elevator_private2 = NULL; 437 rq->elevator_private2 = NULL;
451 init_request_from_bio(rq, q->orig_bar_rq->bio); 438 init_request_from_bio(rq, q->orig_bar_rq->bio);
@@ -455,9 +442,12 @@ static inline struct request *start_ordered(struct request_queue *q,
455 * Queue ordered sequence. As we stack them at the head, we 442 * Queue ordered sequence. As we stack them at the head, we
456 * need to queue in reverse order. Note that we rely on that 443 * need to queue in reverse order. Note that we rely on that
457 * no fs request uses ELEVATOR_INSERT_FRONT and thus no fs 444 * no fs request uses ELEVATOR_INSERT_FRONT and thus no fs
458 * request gets inbetween ordered sequence. 445 * request gets inbetween ordered sequence. If this request is
446 * an empty barrier, we don't need to do a postflush ever since
447 * there will be no data written between the pre and post flush.
448 * Hence a single flush will suffice.
459 */ 449 */
460 if (q->ordered & QUEUE_ORDERED_POSTFLUSH) 450 if ((q->ordered & QUEUE_ORDERED_POSTFLUSH) && !blk_empty_barrier(rq))
461 queue_flush(q, QUEUE_ORDERED_POSTFLUSH); 451 queue_flush(q, QUEUE_ORDERED_POSTFLUSH);
462 else 452 else
463 q->ordseq |= QUEUE_ORDSEQ_POSTFLUSH; 453 q->ordseq |= QUEUE_ORDSEQ_POSTFLUSH;
@@ -481,7 +471,7 @@ static inline struct request *start_ordered(struct request_queue *q,
481int blk_do_ordered(struct request_queue *q, struct request **rqp) 471int blk_do_ordered(struct request_queue *q, struct request **rqp)
482{ 472{
483 struct request *rq = *rqp; 473 struct request *rq = *rqp;
484 int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq); 474 const int is_barrier = blk_fs_request(rq) && blk_barrier_rq(rq);
485 475
486 if (!q->ordseq) { 476 if (!q->ordseq) {
487 if (!is_barrier) 477 if (!is_barrier)
@@ -1329,9 +1319,10 @@ static int blk_hw_contig_segment(struct request_queue *q, struct bio *bio,
1329 * must make sure sg can hold rq->nr_phys_segments entries 1319 * must make sure sg can hold rq->nr_phys_segments entries
1330 */ 1320 */
1331int blk_rq_map_sg(struct request_queue *q, struct request *rq, 1321int blk_rq_map_sg(struct request_queue *q, struct request *rq,
1332 struct scatterlist *sg) 1322 struct scatterlist *sglist)
1333{ 1323{
1334 struct bio_vec *bvec, *bvprv; 1324 struct bio_vec *bvec, *bvprv;
1325 struct scatterlist *next_sg, *sg;
1335 struct req_iterator iter; 1326 struct req_iterator iter;
1336 int nsegs, cluster; 1327 int nsegs, cluster;
1337 1328
@@ -1342,11 +1333,12 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
1342 * for each bio in rq 1333 * for each bio in rq
1343 */ 1334 */
1344 bvprv = NULL; 1335 bvprv = NULL;
1336 sg = next_sg = &sglist[0];
1345 rq_for_each_segment(bvec, rq, iter) { 1337 rq_for_each_segment(bvec, rq, iter) {
1346 int nbytes = bvec->bv_len; 1338 int nbytes = bvec->bv_len;
1347 1339
1348 if (bvprv && cluster) { 1340 if (bvprv && cluster) {
1349 if (sg[nsegs - 1].length + nbytes > q->max_segment_size) 1341 if (sg->length + nbytes > q->max_segment_size)
1350 goto new_segment; 1342 goto new_segment;
1351 1343
1352 if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec)) 1344 if (!BIOVEC_PHYS_MERGEABLE(bvprv, bvec))
@@ -1354,14 +1346,15 @@ int blk_rq_map_sg(struct request_queue *q, struct request *rq,
1354 if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec)) 1346 if (!BIOVEC_SEG_BOUNDARY(q, bvprv, bvec))
1355 goto new_segment; 1347 goto new_segment;
1356 1348
1357 sg[nsegs - 1].length += nbytes; 1349 sg->length += nbytes;
1358 } else { 1350 } else {
1359new_segment: 1351new_segment:
1360 memset(&sg[nsegs],0,sizeof(struct scatterlist)); 1352 sg = next_sg;
1361 sg[nsegs].page = bvec->bv_page; 1353 next_sg = sg_next(sg);
1362 sg[nsegs].length = nbytes;
1363 sg[nsegs].offset = bvec->bv_offset;
1364 1354
1355 sg->page = bvec->bv_page;
1356 sg->length = nbytes;
1357 sg->offset = bvec->bv_offset;
1365 nsegs++; 1358 nsegs++;
1366 } 1359 }
1367 bvprv = bvec; 1360 bvprv = bvec;
@@ -2660,6 +2653,14 @@ int blk_execute_rq(struct request_queue *q, struct gendisk *bd_disk,
2660 2653
2661EXPORT_SYMBOL(blk_execute_rq); 2654EXPORT_SYMBOL(blk_execute_rq);
2662 2655
2656static void bio_end_empty_barrier(struct bio *bio, int err)
2657{
2658 if (err)
2659 clear_bit(BIO_UPTODATE, &bio->bi_flags);
2660
2661 complete(bio->bi_private);
2662}
2663
2663/** 2664/**
2664 * blkdev_issue_flush - queue a flush 2665 * blkdev_issue_flush - queue a flush
2665 * @bdev: blockdev to issue flush for 2666 * @bdev: blockdev to issue flush for
@@ -2672,7 +2673,10 @@ EXPORT_SYMBOL(blk_execute_rq);
2672 */ 2673 */
2673int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector) 2674int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
2674{ 2675{
2676 DECLARE_COMPLETION_ONSTACK(wait);
2675 struct request_queue *q; 2677 struct request_queue *q;
2678 struct bio *bio;
2679 int ret;
2676 2680
2677 if (bdev->bd_disk == NULL) 2681 if (bdev->bd_disk == NULL)
2678 return -ENXIO; 2682 return -ENXIO;
@@ -2680,10 +2684,32 @@ int blkdev_issue_flush(struct block_device *bdev, sector_t *error_sector)
2680 q = bdev_get_queue(bdev); 2684 q = bdev_get_queue(bdev);
2681 if (!q) 2685 if (!q)
2682 return -ENXIO; 2686 return -ENXIO;
2683 if (!q->issue_flush_fn)
2684 return -EOPNOTSUPP;
2685 2687
2686 return q->issue_flush_fn(q, bdev->bd_disk, error_sector); 2688 bio = bio_alloc(GFP_KERNEL, 0);
2689 if (!bio)
2690 return -ENOMEM;
2691
2692 bio->bi_end_io = bio_end_empty_barrier;
2693 bio->bi_private = &wait;
2694 bio->bi_bdev = bdev;
2695 submit_bio(1 << BIO_RW_BARRIER, bio);
2696
2697 wait_for_completion(&wait);
2698
2699 /*
2700 * The driver must store the error location in ->bi_sector, if
2701 * it supports it. For non-stacked drivers, this should be copied
2702 * from rq->sector.
2703 */
2704 if (error_sector)
2705 *error_sector = bio->bi_sector;
2706
2707 ret = 0;
2708 if (!bio_flagged(bio, BIO_UPTODATE))
2709 ret = -EIO;
2710
2711 bio_put(bio);
2712 return ret;
2687} 2713}
2688 2714
2689EXPORT_SYMBOL(blkdev_issue_flush); 2715EXPORT_SYMBOL(blkdev_issue_flush);
@@ -3051,7 +3077,7 @@ static inline void blk_partition_remap(struct bio *bio)
3051{ 3077{
3052 struct block_device *bdev = bio->bi_bdev; 3078 struct block_device *bdev = bio->bi_bdev;
3053 3079
3054 if (bdev != bdev->bd_contains) { 3080 if (bio_sectors(bio) && bdev != bdev->bd_contains) {
3055 struct hd_struct *p = bdev->bd_part; 3081 struct hd_struct *p = bdev->bd_part;
3056 const int rw = bio_data_dir(bio); 3082 const int rw = bio_data_dir(bio);
3057 3083
@@ -3117,6 +3143,35 @@ static inline int should_fail_request(struct bio *bio)
3117 3143
3118#endif /* CONFIG_FAIL_MAKE_REQUEST */ 3144#endif /* CONFIG_FAIL_MAKE_REQUEST */
3119 3145
3146/*
3147 * Check whether this bio extends beyond the end of the device.
3148 */
3149static inline int bio_check_eod(struct bio *bio, unsigned int nr_sectors)
3150{
3151 sector_t maxsector;
3152
3153 if (!nr_sectors)
3154 return 0;
3155
3156 /* Test device or partition size, when known. */
3157 maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
3158 if (maxsector) {
3159 sector_t sector = bio->bi_sector;
3160
3161 if (maxsector < nr_sectors || maxsector - nr_sectors < sector) {
3162 /*
3163 * This may well happen - the kernel calls bread()
3164 * without checking the size of the device, e.g., when
3165 * mounting a device.
3166 */
3167 handle_bad_sector(bio);
3168 return 1;
3169 }
3170 }
3171
3172 return 0;
3173}
3174
3120/** 3175/**
3121 * generic_make_request: hand a buffer to its device driver for I/O 3176 * generic_make_request: hand a buffer to its device driver for I/O
3122 * @bio: The bio describing the location in memory and on the device. 3177 * @bio: The bio describing the location in memory and on the device.
@@ -3144,27 +3199,14 @@ static inline int should_fail_request(struct bio *bio)
3144static inline void __generic_make_request(struct bio *bio) 3199static inline void __generic_make_request(struct bio *bio)
3145{ 3200{
3146 struct request_queue *q; 3201 struct request_queue *q;
3147 sector_t maxsector;
3148 sector_t old_sector; 3202 sector_t old_sector;
3149 int ret, nr_sectors = bio_sectors(bio); 3203 int ret, nr_sectors = bio_sectors(bio);
3150 dev_t old_dev; 3204 dev_t old_dev;
3151 3205
3152 might_sleep(); 3206 might_sleep();
3153 /* Test device or partition size, when known. */
3154 maxsector = bio->bi_bdev->bd_inode->i_size >> 9;
3155 if (maxsector) {
3156 sector_t sector = bio->bi_sector;
3157 3207
3158 if (maxsector < nr_sectors || maxsector - nr_sectors < sector) { 3208 if (bio_check_eod(bio, nr_sectors))
3159 /* 3209 goto end_io;
3160 * This may well happen - the kernel calls bread()
3161 * without checking the size of the device, e.g., when
3162 * mounting a device.
3163 */
3164 handle_bad_sector(bio);
3165 goto end_io;
3166 }
3167 }
3168 3210
3169 /* 3211 /*
3170 * Resolve the mapping until finished. (drivers are 3212 * Resolve the mapping until finished. (drivers are
@@ -3191,7 +3233,7 @@ end_io:
3191 break; 3233 break;
3192 } 3234 }
3193 3235
3194 if (unlikely(bio_sectors(bio) > q->max_hw_sectors)) { 3236 if (unlikely(nr_sectors > q->max_hw_sectors)) {
3195 printk("bio too big device %s (%u > %u)\n", 3237 printk("bio too big device %s (%u > %u)\n",
3196 bdevname(bio->bi_bdev, b), 3238 bdevname(bio->bi_bdev, b),
3197 bio_sectors(bio), 3239 bio_sectors(bio),
@@ -3212,7 +3254,7 @@ end_io:
3212 blk_partition_remap(bio); 3254 blk_partition_remap(bio);
3213 3255
3214 if (old_sector != -1) 3256 if (old_sector != -1)
3215 blk_add_trace_remap(q, bio, old_dev, bio->bi_sector, 3257 blk_add_trace_remap(q, bio, old_dev, bio->bi_sector,
3216 old_sector); 3258 old_sector);
3217 3259
3218 blk_add_trace_bio(q, bio, BLK_TA_QUEUE); 3260 blk_add_trace_bio(q, bio, BLK_TA_QUEUE);
@@ -3220,21 +3262,8 @@ end_io:
3220 old_sector = bio->bi_sector; 3262 old_sector = bio->bi_sector;
3221 old_dev = bio->bi_bdev->bd_dev; 3263 old_dev = bio->bi_bdev->bd_dev;
3222 3264
3223 maxsector = bio->bi_bdev->bd_inode->i_size >> 9; 3265 if (bio_check_eod(bio, nr_sectors))
3224 if (maxsector) { 3266 goto end_io;
3225 sector_t sector = bio->bi_sector;
3226
3227 if (maxsector < nr_sectors ||
3228 maxsector - nr_sectors < sector) {
3229 /*
3230 * This may well happen - partitions are not
3231 * checked to make sure they are within the size
3232 * of the whole device.
3233 */
3234 handle_bad_sector(bio);
3235 goto end_io;
3236 }
3237 }
3238 3267
3239 ret = q->make_request_fn(q, bio); 3268 ret = q->make_request_fn(q, bio);
3240 } while (ret); 3269 } while (ret);
@@ -3307,23 +3336,32 @@ void submit_bio(int rw, struct bio *bio)
3307{ 3336{
3308 int count = bio_sectors(bio); 3337 int count = bio_sectors(bio);
3309 3338
3310 BIO_BUG_ON(!bio->bi_size);
3311 BIO_BUG_ON(!bio->bi_io_vec);
3312 bio->bi_rw |= rw; 3339 bio->bi_rw |= rw;
3313 if (rw & WRITE) {
3314 count_vm_events(PGPGOUT, count);
3315 } else {
3316 task_io_account_read(bio->bi_size);
3317 count_vm_events(PGPGIN, count);
3318 }
3319 3340
3320 if (unlikely(block_dump)) { 3341 /*
3321 char b[BDEVNAME_SIZE]; 3342 * If it's a regular read/write or a barrier with data attached,
3322 printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n", 3343 * go through the normal accounting stuff before submission.
3323 current->comm, current->pid, 3344 */
3324 (rw & WRITE) ? "WRITE" : "READ", 3345 if (!bio_empty_barrier(bio)) {
3325 (unsigned long long)bio->bi_sector, 3346
3326 bdevname(bio->bi_bdev,b)); 3347 BIO_BUG_ON(!bio->bi_size);
3348 BIO_BUG_ON(!bio->bi_io_vec);
3349
3350 if (rw & WRITE) {
3351 count_vm_events(PGPGOUT, count);
3352 } else {
3353 task_io_account_read(bio->bi_size);
3354 count_vm_events(PGPGIN, count);
3355 }
3356
3357 if (unlikely(block_dump)) {
3358 char b[BDEVNAME_SIZE];
3359 printk(KERN_DEBUG "%s(%d): %s block %Lu on %s\n",
3360 current->comm, current->pid,
3361 (rw & WRITE) ? "WRITE" : "READ",
3362 (unsigned long long)bio->bi_sector,
3363 bdevname(bio->bi_bdev,b));
3364 }
3327 } 3365 }
3328 3366
3329 generic_make_request(bio); 3367 generic_make_request(bio);
@@ -3399,6 +3437,14 @@ static int __end_that_request_first(struct request *req, int uptodate,
3399 while ((bio = req->bio) != NULL) { 3437 while ((bio = req->bio) != NULL) {
3400 int nbytes; 3438 int nbytes;
3401 3439
3440 /*
3441 * For an empty barrier request, the low level driver must
3442 * store a potential error location in ->sector. We pass
3443 * that back up in ->bi_sector.
3444 */
3445 if (blk_empty_barrier(req))
3446 bio->bi_sector = req->sector;
3447
3402 if (nr_bytes >= bio->bi_size) { 3448 if (nr_bytes >= bio->bi_size) {
3403 req->bio = bio->bi_next; 3449 req->bio = bio->bi_next;
3404 nbytes = bio->bi_size; 3450 nbytes = bio->bi_size;
@@ -3564,7 +3610,7 @@ static struct notifier_block blk_cpu_notifier __cpuinitdata = {
3564 * Description: 3610 * Description:
3565 * Ends all I/O on a request. It does not handle partial completions, 3611 * Ends all I/O on a request. It does not handle partial completions,
3566 * unless the driver actually implements this in its completion callback 3612 * unless the driver actually implements this in its completion callback
3567 * through requeueing. Theh actual completion happens out-of-order, 3613 * through requeueing. The actual completion happens out-of-order,
3568 * through a softirq handler. The user must have registered a completion 3614 * through a softirq handler. The user must have registered a completion
3569 * callback through blk_queue_softirq_done(). 3615 * callback through blk_queue_softirq_done().
3570 **/ 3616 **/
@@ -3627,15 +3673,83 @@ void end_that_request_last(struct request *req, int uptodate)
3627 3673
3628EXPORT_SYMBOL(end_that_request_last); 3674EXPORT_SYMBOL(end_that_request_last);
3629 3675
3630void end_request(struct request *req, int uptodate) 3676static inline void __end_request(struct request *rq, int uptodate,
3677 unsigned int nr_bytes, int dequeue)
3631{ 3678{
3632 if (!end_that_request_first(req, uptodate, req->hard_cur_sectors)) { 3679 if (!end_that_request_chunk(rq, uptodate, nr_bytes)) {
3633 add_disk_randomness(req->rq_disk); 3680 if (dequeue)
3634 blkdev_dequeue_request(req); 3681 blkdev_dequeue_request(rq);
3635 end_that_request_last(req, uptodate); 3682 add_disk_randomness(rq->rq_disk);
3683 end_that_request_last(rq, uptodate);
3636 } 3684 }
3637} 3685}
3638 3686
3687static unsigned int rq_byte_size(struct request *rq)
3688{
3689 if (blk_fs_request(rq))
3690 return rq->hard_nr_sectors << 9;
3691
3692 return rq->data_len;
3693}
3694
3695/**
3696 * end_queued_request - end all I/O on a queued request
3697 * @rq: the request being processed
3698 * @uptodate: error value or 0/1 uptodate flag
3699 *
3700 * Description:
3701 * Ends all I/O on a request, and removes it from the block layer queues.
3702 * Not suitable for normal IO completion, unless the driver still has
3703 * the request attached to the block layer.
3704 *
3705 **/
3706void end_queued_request(struct request *rq, int uptodate)
3707{
3708 __end_request(rq, uptodate, rq_byte_size(rq), 1);
3709}
3710EXPORT_SYMBOL(end_queued_request);
3711
3712/**
3713 * end_dequeued_request - end all I/O on a dequeued request
3714 * @rq: the request being processed
3715 * @uptodate: error value or 0/1 uptodate flag
3716 *
3717 * Description:
3718 * Ends all I/O on a request. The request must already have been
3719 * dequeued using blkdev_dequeue_request(), as is normally the case
3720 * for most drivers.
3721 *
3722 **/
3723void end_dequeued_request(struct request *rq, int uptodate)
3724{
3725 __end_request(rq, uptodate, rq_byte_size(rq), 0);
3726}
3727EXPORT_SYMBOL(end_dequeued_request);
3728
3729
3730/**
3731 * end_request - end I/O on the current segment of the request
3732 * @rq: the request being processed
3733 * @uptodate: error value or 0/1 uptodate flag
3734 *
3735 * Description:
3736 * Ends I/O on the current segment of a request. If that is the only
3737 * remaining segment, the request is also completed and freed.
3738 *
3739 * This is a remnant of how older block drivers handled IO completions.
3740 * Modern drivers typically end IO on the full request in one go, unless
3741 * they have a residual value to account for. For that case this function
3742 * isn't really useful, unless the residual just happens to be the
3743 * full current segment. In other words, don't use this function in new
3744 * code. Either use end_request_completely(), or the
3745 * end_that_request_chunk() (along with end_that_request_last()) for
3746 * partial completions.
3747 *
3748 **/
3749void end_request(struct request *req, int uptodate)
3750{
3751 __end_request(req, uptodate, req->hard_cur_sectors << 9, 1);
3752}
3639EXPORT_SYMBOL(end_request); 3753EXPORT_SYMBOL(end_request);
3640 3754
3641static void blk_rq_bio_prep(struct request_queue *q, struct request *rq, 3755static void blk_rq_bio_prep(struct request_queue *q, struct request *rq,
@@ -3928,7 +4042,6 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
3928 max_hw_sectors_kb = q->max_hw_sectors >> 1, 4042 max_hw_sectors_kb = q->max_hw_sectors >> 1,
3929 page_kb = 1 << (PAGE_CACHE_SHIFT - 10); 4043 page_kb = 1 << (PAGE_CACHE_SHIFT - 10);
3930 ssize_t ret = queue_var_store(&max_sectors_kb, page, count); 4044 ssize_t ret = queue_var_store(&max_sectors_kb, page, count);
3931 int ra_kb;
3932 4045
3933 if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb) 4046 if (max_sectors_kb > max_hw_sectors_kb || max_sectors_kb < page_kb)
3934 return -EINVAL; 4047 return -EINVAL;
@@ -3937,14 +4050,6 @@ queue_max_sectors_store(struct request_queue *q, const char *page, size_t count)
3937 * values synchronously: 4050 * values synchronously:
3938 */ 4051 */
3939 spin_lock_irq(q->queue_lock); 4052 spin_lock_irq(q->queue_lock);
3940 /*
3941 * Trim readahead window as well, if necessary:
3942 */
3943 ra_kb = q->backing_dev_info.ra_pages << (PAGE_CACHE_SHIFT - 10);
3944 if (ra_kb > max_sectors_kb)
3945 q->backing_dev_info.ra_pages =
3946 max_sectors_kb >> (PAGE_CACHE_SHIFT - 10);
3947
3948 q->max_sectors = max_sectors_kb << 1; 4053 q->max_sectors = max_sectors_kb << 1;
3949 spin_unlock_irq(q->queue_lock); 4054 spin_unlock_irq(q->queue_lock);
3950 4055
@@ -3958,7 +4063,23 @@ static ssize_t queue_max_hw_sectors_show(struct request_queue *q, char *page)
3958 return queue_var_show(max_hw_sectors_kb, (page)); 4063 return queue_var_show(max_hw_sectors_kb, (page));
3959} 4064}
3960 4065
4066static ssize_t queue_max_segments_show(struct request_queue *q, char *page)
4067{
4068 return queue_var_show(q->max_phys_segments, page);
4069}
4070
4071static ssize_t queue_max_segments_store(struct request_queue *q,
4072 const char *page, size_t count)
4073{
4074 unsigned long segments;
4075 ssize_t ret = queue_var_store(&segments, page, count);
4076
4077 spin_lock_irq(q->queue_lock);
4078 q->max_phys_segments = segments;
4079 spin_unlock_irq(q->queue_lock);
3961 4080
4081 return ret;
4082}
3962static struct queue_sysfs_entry queue_requests_entry = { 4083static struct queue_sysfs_entry queue_requests_entry = {
3963 .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR }, 4084 .attr = {.name = "nr_requests", .mode = S_IRUGO | S_IWUSR },
3964 .show = queue_requests_show, 4085 .show = queue_requests_show,
@@ -3982,6 +4103,12 @@ static struct queue_sysfs_entry queue_max_hw_sectors_entry = {
3982 .show = queue_max_hw_sectors_show, 4103 .show = queue_max_hw_sectors_show,
3983}; 4104};
3984 4105
4106static struct queue_sysfs_entry queue_max_segments_entry = {
4107 .attr = {.name = "max_segments", .mode = S_IRUGO | S_IWUSR },
4108 .show = queue_max_segments_show,
4109 .store = queue_max_segments_store,
4110};
4111
3985static struct queue_sysfs_entry queue_iosched_entry = { 4112static struct queue_sysfs_entry queue_iosched_entry = {
3986 .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR }, 4113 .attr = {.name = "scheduler", .mode = S_IRUGO | S_IWUSR },
3987 .show = elv_iosched_show, 4114 .show = elv_iosched_show,
@@ -3993,6 +4120,7 @@ static struct attribute *default_attrs[] = {
3993 &queue_ra_entry.attr, 4120 &queue_ra_entry.attr,
3994 &queue_max_hw_sectors_entry.attr, 4121 &queue_max_hw_sectors_entry.attr,
3995 &queue_max_sectors_entry.attr, 4122 &queue_max_sectors_entry.attr,
4123 &queue_max_segments_entry.attr,
3996 &queue_iosched_entry.attr, 4124 &queue_iosched_entry.attr,
3997 NULL, 4125 NULL,
3998}; 4126};
diff --git a/crypto/digest.c b/crypto/digest.c
index 1bf7414aeb9e..e56de6748b15 100644
--- a/crypto/digest.c
+++ b/crypto/digest.c
@@ -77,7 +77,7 @@ static int update2(struct hash_desc *desc,
77 77
78 if (!nbytes) 78 if (!nbytes)
79 break; 79 break;
80 sg = sg_next(sg); 80 sg = scatterwalk_sg_next(sg);
81 } 81 }
82 82
83 return 0; 83 return 0;
diff --git a/crypto/scatterwalk.c b/crypto/scatterwalk.c
index 3052f6507f53..d6852c33cfb7 100644
--- a/crypto/scatterwalk.c
+++ b/crypto/scatterwalk.c
@@ -62,7 +62,7 @@ static void scatterwalk_pagedone(struct scatter_walk *walk, int out,
62 walk->offset += PAGE_SIZE - 1; 62 walk->offset += PAGE_SIZE - 1;
63 walk->offset &= PAGE_MASK; 63 walk->offset &= PAGE_MASK;
64 if (walk->offset >= walk->sg->offset + walk->sg->length) 64 if (walk->offset >= walk->sg->offset + walk->sg->length)
65 scatterwalk_start(walk, sg_next(walk->sg)); 65 scatterwalk_start(walk, scatterwalk_sg_next(walk->sg));
66 } 66 }
67} 67}
68 68
diff --git a/crypto/scatterwalk.h b/crypto/scatterwalk.h
index 500a220ad908..9c73e37a42ce 100644
--- a/crypto/scatterwalk.h
+++ b/crypto/scatterwalk.h
@@ -20,7 +20,7 @@
20 20
21#include "internal.h" 21#include "internal.h"
22 22
23static inline struct scatterlist *sg_next(struct scatterlist *sg) 23static inline struct scatterlist *scatterwalk_sg_next(struct scatterlist *sg)
24{ 24{
25 return (++sg)->length ? sg : (void *)sg->page; 25 return (++sg)->length ? sg : (void *)sg->page;
26} 26}
diff --git a/drivers/Kconfig b/drivers/Kconfig
index 7bdae47d6b91..4fb134d50da7 100644
--- a/drivers/Kconfig
+++ b/drivers/Kconfig
@@ -84,6 +84,8 @@ source "drivers/rtc/Kconfig"
84 84
85source "drivers/dma/Kconfig" 85source "drivers/dma/Kconfig"
86 86
87source "drivers/dca/Kconfig"
88
87source "drivers/auxdisplay/Kconfig" 89source "drivers/auxdisplay/Kconfig"
88 90
89source "drivers/kvm/Kconfig" 91source "drivers/kvm/Kconfig"
diff --git a/drivers/Makefile b/drivers/Makefile
index a168eacdcd9c..174c27eb4430 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -85,6 +85,7 @@ obj-$(CONFIG_CRYPTO) += crypto/
85obj-$(CONFIG_SUPERH) += sh/ 85obj-$(CONFIG_SUPERH) += sh/
86obj-$(CONFIG_GENERIC_TIME) += clocksource/ 86obj-$(CONFIG_GENERIC_TIME) += clocksource/
87obj-$(CONFIG_DMA_ENGINE) += dma/ 87obj-$(CONFIG_DMA_ENGINE) += dma/
88obj-$(CONFIG_DCA) += dca/
88obj-$(CONFIG_HID) += hid/ 89obj-$(CONFIG_HID) += hid/
89obj-$(CONFIG_PPC_PS3) += ps3/ 90obj-$(CONFIG_PPC_PS3) += ps3/
90obj-$(CONFIG_OF) += of/ 91obj-$(CONFIG_OF) += of/
diff --git a/drivers/ata/libata-core.c b/drivers/ata/libata-core.c
index 68699b3e7998..bbaa545ea999 100644
--- a/drivers/ata/libata-core.c
+++ b/drivers/ata/libata-core.c
@@ -1410,7 +1410,7 @@ static void ata_qc_complete_internal(struct ata_queued_cmd *qc)
1410 */ 1410 */
1411unsigned ata_exec_internal_sg(struct ata_device *dev, 1411unsigned ata_exec_internal_sg(struct ata_device *dev,
1412 struct ata_taskfile *tf, const u8 *cdb, 1412 struct ata_taskfile *tf, const u8 *cdb,
1413 int dma_dir, struct scatterlist *sg, 1413 int dma_dir, struct scatterlist *sgl,
1414 unsigned int n_elem, unsigned long timeout) 1414 unsigned int n_elem, unsigned long timeout)
1415{ 1415{
1416 struct ata_link *link = dev->link; 1416 struct ata_link *link = dev->link;
@@ -1472,11 +1472,12 @@ unsigned ata_exec_internal_sg(struct ata_device *dev,
1472 qc->dma_dir = dma_dir; 1472 qc->dma_dir = dma_dir;
1473 if (dma_dir != DMA_NONE) { 1473 if (dma_dir != DMA_NONE) {
1474 unsigned int i, buflen = 0; 1474 unsigned int i, buflen = 0;
1475 struct scatterlist *sg;
1475 1476
1476 for (i = 0; i < n_elem; i++) 1477 for_each_sg(sgl, sg, n_elem, i)
1477 buflen += sg[i].length; 1478 buflen += sg->length;
1478 1479
1479 ata_sg_init(qc, sg, n_elem); 1480 ata_sg_init(qc, sgl, n_elem);
1480 qc->nbytes = buflen; 1481 qc->nbytes = buflen;
1481 } 1482 }
1482 1483
@@ -4292,7 +4293,7 @@ void ata_sg_clean(struct ata_queued_cmd *qc)
4292 if (qc->n_elem) 4293 if (qc->n_elem)
4293 dma_unmap_sg(ap->dev, sg, qc->n_elem, dir); 4294 dma_unmap_sg(ap->dev, sg, qc->n_elem, dir);
4294 /* restore last sg */ 4295 /* restore last sg */
4295 sg[qc->orig_n_elem - 1].length += qc->pad_len; 4296 sg_last(sg, qc->orig_n_elem)->length += qc->pad_len;
4296 if (pad_buf) { 4297 if (pad_buf) {
4297 struct scatterlist *psg = &qc->pad_sgent; 4298 struct scatterlist *psg = &qc->pad_sgent;
4298 void *addr = kmap_atomic(psg->page, KM_IRQ0); 4299 void *addr = kmap_atomic(psg->page, KM_IRQ0);
@@ -4547,6 +4548,7 @@ void ata_sg_init_one(struct ata_queued_cmd *qc, void *buf, unsigned int buflen)
4547 qc->orig_n_elem = 1; 4548 qc->orig_n_elem = 1;
4548 qc->buf_virt = buf; 4549 qc->buf_virt = buf;
4549 qc->nbytes = buflen; 4550 qc->nbytes = buflen;
4551 qc->cursg = qc->__sg;
4550 4552
4551 sg_init_one(&qc->sgent, buf, buflen); 4553 sg_init_one(&qc->sgent, buf, buflen);
4552} 4554}
@@ -4572,6 +4574,7 @@ void ata_sg_init(struct ata_queued_cmd *qc, struct scatterlist *sg,
4572 qc->__sg = sg; 4574 qc->__sg = sg;
4573 qc->n_elem = n_elem; 4575 qc->n_elem = n_elem;
4574 qc->orig_n_elem = n_elem; 4576 qc->orig_n_elem = n_elem;
4577 qc->cursg = qc->__sg;
4575} 4578}
4576 4579
4577/** 4580/**
@@ -4661,7 +4664,7 @@ static int ata_sg_setup(struct ata_queued_cmd *qc)
4661{ 4664{
4662 struct ata_port *ap = qc->ap; 4665 struct ata_port *ap = qc->ap;
4663 struct scatterlist *sg = qc->__sg; 4666 struct scatterlist *sg = qc->__sg;
4664 struct scatterlist *lsg = &sg[qc->n_elem - 1]; 4667 struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
4665 int n_elem, pre_n_elem, dir, trim_sg = 0; 4668 int n_elem, pre_n_elem, dir, trim_sg = 0;
4666 4669
4667 VPRINTK("ENTER, ata%u\n", ap->print_id); 4670 VPRINTK("ENTER, ata%u\n", ap->print_id);
@@ -4825,7 +4828,6 @@ void ata_data_xfer_noirq(struct ata_device *adev, unsigned char *buf,
4825static void ata_pio_sector(struct ata_queued_cmd *qc) 4828static void ata_pio_sector(struct ata_queued_cmd *qc)
4826{ 4829{
4827 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); 4830 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
4828 struct scatterlist *sg = qc->__sg;
4829 struct ata_port *ap = qc->ap; 4831 struct ata_port *ap = qc->ap;
4830 struct page *page; 4832 struct page *page;
4831 unsigned int offset; 4833 unsigned int offset;
@@ -4834,8 +4836,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
4834 if (qc->curbytes == qc->nbytes - qc->sect_size) 4836 if (qc->curbytes == qc->nbytes - qc->sect_size)
4835 ap->hsm_task_state = HSM_ST_LAST; 4837 ap->hsm_task_state = HSM_ST_LAST;
4836 4838
4837 page = sg[qc->cursg].page; 4839 page = qc->cursg->page;
4838 offset = sg[qc->cursg].offset + qc->cursg_ofs; 4840 offset = qc->cursg->offset + qc->cursg_ofs;
4839 4841
4840 /* get the current page and offset */ 4842 /* get the current page and offset */
4841 page = nth_page(page, (offset >> PAGE_SHIFT)); 4843 page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -4863,8 +4865,8 @@ static void ata_pio_sector(struct ata_queued_cmd *qc)
4863 qc->curbytes += qc->sect_size; 4865 qc->curbytes += qc->sect_size;
4864 qc->cursg_ofs += qc->sect_size; 4866 qc->cursg_ofs += qc->sect_size;
4865 4867
4866 if (qc->cursg_ofs == (&sg[qc->cursg])->length) { 4868 if (qc->cursg_ofs == qc->cursg->length) {
4867 qc->cursg++; 4869 qc->cursg = sg_next(qc->cursg);
4868 qc->cursg_ofs = 0; 4870 qc->cursg_ofs = 0;
4869 } 4871 }
4870} 4872}
@@ -4950,16 +4952,18 @@ static void __atapi_pio_bytes(struct ata_queued_cmd *qc, unsigned int bytes)
4950{ 4952{
4951 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE); 4953 int do_write = (qc->tf.flags & ATA_TFLAG_WRITE);
4952 struct scatterlist *sg = qc->__sg; 4954 struct scatterlist *sg = qc->__sg;
4955 struct scatterlist *lsg = sg_last(qc->__sg, qc->n_elem);
4953 struct ata_port *ap = qc->ap; 4956 struct ata_port *ap = qc->ap;
4954 struct page *page; 4957 struct page *page;
4955 unsigned char *buf; 4958 unsigned char *buf;
4956 unsigned int offset, count; 4959 unsigned int offset, count;
4960 int no_more_sg = 0;
4957 4961
4958 if (qc->curbytes + bytes >= qc->nbytes) 4962 if (qc->curbytes + bytes >= qc->nbytes)
4959 ap->hsm_task_state = HSM_ST_LAST; 4963 ap->hsm_task_state = HSM_ST_LAST;
4960 4964
4961next_sg: 4965next_sg:
4962 if (unlikely(qc->cursg >= qc->n_elem)) { 4966 if (unlikely(no_more_sg)) {
4963 /* 4967 /*
4964 * The end of qc->sg is reached and the device expects 4968 * The end of qc->sg is reached and the device expects
4965 * more data to transfer. In order not to overrun qc->sg 4969 * more data to transfer. In order not to overrun qc->sg
@@ -4982,7 +4986,7 @@ next_sg:
4982 return; 4986 return;
4983 } 4987 }
4984 4988
4985 sg = &qc->__sg[qc->cursg]; 4989 sg = qc->cursg;
4986 4990
4987 page = sg->page; 4991 page = sg->page;
4988 offset = sg->offset + qc->cursg_ofs; 4992 offset = sg->offset + qc->cursg_ofs;
@@ -5021,7 +5025,10 @@ next_sg:
5021 qc->cursg_ofs += count; 5025 qc->cursg_ofs += count;
5022 5026
5023 if (qc->cursg_ofs == sg->length) { 5027 if (qc->cursg_ofs == sg->length) {
5024 qc->cursg++; 5028 if (qc->cursg == lsg)
5029 no_more_sg = 1;
5030
5031 qc->cursg = sg_next(qc->cursg);
5025 qc->cursg_ofs = 0; 5032 qc->cursg_ofs = 0;
5026 } 5033 }
5027 5034
diff --git a/drivers/ata/libata-scsi.c b/drivers/ata/libata-scsi.c
index d63c81ed084f..9fbb39cd0f58 100644
--- a/drivers/ata/libata-scsi.c
+++ b/drivers/ata/libata-scsi.c
@@ -801,8 +801,6 @@ int ata_scsi_slave_config(struct scsi_device *sdev)
801 801
802 ata_scsi_sdev_config(sdev); 802 ata_scsi_sdev_config(sdev);
803 803
804 blk_queue_max_phys_segments(sdev->request_queue, LIBATA_MAX_PRD);
805
806 sdev->manage_start_stop = 1; 804 sdev->manage_start_stop = 1;
807 805
808 if (dev) 806 if (dev)
@@ -3240,7 +3238,7 @@ static void ata_scsi_handle_link_detach(struct ata_link *link)
3240 3238
3241/** 3239/**
3242 * ata_scsi_media_change_notify - send media change event 3240 * ata_scsi_media_change_notify - send media change event
3243 * @atadev: Pointer to the disk device with media change event 3241 * @dev: Pointer to the disk device with media change event
3244 * 3242 *
3245 * Tell the block layer to send a media change notification 3243 * Tell the block layer to send a media change notification
3246 * event. 3244 * event.
diff --git a/drivers/base/memory.c b/drivers/base/memory.c
index 7a1390cd6aad..c41d0728efe2 100644
--- a/drivers/base/memory.c
+++ b/drivers/base/memory.c
@@ -238,7 +238,7 @@ store_mem_state(struct sys_device *dev, const char *buf, size_t count)
238 mem = container_of(dev, struct memory_block, sysdev); 238 mem = container_of(dev, struct memory_block, sysdev);
239 phys_section_nr = mem->phys_index; 239 phys_section_nr = mem->phys_index;
240 240
241 if (!valid_section_nr(phys_section_nr)) 241 if (!present_section_nr(phys_section_nr))
242 goto out; 242 goto out;
243 243
244 if (!strncmp(buf, "online", min((int)count, 6))) 244 if (!strncmp(buf, "online", min((int)count, 6)))
@@ -418,7 +418,7 @@ int register_new_memory(struct mem_section *section)
418 418
419int unregister_memory_section(struct mem_section *section) 419int unregister_memory_section(struct mem_section *section)
420{ 420{
421 if (!valid_section(section)) 421 if (!present_section(section))
422 return -EINVAL; 422 return -EINVAL;
423 423
424 return remove_memory_block(0, section, 0); 424 return remove_memory_block(0, section, 0);
@@ -443,7 +443,7 @@ int __init memory_dev_init(void)
443 * during boot and have been initialized 443 * during boot and have been initialized
444 */ 444 */
445 for (i = 0; i < NR_MEM_SECTIONS; i++) { 445 for (i = 0; i < NR_MEM_SECTIONS; i++) {
446 if (!valid_section_nr(i)) 446 if (!present_section_nr(i))
447 continue; 447 continue;
448 err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0); 448 err = add_memory_block(0, __nr_to_section(i), MEM_ONLINE, 0);
449 if (!ret) 449 if (!ret)
diff --git a/drivers/base/node.c b/drivers/base/node.c
index cae346ef1b20..88eeed72b5d6 100644
--- a/drivers/base/node.c
+++ b/drivers/base/node.c
@@ -12,6 +12,7 @@
12#include <linux/topology.h> 12#include <linux/topology.h>
13#include <linux/nodemask.h> 13#include <linux/nodemask.h>
14#include <linux/cpu.h> 14#include <linux/cpu.h>
15#include <linux/device.h>
15 16
16static struct sysdev_class node_class = { 17static struct sysdev_class node_class = {
17 set_kset_name("node"), 18 set_kset_name("node"),
@@ -232,8 +233,96 @@ void unregister_one_node(int nid)
232 unregister_node(&node_devices[nid]); 233 unregister_node(&node_devices[nid]);
233} 234}
234 235
236/*
237 * node states attributes
238 */
239
240static ssize_t print_nodes_state(enum node_states state, char *buf)
241{
242 int n;
243
244 n = nodelist_scnprintf(buf, PAGE_SIZE, node_states[state]);
245 if (n > 0 && PAGE_SIZE > n + 1) {
246 *(buf + n++) = '\n';
247 *(buf + n++) = '\0';
248 }
249 return n;
250}
251
252static ssize_t print_nodes_possible(struct sysdev_class *class, char *buf)
253{
254 return print_nodes_state(N_POSSIBLE, buf);
255}
256
257static ssize_t print_nodes_online(struct sysdev_class *class, char *buf)
258{
259 return print_nodes_state(N_ONLINE, buf);
260}
261
262static ssize_t print_nodes_has_normal_memory(struct sysdev_class *class,
263 char *buf)
264{
265 return print_nodes_state(N_NORMAL_MEMORY, buf);
266}
267
268static ssize_t print_nodes_has_cpu(struct sysdev_class *class, char *buf)
269{
270 return print_nodes_state(N_CPU, buf);
271}
272
273static SYSDEV_CLASS_ATTR(possible, 0444, print_nodes_possible, NULL);
274static SYSDEV_CLASS_ATTR(online, 0444, print_nodes_online, NULL);
275static SYSDEV_CLASS_ATTR(has_normal_memory, 0444, print_nodes_has_normal_memory,
276 NULL);
277static SYSDEV_CLASS_ATTR(has_cpu, 0444, print_nodes_has_cpu, NULL);
278
279#ifdef CONFIG_HIGHMEM
280static ssize_t print_nodes_has_high_memory(struct sysdev_class *class,
281 char *buf)
282{
283 return print_nodes_state(N_HIGH_MEMORY, buf);
284}
285
286static SYSDEV_CLASS_ATTR(has_high_memory, 0444, print_nodes_has_high_memory,
287 NULL);
288#endif
289
290struct sysdev_class_attribute *node_state_attr[] = {
291 &attr_possible,
292 &attr_online,
293 &attr_has_normal_memory,
294#ifdef CONFIG_HIGHMEM
295 &attr_has_high_memory,
296#endif
297 &attr_has_cpu,
298};
299
300static int node_states_init(void)
301{
302 int i;
303 int err = 0;
304
305 for (i = 0; i < NR_NODE_STATES; i++) {
306 int ret;
307 ret = sysdev_class_create_file(&node_class, node_state_attr[i]);
308 if (!err)
309 err = ret;
310 }
311 return err;
312}
313
235static int __init register_node_type(void) 314static int __init register_node_type(void)
236{ 315{
237 return sysdev_class_register(&node_class); 316 int ret;
317
318 ret = sysdev_class_register(&node_class);
319 if (!ret)
320 ret = node_states_init();
321
322 /*
323 * Note: we're not going to unregister the node class if we fail
324 * to register the node state class attribute files.
325 */
326 return ret;
238} 327}
239postcore_initcall(register_node_type); 328postcore_initcall(register_node_type);
diff --git a/drivers/block/cciss.c b/drivers/block/cciss.c
index 55c3237fb1bc..3fb7e8bc436d 100644
--- a/drivers/block/cciss.c
+++ b/drivers/block/cciss.c
@@ -1191,7 +1191,6 @@ static inline void complete_buffers(struct bio *bio, int status)
1191{ 1191{
1192 while (bio) { 1192 while (bio) {
1193 struct bio *xbh = bio->bi_next; 1193 struct bio *xbh = bio->bi_next;
1194 int nr_sectors = bio_sectors(bio);
1195 1194
1196 bio->bi_next = NULL; 1195 bio->bi_next = NULL;
1197 bio_endio(bio, status ? 0 : -EIO); 1196 bio_endio(bio, status ? 0 : -EIO);
@@ -2570,6 +2569,7 @@ static void do_cciss_request(struct request_queue *q)
2570 (int)creq->nr_sectors); 2569 (int)creq->nr_sectors);
2571#endif /* CCISS_DEBUG */ 2570#endif /* CCISS_DEBUG */
2572 2571
2572 memset(tmp_sg, 0, sizeof(tmp_sg));
2573 seg = blk_rq_map_sg(q, creq, tmp_sg); 2573 seg = blk_rq_map_sg(q, creq, tmp_sg);
2574 2574
2575 /* get the DMA records for the setup */ 2575 /* get the DMA records for the setup */
diff --git a/drivers/block/cpqarray.c b/drivers/block/cpqarray.c
index 3853c9a38d6a..568603d3043e 100644
--- a/drivers/block/cpqarray.c
+++ b/drivers/block/cpqarray.c
@@ -981,9 +981,8 @@ static void start_io(ctlr_info_t *h)
981static inline void complete_buffers(struct bio *bio, int ok) 981static inline void complete_buffers(struct bio *bio, int ok)
982{ 982{
983 struct bio *xbh; 983 struct bio *xbh;
984 while(bio) {
985 int nr_sectors = bio_sectors(bio);
986 984
985 while (bio) {
987 xbh = bio->bi_next; 986 xbh = bio->bi_next;
988 bio->bi_next = NULL; 987 bio->bi_next = NULL;
989 988
diff --git a/drivers/block/loop.c b/drivers/block/loop.c
index b9233a06934c..e5a051577a5e 100644
--- a/drivers/block/loop.c
+++ b/drivers/block/loop.c
@@ -204,14 +204,13 @@ lo_do_transfer(struct loop_device *lo, int cmd,
204 * do_lo_send_aops - helper for writing data to a loop device 204 * do_lo_send_aops - helper for writing data to a loop device
205 * 205 *
206 * This is the fast version for backing filesystems which implement the address 206 * This is the fast version for backing filesystems which implement the address
207 * space operations prepare_write and commit_write. 207 * space operations write_begin and write_end.
208 */ 208 */
209static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec, 209static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
210 int bsize, loff_t pos, struct page *page) 210 int bsize, loff_t pos, struct page *unused)
211{ 211{
212 struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */ 212 struct file *file = lo->lo_backing_file; /* kudos to NFsckingS */
213 struct address_space *mapping = file->f_mapping; 213 struct address_space *mapping = file->f_mapping;
214 const struct address_space_operations *aops = mapping->a_ops;
215 pgoff_t index; 214 pgoff_t index;
216 unsigned offset, bv_offs; 215 unsigned offset, bv_offs;
217 int len, ret; 216 int len, ret;
@@ -223,63 +222,45 @@ static int do_lo_send_aops(struct loop_device *lo, struct bio_vec *bvec,
223 len = bvec->bv_len; 222 len = bvec->bv_len;
224 while (len > 0) { 223 while (len > 0) {
225 sector_t IV; 224 sector_t IV;
226 unsigned size; 225 unsigned size, copied;
227 int transfer_result; 226 int transfer_result;
227 struct page *page;
228 void *fsdata;
228 229
229 IV = ((sector_t)index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9); 230 IV = ((sector_t)index << (PAGE_CACHE_SHIFT - 9))+(offset >> 9);
230 size = PAGE_CACHE_SIZE - offset; 231 size = PAGE_CACHE_SIZE - offset;
231 if (size > len) 232 if (size > len)
232 size = len; 233 size = len;
233 page = grab_cache_page(mapping, index); 234
234 if (unlikely(!page)) 235 ret = pagecache_write_begin(file, mapping, pos, size, 0,
236 &page, &fsdata);
237 if (ret)
235 goto fail; 238 goto fail;
236 ret = aops->prepare_write(file, page, offset, 239
237 offset + size);
238 if (unlikely(ret)) {
239 if (ret == AOP_TRUNCATED_PAGE) {
240 page_cache_release(page);
241 continue;
242 }
243 goto unlock;
244 }
245 transfer_result = lo_do_transfer(lo, WRITE, page, offset, 240 transfer_result = lo_do_transfer(lo, WRITE, page, offset,
246 bvec->bv_page, bv_offs, size, IV); 241 bvec->bv_page, bv_offs, size, IV);
247 if (unlikely(transfer_result)) { 242 copied = size;
248 /*
249 * The transfer failed, but we still write the data to
250 * keep prepare/commit calls balanced.
251 */
252 printk(KERN_ERR "loop: transfer error block %llu\n",
253 (unsigned long long)index);
254 zero_user_page(page, offset, size, KM_USER0);
255 }
256 flush_dcache_page(page);
257 ret = aops->commit_write(file, page, offset,
258 offset + size);
259 if (unlikely(ret)) {
260 if (ret == AOP_TRUNCATED_PAGE) {
261 page_cache_release(page);
262 continue;
263 }
264 goto unlock;
265 }
266 if (unlikely(transfer_result)) 243 if (unlikely(transfer_result))
267 goto unlock; 244 copied = 0;
268 bv_offs += size; 245
269 len -= size; 246 ret = pagecache_write_end(file, mapping, pos, size, copied,
247 page, fsdata);
248 if (ret < 0 || ret != copied)
249 goto fail;
250
251 if (unlikely(transfer_result))
252 goto fail;
253
254 bv_offs += copied;
255 len -= copied;
270 offset = 0; 256 offset = 0;
271 index++; 257 index++;
272 pos += size; 258 pos += copied;
273 unlock_page(page);
274 page_cache_release(page);
275 } 259 }
276 ret = 0; 260 ret = 0;
277out: 261out:
278 mutex_unlock(&mapping->host->i_mutex); 262 mutex_unlock(&mapping->host->i_mutex);
279 return ret; 263 return ret;
280unlock:
281 unlock_page(page);
282 page_cache_release(page);
283fail: 264fail:
284 ret = -1; 265 ret = -1;
285 goto out; 266 goto out;
@@ -313,7 +294,7 @@ static int __do_lo_send_write(struct file *file,
313 * do_lo_send_direct_write - helper for writing data to a loop device 294 * do_lo_send_direct_write - helper for writing data to a loop device
314 * 295 *
315 * This is the fast, non-transforming version for backing filesystems which do 296 * This is the fast, non-transforming version for backing filesystems which do
316 * not implement the address space operations prepare_write and commit_write. 297 * not implement the address space operations write_begin and write_end.
317 * It uses the write file operation which should be present on all writeable 298 * It uses the write file operation which should be present on all writeable
318 * filesystems. 299 * filesystems.
319 */ 300 */
@@ -332,7 +313,7 @@ static int do_lo_send_direct_write(struct loop_device *lo,
332 * do_lo_send_write - helper for writing data to a loop device 313 * do_lo_send_write - helper for writing data to a loop device
333 * 314 *
334 * This is the slow, transforming version for filesystems which do not 315 * This is the slow, transforming version for filesystems which do not
335 * implement the address space operations prepare_write and commit_write. It 316 * implement the address space operations write_begin and write_end. It
336 * uses the write file operation which should be present on all writeable 317 * uses the write file operation which should be present on all writeable
337 * filesystems. 318 * filesystems.
338 * 319 *
@@ -780,7 +761,7 @@ static int loop_set_fd(struct loop_device *lo, struct file *lo_file,
780 */ 761 */
781 if (!file->f_op->splice_read) 762 if (!file->f_op->splice_read)
782 goto out_putf; 763 goto out_putf;
783 if (aops->prepare_write && aops->commit_write) 764 if (aops->prepare_write || aops->write_begin)
784 lo_flags |= LO_FLAGS_USE_AOPS; 765 lo_flags |= LO_FLAGS_USE_AOPS;
785 if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write) 766 if (!(lo_flags & LO_FLAGS_USE_AOPS) && !file->f_op->write)
786 lo_flags |= LO_FLAGS_READ_ONLY; 767 lo_flags |= LO_FLAGS_READ_ONLY;
diff --git a/drivers/block/pktcdvd.c b/drivers/block/pktcdvd.c
index 540bf3676985..a8130a4ad6d4 100644
--- a/drivers/block/pktcdvd.c
+++ b/drivers/block/pktcdvd.c
@@ -1133,16 +1133,21 @@ static void pkt_gather_data(struct pktcdvd_device *pd, struct packet_data *pkt)
1133 * Schedule reads for missing parts of the packet. 1133 * Schedule reads for missing parts of the packet.
1134 */ 1134 */
1135 for (f = 0; f < pkt->frames; f++) { 1135 for (f = 0; f < pkt->frames; f++) {
1136 struct bio_vec *vec;
1137
1136 int p, offset; 1138 int p, offset;
1137 if (written[f]) 1139 if (written[f])
1138 continue; 1140 continue;
1139 bio = pkt->r_bios[f]; 1141 bio = pkt->r_bios[f];
1142 vec = bio->bi_io_vec;
1140 bio_init(bio); 1143 bio_init(bio);
1141 bio->bi_max_vecs = 1; 1144 bio->bi_max_vecs = 1;
1142 bio->bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9); 1145 bio->bi_sector = pkt->sector + f * (CD_FRAMESIZE >> 9);
1143 bio->bi_bdev = pd->bdev; 1146 bio->bi_bdev = pd->bdev;
1144 bio->bi_end_io = pkt_end_io_read; 1147 bio->bi_end_io = pkt_end_io_read;
1145 bio->bi_private = pkt; 1148 bio->bi_private = pkt;
1149 bio->bi_io_vec = vec;
1150 bio->bi_destructor = pkt_bio_destructor;
1146 1151
1147 p = (f * CD_FRAMESIZE) / PAGE_SIZE; 1152 p = (f * CD_FRAMESIZE) / PAGE_SIZE;
1148 offset = (f * CD_FRAMESIZE) % PAGE_SIZE; 1153 offset = (f * CD_FRAMESIZE) % PAGE_SIZE;
@@ -1439,6 +1444,8 @@ static void pkt_start_write(struct pktcdvd_device *pd, struct packet_data *pkt)
1439 pkt->w_bio->bi_bdev = pd->bdev; 1444 pkt->w_bio->bi_bdev = pd->bdev;
1440 pkt->w_bio->bi_end_io = pkt_end_io_packet_write; 1445 pkt->w_bio->bi_end_io = pkt_end_io_packet_write;
1441 pkt->w_bio->bi_private = pkt; 1446 pkt->w_bio->bi_private = pkt;
1447 pkt->w_bio->bi_io_vec = bvec;
1448 pkt->w_bio->bi_destructor = pkt_bio_destructor;
1442 for (f = 0; f < pkt->frames; f++) 1449 for (f = 0; f < pkt->frames; f++)
1443 if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset)) 1450 if (!bio_add_page(pkt->w_bio, bvec[f].bv_page, CD_FRAMESIZE, bvec[f].bv_offset))
1444 BUG(); 1451 BUG();
diff --git a/drivers/block/ps3disk.c b/drivers/block/ps3disk.c
index 06d0552cf49c..e354bfc070e1 100644
--- a/drivers/block/ps3disk.c
+++ b/drivers/block/ps3disk.c
@@ -414,26 +414,6 @@ static void ps3disk_prepare_flush(struct request_queue *q, struct request *req)
414 req->cmd_type = REQ_TYPE_FLUSH; 414 req->cmd_type = REQ_TYPE_FLUSH;
415} 415}
416 416
417static int ps3disk_issue_flush(struct request_queue *q, struct gendisk *gendisk,
418 sector_t *sector)
419{
420 struct ps3_storage_device *dev = q->queuedata;
421 struct request *req;
422 int res;
423
424 dev_dbg(&dev->sbd.core, "%s:%u\n", __func__, __LINE__);
425
426 req = blk_get_request(q, WRITE, __GFP_WAIT);
427 ps3disk_prepare_flush(q, req);
428 res = blk_execute_rq(q, gendisk, req, 0);
429 if (res)
430 dev_err(&dev->sbd.core, "%s:%u: flush request failed %d\n",
431 __func__, __LINE__, res);
432 blk_put_request(req);
433 return res;
434}
435
436
437static unsigned long ps3disk_mask; 417static unsigned long ps3disk_mask;
438 418
439static DEFINE_MUTEX(ps3disk_mask_mutex); 419static DEFINE_MUTEX(ps3disk_mask_mutex);
@@ -506,7 +486,6 @@ static int __devinit ps3disk_probe(struct ps3_system_bus_device *_dev)
506 blk_queue_dma_alignment(queue, dev->blk_size-1); 486 blk_queue_dma_alignment(queue, dev->blk_size-1);
507 blk_queue_hardsect_size(queue, dev->blk_size); 487 blk_queue_hardsect_size(queue, dev->blk_size);
508 488
509 blk_queue_issue_flush_fn(queue, ps3disk_issue_flush);
510 blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH, 489 blk_queue_ordered(queue, QUEUE_ORDERED_DRAIN_FLUSH,
511 ps3disk_prepare_flush); 490 ps3disk_prepare_flush);
512 491
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index b391776e5bf3..f6f8c03047fa 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -896,10 +896,6 @@ config GPIO_TB0219
896 depends on TANBAC_TB022X 896 depends on TANBAC_TB022X
897 select GPIO_VR41XX 897 select GPIO_VR41XX
898 898
899source "drivers/char/agp/Kconfig"
900
901source "drivers/char/drm/Kconfig"
902
903source "drivers/char/pcmcia/Kconfig" 899source "drivers/char/pcmcia/Kconfig"
904 900
905config MWAVE 901config MWAVE
diff --git a/drivers/char/agp/Kconfig b/drivers/char/agp/Kconfig
index 713533d8a86e..f22c253bc09f 100644
--- a/drivers/char/agp/Kconfig
+++ b/drivers/char/agp/Kconfig
@@ -1,4 +1,4 @@
1config AGP 1menuconfig AGP
2 tristate "/dev/agpgart (AGP Support)" 2 tristate "/dev/agpgart (AGP Support)"
3 depends on ALPHA || IA64 || PARISC || PPC || X86 3 depends on ALPHA || IA64 || PARISC || PPC || X86
4 depends on PCI 4 depends on PCI
diff --git a/drivers/char/drm/Kconfig b/drivers/char/drm/Kconfig
index 0b7ffa5191c6..ba3058dd39a7 100644
--- a/drivers/char/drm/Kconfig
+++ b/drivers/char/drm/Kconfig
@@ -4,7 +4,7 @@
4# This driver provides support for the 4# This driver provides support for the
5# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher. 5# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
6# 6#
7config DRM 7menuconfig DRM
8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)" 8 tristate "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
9 depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG 9 depends on (AGP || AGP=n) && PCI && !EMULATED_CMPXCHG
10 help 10 help
diff --git a/drivers/char/drm/radeon_irq.c b/drivers/char/drm/radeon_irq.c
index f89e57665b64..2b2407ee490e 100644
--- a/drivers/char/drm/radeon_irq.c
+++ b/drivers/char/drm/radeon_irq.c
@@ -144,8 +144,8 @@ static int radeon_wait_irq(struct drm_device * dev, int swi_nr)
144 return ret; 144 return ret;
145} 145}
146 146
147int radeon_driver_vblank_do_wait(struct drm_device * dev, unsigned int *sequence, 147static int radeon_driver_vblank_do_wait(struct drm_device * dev,
148 int crtc) 148 unsigned int *sequence, int crtc)
149{ 149{
150 drm_radeon_private_t *dev_priv = 150 drm_radeon_private_t *dev_priv =
151 (drm_radeon_private_t *) dev->dev_private; 151 (drm_radeon_private_t *) dev->dev_private;
diff --git a/drivers/char/mem.c b/drivers/char/mem.c
index bbee97ff355f..64551ab6be03 100644
--- a/drivers/char/mem.c
+++ b/drivers/char/mem.c
@@ -625,65 +625,10 @@ static ssize_t splice_write_null(struct pipe_inode_info *pipe,struct file *out,
625 return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null); 625 return splice_from_pipe(pipe, out, ppos, len, flags, pipe_to_null);
626} 626}
627 627
628#ifdef CONFIG_MMU
629/*
630 * For fun, we are using the MMU for this.
631 */
632static inline size_t read_zero_pagealigned(char __user * buf, size_t size)
633{
634 struct mm_struct *mm;
635 struct vm_area_struct * vma;
636 unsigned long addr=(unsigned long)buf;
637
638 mm = current->mm;
639 /* Oops, this was forgotten before. -ben */
640 down_read(&mm->mmap_sem);
641
642 /* For private mappings, just map in zero pages. */
643 for (vma = find_vma(mm, addr); vma; vma = vma->vm_next) {
644 unsigned long count;
645
646 if (vma->vm_start > addr || (vma->vm_flags & VM_WRITE) == 0)
647 goto out_up;
648 if (vma->vm_flags & (VM_SHARED | VM_HUGETLB))
649 break;
650 count = vma->vm_end - addr;
651 if (count > size)
652 count = size;
653
654 zap_page_range(vma, addr, count, NULL);
655 if (zeromap_page_range(vma, addr, count, PAGE_COPY))
656 break;
657
658 size -= count;
659 buf += count;
660 addr += count;
661 if (size == 0)
662 goto out_up;
663 }
664
665 up_read(&mm->mmap_sem);
666
667 /* The shared case is hard. Let's do the conventional zeroing. */
668 do {
669 unsigned long unwritten = clear_user(buf, PAGE_SIZE);
670 if (unwritten)
671 return size + unwritten - PAGE_SIZE;
672 cond_resched();
673 buf += PAGE_SIZE;
674 size -= PAGE_SIZE;
675 } while (size);
676
677 return size;
678out_up:
679 up_read(&mm->mmap_sem);
680 return size;
681}
682
683static ssize_t read_zero(struct file * file, char __user * buf, 628static ssize_t read_zero(struct file * file, char __user * buf,
684 size_t count, loff_t *ppos) 629 size_t count, loff_t *ppos)
685{ 630{
686 unsigned long left, unwritten, written = 0; 631 size_t written;
687 632
688 if (!count) 633 if (!count)
689 return 0; 634 return 0;
@@ -691,69 +636,33 @@ static ssize_t read_zero(struct file * file, char __user * buf,
691 if (!access_ok(VERIFY_WRITE, buf, count)) 636 if (!access_ok(VERIFY_WRITE, buf, count))
692 return -EFAULT; 637 return -EFAULT;
693 638
694 left = count; 639 written = 0;
695 640 while (count) {
696 /* do we want to be clever? Arbitrary cut-off */ 641 unsigned long unwritten;
697 if (count >= PAGE_SIZE*4) { 642 size_t chunk = count;
698 unsigned long partial;
699 643
700 /* How much left of the page? */ 644 if (chunk > PAGE_SIZE)
701 partial = (PAGE_SIZE-1) & -(unsigned long) buf; 645 chunk = PAGE_SIZE; /* Just for latency reasons */
702 unwritten = clear_user(buf, partial); 646 unwritten = clear_user(buf, chunk);
703 written = partial - unwritten; 647 written += chunk - unwritten;
704 if (unwritten)
705 goto out;
706 left -= partial;
707 buf += partial;
708 unwritten = read_zero_pagealigned(buf, left & PAGE_MASK);
709 written += (left & PAGE_MASK) - unwritten;
710 if (unwritten) 648 if (unwritten)
711 goto out; 649 break;
712 buf += left & PAGE_MASK;
713 left &= ~PAGE_MASK;
714 }
715 unwritten = clear_user(buf, left);
716 written += left - unwritten;
717out:
718 return written ? written : -EFAULT;
719}
720
721static int mmap_zero(struct file * file, struct vm_area_struct * vma)
722{
723 int err;
724
725 if (vma->vm_flags & VM_SHARED)
726 return shmem_zero_setup(vma);
727 err = zeromap_page_range(vma, vma->vm_start,
728 vma->vm_end - vma->vm_start, vma->vm_page_prot);
729 BUG_ON(err == -EEXIST);
730 return err;
731}
732#else /* CONFIG_MMU */
733static ssize_t read_zero(struct file * file, char * buf,
734 size_t count, loff_t *ppos)
735{
736 size_t todo = count;
737
738 while (todo) {
739 size_t chunk = todo;
740
741 if (chunk > 4096)
742 chunk = 4096; /* Just for latency reasons */
743 if (clear_user(buf, chunk))
744 return -EFAULT;
745 buf += chunk; 650 buf += chunk;
746 todo -= chunk; 651 count -= chunk;
747 cond_resched(); 652 cond_resched();
748 } 653 }
749 return count; 654 return written ? written : -EFAULT;
750} 655}
751 656
752static int mmap_zero(struct file * file, struct vm_area_struct * vma) 657static int mmap_zero(struct file * file, struct vm_area_struct * vma)
753{ 658{
659#ifndef CONFIG_MMU
754 return -ENOSYS; 660 return -ENOSYS;
661#endif
662 if (vma->vm_flags & VM_SHARED)
663 return shmem_zero_setup(vma);
664 return 0;
755} 665}
756#endif /* CONFIG_MMU */
757 666
758static ssize_t write_full(struct file * file, const char __user * buf, 667static ssize_t write_full(struct file * file, const char __user * buf,
759 size_t count, loff_t *ppos) 668 size_t count, loff_t *ppos)
diff --git a/drivers/char/mspec.c b/drivers/char/mspec.c
index 04ac155d3a07..82f2e27dca7d 100644
--- a/drivers/char/mspec.c
+++ b/drivers/char/mspec.c
@@ -362,7 +362,7 @@ mspec_init(void)
362 is_sn2 = 1; 362 is_sn2 = 1;
363 if (is_shub2()) { 363 if (is_shub2()) {
364 ret = -ENOMEM; 364 ret = -ENOMEM;
365 for_each_online_node(nid) { 365 for_each_node_state(nid, N_ONLINE) {
366 int actual_nid; 366 int actual_nid;
367 int nasid; 367 int nasid;
368 unsigned long phys; 368 unsigned long phys;
diff --git a/drivers/char/vt.c b/drivers/char/vt.c
index edb7002a3216..0d56f8fc105c 100644
--- a/drivers/char/vt.c
+++ b/drivers/char/vt.c
@@ -750,13 +750,15 @@ int vc_allocate(unsigned int currcons) /* return 0 on success */
750 return 0; 750 return 0;
751} 751}
752 752
753static inline int resize_screen(struct vc_data *vc, int width, int height) 753static inline int resize_screen(struct vc_data *vc, int width, int height,
754 int user)
754{ 755{
755 /* Resizes the resolution of the display adapater */ 756 /* Resizes the resolution of the display adapater */
756 int err = 0; 757 int err = 0;
757 758
758 if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize) 759 if (vc->vc_mode != KD_GRAPHICS && vc->vc_sw->con_resize)
759 err = vc->vc_sw->con_resize(vc, width, height); 760 err = vc->vc_sw->con_resize(vc, width, height, user);
761
760 return err; 762 return err;
761} 763}
762 764
@@ -772,7 +774,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
772 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0; 774 unsigned long old_origin, new_origin, new_scr_end, rlth, rrem, err = 0;
773 unsigned int old_cols, old_rows, old_row_size, old_screen_size; 775 unsigned int old_cols, old_rows, old_row_size, old_screen_size;
774 unsigned int new_cols, new_rows, new_row_size, new_screen_size; 776 unsigned int new_cols, new_rows, new_row_size, new_screen_size;
775 unsigned int end; 777 unsigned int end, user;
776 unsigned short *newscreen; 778 unsigned short *newscreen;
777 779
778 WARN_CONSOLE_UNLOCKED(); 780 WARN_CONSOLE_UNLOCKED();
@@ -780,6 +782,9 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
780 if (!vc) 782 if (!vc)
781 return -ENXIO; 783 return -ENXIO;
782 784
785 user = vc->vc_resize_user;
786 vc->vc_resize_user = 0;
787
783 if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW) 788 if (cols > VC_RESIZE_MAXCOL || lines > VC_RESIZE_MAXROW)
784 return -EINVAL; 789 return -EINVAL;
785 790
@@ -800,7 +805,7 @@ int vc_resize(struct vc_data *vc, unsigned int cols, unsigned int lines)
800 old_row_size = vc->vc_size_row; 805 old_row_size = vc->vc_size_row;
801 old_screen_size = vc->vc_screenbuf_size; 806 old_screen_size = vc->vc_screenbuf_size;
802 807
803 err = resize_screen(vc, new_cols, new_rows); 808 err = resize_screen(vc, new_cols, new_rows, user);
804 if (err) { 809 if (err) {
805 kfree(newscreen); 810 kfree(newscreen);
806 return err; 811 return err;
diff --git a/drivers/char/vt_ioctl.c b/drivers/char/vt_ioctl.c
index 7a61a2a9aafe..f69a8258095c 100644
--- a/drivers/char/vt_ioctl.c
+++ b/drivers/char/vt_ioctl.c
@@ -847,14 +847,24 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
847 case VT_RESIZE: 847 case VT_RESIZE:
848 { 848 {
849 struct vt_sizes __user *vtsizes = up; 849 struct vt_sizes __user *vtsizes = up;
850 struct vc_data *vc;
851
850 ushort ll,cc; 852 ushort ll,cc;
851 if (!perm) 853 if (!perm)
852 return -EPERM; 854 return -EPERM;
853 if (get_user(ll, &vtsizes->v_rows) || 855 if (get_user(ll, &vtsizes->v_rows) ||
854 get_user(cc, &vtsizes->v_cols)) 856 get_user(cc, &vtsizes->v_cols))
855 return -EFAULT; 857 return -EFAULT;
856 for (i = 0; i < MAX_NR_CONSOLES; i++) 858
857 vc_lock_resize(vc_cons[i].d, cc, ll); 859 for (i = 0; i < MAX_NR_CONSOLES; i++) {
860 vc = vc_cons[i].d;
861
862 if (vc) {
863 vc->vc_resize_user = 1;
864 vc_lock_resize(vc_cons[i].d, cc, ll);
865 }
866 }
867
858 return 0; 868 return 0;
859 } 869 }
860 870
@@ -900,6 +910,7 @@ int vt_ioctl(struct tty_struct *tty, struct file * file,
900 vc_cons[i].d->vc_scan_lines = vlin; 910 vc_cons[i].d->vc_scan_lines = vlin;
901 if (clin) 911 if (clin)
902 vc_cons[i].d->vc_font.height = clin; 912 vc_cons[i].d->vc_font.height = clin;
913 vc_cons[i].d->vc_resize_user = 1;
903 vc_resize(vc_cons[i].d, cc, ll); 914 vc_resize(vc_cons[i].d, cc, ll);
904 release_console_sem(); 915 release_console_sem();
905 } 916 }
diff --git a/drivers/dca/Kconfig b/drivers/dca/Kconfig
new file mode 100644
index 000000000000..94f0364a0efb
--- /dev/null
+++ b/drivers/dca/Kconfig
@@ -0,0 +1,7 @@
1#
2# DCA server configuration
3#
4
5config DCA
6 tristate
7
diff --git a/drivers/dca/Makefile b/drivers/dca/Makefile
new file mode 100644
index 000000000000..b2db56bb9dde
--- /dev/null
+++ b/drivers/dca/Makefile
@@ -0,0 +1,2 @@
1obj-$(CONFIG_DCA) += dca.o
2dca-objs := dca-core.o dca-sysfs.o
diff --git a/drivers/dca/dca-core.c b/drivers/dca/dca-core.c
new file mode 100644
index 000000000000..bf5b92f86df7
--- /dev/null
+++ b/drivers/dca/dca-core.c
@@ -0,0 +1,200 @@
1/*
2 * Copyright(c) 2007 Intel Corporation. All rights reserved.
3 *
4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free
6 * Software Foundation; either version 2 of the License, or (at your option)
7 * any later version.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59
16 * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called COPYING.
20 */
21
22/*
23 * This driver supports an interface for DCA clients and providers to meet.
24 */
25
26#include <linux/kernel.h>
27#include <linux/notifier.h>
28#include <linux/device.h>
29#include <linux/dca.h>
30
31MODULE_LICENSE("GPL");
32
33/* For now we're assuming a single, global, DCA provider for the system. */
34
35static DEFINE_SPINLOCK(dca_lock);
36
37static struct dca_provider *global_dca = NULL;
38
39/**
40 * dca_add_requester - add a dca client to the list
41 * @dev - the device that wants dca service
42 */
43int dca_add_requester(struct device *dev)
44{
45 int err, slot;
46
47 if (!global_dca)
48 return -ENODEV;
49
50 spin_lock(&dca_lock);
51 slot = global_dca->ops->add_requester(global_dca, dev);
52 spin_unlock(&dca_lock);
53 if (slot < 0)
54 return slot;
55
56 err = dca_sysfs_add_req(global_dca, dev, slot);
57 if (err) {
58 spin_lock(&dca_lock);
59 global_dca->ops->remove_requester(global_dca, dev);
60 spin_unlock(&dca_lock);
61 return err;
62 }
63
64 return 0;
65}
66EXPORT_SYMBOL_GPL(dca_add_requester);
67
68/**
69 * dca_remove_requester - remove a dca client from the list
70 * @dev - the device that wants dca service
71 */
72int dca_remove_requester(struct device *dev)
73{
74 int slot;
75 if (!global_dca)
76 return -ENODEV;
77
78 spin_lock(&dca_lock);
79 slot = global_dca->ops->remove_requester(global_dca, dev);
80 spin_unlock(&dca_lock);
81 if (slot < 0)
82 return slot;
83
84 dca_sysfs_remove_req(global_dca, slot);
85 return 0;
86}
87EXPORT_SYMBOL_GPL(dca_remove_requester);
88
89/**
90 * dca_get_tag - return the dca tag for the given cpu
91 * @cpu - the cpuid as returned by get_cpu()
92 */
93u8 dca_get_tag(int cpu)
94{
95 if (!global_dca)
96 return -ENODEV;
97 return global_dca->ops->get_tag(global_dca, cpu);
98}
99EXPORT_SYMBOL_GPL(dca_get_tag);
100
101/**
102 * alloc_dca_provider - get data struct for describing a dca provider
103 * @ops - pointer to struct of dca operation function pointers
104 * @priv_size - size of extra mem to be added for provider's needs
105 */
106struct dca_provider *alloc_dca_provider(struct dca_ops *ops, int priv_size)
107{
108 struct dca_provider *dca;
109 int alloc_size;
110
111 alloc_size = (sizeof(*dca) + priv_size);
112 dca = kzalloc(alloc_size, GFP_KERNEL);
113 if (!dca)
114 return NULL;
115 dca->ops = ops;
116
117 return dca;
118}
119EXPORT_SYMBOL_GPL(alloc_dca_provider);
120
121/**
122 * free_dca_provider - release the dca provider data struct
123 * @ops - pointer to struct of dca operation function pointers
124 * @priv_size - size of extra mem to be added for provider's needs
125 */
126void free_dca_provider(struct dca_provider *dca)
127{
128 kfree(dca);
129}
130EXPORT_SYMBOL_GPL(free_dca_provider);
131
132static BLOCKING_NOTIFIER_HEAD(dca_provider_chain);
133
134/**
135 * register_dca_provider - register a dca provider
136 * @dca - struct created by alloc_dca_provider()
137 * @dev - device providing dca services
138 */
139int register_dca_provider(struct dca_provider *dca, struct device *dev)
140{
141 int err;
142
143 if (global_dca)
144 return -EEXIST;
145 err = dca_sysfs_add_provider(dca, dev);
146 if (err)
147 return err;
148 global_dca = dca;
149 blocking_notifier_call_chain(&dca_provider_chain,
150 DCA_PROVIDER_ADD, NULL);
151 return 0;
152}
153EXPORT_SYMBOL_GPL(register_dca_provider);
154
155/**
156 * unregister_dca_provider - remove a dca provider
157 * @dca - struct created by alloc_dca_provider()
158 */
159void unregister_dca_provider(struct dca_provider *dca)
160{
161 if (!global_dca)
162 return;
163 blocking_notifier_call_chain(&dca_provider_chain,
164 DCA_PROVIDER_REMOVE, NULL);
165 global_dca = NULL;
166 dca_sysfs_remove_provider(dca);
167}
168EXPORT_SYMBOL_GPL(unregister_dca_provider);
169
170/**
171 * dca_register_notify - register a client's notifier callback
172 */
173void dca_register_notify(struct notifier_block *nb)
174{
175 blocking_notifier_chain_register(&dca_provider_chain, nb);
176}
177EXPORT_SYMBOL_GPL(dca_register_notify);
178
179/**
180 * dca_unregister_notify - remove a client's notifier callback
181 */
182void dca_unregister_notify(struct notifier_block *nb)
183{
184 blocking_notifier_chain_unregister(&dca_provider_chain, nb);
185}
186EXPORT_SYMBOL_GPL(dca_unregister_notify);
187
188static int __init dca_init(void)
189{
190 return dca_sysfs_init();
191}
192
193static void __exit dca_exit(void)
194{
195 dca_sysfs_exit();
196}
197
198module_init(dca_init);
199module_exit(dca_exit);
200
diff --git a/drivers/dca/dca-sysfs.c b/drivers/dca/dca-sysfs.c
new file mode 100644
index 000000000000..24a263b6844c
--- /dev/null
+++ b/drivers/dca/dca-sysfs.c
@@ -0,0 +1,88 @@
1#include <linux/kernel.h>
2#include <linux/spinlock.h>
3#include <linux/device.h>
4#include <linux/idr.h>
5#include <linux/kdev_t.h>
6#include <linux/err.h>
7#include <linux/dca.h>
8
9static struct class *dca_class;
10static struct idr dca_idr;
11static spinlock_t dca_idr_lock;
12
13int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot)
14{
15 struct class_device *cd;
16
17 cd = class_device_create(dca_class, dca->cd, MKDEV(0, slot + 1),
18 dev, "requester%d", slot);
19 if (IS_ERR(cd))
20 return PTR_ERR(cd);
21 return 0;
22}
23
24void dca_sysfs_remove_req(struct dca_provider *dca, int slot)
25{
26 class_device_destroy(dca_class, MKDEV(0, slot + 1));
27}
28
29int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev)
30{
31 struct class_device *cd;
32 int err = 0;
33
34idr_try_again:
35 if (!idr_pre_get(&dca_idr, GFP_KERNEL))
36 return -ENOMEM;
37 spin_lock(&dca_idr_lock);
38 err = idr_get_new(&dca_idr, dca, &dca->id);
39 spin_unlock(&dca_idr_lock);
40 switch (err) {
41 case 0:
42 break;
43 case -EAGAIN:
44 goto idr_try_again;
45 default:
46 return err;
47 }
48
49 cd = class_device_create(dca_class, NULL, MKDEV(0, 0),
50 dev, "dca%d", dca->id);
51 if (IS_ERR(cd)) {
52 spin_lock(&dca_idr_lock);
53 idr_remove(&dca_idr, dca->id);
54 spin_unlock(&dca_idr_lock);
55 return PTR_ERR(cd);
56 }
57 dca->cd = cd;
58 return 0;
59}
60
61void dca_sysfs_remove_provider(struct dca_provider *dca)
62{
63 class_device_unregister(dca->cd);
64 dca->cd = NULL;
65 spin_lock(&dca_idr_lock);
66 idr_remove(&dca_idr, dca->id);
67 spin_unlock(&dca_idr_lock);
68}
69
70int __init dca_sysfs_init(void)
71{
72 idr_init(&dca_idr);
73 spin_lock_init(&dca_idr_lock);
74
75 dca_class = class_create(THIS_MODULE, "dca");
76 if (IS_ERR(dca_class)) {
77 idr_destroy(&dca_idr);
78 return PTR_ERR(dca_class);
79 }
80 return 0;
81}
82
83void __exit dca_sysfs_exit(void)
84{
85 class_destroy(dca_class);
86 idr_destroy(&dca_idr);
87}
88
diff --git a/drivers/dma/Kconfig b/drivers/dma/Kconfig
index 8f670dae53bb..9c91b0fd134f 100644
--- a/drivers/dma/Kconfig
+++ b/drivers/dma/Kconfig
@@ -2,42 +2,52 @@
2# DMA engine configuration 2# DMA engine configuration
3# 3#
4 4
5menu "DMA Engine support" 5menuconfig DMADEVICES
6 depends on HAS_DMA 6 bool "DMA Offload Engine support"
7 depends on (PCI && X86) || ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
8 help
9 Intel(R) offload engines enable offloading memory copies in the
10 network stack and RAID operations in the MD driver.
11
12if DMADEVICES
13
14comment "DMA Devices"
15
16config INTEL_IOATDMA
17 tristate "Intel I/OAT DMA support"
18 depends on PCI && X86
19 select DMA_ENGINE
20 select DCA
21 help
22 Enable support for the Intel(R) I/OAT DMA engine present
23 in recent Intel Xeon chipsets.
24
25 Say Y here if you have such a chipset.
26
27 If unsure, say N.
28
29config INTEL_IOP_ADMA
30 tristate "Intel IOP ADMA support"
31 depends on ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX
32 select ASYNC_CORE
33 select DMA_ENGINE
34 help
35 Enable support for the Intel(R) IOP Series RAID engines.
7 36
8config DMA_ENGINE 37config DMA_ENGINE
9 bool "Support for DMA engines" 38 bool
10 ---help---
11 DMA engines offload bulk memory operations from the CPU to dedicated
12 hardware, allowing the operations to happen asynchronously.
13 39
14comment "DMA Clients" 40comment "DMA Clients"
41 depends on DMA_ENGINE
15 42
16config NET_DMA 43config NET_DMA
17 bool "Network: TCP receive copy offload" 44 bool "Network: TCP receive copy offload"
18 depends on DMA_ENGINE && NET 45 depends on DMA_ENGINE && NET
19 default y 46 default y
20 ---help--- 47 help
21 This enables the use of DMA engines in the network stack to 48 This enables the use of DMA engines in the network stack to
22 offload receive copy-to-user operations, freeing CPU cycles. 49 offload receive copy-to-user operations, freeing CPU cycles.
23 Since this is the main user of the DMA engine, it should be enabled; 50 Since this is the main user of the DMA engine, it should be enabled;
24 say Y here. 51 say Y here.
25 52
26comment "DMA Devices" 53endif
27
28config INTEL_IOATDMA
29 tristate "Intel I/OAT DMA support"
30 depends on DMA_ENGINE && PCI
31 default m
32 ---help---
33 Enable support for the Intel(R) I/OAT DMA engine.
34
35config INTEL_IOP_ADMA
36 tristate "Intel IOP ADMA support"
37 depends on DMA_ENGINE && (ARCH_IOP32X || ARCH_IOP33X || ARCH_IOP13XX)
38 select ASYNC_CORE
39 default m
40 ---help---
41 Enable support for the Intel(R) IOP Series RAID engines.
42
43endmenu
diff --git a/drivers/dma/Makefile b/drivers/dma/Makefile
index b3839b687ae0..b152cd84e123 100644
--- a/drivers/dma/Makefile
+++ b/drivers/dma/Makefile
@@ -1,4 +1,5 @@
1obj-$(CONFIG_DMA_ENGINE) += dmaengine.o 1obj-$(CONFIG_DMA_ENGINE) += dmaengine.o
2obj-$(CONFIG_NET_DMA) += iovlock.o 2obj-$(CONFIG_NET_DMA) += iovlock.o
3obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o 3obj-$(CONFIG_INTEL_IOATDMA) += ioatdma.o
4ioatdma-objs := ioat.o ioat_dma.o ioat_dca.o
4obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o 5obj-$(CONFIG_INTEL_IOP_ADMA) += iop-adma.o
diff --git a/drivers/dma/ioat.c b/drivers/dma/ioat.c
new file mode 100644
index 000000000000..f7276bf2fe7e
--- /dev/null
+++ b/drivers/dma/ioat.c
@@ -0,0 +1,211 @@
1/*
2 * Intel I/OAT DMA Linux driver
3 * Copyright(c) 2007 Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 */
22
23/*
24 * This driver supports an Intel I/OAT DMA engine, which does asynchronous
25 * copy operations.
26 */
27
28#include <linux/init.h>
29#include <linux/module.h>
30#include <linux/pci.h>
31#include <linux/interrupt.h>
32#include <linux/dca.h>
33#include "ioatdma.h"
34#include "ioatdma_registers.h"
35#include "ioatdma_hw.h"
36
37MODULE_VERSION("1.24");
38MODULE_LICENSE("GPL");
39MODULE_AUTHOR("Intel Corporation");
40
41static struct pci_device_id ioat_pci_tbl[] = {
42 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
43 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_CNB) },
44 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT_SCNB) },
45 { PCI_DEVICE(PCI_VENDOR_ID_UNISYS, PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR) },
46 { 0, }
47};
48
49struct ioat_device {
50 struct pci_dev *pdev;
51 void __iomem *iobase;
52 struct ioatdma_device *dma;
53 struct dca_provider *dca;
54};
55
56static int __devinit ioat_probe(struct pci_dev *pdev,
57 const struct pci_device_id *id);
58#ifdef IOAT_DMA_REMOVE
59static void __devexit ioat_remove(struct pci_dev *pdev);
60#endif
61
62static int ioat_dca_enabled = 1;
63module_param(ioat_dca_enabled, int, 0644);
64MODULE_PARM_DESC(ioat_dca_enabled, "control support of dca service (default: 1)");
65
66static int ioat_setup_functionality(struct pci_dev *pdev, void __iomem *iobase)
67{
68 struct ioat_device *device = pci_get_drvdata(pdev);
69 u8 version;
70 int err = 0;
71
72 version = readb(iobase + IOAT_VER_OFFSET);
73 switch (version) {
74 case IOAT_VER_1_2:
75 device->dma = ioat_dma_probe(pdev, iobase);
76 if (ioat_dca_enabled)
77 device->dca = ioat_dca_init(pdev, iobase);
78 break;
79 default:
80 err = -ENODEV;
81 break;
82 }
83 return err;
84}
85
86static void ioat_shutdown_functionality(struct pci_dev *pdev)
87{
88 struct ioat_device *device = pci_get_drvdata(pdev);
89
90 if (device->dma) {
91 ioat_dma_remove(device->dma);
92 device->dma = NULL;
93 }
94
95 if (device->dca) {
96 unregister_dca_provider(device->dca);
97 free_dca_provider(device->dca);
98 device->dca = NULL;
99 }
100
101}
102
103static struct pci_driver ioat_pci_drv = {
104 .name = "ioatdma",
105 .id_table = ioat_pci_tbl,
106 .probe = ioat_probe,
107 .shutdown = ioat_shutdown_functionality,
108#ifdef IOAT_DMA_REMOVE
109 .remove = __devexit_p(ioat_remove),
110#endif
111};
112
113static int __devinit ioat_probe(struct pci_dev *pdev,
114 const struct pci_device_id *id)
115{
116 void __iomem *iobase;
117 struct ioat_device *device;
118 unsigned long mmio_start, mmio_len;
119 int err;
120
121 err = pci_enable_device(pdev);
122 if (err)
123 goto err_enable_device;
124
125 err = pci_request_regions(pdev, ioat_pci_drv.name);
126 if (err)
127 goto err_request_regions;
128
129 err = pci_set_dma_mask(pdev, DMA_64BIT_MASK);
130 if (err)
131 err = pci_set_dma_mask(pdev, DMA_32BIT_MASK);
132 if (err)
133 goto err_set_dma_mask;
134
135 err = pci_set_consistent_dma_mask(pdev, DMA_64BIT_MASK);
136 if (err)
137 err = pci_set_consistent_dma_mask(pdev, DMA_32BIT_MASK);
138 if (err)
139 goto err_set_dma_mask;
140
141 mmio_start = pci_resource_start(pdev, 0);
142 mmio_len = pci_resource_len(pdev, 0);
143 iobase = ioremap(mmio_start, mmio_len);
144 if (!iobase) {
145 err = -ENOMEM;
146 goto err_ioremap;
147 }
148
149 device = kzalloc(sizeof(*device), GFP_KERNEL);
150 if (!device) {
151 err = -ENOMEM;
152 goto err_kzalloc;
153 }
154 device->pdev = pdev;
155 pci_set_drvdata(pdev, device);
156 device->iobase = iobase;
157
158 pci_set_master(pdev);
159
160 err = ioat_setup_functionality(pdev, iobase);
161 if (err)
162 goto err_version;
163
164 return 0;
165
166err_version:
167 kfree(device);
168err_kzalloc:
169 iounmap(iobase);
170err_ioremap:
171err_set_dma_mask:
172 pci_release_regions(pdev);
173 pci_disable_device(pdev);
174err_request_regions:
175err_enable_device:
176 return err;
177}
178
179#ifdef IOAT_DMA_REMOVE
180/*
181 * It is unsafe to remove this module: if removed while a requested
182 * dma is outstanding, esp. from tcp, it is possible to hang while
183 * waiting for something that will never finish, thus hanging at
184 * least one cpu. However, if you're feeling lucky and need to do
185 * some testing, this usually works just fine.
186 */
187static void __devexit ioat_remove(struct pci_dev *pdev)
188{
189 struct ioat_device *device = pci_get_drvdata(pdev);
190
191 ioat_shutdown_functionality(pdev);
192
193 kfree(device);
194
195 iounmap(device->iobase);
196 pci_release_regions(pdev);
197 pci_disable_device(pdev);
198}
199#endif
200
201static int __init ioat_init_module(void)
202{
203 return pci_register_driver(&ioat_pci_drv);
204}
205module_init(ioat_init_module);
206
207static void __exit ioat_exit_module(void)
208{
209 pci_unregister_driver(&ioat_pci_drv);
210}
211module_exit(ioat_exit_module);
diff --git a/drivers/dma/ioat_dca.c b/drivers/dma/ioat_dca.c
new file mode 100644
index 000000000000..2ae04c30edeb
--- /dev/null
+++ b/drivers/dma/ioat_dca.c
@@ -0,0 +1,263 @@
1/*
2 * Intel I/OAT DMA Linux driver
3 * Copyright(c) 2007 Intel Corporation.
4 *
5 * This program is free software; you can redistribute it and/or modify it
6 * under the terms and conditions of the GNU General Public License,
7 * version 2, as published by the Free Software Foundation.
8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
12 * more details.
13 *
14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
20 *
21 */
22
23#include <linux/kernel.h>
24#include <linux/pci.h>
25#include <linux/smp.h>
26#include <linux/interrupt.h>
27#include <linux/dca.h>
28
29/* either a kernel change is needed, or we need something like this in kernel */
30#ifndef CONFIG_SMP
31#include <asm/smp.h>
32#undef cpu_physical_id
33#define cpu_physical_id(cpu) (cpuid_ebx(1) >> 24)
34#endif
35
36#include "ioatdma.h"
37#include "ioatdma_registers.h"
38
39/*
40 * Bit 16 of a tag map entry is the "valid" bit, if it is set then bits 0:15
41 * contain the bit number of the APIC ID to map into the DCA tag. If the valid
42 * bit is not set, then the value must be 0 or 1 and defines the bit in the tag.
43 */
44#define DCA_TAG_MAP_VALID 0x80
45
46/*
47 * "Legacy" DCA systems do not implement the DCA register set in the
48 * I/OAT device. Software needs direct support for their tag mappings.
49 */
50
51#define APICID_BIT(x) (DCA_TAG_MAP_VALID | (x))
52#define IOAT_TAG_MAP_LEN 8
53
54static u8 ioat_tag_map_BNB[IOAT_TAG_MAP_LEN] = {
55 1, APICID_BIT(1), APICID_BIT(2), APICID_BIT(2), };
56static u8 ioat_tag_map_SCNB[IOAT_TAG_MAP_LEN] = {
57 1, APICID_BIT(1), APICID_BIT(2), APICID_BIT(2), };
58static u8 ioat_tag_map_CNB[IOAT_TAG_MAP_LEN] = {
59 1, APICID_BIT(1), APICID_BIT(3), APICID_BIT(4), APICID_BIT(2), };
60static u8 ioat_tag_map_UNISYS[IOAT_TAG_MAP_LEN] = { 0 };
61
62/* pack PCI B/D/F into a u16 */
63static inline u16 dcaid_from_pcidev(struct pci_dev *pci)
64{
65 return (pci->bus->number << 8) | pci->devfn;
66}
67
68static int dca_enabled_in_bios(void)
69{
70 /* CPUID level 9 returns DCA configuration */
71 /* Bit 0 indicates DCA enabled by the BIOS */
72 unsigned long cpuid_level_9;
73 int res;
74
75 cpuid_level_9 = cpuid_eax(9);
76 res = test_bit(0, &cpuid_level_9);
77 if (!res)
78 printk(KERN_ERR "ioat dma: DCA is disabled in BIOS\n");
79
80 return res;
81}
82
83static int system_has_dca_enabled(void)
84{
85 if (boot_cpu_has(X86_FEATURE_DCA))
86 return dca_enabled_in_bios();
87
88 printk(KERN_ERR "ioat dma: boot cpu doesn't have X86_FEATURE_DCA\n");
89 return 0;
90}
91
92struct ioat_dca_slot {
93 struct pci_dev *pdev; /* requester device */
94 u16 rid; /* requester id, as used by IOAT */
95};
96
97#define IOAT_DCA_MAX_REQ 6
98
99struct ioat_dca_priv {
100 void __iomem *iobase;
101 void *dca_base;
102 int max_requesters;
103 int requester_count;
104 u8 tag_map[IOAT_TAG_MAP_LEN];
105 struct ioat_dca_slot req_slots[0];
106};
107
108/* 5000 series chipset DCA Port Requester ID Table Entry Format
109 * [15:8] PCI-Express Bus Number
110 * [7:3] PCI-Express Device Number
111 * [2:0] PCI-Express Function Number
112 *
113 * 5000 series chipset DCA control register format
114 * [7:1] Reserved (0)
115 * [0] Ignore Function Number
116 */
117
118static int ioat_dca_add_requester(struct dca_provider *dca, struct device *dev)
119{
120 struct ioat_dca_priv *ioatdca = dca_priv(dca);
121 struct pci_dev *pdev;
122 int i;
123 u16 id;
124
125 /* This implementation only supports PCI-Express */
126 if (dev->bus != &pci_bus_type)
127 return -ENODEV;
128 pdev = to_pci_dev(dev);
129 id = dcaid_from_pcidev(pdev);
130
131 if (ioatdca->requester_count == ioatdca->max_requesters)
132 return -ENODEV;
133
134 for (i = 0; i < ioatdca->max_requesters; i++) {
135 if (ioatdca->req_slots[i].pdev == NULL) {
136 /* found an empty slot */
137 ioatdca->requester_count++;
138 ioatdca->req_slots[i].pdev = pdev;
139 ioatdca->req_slots[i].rid = id;
140 writew(id, ioatdca->dca_base + (i * 4));
141 /* make sure the ignore function bit is off */
142 writeb(0, ioatdca->dca_base + (i * 4) + 2);
143 return i;
144 }
145 }
146 /* Error, ioatdma->requester_count is out of whack */
147 return -EFAULT;
148}
149
150static int ioat_dca_remove_requester(struct dca_provider *dca,
151 struct device *dev)
152{
153 struct ioat_dca_priv *ioatdca = dca_priv(dca);
154 struct pci_dev *pdev;
155 int i;
156
157 /* This implementation only supports PCI-Express */
158 if (dev->bus != &pci_bus_type)
159 return -ENODEV;
160 pdev = to_pci_dev(dev);
161
162 for (i = 0; i < ioatdca->max_requesters; i++) {
163 if (ioatdca->req_slots[i].pdev == pdev) {
164 writew(0, ioatdca->dca_base + (i * 4));
165 ioatdca->req_slots[i].pdev = NULL;
166 ioatdca->req_slots[i].rid = 0;
167 ioatdca->requester_count--;
168 return i;
169 }
170 }
171 return -ENODEV;
172}
173
174static u8 ioat_dca_get_tag(struct dca_provider *dca, int cpu)
175{
176 struct ioat_dca_priv *ioatdca = dca_priv(dca);
177 int i, apic_id, bit, value;
178 u8 entry, tag;
179
180 tag = 0;
181 apic_id = cpu_physical_id(cpu);
182
183 for (i = 0; i < IOAT_TAG_MAP_LEN; i++) {
184 entry = ioatdca->tag_map[i];
185 if (entry & DCA_TAG_MAP_VALID) {
186 bit = entry & ~DCA_TAG_MAP_VALID;
187 value = (apic_id & (1 << bit)) ? 1 : 0;
188 } else {
189 value = entry ? 1 : 0;
190 }
191 tag |= (value << i);
192 }
193 return tag;
194}
195
196static struct dca_ops ioat_dca_ops = {
197 .add_requester = ioat_dca_add_requester,
198 .remove_requester = ioat_dca_remove_requester,
199 .get_tag = ioat_dca_get_tag,
200};
201
202
203struct dca_provider *ioat_dca_init(struct pci_dev *pdev, void __iomem *iobase)
204{
205 struct dca_provider *dca;
206 struct ioat_dca_priv *ioatdca;
207 u8 *tag_map = NULL;
208 int i;
209 int err;
210
211 if (!system_has_dca_enabled())
212 return NULL;
213
214 /* I/OAT v1 systems must have a known tag_map to support DCA */
215 switch (pdev->vendor) {
216 case PCI_VENDOR_ID_INTEL:
217 switch (pdev->device) {
218 case PCI_DEVICE_ID_INTEL_IOAT:
219 tag_map = ioat_tag_map_BNB;
220 break;
221 case PCI_DEVICE_ID_INTEL_IOAT_CNB:
222 tag_map = ioat_tag_map_CNB;
223 break;
224 case PCI_DEVICE_ID_INTEL_IOAT_SCNB:
225 tag_map = ioat_tag_map_SCNB;
226 break;
227 }
228 break;
229 case PCI_VENDOR_ID_UNISYS:
230 switch (pdev->device) {
231 case PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR:
232 tag_map = ioat_tag_map_UNISYS;
233 break;
234 }
235 break;
236 }
237 if (tag_map == NULL)
238 return NULL;
239
240 dca = alloc_dca_provider(&ioat_dca_ops,
241 sizeof(*ioatdca) +
242 (sizeof(struct ioat_dca_slot) * IOAT_DCA_MAX_REQ));
243 if (!dca)
244 return NULL;
245
246 ioatdca = dca_priv(dca);
247 ioatdca->max_requesters = IOAT_DCA_MAX_REQ;
248
249 ioatdca->dca_base = iobase + 0x54;
250
251 /* copy over the APIC ID to DCA tag mapping */
252 for (i = 0; i < IOAT_TAG_MAP_LEN; i++)
253 ioatdca->tag_map[i] = tag_map[i];
254
255 err = register_dca_provider(dca, &pdev->dev);
256 if (err) {
257 free_dca_provider(dca);
258 return NULL;
259 }
260
261 return dca;
262}
263
diff --git a/drivers/dma/ioatdma.c b/drivers/dma/ioat_dma.c
index 41b18c5a3141..66c5bb53211b 100644
--- a/drivers/dma/ioatdma.c
+++ b/drivers/dma/ioat_dma.c
@@ -1,10 +1,10 @@
1/* 1/*
2 * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. 2 * Intel I/OAT DMA Linux driver
3 * Copyright(c) 2004 - 2007 Intel Corporation.
3 * 4 *
4 * This program is free software; you can redistribute it and/or modify it 5 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free 6 * under the terms and conditions of the GNU General Public License,
6 * Software Foundation; either version 2 of the License, or (at your option) 7 * version 2, as published by the Free Software Foundation.
7 * any later version.
8 * 8 *
9 * This program is distributed in the hope that it will be useful, but WITHOUT 9 * This program is distributed in the hope that it will be useful, but WITHOUT
10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
@@ -12,11 +12,12 @@
12 * more details. 12 * more details.
13 * 13 *
14 * You should have received a copy of the GNU General Public License along with 14 * You should have received a copy of the GNU General Public License along with
15 * this program; if not, write to the Free Software Foundation, Inc., 59 15 * this program; if not, write to the Free Software Foundation, Inc.,
16 * Temple Place - Suite 330, Boston, MA 02111-1307, USA. 16 * 51 Franklin St - Fifth Floor, Boston, MA 02110-1301 USA.
17 *
18 * The full GNU General Public License is included in this distribution in
19 * the file called "COPYING".
17 * 20 *
18 * The full GNU General Public License is included in this distribution in the
19 * file called COPYING.
20 */ 21 */
21 22
22/* 23/*
@@ -35,17 +36,77 @@
35#include "ioatdma_registers.h" 36#include "ioatdma_registers.h"
36#include "ioatdma_hw.h" 37#include "ioatdma_hw.h"
37 38
39#define INITIAL_IOAT_DESC_COUNT 128
40
38#define to_ioat_chan(chan) container_of(chan, struct ioat_dma_chan, common) 41#define to_ioat_chan(chan) container_of(chan, struct ioat_dma_chan, common)
39#define to_ioat_device(dev) container_of(dev, struct ioat_device, common) 42#define to_ioatdma_device(dev) container_of(dev, struct ioatdma_device, common)
40#define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node) 43#define to_ioat_desc(lh) container_of(lh, struct ioat_desc_sw, node)
41#define tx_to_ioat_desc(tx) container_of(tx, struct ioat_desc_sw, async_tx) 44#define tx_to_ioat_desc(tx) container_of(tx, struct ioat_desc_sw, async_tx)
42 45
43/* internal functions */ 46/* internal functions */
44static int __devinit ioat_probe(struct pci_dev *pdev, const struct pci_device_id *ent); 47static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan);
45static void ioat_shutdown(struct pci_dev *pdev); 48static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan);
46static void __devexit ioat_remove(struct pci_dev *pdev);
47 49
48static int enumerate_dma_channels(struct ioat_device *device) 50static struct ioat_dma_chan *ioat_lookup_chan_by_index(struct ioatdma_device *device,
51 int index)
52{
53 return device->idx[index];
54}
55
56/**
57 * ioat_dma_do_interrupt - handler used for single vector interrupt mode
58 * @irq: interrupt id
59 * @data: interrupt data
60 */
61static irqreturn_t ioat_dma_do_interrupt(int irq, void *data)
62{
63 struct ioatdma_device *instance = data;
64 struct ioat_dma_chan *ioat_chan;
65 unsigned long attnstatus;
66 int bit;
67 u8 intrctrl;
68
69 intrctrl = readb(instance->reg_base + IOAT_INTRCTRL_OFFSET);
70
71 if (!(intrctrl & IOAT_INTRCTRL_MASTER_INT_EN))
72 return IRQ_NONE;
73
74 if (!(intrctrl & IOAT_INTRCTRL_INT_STATUS)) {
75 writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
76 return IRQ_NONE;
77 }
78
79 attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET);
80 for_each_bit(bit, &attnstatus, BITS_PER_LONG) {
81 ioat_chan = ioat_lookup_chan_by_index(instance, bit);
82 tasklet_schedule(&ioat_chan->cleanup_task);
83 }
84
85 writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
86 return IRQ_HANDLED;
87}
88
89/**
90 * ioat_dma_do_interrupt_msix - handler used for vector-per-channel interrupt mode
91 * @irq: interrupt id
92 * @data: interrupt data
93 */
94static irqreturn_t ioat_dma_do_interrupt_msix(int irq, void *data)
95{
96 struct ioat_dma_chan *ioat_chan = data;
97
98 tasklet_schedule(&ioat_chan->cleanup_task);
99
100 return IRQ_HANDLED;
101}
102
103static void ioat_dma_cleanup_tasklet(unsigned long data);
104
105/**
106 * ioat_dma_enumerate_channels - find and initialize the device's channels
107 * @device: the device to be enumerated
108 */
109static int ioat_dma_enumerate_channels(struct ioatdma_device *device)
49{ 110{
50 u8 xfercap_scale; 111 u8 xfercap_scale;
51 u32 xfercap; 112 u32 xfercap;
@@ -73,13 +134,19 @@ static int enumerate_dma_channels(struct ioat_device *device)
73 /* This should be made common somewhere in dmaengine.c */ 134 /* This should be made common somewhere in dmaengine.c */
74 ioat_chan->common.device = &device->common; 135 ioat_chan->common.device = &device->common;
75 list_add_tail(&ioat_chan->common.device_node, 136 list_add_tail(&ioat_chan->common.device_node,
76 &device->common.channels); 137 &device->common.channels);
138 device->idx[i] = ioat_chan;
139 tasklet_init(&ioat_chan->cleanup_task,
140 ioat_dma_cleanup_tasklet,
141 (unsigned long) ioat_chan);
142 tasklet_disable(&ioat_chan->cleanup_task);
77 } 143 }
78 return device->common.chancnt; 144 return device->common.chancnt;
79} 145}
80 146
81static void 147static void ioat_set_src(dma_addr_t addr,
82ioat_set_src(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index) 148 struct dma_async_tx_descriptor *tx,
149 int index)
83{ 150{
84 struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx); 151 struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx);
85 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); 152 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
@@ -93,8 +160,9 @@ ioat_set_src(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
93 160
94} 161}
95 162
96static void 163static void ioat_set_dest(dma_addr_t addr,
97ioat_set_dest(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index) 164 struct dma_async_tx_descriptor *tx,
165 int index)
98{ 166{
99 struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx); 167 struct ioat_desc_sw *iter, *desc = tx_to_ioat_desc(tx);
100 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); 168 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
@@ -107,8 +175,7 @@ ioat_set_dest(dma_addr_t addr, struct dma_async_tx_descriptor *tx, int index)
107 } 175 }
108} 176}
109 177
110static dma_cookie_t 178static dma_cookie_t ioat_tx_submit(struct dma_async_tx_descriptor *tx)
111ioat_tx_submit(struct dma_async_tx_descriptor *tx)
112{ 179{
113 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan); 180 struct ioat_dma_chan *ioat_chan = to_ioat_chan(tx->chan);
114 struct ioat_desc_sw *desc = tx_to_ioat_desc(tx); 181 struct ioat_desc_sw *desc = tx_to_ioat_desc(tx);
@@ -141,27 +208,27 @@ ioat_tx_submit(struct dma_async_tx_descriptor *tx)
141 if (append) 208 if (append)
142 writeb(IOAT_CHANCMD_APPEND, 209 writeb(IOAT_CHANCMD_APPEND,
143 ioat_chan->reg_base + IOAT_CHANCMD_OFFSET); 210 ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
144 211
145 return cookie; 212 return cookie;
146} 213}
147 214
148static struct ioat_desc_sw *ioat_dma_alloc_descriptor( 215static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
149 struct ioat_dma_chan *ioat_chan, 216 struct ioat_dma_chan *ioat_chan,
150 gfp_t flags) 217 gfp_t flags)
151{ 218{
152 struct ioat_dma_descriptor *desc; 219 struct ioat_dma_descriptor *desc;
153 struct ioat_desc_sw *desc_sw; 220 struct ioat_desc_sw *desc_sw;
154 struct ioat_device *ioat_device; 221 struct ioatdma_device *ioatdma_device;
155 dma_addr_t phys; 222 dma_addr_t phys;
156 223
157 ioat_device = to_ioat_device(ioat_chan->common.device); 224 ioatdma_device = to_ioatdma_device(ioat_chan->common.device);
158 desc = pci_pool_alloc(ioat_device->dma_pool, flags, &phys); 225 desc = pci_pool_alloc(ioatdma_device->dma_pool, flags, &phys);
159 if (unlikely(!desc)) 226 if (unlikely(!desc))
160 return NULL; 227 return NULL;
161 228
162 desc_sw = kzalloc(sizeof(*desc_sw), flags); 229 desc_sw = kzalloc(sizeof(*desc_sw), flags);
163 if (unlikely(!desc_sw)) { 230 if (unlikely(!desc_sw)) {
164 pci_pool_free(ioat_device->dma_pool, desc, phys); 231 pci_pool_free(ioatdma_device->dma_pool, desc, phys);
165 return NULL; 232 return NULL;
166 } 233 }
167 234
@@ -177,10 +244,6 @@ static struct ioat_desc_sw *ioat_dma_alloc_descriptor(
177 return desc_sw; 244 return desc_sw;
178} 245}
179 246
180#define INITIAL_IOAT_DESC_COUNT 128
181
182static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan);
183
184/* returns the actual number of allocated descriptors */ 247/* returns the actual number of allocated descriptors */
185static int ioat_dma_alloc_chan_resources(struct dma_chan *chan) 248static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
186{ 249{
@@ -195,15 +258,16 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
195 if (!list_empty(&ioat_chan->free_desc)) 258 if (!list_empty(&ioat_chan->free_desc))
196 return INITIAL_IOAT_DESC_COUNT; 259 return INITIAL_IOAT_DESC_COUNT;
197 260
198 /* Setup register to interrupt and write completion status on error */ 261 /* Setup register to interrupt and write completion status on error */
199 chanctrl = IOAT_CHANCTRL_ERR_INT_EN | 262 chanctrl = IOAT_CHANCTRL_ERR_INT_EN |
200 IOAT_CHANCTRL_ANY_ERR_ABORT_EN | 263 IOAT_CHANCTRL_ANY_ERR_ABORT_EN |
201 IOAT_CHANCTRL_ERR_COMPLETION_EN; 264 IOAT_CHANCTRL_ERR_COMPLETION_EN;
202 writew(chanctrl, ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET); 265 writew(chanctrl, ioat_chan->reg_base + IOAT_CHANCTRL_OFFSET);
203 266
204 chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET); 267 chanerr = readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
205 if (chanerr) { 268 if (chanerr) {
206 printk("IOAT: CHANERR = %x, clearing\n", chanerr); 269 dev_err(&ioat_chan->device->pdev->dev,
270 "ioatdma: CHANERR = %x, clearing\n", chanerr);
207 writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET); 271 writel(chanerr, ioat_chan->reg_base + IOAT_CHANERR_OFFSET);
208 } 272 }
209 273
@@ -211,7 +275,8 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
211 for (i = 0; i < INITIAL_IOAT_DESC_COUNT; i++) { 275 for (i = 0; i < INITIAL_IOAT_DESC_COUNT; i++) {
212 desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL); 276 desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
213 if (!desc) { 277 if (!desc) {
214 printk(KERN_ERR "IOAT: Only %d initial descriptors\n", i); 278 dev_err(&ioat_chan->device->pdev->dev,
279 "ioatdma: Only %d initial descriptors\n", i);
215 break; 280 break;
216 } 281 }
217 list_add_tail(&desc->node, &tmp_list); 282 list_add_tail(&desc->node, &tmp_list);
@@ -224,8 +289,8 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
224 /* doing 2 32bit writes to mmio since 1 64b write doesn't work */ 289 /* doing 2 32bit writes to mmio since 1 64b write doesn't work */
225 ioat_chan->completion_virt = 290 ioat_chan->completion_virt =
226 pci_pool_alloc(ioat_chan->device->completion_pool, 291 pci_pool_alloc(ioat_chan->device->completion_pool,
227 GFP_KERNEL, 292 GFP_KERNEL,
228 &ioat_chan->completion_addr); 293 &ioat_chan->completion_addr);
229 memset(ioat_chan->completion_virt, 0, 294 memset(ioat_chan->completion_virt, 0,
230 sizeof(*ioat_chan->completion_virt)); 295 sizeof(*ioat_chan->completion_virt));
231 writel(((u64) ioat_chan->completion_addr) & 0x00000000FFFFFFFF, 296 writel(((u64) ioat_chan->completion_addr) & 0x00000000FFFFFFFF,
@@ -233,54 +298,88 @@ static int ioat_dma_alloc_chan_resources(struct dma_chan *chan)
233 writel(((u64) ioat_chan->completion_addr) >> 32, 298 writel(((u64) ioat_chan->completion_addr) >> 32,
234 ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH); 299 ioat_chan->reg_base + IOAT_CHANCMP_OFFSET_HIGH);
235 300
236 ioat_start_null_desc(ioat_chan); 301 tasklet_enable(&ioat_chan->cleanup_task);
302 ioat_dma_start_null_desc(ioat_chan);
237 return i; 303 return i;
238} 304}
239 305
240static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan);
241
242static void ioat_dma_free_chan_resources(struct dma_chan *chan) 306static void ioat_dma_free_chan_resources(struct dma_chan *chan)
243{ 307{
244 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); 308 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
245 struct ioat_device *ioat_device = to_ioat_device(chan->device); 309 struct ioatdma_device *ioatdma_device = to_ioatdma_device(chan->device);
246 struct ioat_desc_sw *desc, *_desc; 310 struct ioat_desc_sw *desc, *_desc;
247 u16 chanctrl;
248 int in_use_descs = 0; 311 int in_use_descs = 0;
249 312
313 tasklet_disable(&ioat_chan->cleanup_task);
250 ioat_dma_memcpy_cleanup(ioat_chan); 314 ioat_dma_memcpy_cleanup(ioat_chan);
251 315
316 /* Delay 100ms after reset to allow internal DMA logic to quiesce
317 * before removing DMA descriptor resources.
318 */
252 writeb(IOAT_CHANCMD_RESET, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET); 319 writeb(IOAT_CHANCMD_RESET, ioat_chan->reg_base + IOAT_CHANCMD_OFFSET);
320 mdelay(100);
253 321
254 spin_lock_bh(&ioat_chan->desc_lock); 322 spin_lock_bh(&ioat_chan->desc_lock);
255 list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) { 323 list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) {
256 in_use_descs++; 324 in_use_descs++;
257 list_del(&desc->node); 325 list_del(&desc->node);
258 pci_pool_free(ioat_device->dma_pool, desc->hw, 326 pci_pool_free(ioatdma_device->dma_pool, desc->hw,
259 desc->async_tx.phys); 327 desc->async_tx.phys);
260 kfree(desc); 328 kfree(desc);
261 } 329 }
262 list_for_each_entry_safe(desc, _desc, &ioat_chan->free_desc, node) { 330 list_for_each_entry_safe(desc, _desc, &ioat_chan->free_desc, node) {
263 list_del(&desc->node); 331 list_del(&desc->node);
264 pci_pool_free(ioat_device->dma_pool, desc->hw, 332 pci_pool_free(ioatdma_device->dma_pool, desc->hw,
265 desc->async_tx.phys); 333 desc->async_tx.phys);
266 kfree(desc); 334 kfree(desc);
267 } 335 }
268 spin_unlock_bh(&ioat_chan->desc_lock); 336 spin_unlock_bh(&ioat_chan->desc_lock);
269 337
270 pci_pool_free(ioat_device->completion_pool, 338 pci_pool_free(ioatdma_device->completion_pool,
271 ioat_chan->completion_virt, 339 ioat_chan->completion_virt,
272 ioat_chan->completion_addr); 340 ioat_chan->completion_addr);
273 341
274 /* one is ok since we left it on there on purpose */ 342 /* one is ok since we left it on there on purpose */
275 if (in_use_descs > 1) 343 if (in_use_descs > 1)
276 printk(KERN_ERR "IOAT: Freeing %d in use descriptors!\n", 344 dev_err(&ioat_chan->device->pdev->dev,
345 "ioatdma: Freeing %d in use descriptors!\n",
277 in_use_descs - 1); 346 in_use_descs - 1);
278 347
279 ioat_chan->last_completion = ioat_chan->completion_addr = 0; 348 ioat_chan->last_completion = ioat_chan->completion_addr = 0;
349 ioat_chan->pending = 0;
350}
351/**
352 * ioat_dma_get_next_descriptor - return the next available descriptor
353 * @ioat_chan: IOAT DMA channel handle
354 *
355 * Gets the next descriptor from the chain, and must be called with the
356 * channel's desc_lock held. Allocates more descriptors if the channel
357 * has run out.
358 */
359static struct ioat_desc_sw *ioat_dma_get_next_descriptor(
360 struct ioat_dma_chan *ioat_chan)
361{
362 struct ioat_desc_sw *new = NULL;
363
364 if (!list_empty(&ioat_chan->free_desc)) {
365 new = to_ioat_desc(ioat_chan->free_desc.next);
366 list_del(&new->node);
367 } else {
368 /* try to get another desc */
369 new = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC);
370 /* will this ever happen? */
371 /* TODO add upper limit on these */
372 BUG_ON(!new);
373 }
374
375 prefetch(new->hw);
376 return new;
280} 377}
281 378
282static struct dma_async_tx_descriptor * 379static struct dma_async_tx_descriptor *ioat_dma_prep_memcpy(
283ioat_dma_prep_memcpy(struct dma_chan *chan, size_t len, int int_en) 380 struct dma_chan *chan,
381 size_t len,
382 int int_en)
284{ 383{
285 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); 384 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
286 struct ioat_desc_sw *first, *prev, *new; 385 struct ioat_desc_sw *first, *prev, *new;
@@ -299,17 +398,7 @@ ioat_dma_prep_memcpy(struct dma_chan *chan, size_t len, int int_en)
299 398
300 spin_lock_bh(&ioat_chan->desc_lock); 399 spin_lock_bh(&ioat_chan->desc_lock);
301 while (len) { 400 while (len) {
302 if (!list_empty(&ioat_chan->free_desc)) { 401 new = ioat_dma_get_next_descriptor(ioat_chan);
303 new = to_ioat_desc(ioat_chan->free_desc.next);
304 list_del(&new->node);
305 } else {
306 /* try to get another desc */
307 new = ioat_dma_alloc_descriptor(ioat_chan, GFP_ATOMIC);
308 /* will this ever happen? */
309 /* TODO add upper limit on these */
310 BUG_ON(!new);
311 }
312
313 copy = min((u32) len, ioat_chan->xfercap); 402 copy = min((u32) len, ioat_chan->xfercap);
314 403
315 new->hw->size = copy; 404 new->hw->size = copy;
@@ -343,12 +432,11 @@ ioat_dma_prep_memcpy(struct dma_chan *chan, size_t len, int int_en)
343 return new ? &new->async_tx : NULL; 432 return new ? &new->async_tx : NULL;
344} 433}
345 434
346
347/** 435/**
348 * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended descriptors to hw 436 * ioat_dma_memcpy_issue_pending - push potentially unrecognized appended
437 * descriptors to hw
349 * @chan: DMA channel handle 438 * @chan: DMA channel handle
350 */ 439 */
351
352static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan) 440static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan)
353{ 441{
354 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); 442 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
@@ -360,15 +448,23 @@ static void ioat_dma_memcpy_issue_pending(struct dma_chan *chan)
360 } 448 }
361} 449}
362 450
363static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan) 451static void ioat_dma_cleanup_tasklet(unsigned long data)
452{
453 struct ioat_dma_chan *chan = (void *)data;
454 ioat_dma_memcpy_cleanup(chan);
455 writew(IOAT_CHANCTRL_INT_DISABLE,
456 chan->reg_base + IOAT_CHANCTRL_OFFSET);
457}
458
459static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *ioat_chan)
364{ 460{
365 unsigned long phys_complete; 461 unsigned long phys_complete;
366 struct ioat_desc_sw *desc, *_desc; 462 struct ioat_desc_sw *desc, *_desc;
367 dma_cookie_t cookie = 0; 463 dma_cookie_t cookie = 0;
368 464
369 prefetch(chan->completion_virt); 465 prefetch(ioat_chan->completion_virt);
370 466
371 if (!spin_trylock(&chan->cleanup_lock)) 467 if (!spin_trylock(&ioat_chan->cleanup_lock))
372 return; 468 return;
373 469
374 /* The completion writeback can happen at any time, 470 /* The completion writeback can happen at any time,
@@ -378,26 +474,28 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan)
378 474
379#if (BITS_PER_LONG == 64) 475#if (BITS_PER_LONG == 64)
380 phys_complete = 476 phys_complete =
381 chan->completion_virt->full & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR; 477 ioat_chan->completion_virt->full & IOAT_CHANSTS_COMPLETED_DESCRIPTOR_ADDR;
382#else 478#else
383 phys_complete = chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK; 479 phys_complete = ioat_chan->completion_virt->low & IOAT_LOW_COMPLETION_MASK;
384#endif 480#endif
385 481
386 if ((chan->completion_virt->full & IOAT_CHANSTS_DMA_TRANSFER_STATUS) == 482 if ((ioat_chan->completion_virt->full & IOAT_CHANSTS_DMA_TRANSFER_STATUS) ==
387 IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) { 483 IOAT_CHANSTS_DMA_TRANSFER_STATUS_HALTED) {
388 printk("IOAT: Channel halted, chanerr = %x\n", 484 dev_err(&ioat_chan->device->pdev->dev,
389 readl(chan->reg_base + IOAT_CHANERR_OFFSET)); 485 "ioatdma: Channel halted, chanerr = %x\n",
486 readl(ioat_chan->reg_base + IOAT_CHANERR_OFFSET));
390 487
391 /* TODO do something to salvage the situation */ 488 /* TODO do something to salvage the situation */
392 } 489 }
393 490
394 if (phys_complete == chan->last_completion) { 491 if (phys_complete == ioat_chan->last_completion) {
395 spin_unlock(&chan->cleanup_lock); 492 spin_unlock(&ioat_chan->cleanup_lock);
396 return; 493 return;
397 } 494 }
398 495
399 spin_lock_bh(&chan->desc_lock); 496 cookie = 0;
400 list_for_each_entry_safe(desc, _desc, &chan->used_desc, node) { 497 spin_lock_bh(&ioat_chan->desc_lock);
498 list_for_each_entry_safe(desc, _desc, &ioat_chan->used_desc, node) {
401 499
402 /* 500 /*
403 * Incoming DMA requests may use multiple descriptors, due to 501 * Incoming DMA requests may use multiple descriptors, due to
@@ -407,31 +505,36 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan)
407 if (desc->async_tx.cookie) { 505 if (desc->async_tx.cookie) {
408 cookie = desc->async_tx.cookie; 506 cookie = desc->async_tx.cookie;
409 507
410 /* yes we are unmapping both _page and _single alloc'd 508 /*
411 regions with unmap_page. Is this *really* that bad? 509 * yes we are unmapping both _page and _single alloc'd
412 */ 510 * regions with unmap_page. Is this *really* that bad?
413 pci_unmap_page(chan->device->pdev, 511 */
512 pci_unmap_page(ioat_chan->device->pdev,
414 pci_unmap_addr(desc, dst), 513 pci_unmap_addr(desc, dst),
415 pci_unmap_len(desc, len), 514 pci_unmap_len(desc, len),
416 PCI_DMA_FROMDEVICE); 515 PCI_DMA_FROMDEVICE);
417 pci_unmap_page(chan->device->pdev, 516 pci_unmap_page(ioat_chan->device->pdev,
418 pci_unmap_addr(desc, src), 517 pci_unmap_addr(desc, src),
419 pci_unmap_len(desc, len), 518 pci_unmap_len(desc, len),
420 PCI_DMA_TODEVICE); 519 PCI_DMA_TODEVICE);
421 } 520 }
422 521
423 if (desc->async_tx.phys != phys_complete) { 522 if (desc->async_tx.phys != phys_complete) {
424 /* a completed entry, but not the last, so cleanup 523 /*
524 * a completed entry, but not the last, so cleanup
425 * if the client is done with the descriptor 525 * if the client is done with the descriptor
426 */ 526 */
427 if (desc->async_tx.ack) { 527 if (desc->async_tx.ack) {
428 list_del(&desc->node); 528 list_del(&desc->node);
429 list_add_tail(&desc->node, &chan->free_desc); 529 list_add_tail(&desc->node,
530 &ioat_chan->free_desc);
430 } else 531 } else
431 desc->async_tx.cookie = 0; 532 desc->async_tx.cookie = 0;
432 } else { 533 } else {
433 /* last used desc. Do not remove, so we can append from 534 /*
434 it, but don't look at it next time, either */ 535 * last used desc. Do not remove, so we can append from
536 * it, but don't look at it next time, either
537 */
435 desc->async_tx.cookie = 0; 538 desc->async_tx.cookie = 0;
436 539
437 /* TODO check status bits? */ 540 /* TODO check status bits? */
@@ -439,13 +542,13 @@ static void ioat_dma_memcpy_cleanup(struct ioat_dma_chan *chan)
439 } 542 }
440 } 543 }
441 544
442 spin_unlock_bh(&chan->desc_lock); 545 spin_unlock_bh(&ioat_chan->desc_lock);
443 546
444 chan->last_completion = phys_complete; 547 ioat_chan->last_completion = phys_complete;
445 if (cookie != 0) 548 if (cookie != 0)
446 chan->completed_cookie = cookie; 549 ioat_chan->completed_cookie = cookie;
447 550
448 spin_unlock(&chan->cleanup_lock); 551 spin_unlock(&ioat_chan->cleanup_lock);
449} 552}
450 553
451static void ioat_dma_dependency_added(struct dma_chan *chan) 554static void ioat_dma_dependency_added(struct dma_chan *chan)
@@ -466,11 +569,10 @@ static void ioat_dma_dependency_added(struct dma_chan *chan)
466 * @done: if not %NULL, updated with last completed transaction 569 * @done: if not %NULL, updated with last completed transaction
467 * @used: if not %NULL, updated with last used transaction 570 * @used: if not %NULL, updated with last used transaction
468 */ 571 */
469
470static enum dma_status ioat_dma_is_complete(struct dma_chan *chan, 572static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
471 dma_cookie_t cookie, 573 dma_cookie_t cookie,
472 dma_cookie_t *done, 574 dma_cookie_t *done,
473 dma_cookie_t *used) 575 dma_cookie_t *used)
474{ 576{
475 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan); 577 struct ioat_dma_chan *ioat_chan = to_ioat_chan(chan);
476 dma_cookie_t last_used; 578 dma_cookie_t last_used;
@@ -481,7 +583,7 @@ static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
481 last_complete = ioat_chan->completed_cookie; 583 last_complete = ioat_chan->completed_cookie;
482 584
483 if (done) 585 if (done)
484 *done= last_complete; 586 *done = last_complete;
485 if (used) 587 if (used)
486 *used = last_used; 588 *used = last_used;
487 589
@@ -495,7 +597,7 @@ static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
495 last_complete = ioat_chan->completed_cookie; 597 last_complete = ioat_chan->completed_cookie;
496 598
497 if (done) 599 if (done)
498 *done= last_complete; 600 *done = last_complete;
499 if (used) 601 if (used)
500 *used = last_used; 602 *used = last_used;
501 603
@@ -504,63 +606,13 @@ static enum dma_status ioat_dma_is_complete(struct dma_chan *chan,
504 606
505/* PCI API */ 607/* PCI API */
506 608
507static struct pci_device_id ioat_pci_tbl[] = { 609static void ioat_dma_start_null_desc(struct ioat_dma_chan *ioat_chan)
508 { PCI_DEVICE(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_IOAT) },
509 { PCI_DEVICE(PCI_VENDOR_ID_UNISYS,
510 PCI_DEVICE_ID_UNISYS_DMA_DIRECTOR) },
511 { 0, }
512};
513
514static struct pci_driver ioat_pci_driver = {
515 .name = "ioatdma",
516 .id_table = ioat_pci_tbl,
517 .probe = ioat_probe,
518 .shutdown = ioat_shutdown,
519 .remove = __devexit_p(ioat_remove),
520};
521
522static irqreturn_t ioat_do_interrupt(int irq, void *data)
523{
524 struct ioat_device *instance = data;
525 unsigned long attnstatus;
526 u8 intrctrl;
527
528 intrctrl = readb(instance->reg_base + IOAT_INTRCTRL_OFFSET);
529
530 if (!(intrctrl & IOAT_INTRCTRL_MASTER_INT_EN))
531 return IRQ_NONE;
532
533 if (!(intrctrl & IOAT_INTRCTRL_INT_STATUS)) {
534 writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
535 return IRQ_NONE;
536 }
537
538 attnstatus = readl(instance->reg_base + IOAT_ATTNSTATUS_OFFSET);
539
540 printk(KERN_ERR "ioatdma error: interrupt! status %lx\n", attnstatus);
541
542 writeb(intrctrl, instance->reg_base + IOAT_INTRCTRL_OFFSET);
543 return IRQ_HANDLED;
544}
545
546static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan)
547{ 610{
548 struct ioat_desc_sw *desc; 611 struct ioat_desc_sw *desc;
549 612
550 spin_lock_bh(&ioat_chan->desc_lock); 613 spin_lock_bh(&ioat_chan->desc_lock);
551 614
552 if (!list_empty(&ioat_chan->free_desc)) { 615 desc = ioat_dma_get_next_descriptor(ioat_chan);
553 desc = to_ioat_desc(ioat_chan->free_desc.next);
554 list_del(&desc->node);
555 } else {
556 /* try to get another desc */
557 spin_unlock_bh(&ioat_chan->desc_lock);
558 desc = ioat_dma_alloc_descriptor(ioat_chan, GFP_KERNEL);
559 spin_lock_bh(&ioat_chan->desc_lock);
560 /* will this ever happen? */
561 BUG_ON(!desc);
562 }
563
564 desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL; 616 desc->hw->ctl = IOAT_DMA_DESCRIPTOR_NUL;
565 desc->hw->next = 0; 617 desc->hw->next = 0;
566 desc->async_tx.ack = 1; 618 desc->async_tx.ack = 1;
@@ -581,7 +633,11 @@ static void ioat_start_null_desc(struct ioat_dma_chan *ioat_chan)
581 */ 633 */
582#define IOAT_TEST_SIZE 2000 634#define IOAT_TEST_SIZE 2000
583 635
584static int ioat_self_test(struct ioat_device *device) 636/**
637 * ioat_dma_self_test - Perform a IOAT transaction to verify the HW works.
638 * @device: device to be tested
639 */
640static int ioat_dma_self_test(struct ioatdma_device *device)
585{ 641{
586 int i; 642 int i;
587 u8 *src; 643 u8 *src;
@@ -607,9 +663,11 @@ static int ioat_self_test(struct ioat_device *device)
607 663
608 /* Start copy, using first DMA channel */ 664 /* Start copy, using first DMA channel */
609 dma_chan = container_of(device->common.channels.next, 665 dma_chan = container_of(device->common.channels.next,
610 struct dma_chan, 666 struct dma_chan,
611 device_node); 667 device_node);
612 if (ioat_dma_alloc_chan_resources(dma_chan) < 1) { 668 if (ioat_dma_alloc_chan_resources(dma_chan) < 1) {
669 dev_err(&device->pdev->dev,
670 "selftest cannot allocate chan resource\n");
613 err = -ENODEV; 671 err = -ENODEV;
614 goto out; 672 goto out;
615 } 673 }
@@ -627,12 +685,14 @@ static int ioat_self_test(struct ioat_device *device)
627 msleep(1); 685 msleep(1);
628 686
629 if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) { 687 if (ioat_dma_is_complete(dma_chan, cookie, NULL, NULL) != DMA_SUCCESS) {
630 printk(KERN_ERR "ioatdma: Self-test copy timed out, disabling\n"); 688 dev_err(&device->pdev->dev,
689 "ioatdma: Self-test copy timed out, disabling\n");
631 err = -ENODEV; 690 err = -ENODEV;
632 goto free_resources; 691 goto free_resources;
633 } 692 }
634 if (memcmp(src, dest, IOAT_TEST_SIZE)) { 693 if (memcmp(src, dest, IOAT_TEST_SIZE)) {
635 printk(KERN_ERR "ioatdma: Self-test copy failed compare, disabling\n"); 694 dev_err(&device->pdev->dev,
695 "ioatdma: Self-test copy failed compare, disabling\n");
636 err = -ENODEV; 696 err = -ENODEV;
637 goto free_resources; 697 goto free_resources;
638 } 698 }
@@ -645,147 +705,252 @@ out:
645 return err; 705 return err;
646} 706}
647 707
648static int __devinit ioat_probe(struct pci_dev *pdev, 708static char ioat_interrupt_style[32] = "msix";
649 const struct pci_device_id *ent) 709module_param_string(ioat_interrupt_style, ioat_interrupt_style,
710 sizeof(ioat_interrupt_style), 0644);
711MODULE_PARM_DESC(ioat_interrupt_style,
712 "set ioat interrupt style: msix (default), "
713 "msix-single-vector, msi, intx)");
714
715/**
716 * ioat_dma_setup_interrupts - setup interrupt handler
717 * @device: ioat device
718 */
719static int ioat_dma_setup_interrupts(struct ioatdma_device *device)
650{ 720{
651 int err; 721 struct ioat_dma_chan *ioat_chan;
652 unsigned long mmio_start, mmio_len; 722 int err, i, j, msixcnt;
653 void __iomem *reg_base; 723 u8 intrctrl = 0;
654 struct ioat_device *device; 724
725 if (!strcmp(ioat_interrupt_style, "msix"))
726 goto msix;
727 if (!strcmp(ioat_interrupt_style, "msix-single-vector"))
728 goto msix_single_vector;
729 if (!strcmp(ioat_interrupt_style, "msi"))
730 goto msi;
731 if (!strcmp(ioat_interrupt_style, "intx"))
732 goto intx;
733
734msix:
735 /* The number of MSI-X vectors should equal the number of channels */
736 msixcnt = device->common.chancnt;
737 for (i = 0; i < msixcnt; i++)
738 device->msix_entries[i].entry = i;
739
740 err = pci_enable_msix(device->pdev, device->msix_entries, msixcnt);
741 if (err < 0)
742 goto msi;
743 if (err > 0)
744 goto msix_single_vector;
745
746 for (i = 0; i < msixcnt; i++) {
747 ioat_chan = ioat_lookup_chan_by_index(device, i);
748 err = request_irq(device->msix_entries[i].vector,
749 ioat_dma_do_interrupt_msix,
750 0, "ioat-msix", ioat_chan);
751 if (err) {
752 for (j = 0; j < i; j++) {
753 ioat_chan =
754 ioat_lookup_chan_by_index(device, j);
755 free_irq(device->msix_entries[j].vector,
756 ioat_chan);
757 }
758 goto msix_single_vector;
759 }
760 }
761 intrctrl |= IOAT_INTRCTRL_MSIX_VECTOR_CONTROL;
762 device->irq_mode = msix_multi_vector;
763 goto done;
655 764
656 err = pci_enable_device(pdev); 765msix_single_vector:
766 device->msix_entries[0].entry = 0;
767 err = pci_enable_msix(device->pdev, device->msix_entries, 1);
657 if (err) 768 if (err)
658 goto err_enable_device; 769 goto msi;
659 770
660 err = pci_set_dma_mask(pdev, DMA_64BIT_MASK); 771 err = request_irq(device->msix_entries[0].vector, ioat_dma_do_interrupt,
661 if (err) 772 0, "ioat-msix", device);
662 err = pci_set_dma_mask(pdev, DMA_32BIT_MASK); 773 if (err) {
774 pci_disable_msix(device->pdev);
775 goto msi;
776 }
777 device->irq_mode = msix_single_vector;
778 goto done;
779
780msi:
781 err = pci_enable_msi(device->pdev);
663 if (err) 782 if (err)
664 goto err_set_dma_mask; 783 goto intx;
665 784
666 err = pci_request_regions(pdev, ioat_pci_driver.name); 785 err = request_irq(device->pdev->irq, ioat_dma_do_interrupt,
786 0, "ioat-msi", device);
787 if (err) {
788 pci_disable_msi(device->pdev);
789 goto intx;
790 }
791 /*
792 * CB 1.2 devices need a bit set in configuration space to enable MSI
793 */
794 if (device->version == IOAT_VER_1_2) {
795 u32 dmactrl;
796 pci_read_config_dword(device->pdev,
797 IOAT_PCI_DMACTRL_OFFSET, &dmactrl);
798 dmactrl |= IOAT_PCI_DMACTRL_MSI_EN;
799 pci_write_config_dword(device->pdev,
800 IOAT_PCI_DMACTRL_OFFSET, dmactrl);
801 }
802 device->irq_mode = msi;
803 goto done;
804
805intx:
806 err = request_irq(device->pdev->irq, ioat_dma_do_interrupt,
807 IRQF_SHARED, "ioat-intx", device);
667 if (err) 808 if (err)
668 goto err_request_regions; 809 goto err_no_irq;
810 device->irq_mode = intx;
669 811
670 mmio_start = pci_resource_start(pdev, 0); 812done:
671 mmio_len = pci_resource_len(pdev, 0); 813 intrctrl |= IOAT_INTRCTRL_MASTER_INT_EN;
814 writeb(intrctrl, device->reg_base + IOAT_INTRCTRL_OFFSET);
815 return 0;
672 816
673 reg_base = ioremap(mmio_start, mmio_len); 817err_no_irq:
674 if (!reg_base) { 818 /* Disable all interrupt generation */
675 err = -ENOMEM; 819 writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET);
676 goto err_ioremap; 820 dev_err(&device->pdev->dev, "no usable interrupts\n");
821 device->irq_mode = none;
822 return -1;
823}
824
825/**
826 * ioat_dma_remove_interrupts - remove whatever interrupts were set
827 * @device: ioat device
828 */
829static void ioat_dma_remove_interrupts(struct ioatdma_device *device)
830{
831 struct ioat_dma_chan *ioat_chan;
832 int i;
833
834 /* Disable all interrupt generation */
835 writeb(0, device->reg_base + IOAT_INTRCTRL_OFFSET);
836
837 switch (device->irq_mode) {
838 case msix_multi_vector:
839 for (i = 0; i < device->common.chancnt; i++) {
840 ioat_chan = ioat_lookup_chan_by_index(device, i);
841 free_irq(device->msix_entries[i].vector, ioat_chan);
842 }
843 pci_disable_msix(device->pdev);
844 break;
845 case msix_single_vector:
846 free_irq(device->msix_entries[0].vector, device);
847 pci_disable_msix(device->pdev);
848 break;
849 case msi:
850 free_irq(device->pdev->irq, device);
851 pci_disable_msi(device->pdev);
852 break;
853 case intx:
854 free_irq(device->pdev->irq, device);
855 break;
856 case none:
857 dev_warn(&device->pdev->dev,
858 "call to %s without interrupts setup\n", __func__);
677 } 859 }
860 device->irq_mode = none;
861}
862
863struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
864 void __iomem *iobase)
865{
866 int err;
867 struct ioatdma_device *device;
678 868
679 device = kzalloc(sizeof(*device), GFP_KERNEL); 869 device = kzalloc(sizeof(*device), GFP_KERNEL);
680 if (!device) { 870 if (!device) {
681 err = -ENOMEM; 871 err = -ENOMEM;
682 goto err_kzalloc; 872 goto err_kzalloc;
683 } 873 }
874 device->pdev = pdev;
875 device->reg_base = iobase;
876 device->version = readb(device->reg_base + IOAT_VER_OFFSET);
684 877
685 /* DMA coherent memory pool for DMA descriptor allocations */ 878 /* DMA coherent memory pool for DMA descriptor allocations */
686 device->dma_pool = pci_pool_create("dma_desc_pool", pdev, 879 device->dma_pool = pci_pool_create("dma_desc_pool", pdev,
687 sizeof(struct ioat_dma_descriptor), 64, 0); 880 sizeof(struct ioat_dma_descriptor),
881 64, 0);
688 if (!device->dma_pool) { 882 if (!device->dma_pool) {
689 err = -ENOMEM; 883 err = -ENOMEM;
690 goto err_dma_pool; 884 goto err_dma_pool;
691 } 885 }
692 886
693 device->completion_pool = pci_pool_create("completion_pool", pdev, sizeof(u64), SMP_CACHE_BYTES, SMP_CACHE_BYTES); 887 device->completion_pool = pci_pool_create("completion_pool", pdev,
888 sizeof(u64), SMP_CACHE_BYTES,
889 SMP_CACHE_BYTES);
694 if (!device->completion_pool) { 890 if (!device->completion_pool) {
695 err = -ENOMEM; 891 err = -ENOMEM;
696 goto err_completion_pool; 892 goto err_completion_pool;
697 } 893 }
698 894
699 device->pdev = pdev;
700 pci_set_drvdata(pdev, device);
701#ifdef CONFIG_PCI_MSI
702 if (pci_enable_msi(pdev) == 0) {
703 device->msi = 1;
704 } else {
705 device->msi = 0;
706 }
707#endif
708 err = request_irq(pdev->irq, &ioat_do_interrupt, IRQF_SHARED, "ioat",
709 device);
710 if (err)
711 goto err_irq;
712
713 device->reg_base = reg_base;
714
715 writeb(IOAT_INTRCTRL_MASTER_INT_EN, device->reg_base + IOAT_INTRCTRL_OFFSET);
716 pci_set_master(pdev);
717
718 INIT_LIST_HEAD(&device->common.channels); 895 INIT_LIST_HEAD(&device->common.channels);
719 enumerate_dma_channels(device); 896 ioat_dma_enumerate_channels(device);
720 897
721 dma_cap_set(DMA_MEMCPY, device->common.cap_mask); 898 dma_cap_set(DMA_MEMCPY, device->common.cap_mask);
722 device->common.device_alloc_chan_resources = ioat_dma_alloc_chan_resources; 899 device->common.device_alloc_chan_resources =
723 device->common.device_free_chan_resources = ioat_dma_free_chan_resources; 900 ioat_dma_alloc_chan_resources;
901 device->common.device_free_chan_resources =
902 ioat_dma_free_chan_resources;
724 device->common.device_prep_dma_memcpy = ioat_dma_prep_memcpy; 903 device->common.device_prep_dma_memcpy = ioat_dma_prep_memcpy;
725 device->common.device_is_tx_complete = ioat_dma_is_complete; 904 device->common.device_is_tx_complete = ioat_dma_is_complete;
726 device->common.device_issue_pending = ioat_dma_memcpy_issue_pending; 905 device->common.device_issue_pending = ioat_dma_memcpy_issue_pending;
727 device->common.device_dependency_added = ioat_dma_dependency_added; 906 device->common.device_dependency_added = ioat_dma_dependency_added;
728 device->common.dev = &pdev->dev; 907 device->common.dev = &pdev->dev;
729 printk(KERN_INFO "Intel(R) I/OAT DMA Engine found, %d channels\n", 908 dev_err(&device->pdev->dev,
730 device->common.chancnt); 909 "ioatdma: Intel(R) I/OAT DMA Engine found,"
910 " %d channels, device version 0x%02x\n",
911 device->common.chancnt, device->version);
731 912
732 err = ioat_self_test(device); 913 err = ioat_dma_setup_interrupts(device);
914 if (err)
915 goto err_setup_interrupts;
916
917 err = ioat_dma_self_test(device);
733 if (err) 918 if (err)
734 goto err_self_test; 919 goto err_self_test;
735 920
736 dma_async_device_register(&device->common); 921 dma_async_device_register(&device->common);
737 922
738 return 0; 923 return device;
739 924
740err_self_test: 925err_self_test:
741err_irq: 926 ioat_dma_remove_interrupts(device);
927err_setup_interrupts:
742 pci_pool_destroy(device->completion_pool); 928 pci_pool_destroy(device->completion_pool);
743err_completion_pool: 929err_completion_pool:
744 pci_pool_destroy(device->dma_pool); 930 pci_pool_destroy(device->dma_pool);
745err_dma_pool: 931err_dma_pool:
746 kfree(device); 932 kfree(device);
747err_kzalloc: 933err_kzalloc:
748 iounmap(reg_base); 934 iounmap(iobase);
749err_ioremap: 935 dev_err(&device->pdev->dev,
750 pci_release_regions(pdev); 936 "ioatdma: Intel(R) I/OAT DMA Engine initialization failed\n");
751err_request_regions: 937 return NULL;
752err_set_dma_mask:
753 pci_disable_device(pdev);
754err_enable_device:
755
756 printk(KERN_ERR "Intel(R) I/OAT DMA Engine initialization failed\n");
757
758 return err;
759} 938}
760 939
761static void ioat_shutdown(struct pci_dev *pdev) 940void ioat_dma_remove(struct ioatdma_device *device)
762{ 941{
763 struct ioat_device *device;
764 device = pci_get_drvdata(pdev);
765
766 dma_async_device_unregister(&device->common);
767}
768
769static void __devexit ioat_remove(struct pci_dev *pdev)
770{
771 struct ioat_device *device;
772 struct dma_chan *chan, *_chan; 942 struct dma_chan *chan, *_chan;
773 struct ioat_dma_chan *ioat_chan; 943 struct ioat_dma_chan *ioat_chan;
774 944
775 device = pci_get_drvdata(pdev);
776 dma_async_device_unregister(&device->common); 945 dma_async_device_unregister(&device->common);
777 946
778 free_irq(device->pdev->irq, device); 947 ioat_dma_remove_interrupts(device);
779#ifdef CONFIG_PCI_MSI 948
780 if (device->msi)
781 pci_disable_msi(device->pdev);
782#endif
783 pci_pool_destroy(device->dma_pool); 949 pci_pool_destroy(device->dma_pool);
784 pci_pool_destroy(device->completion_pool); 950 pci_pool_destroy(device->completion_pool);
785 iounmap(device->reg_base); 951
786 pci_release_regions(pdev); 952 list_for_each_entry_safe(chan, _chan,
787 pci_disable_device(pdev); 953 &device->common.channels, device_node) {
788 list_for_each_entry_safe(chan, _chan, &device->common.channels, device_node) {
789 ioat_chan = to_ioat_chan(chan); 954 ioat_chan = to_ioat_chan(chan);
790 list_del(&chan->device_node); 955 list_del(&chan->device_node);
791 kfree(ioat_chan); 956 kfree(ioat_chan);
@@ -793,25 +958,3 @@ static void __devexit ioat_remove(struct pci_dev *pdev)
793 kfree(device); 958 kfree(device);
794} 959}
795 960
796/* MODULE API */
797MODULE_VERSION("1.9");
798MODULE_LICENSE("GPL");
799MODULE_AUTHOR("Intel Corporation");
800
801static int __init ioat_init_module(void)
802{
803 /* it's currently unsafe to unload this module */
804 /* if forced, worst case is that rmmod hangs */
805 __unsafe(THIS_MODULE);
806
807 return pci_register_driver(&ioat_pci_driver);
808}
809
810module_init(ioat_init_module);
811
812static void __exit ioat_exit_module(void)
813{
814 pci_unregister_driver(&ioat_pci_driver);
815}
816
817module_exit(ioat_exit_module);
diff --git a/drivers/dma/ioatdma.h b/drivers/dma/ioatdma.h
index bf4dad70e0f5..2a319e124ece 100644
--- a/drivers/dma/ioatdma.h
+++ b/drivers/dma/ioatdma.h
@@ -28,25 +28,35 @@
28#include <linux/cache.h> 28#include <linux/cache.h>
29#include <linux/pci_ids.h> 29#include <linux/pci_ids.h>
30 30
31enum ioat_interrupt {
32 none = 0,
33 msix_multi_vector = 1,
34 msix_single_vector = 2,
35 msi = 3,
36 intx = 4,
37};
38
31#define IOAT_LOW_COMPLETION_MASK 0xffffffc0 39#define IOAT_LOW_COMPLETION_MASK 0xffffffc0
32 40
33/** 41/**
34 * struct ioat_device - internal representation of a IOAT device 42 * struct ioatdma_device - internal representation of a IOAT device
35 * @pdev: PCI-Express device 43 * @pdev: PCI-Express device
36 * @reg_base: MMIO register space base address 44 * @reg_base: MMIO register space base address
37 * @dma_pool: for allocating DMA descriptors 45 * @dma_pool: for allocating DMA descriptors
38 * @common: embedded struct dma_device 46 * @common: embedded struct dma_device
39 * @msi: Message Signaled Interrupt number 47 * @version: version of ioatdma device
40 */ 48 */
41 49
42struct ioat_device { 50struct ioatdma_device {
43 struct pci_dev *pdev; 51 struct pci_dev *pdev;
44 void __iomem *reg_base; 52 void __iomem *reg_base;
45 struct pci_pool *dma_pool; 53 struct pci_pool *dma_pool;
46 struct pci_pool *completion_pool; 54 struct pci_pool *completion_pool;
47
48 struct dma_device common; 55 struct dma_device common;
49 u8 msi; 56 u8 version;
57 enum ioat_interrupt irq_mode;
58 struct msix_entry msix_entries[4];
59 struct ioat_dma_chan *idx[4];
50}; 60};
51 61
52/** 62/**
@@ -84,7 +94,7 @@ struct ioat_dma_chan {
84 94
85 int pending; 95 int pending;
86 96
87 struct ioat_device *device; 97 struct ioatdma_device *device;
88 struct dma_chan common; 98 struct dma_chan common;
89 99
90 dma_addr_t completion_addr; 100 dma_addr_t completion_addr;
@@ -95,6 +105,7 @@ struct ioat_dma_chan {
95 u32 high; 105 u32 high;
96 }; 106 };
97 } *completion_virt; 107 } *completion_virt;
108 struct tasklet_struct cleanup_task;
98}; 109};
99 110
100/* wrapper around hardware descriptor format + additional software fields */ 111/* wrapper around hardware descriptor format + additional software fields */
@@ -117,4 +128,16 @@ struct ioat_desc_sw {
117 struct dma_async_tx_descriptor async_tx; 128 struct dma_async_tx_descriptor async_tx;
118}; 129};
119 130
131#if defined(CONFIG_INTEL_IOATDMA) || defined(CONFIG_INTEL_IOATDMA_MODULE)
132struct ioatdma_device *ioat_dma_probe(struct pci_dev *pdev,
133 void __iomem *iobase);
134void ioat_dma_remove(struct ioatdma_device *device);
135struct dca_provider *ioat_dca_init(struct pci_dev *pdev,
136 void __iomem *iobase);
137#else
138#define ioat_dma_probe(pdev, iobase) NULL
139#define ioat_dma_remove(device) do { } while (0)
140#define ioat_dca_init(pdev, iobase) NULL
141#endif
142
120#endif /* IOATDMA_H */ 143#endif /* IOATDMA_H */
diff --git a/drivers/dma/ioatdma_hw.h b/drivers/dma/ioatdma_hw.h
index 4d7a12880be3..9e7434e1551f 100644
--- a/drivers/dma/ioatdma_hw.h
+++ b/drivers/dma/ioatdma_hw.h
@@ -27,7 +27,7 @@
27#define IOAT_PCI_RID 0x00 27#define IOAT_PCI_RID 0x00
28#define IOAT_PCI_SVID 0x8086 28#define IOAT_PCI_SVID 0x8086
29#define IOAT_PCI_SID 0x8086 29#define IOAT_PCI_SID 0x8086
30#define IOAT_VER 0x12 /* Version 1.2 */ 30#define IOAT_VER_1_2 0x12 /* Version 1.2 */
31 31
32struct ioat_dma_descriptor { 32struct ioat_dma_descriptor {
33 uint32_t size; 33 uint32_t size;
diff --git a/drivers/dma/ioatdma_registers.h b/drivers/dma/ioatdma_registers.h
index a30c7349075a..baaab5ea146a 100644
--- a/drivers/dma/ioatdma_registers.h
+++ b/drivers/dma/ioatdma_registers.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright(c) 2004 - 2006 Intel Corporation. All rights reserved. 2 * Copyright(c) 2004 - 2007 Intel Corporation. All rights reserved.
3 * 3 *
4 * This program is free software; you can redistribute it and/or modify it 4 * This program is free software; you can redistribute it and/or modify it
5 * under the terms of the GNU General Public License as published by the Free 5 * under the terms of the GNU General Public License as published by the Free
@@ -21,6 +21,9 @@
21#ifndef _IOAT_REGISTERS_H_ 21#ifndef _IOAT_REGISTERS_H_
22#define _IOAT_REGISTERS_H_ 22#define _IOAT_REGISTERS_H_
23 23
24#define IOAT_PCI_DMACTRL_OFFSET 0x48
25#define IOAT_PCI_DMACTRL_DMA_EN 0x00000001
26#define IOAT_PCI_DMACTRL_MSI_EN 0x00000002
24 27
25/* MMIO Device Registers */ 28/* MMIO Device Registers */
26#define IOAT_CHANCNT_OFFSET 0x00 /* 8-bit */ 29#define IOAT_CHANCNT_OFFSET 0x00 /* 8-bit */
@@ -39,6 +42,7 @@
39#define IOAT_INTRCTRL_MASTER_INT_EN 0x01 /* Master Interrupt Enable */ 42#define IOAT_INTRCTRL_MASTER_INT_EN 0x01 /* Master Interrupt Enable */
40#define IOAT_INTRCTRL_INT_STATUS 0x02 /* ATTNSTATUS -or- Channel Int */ 43#define IOAT_INTRCTRL_INT_STATUS 0x02 /* ATTNSTATUS -or- Channel Int */
41#define IOAT_INTRCTRL_INT 0x04 /* INT_STATUS -and- MASTER_INT_EN */ 44#define IOAT_INTRCTRL_INT 0x04 /* INT_STATUS -and- MASTER_INT_EN */
45#define IOAT_INTRCTRL_MSIX_VECTOR_CONTROL 0x08 /* Enable all MSI-X vectors */
42 46
43#define IOAT_ATTNSTATUS_OFFSET 0x04 /* Each bit is a channel */ 47#define IOAT_ATTNSTATUS_OFFSET 0x04 /* Each bit is a channel */
44 48
diff --git a/drivers/ide/cris/ide-cris.c b/drivers/ide/cris/ide-cris.c
index 2b4d2a0ae5c2..c306c9f534ab 100644
--- a/drivers/ide/cris/ide-cris.c
+++ b/drivers/ide/cris/ide-cris.c
@@ -939,7 +939,8 @@ static int cris_ide_build_dmatable (ide_drive_t *drive)
939 /* group sequential buffers into one large buffer */ 939 /* group sequential buffers into one large buffer */
940 addr = page_to_phys(sg->page) + sg->offset; 940 addr = page_to_phys(sg->page) + sg->offset;
941 size = sg_dma_len(sg); 941 size = sg_dma_len(sg);
942 while (sg++, --i) { 942 while (--i) {
943 sg = sg_next(sg);
943 if ((addr + size) != page_to_phys(sg->page) + sg->offset) 944 if ((addr + size) != page_to_phys(sg->page) + sg->offset)
944 break; 945 break;
945 size += sg_dma_len(sg); 946 size += sg_dma_len(sg);
diff --git a/drivers/ide/ide-disk.c b/drivers/ide/ide-disk.c
index 4754769eda97..92177ca48b4d 100644
--- a/drivers/ide/ide-disk.c
+++ b/drivers/ide/ide-disk.c
@@ -716,32 +716,6 @@ static void idedisk_prepare_flush(struct request_queue *q, struct request *rq)
716 rq->buffer = rq->cmd; 716 rq->buffer = rq->cmd;
717} 717}
718 718
719static int idedisk_issue_flush(struct request_queue *q, struct gendisk *disk,
720 sector_t *error_sector)
721{
722 ide_drive_t *drive = q->queuedata;
723 struct request *rq;
724 int ret;
725
726 if (!drive->wcache)
727 return 0;
728
729 rq = blk_get_request(q, WRITE, __GFP_WAIT);
730
731 idedisk_prepare_flush(q, rq);
732
733 ret = blk_execute_rq(q, disk, rq, 0);
734
735 /*
736 * if we failed and caller wants error offset, get it
737 */
738 if (ret && error_sector)
739 *error_sector = ide_get_error_location(drive, rq->cmd);
740
741 blk_put_request(rq);
742 return ret;
743}
744
745/* 719/*
746 * This is tightly woven into the driver->do_special can not touch. 720 * This is tightly woven into the driver->do_special can not touch.
747 * DON'T do it again until a total personality rewrite is committed. 721 * DON'T do it again until a total personality rewrite is committed.
@@ -781,7 +755,6 @@ static void update_ordered(ide_drive_t *drive)
781 struct hd_driveid *id = drive->id; 755 struct hd_driveid *id = drive->id;
782 unsigned ordered = QUEUE_ORDERED_NONE; 756 unsigned ordered = QUEUE_ORDERED_NONE;
783 prepare_flush_fn *prep_fn = NULL; 757 prepare_flush_fn *prep_fn = NULL;
784 issue_flush_fn *issue_fn = NULL;
785 758
786 if (drive->wcache) { 759 if (drive->wcache) {
787 unsigned long long capacity; 760 unsigned long long capacity;
@@ -805,13 +778,11 @@ static void update_ordered(ide_drive_t *drive)
805 if (barrier) { 778 if (barrier) {
806 ordered = QUEUE_ORDERED_DRAIN_FLUSH; 779 ordered = QUEUE_ORDERED_DRAIN_FLUSH;
807 prep_fn = idedisk_prepare_flush; 780 prep_fn = idedisk_prepare_flush;
808 issue_fn = idedisk_issue_flush;
809 } 781 }
810 } else 782 } else
811 ordered = QUEUE_ORDERED_DRAIN; 783 ordered = QUEUE_ORDERED_DRAIN;
812 784
813 blk_queue_ordered(drive->queue, ordered, prep_fn); 785 blk_queue_ordered(drive->queue, ordered, prep_fn);
814 blk_queue_issue_flush_fn(drive->queue, issue_fn);
815} 786}
816 787
817static int write_cache(ide_drive_t *drive, int arg) 788static int write_cache(ide_drive_t *drive, int arg)
diff --git a/drivers/ide/ide-dma.c b/drivers/ide/ide-dma.c
index b453211ee0fc..a4cbbbaccde9 100644
--- a/drivers/ide/ide-dma.c
+++ b/drivers/ide/ide-dma.c
@@ -280,7 +280,7 @@ int ide_build_dmatable (ide_drive_t *drive, struct request *rq)
280 } 280 }
281 } 281 }
282 282
283 sg++; 283 sg = sg_next(sg);
284 i--; 284 i--;
285 } 285 }
286 286
diff --git a/drivers/ide/ide-io.c b/drivers/ide/ide-io.c
index 4cece930114c..04273d3c147c 100644
--- a/drivers/ide/ide-io.c
+++ b/drivers/ide/ide-io.c
@@ -322,41 +322,6 @@ static void ide_complete_pm_request (ide_drive_t *drive, struct request *rq)
322 spin_unlock_irqrestore(&ide_lock, flags); 322 spin_unlock_irqrestore(&ide_lock, flags);
323} 323}
324 324
325/*
326 * FIXME: probably move this somewhere else, name is bad too :)
327 */
328u64 ide_get_error_location(ide_drive_t *drive, char *args)
329{
330 u32 high, low;
331 u8 hcyl, lcyl, sect;
332 u64 sector;
333
334 high = 0;
335 hcyl = args[5];
336 lcyl = args[4];
337 sect = args[3];
338
339 if (ide_id_has_flush_cache_ext(drive->id)) {
340 low = (hcyl << 16) | (lcyl << 8) | sect;
341 HWIF(drive)->OUTB(drive->ctl|0x80, IDE_CONTROL_REG);
342 high = ide_read_24(drive);
343 } else {
344 u8 cur = HWIF(drive)->INB(IDE_SELECT_REG);
345 if (cur & 0x40) {
346 high = cur & 0xf;
347 low = (hcyl << 16) | (lcyl << 8) | sect;
348 } else {
349 low = hcyl * drive->head * drive->sect;
350 low += lcyl * drive->sect;
351 low += sect - 1;
352 }
353 }
354
355 sector = ((u64) high << 24) | low;
356 return sector;
357}
358EXPORT_SYMBOL(ide_get_error_location);
359
360/** 325/**
361 * ide_end_drive_cmd - end an explicit drive command 326 * ide_end_drive_cmd - end an explicit drive command
362 * @drive: command 327 * @drive: command
@@ -881,7 +846,8 @@ void ide_init_sg_cmd(ide_drive_t *drive, struct request *rq)
881 ide_hwif_t *hwif = drive->hwif; 846 ide_hwif_t *hwif = drive->hwif;
882 847
883 hwif->nsect = hwif->nleft = rq->nr_sectors; 848 hwif->nsect = hwif->nleft = rq->nr_sectors;
884 hwif->cursg = hwif->cursg_ofs = 0; 849 hwif->cursg_ofs = 0;
850 hwif->cursg = NULL;
885} 851}
886 852
887EXPORT_SYMBOL_GPL(ide_init_sg_cmd); 853EXPORT_SYMBOL_GPL(ide_init_sg_cmd);
diff --git a/drivers/ide/ide-probe.c b/drivers/ide/ide-probe.c
index d1011712601c..34b1fb65bc79 100644
--- a/drivers/ide/ide-probe.c
+++ b/drivers/ide/ide-probe.c
@@ -1349,7 +1349,7 @@ static int hwif_init(ide_hwif_t *hwif)
1349 if (!hwif->sg_max_nents) 1349 if (!hwif->sg_max_nents)
1350 hwif->sg_max_nents = PRD_ENTRIES; 1350 hwif->sg_max_nents = PRD_ENTRIES;
1351 1351
1352 hwif->sg_table = kmalloc(sizeof(struct scatterlist)*hwif->sg_max_nents, 1352 hwif->sg_table = kzalloc(sizeof(struct scatterlist)*hwif->sg_max_nents,
1353 GFP_KERNEL); 1353 GFP_KERNEL);
1354 if (!hwif->sg_table) { 1354 if (!hwif->sg_table) {
1355 printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name); 1355 printk(KERN_ERR "%s: unable to allocate SG table.\n", hwif->name);
diff --git a/drivers/ide/ide-taskfile.c b/drivers/ide/ide-taskfile.c
index aa06dafb74ac..2a3c8d498343 100644
--- a/drivers/ide/ide-taskfile.c
+++ b/drivers/ide/ide-taskfile.c
@@ -45,6 +45,7 @@
45#include <linux/hdreg.h> 45#include <linux/hdreg.h>
46#include <linux/ide.h> 46#include <linux/ide.h>
47#include <linux/bitops.h> 47#include <linux/bitops.h>
48#include <linux/scatterlist.h>
48 49
49#include <asm/byteorder.h> 50#include <asm/byteorder.h>
50#include <asm/irq.h> 51#include <asm/irq.h>
@@ -263,6 +264,7 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
263{ 264{
264 ide_hwif_t *hwif = drive->hwif; 265 ide_hwif_t *hwif = drive->hwif;
265 struct scatterlist *sg = hwif->sg_table; 266 struct scatterlist *sg = hwif->sg_table;
267 struct scatterlist *cursg = hwif->cursg;
266 struct page *page; 268 struct page *page;
267#ifdef CONFIG_HIGHMEM 269#ifdef CONFIG_HIGHMEM
268 unsigned long flags; 270 unsigned long flags;
@@ -270,8 +272,14 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
270 unsigned int offset; 272 unsigned int offset;
271 u8 *buf; 273 u8 *buf;
272 274
273 page = sg[hwif->cursg].page; 275 cursg = hwif->cursg;
274 offset = sg[hwif->cursg].offset + hwif->cursg_ofs * SECTOR_SIZE; 276 if (!cursg) {
277 cursg = sg;
278 hwif->cursg = sg;
279 }
280
281 page = cursg->page;
282 offset = cursg->offset + hwif->cursg_ofs * SECTOR_SIZE;
275 283
276 /* get the current page and offset */ 284 /* get the current page and offset */
277 page = nth_page(page, (offset >> PAGE_SHIFT)); 285 page = nth_page(page, (offset >> PAGE_SHIFT));
@@ -285,8 +293,8 @@ static void ide_pio_sector(ide_drive_t *drive, unsigned int write)
285 hwif->nleft--; 293 hwif->nleft--;
286 hwif->cursg_ofs++; 294 hwif->cursg_ofs++;
287 295
288 if ((hwif->cursg_ofs * SECTOR_SIZE) == sg[hwif->cursg].length) { 296 if ((hwif->cursg_ofs * SECTOR_SIZE) == cursg->length) {
289 hwif->cursg++; 297 hwif->cursg = sg_next(hwif->cursg);
290 hwif->cursg_ofs = 0; 298 hwif->cursg_ofs = 0;
291 } 299 }
292 300
@@ -367,6 +375,8 @@ static ide_startstop_t task_error(ide_drive_t *drive, struct request *rq,
367 375
368static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat) 376static void task_end_request(ide_drive_t *drive, struct request *rq, u8 stat)
369{ 377{
378 HWIF(drive)->cursg = NULL;
379
370 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) { 380 if (rq->cmd_type == REQ_TYPE_ATA_TASKFILE) {
371 ide_task_t *task = rq->special; 381 ide_task_t *task = rq->special;
372 382
diff --git a/drivers/ide/mips/au1xxx-ide.c b/drivers/ide/mips/au1xxx-ide.c
index aebde49365d1..892d08f61dc0 100644
--- a/drivers/ide/mips/au1xxx-ide.c
+++ b/drivers/ide/mips/au1xxx-ide.c
@@ -296,7 +296,7 @@ static int auide_build_dmatable(ide_drive_t *drive)
296 cur_addr += tc; 296 cur_addr += tc;
297 cur_len -= tc; 297 cur_len -= tc;
298 } 298 }
299 sg++; 299 sg = sg_next(sg);
300 i--; 300 i--;
301 } 301 }
302 302
diff --git a/drivers/ide/pci/sgiioc4.c b/drivers/ide/pci/sgiioc4.c
index 85ffaaa39b1b..c74fef6bbc91 100644
--- a/drivers/ide/pci/sgiioc4.c
+++ b/drivers/ide/pci/sgiioc4.c
@@ -29,6 +29,7 @@
29#include <linux/mm.h> 29#include <linux/mm.h>
30#include <linux/ioport.h> 30#include <linux/ioport.h>
31#include <linux/blkdev.h> 31#include <linux/blkdev.h>
32#include <linux/scatterlist.h>
32#include <linux/ioc4.h> 33#include <linux/ioc4.h>
33#include <asm/io.h> 34#include <asm/io.h>
34 35
@@ -537,7 +538,7 @@ sgiioc4_build_dma_table(ide_drive_t * drive, struct request *rq, int ddir)
537 } 538 }
538 } 539 }
539 540
540 sg++; 541 sg = sg_next(sg);
541 i--; 542 i--;
542 } 543 }
543 544
diff --git a/drivers/ide/ppc/pmac.c b/drivers/ide/ppc/pmac.c
index 7d8873839e21..9e86406bf44b 100644
--- a/drivers/ide/ppc/pmac.c
+++ b/drivers/ide/ppc/pmac.c
@@ -1539,7 +1539,7 @@ pmac_ide_build_dmatable(ide_drive_t *drive, struct request *rq)
1539 cur_len -= tc; 1539 cur_len -= tc;
1540 ++table; 1540 ++table;
1541 } 1541 }
1542 sg++; 1542 sg = sg_next(sg);
1543 i--; 1543 i--;
1544 } 1544 }
1545 1545
diff --git a/drivers/infiniband/hw/ipath/ipath_dma.c b/drivers/infiniband/hw/ipath/ipath_dma.c
index f87f003e3ef8..22709a4f8fc8 100644
--- a/drivers/infiniband/hw/ipath/ipath_dma.c
+++ b/drivers/infiniband/hw/ipath/ipath_dma.c
@@ -30,6 +30,7 @@
30 * SOFTWARE. 30 * SOFTWARE.
31 */ 31 */
32 32
33#include <linux/scatterlist.h>
33#include <rdma/ib_verbs.h> 34#include <rdma/ib_verbs.h>
34 35
35#include "ipath_verbs.h" 36#include "ipath_verbs.h"
@@ -96,17 +97,18 @@ static void ipath_dma_unmap_page(struct ib_device *dev,
96 BUG_ON(!valid_dma_direction(direction)); 97 BUG_ON(!valid_dma_direction(direction));
97} 98}
98 99
99static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sg, int nents, 100static int ipath_map_sg(struct ib_device *dev, struct scatterlist *sgl,
100 enum dma_data_direction direction) 101 int nents, enum dma_data_direction direction)
101{ 102{
103 struct scatterlist *sg;
102 u64 addr; 104 u64 addr;
103 int i; 105 int i;
104 int ret = nents; 106 int ret = nents;
105 107
106 BUG_ON(!valid_dma_direction(direction)); 108 BUG_ON(!valid_dma_direction(direction));
107 109
108 for (i = 0; i < nents; i++) { 110 for_each_sg(sgl, sg, nents, i) {
109 addr = (u64) page_address(sg[i].page); 111 addr = (u64) page_address(sg->page);
110 /* TODO: handle highmem pages */ 112 /* TODO: handle highmem pages */
111 if (!addr) { 113 if (!addr) {
112 ret = 0; 114 ret = 0;
diff --git a/drivers/infiniband/ulp/iser/iser_memory.c b/drivers/infiniband/ulp/iser/iser_memory.c
index e05690e3592f..f3529b6f0a33 100644
--- a/drivers/infiniband/ulp/iser/iser_memory.c
+++ b/drivers/infiniband/ulp/iser/iser_memory.c
@@ -124,17 +124,19 @@ static int iser_start_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
124 124
125 if (cmd_dir == ISER_DIR_OUT) { 125 if (cmd_dir == ISER_DIR_OUT) {
126 /* copy the unaligned sg the buffer which is used for RDMA */ 126 /* copy the unaligned sg the buffer which is used for RDMA */
127 struct scatterlist *sg = (struct scatterlist *)data->buf; 127 struct scatterlist *sgl = (struct scatterlist *)data->buf;
128 struct scatterlist *sg;
128 int i; 129 int i;
129 char *p, *from; 130 char *p, *from;
130 131
131 for (p = mem, i = 0; i < data->size; i++) { 132 p = mem;
132 from = kmap_atomic(sg[i].page, KM_USER0); 133 for_each_sg(sgl, sg, data->size, i) {
134 from = kmap_atomic(sg->page, KM_USER0);
133 memcpy(p, 135 memcpy(p,
134 from + sg[i].offset, 136 from + sg->offset,
135 sg[i].length); 137 sg->length);
136 kunmap_atomic(from, KM_USER0); 138 kunmap_atomic(from, KM_USER0);
137 p += sg[i].length; 139 p += sg->length;
138 } 140 }
139 } 141 }
140 142
@@ -176,7 +178,7 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
176 178
177 if (cmd_dir == ISER_DIR_IN) { 179 if (cmd_dir == ISER_DIR_IN) {
178 char *mem; 180 char *mem;
179 struct scatterlist *sg; 181 struct scatterlist *sgl, *sg;
180 unsigned char *p, *to; 182 unsigned char *p, *to;
181 unsigned int sg_size; 183 unsigned int sg_size;
182 int i; 184 int i;
@@ -184,16 +186,17 @@ void iser_finalize_rdma_unaligned_sg(struct iscsi_iser_cmd_task *iser_ctask,
184 /* copy back read RDMA to unaligned sg */ 186 /* copy back read RDMA to unaligned sg */
185 mem = mem_copy->copy_buf; 187 mem = mem_copy->copy_buf;
186 188
187 sg = (struct scatterlist *)iser_ctask->data[ISER_DIR_IN].buf; 189 sgl = (struct scatterlist *)iser_ctask->data[ISER_DIR_IN].buf;
188 sg_size = iser_ctask->data[ISER_DIR_IN].size; 190 sg_size = iser_ctask->data[ISER_DIR_IN].size;
189 191
190 for (p = mem, i = 0; i < sg_size; i++){ 192 p = mem;
191 to = kmap_atomic(sg[i].page, KM_SOFTIRQ0); 193 for_each_sg(sgl, sg, sg_size, i) {
192 memcpy(to + sg[i].offset, 194 to = kmap_atomic(sg->page, KM_SOFTIRQ0);
195 memcpy(to + sg->offset,
193 p, 196 p,
194 sg[i].length); 197 sg->length);
195 kunmap_atomic(to, KM_SOFTIRQ0); 198 kunmap_atomic(to, KM_SOFTIRQ0);
196 p += sg[i].length; 199 p += sg->length;
197 } 200 }
198 } 201 }
199 202
@@ -224,7 +227,8 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
224 struct iser_page_vec *page_vec, 227 struct iser_page_vec *page_vec,
225 struct ib_device *ibdev) 228 struct ib_device *ibdev)
226{ 229{
227 struct scatterlist *sg = (struct scatterlist *)data->buf; 230 struct scatterlist *sgl = (struct scatterlist *)data->buf;
231 struct scatterlist *sg;
228 u64 first_addr, last_addr, page; 232 u64 first_addr, last_addr, page;
229 int end_aligned; 233 int end_aligned;
230 unsigned int cur_page = 0; 234 unsigned int cur_page = 0;
@@ -232,24 +236,25 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
232 int i; 236 int i;
233 237
234 /* compute the offset of first element */ 238 /* compute the offset of first element */
235 page_vec->offset = (u64) sg[0].offset & ~MASK_4K; 239 page_vec->offset = (u64) sgl[0].offset & ~MASK_4K;
236 240
237 for (i = 0; i < data->dma_nents; i++) { 241 for_each_sg(sgl, sg, data->dma_nents, i) {
238 unsigned int dma_len = ib_sg_dma_len(ibdev, &sg[i]); 242 unsigned int dma_len = ib_sg_dma_len(ibdev, sg);
239 243
240 total_sz += dma_len; 244 total_sz += dma_len;
241 245
242 first_addr = ib_sg_dma_address(ibdev, &sg[i]); 246 first_addr = ib_sg_dma_address(ibdev, sg);
243 last_addr = first_addr + dma_len; 247 last_addr = first_addr + dma_len;
244 248
245 end_aligned = !(last_addr & ~MASK_4K); 249 end_aligned = !(last_addr & ~MASK_4K);
246 250
247 /* continue to collect page fragments till aligned or SG ends */ 251 /* continue to collect page fragments till aligned or SG ends */
248 while (!end_aligned && (i + 1 < data->dma_nents)) { 252 while (!end_aligned && (i + 1 < data->dma_nents)) {
253 sg = sg_next(sg);
249 i++; 254 i++;
250 dma_len = ib_sg_dma_len(ibdev, &sg[i]); 255 dma_len = ib_sg_dma_len(ibdev, sg);
251 total_sz += dma_len; 256 total_sz += dma_len;
252 last_addr = ib_sg_dma_address(ibdev, &sg[i]) + dma_len; 257 last_addr = ib_sg_dma_address(ibdev, sg) + dma_len;
253 end_aligned = !(last_addr & ~MASK_4K); 258 end_aligned = !(last_addr & ~MASK_4K);
254 } 259 }
255 260
@@ -284,25 +289,26 @@ static int iser_sg_to_page_vec(struct iser_data_buf *data,
284static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data, 289static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data,
285 struct ib_device *ibdev) 290 struct ib_device *ibdev)
286{ 291{
287 struct scatterlist *sg; 292 struct scatterlist *sgl, *sg;
288 u64 end_addr, next_addr; 293 u64 end_addr, next_addr;
289 int i, cnt; 294 int i, cnt;
290 unsigned int ret_len = 0; 295 unsigned int ret_len = 0;
291 296
292 sg = (struct scatterlist *)data->buf; 297 sgl = (struct scatterlist *)data->buf;
293 298
294 for (cnt = 0, i = 0; i < data->dma_nents; i++, cnt++) { 299 cnt = 0;
300 for_each_sg(sgl, sg, data->dma_nents, i) {
295 /* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX " 301 /* iser_dbg("Checking sg iobuf [%d]: phys=0x%08lX "
296 "offset: %ld sz: %ld\n", i, 302 "offset: %ld sz: %ld\n", i,
297 (unsigned long)page_to_phys(sg[i].page), 303 (unsigned long)page_to_phys(sg->page),
298 (unsigned long)sg[i].offset, 304 (unsigned long)sg->offset,
299 (unsigned long)sg[i].length); */ 305 (unsigned long)sg->length); */
300 end_addr = ib_sg_dma_address(ibdev, &sg[i]) + 306 end_addr = ib_sg_dma_address(ibdev, sg) +
301 ib_sg_dma_len(ibdev, &sg[i]); 307 ib_sg_dma_len(ibdev, sg);
302 /* iser_dbg("Checking sg iobuf end address " 308 /* iser_dbg("Checking sg iobuf end address "
303 "0x%08lX\n", end_addr); */ 309 "0x%08lX\n", end_addr); */
304 if (i + 1 < data->dma_nents) { 310 if (i + 1 < data->dma_nents) {
305 next_addr = ib_sg_dma_address(ibdev, &sg[i+1]); 311 next_addr = ib_sg_dma_address(ibdev, sg_next(sg));
306 /* are i, i+1 fragments of the same page? */ 312 /* are i, i+1 fragments of the same page? */
307 if (end_addr == next_addr) 313 if (end_addr == next_addr)
308 continue; 314 continue;
@@ -322,15 +328,16 @@ static unsigned int iser_data_buf_aligned_len(struct iser_data_buf *data,
322static void iser_data_buf_dump(struct iser_data_buf *data, 328static void iser_data_buf_dump(struct iser_data_buf *data,
323 struct ib_device *ibdev) 329 struct ib_device *ibdev)
324{ 330{
325 struct scatterlist *sg = (struct scatterlist *)data->buf; 331 struct scatterlist *sgl = (struct scatterlist *)data->buf;
332 struct scatterlist *sg;
326 int i; 333 int i;
327 334
328 for (i = 0; i < data->dma_nents; i++) 335 for_each_sg(sgl, sg, data->dma_nents, i)
329 iser_err("sg[%d] dma_addr:0x%lX page:0x%p " 336 iser_err("sg[%d] dma_addr:0x%lX page:0x%p "
330 "off:0x%x sz:0x%x dma_len:0x%x\n", 337 "off:0x%x sz:0x%x dma_len:0x%x\n",
331 i, (unsigned long)ib_sg_dma_address(ibdev, &sg[i]), 338 i, (unsigned long)ib_sg_dma_address(ibdev, sg),
332 sg[i].page, sg[i].offset, 339 sg->page, sg->offset,
333 sg[i].length, ib_sg_dma_len(ibdev, &sg[i])); 340 sg->length, ib_sg_dma_len(ibdev, sg));
334} 341}
335 342
336static void iser_dump_page_vec(struct iser_page_vec *page_vec) 343static void iser_dump_page_vec(struct iser_page_vec *page_vec)
diff --git a/drivers/isdn/capi/capidrv.c b/drivers/isdn/capi/capidrv.c
index 23b6f7bc16b7..476012b6dfac 100644
--- a/drivers/isdn/capi/capidrv.c
+++ b/drivers/isdn/capi/capidrv.c
@@ -506,9 +506,14 @@ static void send_message(capidrv_contr * card, _cmsg * cmsg)
506{ 506{
507 struct sk_buff *skb; 507 struct sk_buff *skb;
508 size_t len; 508 size_t len;
509
509 capi_cmsg2message(cmsg, cmsg->buf); 510 capi_cmsg2message(cmsg, cmsg->buf);
510 len = CAPIMSG_LEN(cmsg->buf); 511 len = CAPIMSG_LEN(cmsg->buf);
511 skb = alloc_skb(len, GFP_ATOMIC); 512 skb = alloc_skb(len, GFP_ATOMIC);
513 if (!skb) {
514 printk(KERN_ERR "capidrv::send_message: can't allocate mem\n");
515 return;
516 }
512 memcpy(skb_put(skb, len), cmsg->buf, len); 517 memcpy(skb_put(skb, len), cmsg->buf, len);
513 if (capi20_put_message(&global.ap, skb) != CAPI_NOERROR) 518 if (capi20_put_message(&global.ap, skb) != CAPI_NOERROR)
514 kfree_skb(skb); 519 kfree_skb(skb);
diff --git a/drivers/isdn/capi/kcapi.c b/drivers/isdn/capi/kcapi.c
index 9f73bc2727c2..f55531869313 100644
--- a/drivers/isdn/capi/kcapi.c
+++ b/drivers/isdn/capi/kcapi.c
@@ -821,6 +821,8 @@ static int old_capi_manufacturer(unsigned int cmd, void __user *data)
821 return -EFAULT; 821 return -EFAULT;
822 } 822 }
823 card = get_capi_ctr_by_nr(ldef.contr); 823 card = get_capi_ctr_by_nr(ldef.contr);
824 if (!card)
825 return -EINVAL;
824 card = capi_ctr_get(card); 826 card = capi_ctr_get(card);
825 if (!card) 827 if (!card)
826 return -ESRCH; 828 return -ESRCH;
diff --git a/drivers/isdn/gigaset/bas-gigaset.c b/drivers/isdn/gigaset/bas-gigaset.c
index 00e31609a238..af7648274b38 100644
--- a/drivers/isdn/gigaset/bas-gigaset.c
+++ b/drivers/isdn/gigaset/bas-gigaset.c
@@ -1936,14 +1936,7 @@ static int gigaset_write_room(struct cardstate *cs)
1936 */ 1936 */
1937static int gigaset_chars_in_buffer(struct cardstate *cs) 1937static int gigaset_chars_in_buffer(struct cardstate *cs)
1938{ 1938{
1939 unsigned long flags; 1939 return cs->cmdbytes;
1940 unsigned bytes;
1941
1942 spin_lock_irqsave(&cs->cmdlock, flags);
1943 bytes = cs->cmdbytes;
1944 spin_unlock_irqrestore(&cs->cmdlock, flags);
1945
1946 return bytes;
1947} 1940}
1948 1941
1949/* gigaset_brkchars 1942/* gigaset_brkchars
diff --git a/drivers/isdn/gigaset/i4l.c b/drivers/isdn/gigaset/i4l.c
index 1654fa413575..9e089f06a942 100644
--- a/drivers/isdn/gigaset/i4l.c
+++ b/drivers/isdn/gigaset/i4l.c
@@ -109,13 +109,9 @@ EXPORT_SYMBOL_GPL(gigaset_skb_sent);
109static int command_from_LL(isdn_ctrl *cntrl) 109static int command_from_LL(isdn_ctrl *cntrl)
110{ 110{
111 struct cardstate *cs = gigaset_get_cs_by_id(cntrl->driver); 111 struct cardstate *cs = gigaset_get_cs_by_id(cntrl->driver);
112 //isdn_ctrl response;
113 //unsigned long flags;
114 struct bc_state *bcs; 112 struct bc_state *bcs;
115 int retval = 0; 113 int retval = 0;
116 struct setup_parm *sp; 114 struct setup_parm *sp;
117 unsigned param;
118 unsigned long flags;
119 115
120 gigaset_debugdrivers(); 116 gigaset_debugdrivers();
121 117
@@ -162,12 +158,8 @@ static int command_from_LL(isdn_ctrl *cntrl)
162 } 158 }
163 *sp = cntrl->parm.setup; 159 *sp = cntrl->parm.setup;
164 160
165 spin_lock_irqsave(&cs->lock, flags); 161 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp,
166 param = bcs->at_state.seq_index; 162 bcs->at_state.seq_index, NULL)) {
167 spin_unlock_irqrestore(&cs->lock, flags);
168
169 if (!gigaset_add_event(cs, &bcs->at_state, EV_DIAL, sp, param,
170 NULL)) {
171 //FIXME what should we do? 163 //FIXME what should we do?
172 kfree(sp); 164 kfree(sp);
173 gigaset_free_channel(bcs); 165 gigaset_free_channel(bcs);
diff --git a/drivers/isdn/gigaset/proc.c b/drivers/isdn/gigaset/proc.c
index e767afa55abf..da6f3acf9fd0 100644
--- a/drivers/isdn/gigaset/proc.c
+++ b/drivers/isdn/gigaset/proc.c
@@ -19,15 +19,9 @@
19static ssize_t show_cidmode(struct device *dev, 19static ssize_t show_cidmode(struct device *dev,
20 struct device_attribute *attr, char *buf) 20 struct device_attribute *attr, char *buf)
21{ 21{
22 int ret;
23 unsigned long flags;
24 struct cardstate *cs = dev_get_drvdata(dev); 22 struct cardstate *cs = dev_get_drvdata(dev);
25 23
26 spin_lock_irqsave(&cs->lock, flags); 24 return sprintf(buf, "%u\n", cs->cidmode);
27 ret = sprintf(buf, "%u\n", cs->cidmode);
28 spin_unlock_irqrestore(&cs->lock, flags);
29
30 return ret;
31} 25}
32 26
33static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr, 27static ssize_t set_cidmode(struct device *dev, struct device_attribute *attr,
diff --git a/drivers/isdn/gigaset/usb-gigaset.c b/drivers/isdn/gigaset/usb-gigaset.c
index a1263019df5e..ca4bee173cfb 100644
--- a/drivers/isdn/gigaset/usb-gigaset.c
+++ b/drivers/isdn/gigaset/usb-gigaset.c
@@ -310,7 +310,6 @@ static void gigaset_modem_fill(unsigned long data)
310 struct cardstate *cs = (struct cardstate *) data; 310 struct cardstate *cs = (struct cardstate *) data;
311 struct bc_state *bcs = &cs->bcs[0]; /* only one channel */ 311 struct bc_state *bcs = &cs->bcs[0]; /* only one channel */
312 struct cmdbuf_t *cb; 312 struct cmdbuf_t *cb;
313 unsigned long flags;
314 int again; 313 int again;
315 314
316 gig_dbg(DEBUG_OUTPUT, "modem_fill"); 315 gig_dbg(DEBUG_OUTPUT, "modem_fill");
@@ -323,9 +322,7 @@ static void gigaset_modem_fill(unsigned long data)
323 do { 322 do {
324 again = 0; 323 again = 0;
325 if (!bcs->tx_skb) { /* no skb is being sent */ 324 if (!bcs->tx_skb) { /* no skb is being sent */
326 spin_lock_irqsave(&cs->cmdlock, flags);
327 cb = cs->cmdbuf; 325 cb = cs->cmdbuf;
328 spin_unlock_irqrestore(&cs->cmdlock, flags);
329 if (cb) { /* commands to send? */ 326 if (cb) { /* commands to send? */
330 gig_dbg(DEBUG_OUTPUT, "modem_fill: cb"); 327 gig_dbg(DEBUG_OUTPUT, "modem_fill: cb");
331 if (send_cb(cs, cb) < 0) { 328 if (send_cb(cs, cb) < 0) {
@@ -546,13 +543,9 @@ static int gigaset_write_cmd(struct cardstate *cs, const unsigned char *buf,
546 543
547static int gigaset_write_room(struct cardstate *cs) 544static int gigaset_write_room(struct cardstate *cs)
548{ 545{
549 unsigned long flags;
550 unsigned bytes; 546 unsigned bytes;
551 547
552 spin_lock_irqsave(&cs->cmdlock, flags);
553 bytes = cs->cmdbytes; 548 bytes = cs->cmdbytes;
554 spin_unlock_irqrestore(&cs->cmdlock, flags);
555
556 return bytes < IF_WRITEBUF ? IF_WRITEBUF - bytes : 0; 549 return bytes < IF_WRITEBUF ? IF_WRITEBUF - bytes : 0;
557} 550}
558 551
diff --git a/drivers/isdn/i4l/isdn_common.c b/drivers/isdn/i4l/isdn_common.c
index 4910bca52640..c6df2925ebd0 100644
--- a/drivers/isdn/i4l/isdn_common.c
+++ b/drivers/isdn/i4l/isdn_common.c
@@ -1365,7 +1365,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1365 } else { 1365 } else {
1366 s = NULL; 1366 s = NULL;
1367 } 1367 }
1368 ret = down_interruptible(&dev->sem); 1368 ret = mutex_lock_interruptible(&dev->mtx);
1369 if( ret ) return ret; 1369 if( ret ) return ret;
1370 if ((s = isdn_net_new(s, NULL))) { 1370 if ((s = isdn_net_new(s, NULL))) {
1371 if (copy_to_user(argp, s, strlen(s) + 1)){ 1371 if (copy_to_user(argp, s, strlen(s) + 1)){
@@ -1375,7 +1375,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1375 } 1375 }
1376 } else 1376 } else
1377 ret = -ENODEV; 1377 ret = -ENODEV;
1378 up(&dev->sem); 1378 mutex_unlock(&dev->mtx);
1379 return ret; 1379 return ret;
1380 case IIOCNETASL: 1380 case IIOCNETASL:
1381 /* Add a slave to a network-interface */ 1381 /* Add a slave to a network-interface */
@@ -1384,7 +1384,7 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1384 return -EFAULT; 1384 return -EFAULT;
1385 } else 1385 } else
1386 return -EINVAL; 1386 return -EINVAL;
1387 ret = down_interruptible(&dev->sem); 1387 ret = mutex_lock_interruptible(&dev->mtx);
1388 if( ret ) return ret; 1388 if( ret ) return ret;
1389 if ((s = isdn_net_newslave(bname))) { 1389 if ((s = isdn_net_newslave(bname))) {
1390 if (copy_to_user(argp, s, strlen(s) + 1)){ 1390 if (copy_to_user(argp, s, strlen(s) + 1)){
@@ -1394,17 +1394,17 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1394 } 1394 }
1395 } else 1395 } else
1396 ret = -ENODEV; 1396 ret = -ENODEV;
1397 up(&dev->sem); 1397 mutex_unlock(&dev->mtx);
1398 return ret; 1398 return ret;
1399 case IIOCNETDIF: 1399 case IIOCNETDIF:
1400 /* Delete a network-interface */ 1400 /* Delete a network-interface */
1401 if (arg) { 1401 if (arg) {
1402 if (copy_from_user(name, argp, sizeof(name))) 1402 if (copy_from_user(name, argp, sizeof(name)))
1403 return -EFAULT; 1403 return -EFAULT;
1404 ret = down_interruptible(&dev->sem); 1404 ret = mutex_lock_interruptible(&dev->mtx);
1405 if( ret ) return ret; 1405 if( ret ) return ret;
1406 ret = isdn_net_rm(name); 1406 ret = isdn_net_rm(name);
1407 up(&dev->sem); 1407 mutex_unlock(&dev->mtx);
1408 return ret; 1408 return ret;
1409 } else 1409 } else
1410 return -EINVAL; 1410 return -EINVAL;
@@ -1433,10 +1433,10 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1433 if (arg) { 1433 if (arg) {
1434 if (copy_from_user(&phone, argp, sizeof(phone))) 1434 if (copy_from_user(&phone, argp, sizeof(phone)))
1435 return -EFAULT; 1435 return -EFAULT;
1436 ret = down_interruptible(&dev->sem); 1436 ret = mutex_lock_interruptible(&dev->mtx);
1437 if( ret ) return ret; 1437 if( ret ) return ret;
1438 ret = isdn_net_addphone(&phone); 1438 ret = isdn_net_addphone(&phone);
1439 up(&dev->sem); 1439 mutex_unlock(&dev->mtx);
1440 return ret; 1440 return ret;
1441 } else 1441 } else
1442 return -EINVAL; 1442 return -EINVAL;
@@ -1445,10 +1445,10 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1445 if (arg) { 1445 if (arg) {
1446 if (copy_from_user(&phone, argp, sizeof(phone))) 1446 if (copy_from_user(&phone, argp, sizeof(phone)))
1447 return -EFAULT; 1447 return -EFAULT;
1448 ret = down_interruptible(&dev->sem); 1448 ret = mutex_lock_interruptible(&dev->mtx);
1449 if( ret ) return ret; 1449 if( ret ) return ret;
1450 ret = isdn_net_getphones(&phone, argp); 1450 ret = isdn_net_getphones(&phone, argp);
1451 up(&dev->sem); 1451 mutex_unlock(&dev->mtx);
1452 return ret; 1452 return ret;
1453 } else 1453 } else
1454 return -EINVAL; 1454 return -EINVAL;
@@ -1457,10 +1457,10 @@ isdn_ioctl(struct inode *inode, struct file *file, uint cmd, ulong arg)
1457 if (arg) { 1457 if (arg) {
1458 if (copy_from_user(&phone, argp, sizeof(phone))) 1458 if (copy_from_user(&phone, argp, sizeof(phone)))
1459 return -EFAULT; 1459 return -EFAULT;
1460 ret = down_interruptible(&dev->sem); 1460 ret = mutex_lock_interruptible(&dev->mtx);
1461 if( ret ) return ret; 1461 if( ret ) return ret;
1462 ret = isdn_net_delphone(&phone); 1462 ret = isdn_net_delphone(&phone);
1463 up(&dev->sem); 1463 mutex_unlock(&dev->mtx);
1464 return ret; 1464 return ret;
1465 } else 1465 } else
1466 return -EINVAL; 1466 return -EINVAL;
@@ -2304,7 +2304,7 @@ static int __init isdn_init(void)
2304#ifdef MODULE 2304#ifdef MODULE
2305 dev->owner = THIS_MODULE; 2305 dev->owner = THIS_MODULE;
2306#endif 2306#endif
2307 init_MUTEX(&dev->sem); 2307 mutex_init(&dev->mtx);
2308 init_waitqueue_head(&dev->info_waitq); 2308 init_waitqueue_head(&dev->info_waitq);
2309 for (i = 0; i < ISDN_MAX_CHANNELS; i++) { 2309 for (i = 0; i < ISDN_MAX_CHANNELS; i++) {
2310 dev->drvmap[i] = -1; 2310 dev->drvmap[i] = -1;
diff --git a/drivers/md/dm-crypt.c b/drivers/md/dm-crypt.c
index 8216a6f75be5..64fee90bb68b 100644
--- a/drivers/md/dm-crypt.c
+++ b/drivers/md/dm-crypt.c
@@ -441,33 +441,12 @@ static struct bio *crypt_alloc_buffer(struct dm_crypt_io *io, unsigned size)
441 return clone; 441 return clone;
442} 442}
443 443
444static void crypt_free_buffer_pages(struct crypt_config *cc, 444static void crypt_free_buffer_pages(struct crypt_config *cc, struct bio *clone)
445 struct bio *clone, unsigned int bytes)
446{ 445{
447 unsigned int i, start, end; 446 unsigned int i;
448 struct bio_vec *bv; 447 struct bio_vec *bv;
449 448
450 /* 449 for (i = 0; i < clone->bi_vcnt; i++) {
451 * This is ugly, but Jens Axboe thinks that using bi_idx in the
452 * endio function is too dangerous at the moment, so I calculate the
453 * correct position using bi_vcnt and bi_size.
454 * The bv_offset and bv_len fields might already be modified but we
455 * know that we always allocated whole pages.
456 * A fix to the bi_idx issue in the kernel is in the works, so
457 * we will hopefully be able to revert to the cleaner solution soon.
458 */
459 i = clone->bi_vcnt - 1;
460 bv = bio_iovec_idx(clone, i);
461 end = (i << PAGE_SHIFT) + (bv->bv_offset + bv->bv_len) - clone->bi_size;
462 start = end - bytes;
463
464 start >>= PAGE_SHIFT;
465 if (!clone->bi_size)
466 end = clone->bi_vcnt;
467 else
468 end >>= PAGE_SHIFT;
469
470 for (i = start; i < end; i++) {
471 bv = bio_iovec_idx(clone, i); 450 bv = bio_iovec_idx(clone, i);
472 BUG_ON(!bv->bv_page); 451 BUG_ON(!bv->bv_page);
473 mempool_free(bv->bv_page, cc->page_pool); 452 mempool_free(bv->bv_page, cc->page_pool);
@@ -519,7 +498,7 @@ static void crypt_endio(struct bio *clone, int error)
519 * free the processed pages 498 * free the processed pages
520 */ 499 */
521 if (!read_io) { 500 if (!read_io) {
522 crypt_free_buffer_pages(cc, clone, clone->bi_size); 501 crypt_free_buffer_pages(cc, clone);
523 goto out; 502 goto out;
524 } 503 }
525 504
@@ -608,7 +587,7 @@ static void process_write(struct dm_crypt_io *io)
608 ctx.idx_out = 0; 587 ctx.idx_out = 0;
609 588
610 if (unlikely(crypt_convert(cc, &ctx) < 0)) { 589 if (unlikely(crypt_convert(cc, &ctx) < 0)) {
611 crypt_free_buffer_pages(cc, clone, clone->bi_size); 590 crypt_free_buffer_pages(cc, clone);
612 bio_put(clone); 591 bio_put(clone);
613 dec_pending(io, -EIO); 592 dec_pending(io, -EIO);
614 return; 593 return;
diff --git a/drivers/md/dm-table.c b/drivers/md/dm-table.c
index 2bcde5798b5a..fbe477bb2c68 100644
--- a/drivers/md/dm-table.c
+++ b/drivers/md/dm-table.c
@@ -999,33 +999,6 @@ void dm_table_unplug_all(struct dm_table *t)
999 } 999 }
1000} 1000}
1001 1001
1002int dm_table_flush_all(struct dm_table *t)
1003{
1004 struct list_head *d, *devices = dm_table_get_devices(t);
1005 int ret = 0;
1006 unsigned i;
1007
1008 for (i = 0; i < t->num_targets; i++)
1009 if (t->targets[i].type->flush)
1010 t->targets[i].type->flush(&t->targets[i]);
1011
1012 for (d = devices->next; d != devices; d = d->next) {
1013 struct dm_dev *dd = list_entry(d, struct dm_dev, list);
1014 struct request_queue *q = bdev_get_queue(dd->bdev);
1015 int err;
1016
1017 if (!q->issue_flush_fn)
1018 err = -EOPNOTSUPP;
1019 else
1020 err = q->issue_flush_fn(q, dd->bdev->bd_disk, NULL);
1021
1022 if (!ret)
1023 ret = err;
1024 }
1025
1026 return ret;
1027}
1028
1029struct mapped_device *dm_table_get_md(struct dm_table *t) 1002struct mapped_device *dm_table_get_md(struct dm_table *t)
1030{ 1003{
1031 dm_get(t->md); 1004 dm_get(t->md);
@@ -1043,4 +1016,3 @@ EXPORT_SYMBOL(dm_table_get_md);
1043EXPORT_SYMBOL(dm_table_put); 1016EXPORT_SYMBOL(dm_table_put);
1044EXPORT_SYMBOL(dm_table_get); 1017EXPORT_SYMBOL(dm_table_get);
1045EXPORT_SYMBOL(dm_table_unplug_all); 1018EXPORT_SYMBOL(dm_table_unplug_all);
1046EXPORT_SYMBOL(dm_table_flush_all);
diff --git a/drivers/md/dm.c b/drivers/md/dm.c
index 167765c47747..d837d37f6209 100644
--- a/drivers/md/dm.c
+++ b/drivers/md/dm.c
@@ -840,21 +840,6 @@ static int dm_request(struct request_queue *q, struct bio *bio)
840 return 0; 840 return 0;
841} 841}
842 842
843static int dm_flush_all(struct request_queue *q, struct gendisk *disk,
844 sector_t *error_sector)
845{
846 struct mapped_device *md = q->queuedata;
847 struct dm_table *map = dm_get_table(md);
848 int ret = -ENXIO;
849
850 if (map) {
851 ret = dm_table_flush_all(map);
852 dm_table_put(map);
853 }
854
855 return ret;
856}
857
858static void dm_unplug_all(struct request_queue *q) 843static void dm_unplug_all(struct request_queue *q)
859{ 844{
860 struct mapped_device *md = q->queuedata; 845 struct mapped_device *md = q->queuedata;
@@ -1003,7 +988,6 @@ static struct mapped_device *alloc_dev(int minor)
1003 blk_queue_make_request(md->queue, dm_request); 988 blk_queue_make_request(md->queue, dm_request);
1004 blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY); 989 blk_queue_bounce_limit(md->queue, BLK_BOUNCE_ANY);
1005 md->queue->unplug_fn = dm_unplug_all; 990 md->queue->unplug_fn = dm_unplug_all;
1006 md->queue->issue_flush_fn = dm_flush_all;
1007 991
1008 md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache); 992 md->io_pool = mempool_create_slab_pool(MIN_IOS, _io_cache);
1009 if (!md->io_pool) 993 if (!md->io_pool)
diff --git a/drivers/md/dm.h b/drivers/md/dm.h
index 462ee652a890..4b3faa45277e 100644
--- a/drivers/md/dm.h
+++ b/drivers/md/dm.h
@@ -111,7 +111,6 @@ void dm_table_postsuspend_targets(struct dm_table *t);
111int dm_table_resume_targets(struct dm_table *t); 111int dm_table_resume_targets(struct dm_table *t);
112int dm_table_any_congested(struct dm_table *t, int bdi_bits); 112int dm_table_any_congested(struct dm_table *t, int bdi_bits);
113void dm_table_unplug_all(struct dm_table *t); 113void dm_table_unplug_all(struct dm_table *t);
114int dm_table_flush_all(struct dm_table *t);
115 114
116/*----------------------------------------------------------------- 115/*-----------------------------------------------------------------
117 * A registry of target types. 116 * A registry of target types.
diff --git a/drivers/md/linear.c b/drivers/md/linear.c
index 550148770bb2..56a11f6c127b 100644
--- a/drivers/md/linear.c
+++ b/drivers/md/linear.c
@@ -92,25 +92,6 @@ static void linear_unplug(struct request_queue *q)
92 } 92 }
93} 93}
94 94
95static int linear_issue_flush(struct request_queue *q, struct gendisk *disk,
96 sector_t *error_sector)
97{
98 mddev_t *mddev = q->queuedata;
99 linear_conf_t *conf = mddev_to_conf(mddev);
100 int i, ret = 0;
101
102 for (i=0; i < mddev->raid_disks && ret == 0; i++) {
103 struct block_device *bdev = conf->disks[i].rdev->bdev;
104 struct request_queue *r_queue = bdev_get_queue(bdev);
105
106 if (!r_queue->issue_flush_fn)
107 ret = -EOPNOTSUPP;
108 else
109 ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk, error_sector);
110 }
111 return ret;
112}
113
114static int linear_congested(void *data, int bits) 95static int linear_congested(void *data, int bits)
115{ 96{
116 mddev_t *mddev = data; 97 mddev_t *mddev = data;
@@ -279,7 +260,6 @@ static int linear_run (mddev_t *mddev)
279 260
280 blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec); 261 blk_queue_merge_bvec(mddev->queue, linear_mergeable_bvec);
281 mddev->queue->unplug_fn = linear_unplug; 262 mddev->queue->unplug_fn = linear_unplug;
282 mddev->queue->issue_flush_fn = linear_issue_flush;
283 mddev->queue->backing_dev_info.congested_fn = linear_congested; 263 mddev->queue->backing_dev_info.congested_fn = linear_congested;
284 mddev->queue->backing_dev_info.congested_data = mddev; 264 mddev->queue->backing_dev_info.congested_data = mddev;
285 return 0; 265 return 0;
diff --git a/drivers/md/md.c b/drivers/md/md.c
index acf1b81b47cb..0dc563d76b39 100644
--- a/drivers/md/md.c
+++ b/drivers/md/md.c
@@ -3463,7 +3463,6 @@ static int do_md_stop(mddev_t * mddev, int mode)
3463 mddev->pers->stop(mddev); 3463 mddev->pers->stop(mddev);
3464 mddev->queue->merge_bvec_fn = NULL; 3464 mddev->queue->merge_bvec_fn = NULL;
3465 mddev->queue->unplug_fn = NULL; 3465 mddev->queue->unplug_fn = NULL;
3466 mddev->queue->issue_flush_fn = NULL;
3467 mddev->queue->backing_dev_info.congested_fn = NULL; 3466 mddev->queue->backing_dev_info.congested_fn = NULL;
3468 if (mddev->pers->sync_request) 3467 if (mddev->pers->sync_request)
3469 sysfs_remove_group(&mddev->kobj, &md_redundancy_group); 3468 sysfs_remove_group(&mddev->kobj, &md_redundancy_group);
diff --git a/drivers/md/multipath.c b/drivers/md/multipath.c
index f2a63f394ad9..b35731cceac6 100644
--- a/drivers/md/multipath.c
+++ b/drivers/md/multipath.c
@@ -194,35 +194,6 @@ static void multipath_status (struct seq_file *seq, mddev_t *mddev)
194 seq_printf (seq, "]"); 194 seq_printf (seq, "]");
195} 195}
196 196
197static int multipath_issue_flush(struct request_queue *q, struct gendisk *disk,
198 sector_t *error_sector)
199{
200 mddev_t *mddev = q->queuedata;
201 multipath_conf_t *conf = mddev_to_conf(mddev);
202 int i, ret = 0;
203
204 rcu_read_lock();
205 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
206 mdk_rdev_t *rdev = rcu_dereference(conf->multipaths[i].rdev);
207 if (rdev && !test_bit(Faulty, &rdev->flags)) {
208 struct block_device *bdev = rdev->bdev;
209 struct request_queue *r_queue = bdev_get_queue(bdev);
210
211 if (!r_queue->issue_flush_fn)
212 ret = -EOPNOTSUPP;
213 else {
214 atomic_inc(&rdev->nr_pending);
215 rcu_read_unlock();
216 ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk,
217 error_sector);
218 rdev_dec_pending(rdev, mddev);
219 rcu_read_lock();
220 }
221 }
222 }
223 rcu_read_unlock();
224 return ret;
225}
226static int multipath_congested(void *data, int bits) 197static int multipath_congested(void *data, int bits)
227{ 198{
228 mddev_t *mddev = data; 199 mddev_t *mddev = data;
@@ -527,7 +498,6 @@ static int multipath_run (mddev_t *mddev)
527 mddev->array_size = mddev->size; 498 mddev->array_size = mddev->size;
528 499
529 mddev->queue->unplug_fn = multipath_unplug; 500 mddev->queue->unplug_fn = multipath_unplug;
530 mddev->queue->issue_flush_fn = multipath_issue_flush;
531 mddev->queue->backing_dev_info.congested_fn = multipath_congested; 501 mddev->queue->backing_dev_info.congested_fn = multipath_congested;
532 mddev->queue->backing_dev_info.congested_data = mddev; 502 mddev->queue->backing_dev_info.congested_data = mddev;
533 503
diff --git a/drivers/md/raid0.c b/drivers/md/raid0.c
index ef0da2d84959..e79e1a538d44 100644
--- a/drivers/md/raid0.c
+++ b/drivers/md/raid0.c
@@ -40,26 +40,6 @@ static void raid0_unplug(struct request_queue *q)
40 } 40 }
41} 41}
42 42
43static int raid0_issue_flush(struct request_queue *q, struct gendisk *disk,
44 sector_t *error_sector)
45{
46 mddev_t *mddev = q->queuedata;
47 raid0_conf_t *conf = mddev_to_conf(mddev);
48 mdk_rdev_t **devlist = conf->strip_zone[0].dev;
49 int i, ret = 0;
50
51 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
52 struct block_device *bdev = devlist[i]->bdev;
53 struct request_queue *r_queue = bdev_get_queue(bdev);
54
55 if (!r_queue->issue_flush_fn)
56 ret = -EOPNOTSUPP;
57 else
58 ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk, error_sector);
59 }
60 return ret;
61}
62
63static int raid0_congested(void *data, int bits) 43static int raid0_congested(void *data, int bits)
64{ 44{
65 mddev_t *mddev = data; 45 mddev_t *mddev = data;
@@ -250,7 +230,6 @@ static int create_strip_zones (mddev_t *mddev)
250 230
251 mddev->queue->unplug_fn = raid0_unplug; 231 mddev->queue->unplug_fn = raid0_unplug;
252 232
253 mddev->queue->issue_flush_fn = raid0_issue_flush;
254 mddev->queue->backing_dev_info.congested_fn = raid0_congested; 233 mddev->queue->backing_dev_info.congested_fn = raid0_congested;
255 mddev->queue->backing_dev_info.congested_data = mddev; 234 mddev->queue->backing_dev_info.congested_data = mddev;
256 235
diff --git a/drivers/md/raid1.c b/drivers/md/raid1.c
index 6d03bea6fa58..0bcefad82413 100644
--- a/drivers/md/raid1.c
+++ b/drivers/md/raid1.c
@@ -567,36 +567,6 @@ static void raid1_unplug(struct request_queue *q)
567 md_wakeup_thread(mddev->thread); 567 md_wakeup_thread(mddev->thread);
568} 568}
569 569
570static int raid1_issue_flush(struct request_queue *q, struct gendisk *disk,
571 sector_t *error_sector)
572{
573 mddev_t *mddev = q->queuedata;
574 conf_t *conf = mddev_to_conf(mddev);
575 int i, ret = 0;
576
577 rcu_read_lock();
578 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
579 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
580 if (rdev && !test_bit(Faulty, &rdev->flags)) {
581 struct block_device *bdev = rdev->bdev;
582 struct request_queue *r_queue = bdev_get_queue(bdev);
583
584 if (!r_queue->issue_flush_fn)
585 ret = -EOPNOTSUPP;
586 else {
587 atomic_inc(&rdev->nr_pending);
588 rcu_read_unlock();
589 ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk,
590 error_sector);
591 rdev_dec_pending(rdev, mddev);
592 rcu_read_lock();
593 }
594 }
595 }
596 rcu_read_unlock();
597 return ret;
598}
599
600static int raid1_congested(void *data, int bits) 570static int raid1_congested(void *data, int bits)
601{ 571{
602 mddev_t *mddev = data; 572 mddev_t *mddev = data;
@@ -1997,7 +1967,6 @@ static int run(mddev_t *mddev)
1997 mddev->array_size = mddev->size; 1967 mddev->array_size = mddev->size;
1998 1968
1999 mddev->queue->unplug_fn = raid1_unplug; 1969 mddev->queue->unplug_fn = raid1_unplug;
2000 mddev->queue->issue_flush_fn = raid1_issue_flush;
2001 mddev->queue->backing_dev_info.congested_fn = raid1_congested; 1970 mddev->queue->backing_dev_info.congested_fn = raid1_congested;
2002 mddev->queue->backing_dev_info.congested_data = mddev; 1971 mddev->queue->backing_dev_info.congested_data = mddev;
2003 1972
diff --git a/drivers/md/raid10.c b/drivers/md/raid10.c
index 25a96c42bdb0..fc6607acb6e4 100644
--- a/drivers/md/raid10.c
+++ b/drivers/md/raid10.c
@@ -611,36 +611,6 @@ static void raid10_unplug(struct request_queue *q)
611 md_wakeup_thread(mddev->thread); 611 md_wakeup_thread(mddev->thread);
612} 612}
613 613
614static int raid10_issue_flush(struct request_queue *q, struct gendisk *disk,
615 sector_t *error_sector)
616{
617 mddev_t *mddev = q->queuedata;
618 conf_t *conf = mddev_to_conf(mddev);
619 int i, ret = 0;
620
621 rcu_read_lock();
622 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
623 mdk_rdev_t *rdev = rcu_dereference(conf->mirrors[i].rdev);
624 if (rdev && !test_bit(Faulty, &rdev->flags)) {
625 struct block_device *bdev = rdev->bdev;
626 struct request_queue *r_queue = bdev_get_queue(bdev);
627
628 if (!r_queue->issue_flush_fn)
629 ret = -EOPNOTSUPP;
630 else {
631 atomic_inc(&rdev->nr_pending);
632 rcu_read_unlock();
633 ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk,
634 error_sector);
635 rdev_dec_pending(rdev, mddev);
636 rcu_read_lock();
637 }
638 }
639 }
640 rcu_read_unlock();
641 return ret;
642}
643
644static int raid10_congested(void *data, int bits) 614static int raid10_congested(void *data, int bits)
645{ 615{
646 mddev_t *mddev = data; 616 mddev_t *mddev = data;
@@ -2118,7 +2088,6 @@ static int run(mddev_t *mddev)
2118 mddev->resync_max_sectors = size << conf->chunk_shift; 2088 mddev->resync_max_sectors = size << conf->chunk_shift;
2119 2089
2120 mddev->queue->unplug_fn = raid10_unplug; 2090 mddev->queue->unplug_fn = raid10_unplug;
2121 mddev->queue->issue_flush_fn = raid10_issue_flush;
2122 mddev->queue->backing_dev_info.congested_fn = raid10_congested; 2091 mddev->queue->backing_dev_info.congested_fn = raid10_congested;
2123 mddev->queue->backing_dev_info.congested_data = mddev; 2092 mddev->queue->backing_dev_info.congested_data = mddev;
2124 2093
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index caaca9e178bc..8ee181a01f52 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -3204,36 +3204,6 @@ static void raid5_unplug_device(struct request_queue *q)
3204 unplug_slaves(mddev); 3204 unplug_slaves(mddev);
3205} 3205}
3206 3206
3207static int raid5_issue_flush(struct request_queue *q, struct gendisk *disk,
3208 sector_t *error_sector)
3209{
3210 mddev_t *mddev = q->queuedata;
3211 raid5_conf_t *conf = mddev_to_conf(mddev);
3212 int i, ret = 0;
3213
3214 rcu_read_lock();
3215 for (i=0; i<mddev->raid_disks && ret == 0; i++) {
3216 mdk_rdev_t *rdev = rcu_dereference(conf->disks[i].rdev);
3217 if (rdev && !test_bit(Faulty, &rdev->flags)) {
3218 struct block_device *bdev = rdev->bdev;
3219 struct request_queue *r_queue = bdev_get_queue(bdev);
3220
3221 if (!r_queue->issue_flush_fn)
3222 ret = -EOPNOTSUPP;
3223 else {
3224 atomic_inc(&rdev->nr_pending);
3225 rcu_read_unlock();
3226 ret = r_queue->issue_flush_fn(r_queue, bdev->bd_disk,
3227 error_sector);
3228 rdev_dec_pending(rdev, mddev);
3229 rcu_read_lock();
3230 }
3231 }
3232 }
3233 rcu_read_unlock();
3234 return ret;
3235}
3236
3237static int raid5_congested(void *data, int bits) 3207static int raid5_congested(void *data, int bits)
3238{ 3208{
3239 mddev_t *mddev = data; 3209 mddev_t *mddev = data;
@@ -4263,7 +4233,6 @@ static int run(mddev_t *mddev)
4263 mdname(mddev)); 4233 mdname(mddev));
4264 4234
4265 mddev->queue->unplug_fn = raid5_unplug_device; 4235 mddev->queue->unplug_fn = raid5_unplug_device;
4266 mddev->queue->issue_flush_fn = raid5_issue_flush;
4267 mddev->queue->backing_dev_info.congested_data = mddev; 4236 mddev->queue->backing_dev_info.congested_data = mddev;
4268 mddev->queue->backing_dev_info.congested_fn = raid5_congested; 4237 mddev->queue->backing_dev_info.congested_fn = raid5_congested;
4269 4238
diff --git a/drivers/message/fusion/mptscsih.c b/drivers/message/fusion/mptscsih.c
index bdff950a54a1..626bb3c9af2b 100644
--- a/drivers/message/fusion/mptscsih.c
+++ b/drivers/message/fusion/mptscsih.c
@@ -293,7 +293,7 @@ nextSGEset:
293 for (ii=0; ii < (numSgeThisFrame-1); ii++) { 293 for (ii=0; ii < (numSgeThisFrame-1); ii++) {
294 thisxfer = sg_dma_len(sg); 294 thisxfer = sg_dma_len(sg);
295 if (thisxfer == 0) { 295 if (thisxfer == 0) {
296 sg ++; /* Get next SG element from the OS */ 296 sg = sg_next(sg); /* Get next SG element from the OS */
297 sg_done++; 297 sg_done++;
298 continue; 298 continue;
299 } 299 }
@@ -301,7 +301,7 @@ nextSGEset:
301 v2 = sg_dma_address(sg); 301 v2 = sg_dma_address(sg);
302 mptscsih_add_sge(psge, sgflags | thisxfer, v2); 302 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
303 303
304 sg++; /* Get next SG element from the OS */ 304 sg = sg_next(sg); /* Get next SG element from the OS */
305 psge += (sizeof(u32) + sizeof(dma_addr_t)); 305 psge += (sizeof(u32) + sizeof(dma_addr_t));
306 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t)); 306 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
307 sg_done++; 307 sg_done++;
@@ -322,7 +322,7 @@ nextSGEset:
322 v2 = sg_dma_address(sg); 322 v2 = sg_dma_address(sg);
323 mptscsih_add_sge(psge, sgflags | thisxfer, v2); 323 mptscsih_add_sge(psge, sgflags | thisxfer, v2);
324 /* 324 /*
325 sg++; 325 sg = sg_next(sg);
326 psge += (sizeof(u32) + sizeof(dma_addr_t)); 326 psge += (sizeof(u32) + sizeof(dma_addr_t));
327 */ 327 */
328 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t)); 328 sgeOffset += (sizeof(u32) + sizeof(dma_addr_t));
@@ -2605,14 +2605,10 @@ mptscsih_set_scsi_lookup(MPT_ADAPTER *ioc, int i, struct scsi_cmnd *scmd)
2605} 2605}
2606 2606
2607/** 2607/**
2608 * SCPNT_TO_LOOKUP_IDX 2608 * SCPNT_TO_LOOKUP_IDX - searches for a given scmd in the ScsiLookup[] array list
2609 *
2610 * search's for a given scmd in the ScsiLookup[] array list
2611 *
2612 * @ioc: Pointer to MPT_ADAPTER structure 2609 * @ioc: Pointer to MPT_ADAPTER structure
2613 * @scmd: scsi_cmnd pointer 2610 * @sc: scsi_cmnd pointer
2614 * 2611 */
2615 **/
2616static int 2612static int
2617SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc) 2613SCPNT_TO_LOOKUP_IDX(MPT_ADAPTER *ioc, struct scsi_cmnd *sc)
2618{ 2614{
diff --git a/drivers/message/i2o/i2o_block.c b/drivers/message/i2o/i2o_block.c
index 50b2c7334410..d602ba6d5417 100644
--- a/drivers/message/i2o/i2o_block.c
+++ b/drivers/message/i2o/i2o_block.c
@@ -149,29 +149,6 @@ static int i2o_block_device_flush(struct i2o_device *dev)
149}; 149};
150 150
151/** 151/**
152 * i2o_block_issue_flush - device-flush interface for block-layer
153 * @queue: the request queue of the device which should be flushed
154 * @disk: gendisk
155 * @error_sector: error offset
156 *
157 * Helper function to provide flush functionality to block-layer.
158 *
159 * Returns 0 on success or negative error code on failure.
160 */
161
162static int i2o_block_issue_flush(struct request_queue * queue, struct gendisk *disk,
163 sector_t * error_sector)
164{
165 struct i2o_block_device *i2o_blk_dev = queue->queuedata;
166 int rc = -ENODEV;
167
168 if (likely(i2o_blk_dev))
169 rc = i2o_block_device_flush(i2o_blk_dev->i2o_dev);
170
171 return rc;
172}
173
174/**
175 * i2o_block_device_mount - Mount (load) the media of device dev 152 * i2o_block_device_mount - Mount (load) the media of device dev
176 * @dev: I2O device which should receive the mount request 153 * @dev: I2O device which should receive the mount request
177 * @media_id: Media Identifier 154 * @media_id: Media Identifier
@@ -1009,7 +986,6 @@ static struct i2o_block_device *i2o_block_device_alloc(void)
1009 } 986 }
1010 987
1011 blk_queue_prep_rq(queue, i2o_block_prep_req_fn); 988 blk_queue_prep_rq(queue, i2o_block_prep_req_fn);
1012 blk_queue_issue_flush_fn(queue, i2o_block_issue_flush);
1013 989
1014 gd->major = I2O_MAJOR; 990 gd->major = I2O_MAJOR;
1015 gd->queue = queue; 991 gd->queue = queue;
diff --git a/drivers/mmc/card/queue.c b/drivers/mmc/card/queue.c
index b0abc7d92805..a5d0354bbbda 100644
--- a/drivers/mmc/card/queue.c
+++ b/drivers/mmc/card/queue.c
@@ -153,14 +153,14 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
153 blk_queue_max_hw_segments(mq->queue, bouncesz / 512); 153 blk_queue_max_hw_segments(mq->queue, bouncesz / 512);
154 blk_queue_max_segment_size(mq->queue, bouncesz); 154 blk_queue_max_segment_size(mq->queue, bouncesz);
155 155
156 mq->sg = kmalloc(sizeof(struct scatterlist), 156 mq->sg = kzalloc(sizeof(struct scatterlist),
157 GFP_KERNEL); 157 GFP_KERNEL);
158 if (!mq->sg) { 158 if (!mq->sg) {
159 ret = -ENOMEM; 159 ret = -ENOMEM;
160 goto cleanup_queue; 160 goto cleanup_queue;
161 } 161 }
162 162
163 mq->bounce_sg = kmalloc(sizeof(struct scatterlist) * 163 mq->bounce_sg = kzalloc(sizeof(struct scatterlist) *
164 bouncesz / 512, GFP_KERNEL); 164 bouncesz / 512, GFP_KERNEL);
165 if (!mq->bounce_sg) { 165 if (!mq->bounce_sg) {
166 ret = -ENOMEM; 166 ret = -ENOMEM;
@@ -177,7 +177,7 @@ int mmc_init_queue(struct mmc_queue *mq, struct mmc_card *card, spinlock_t *lock
177 blk_queue_max_hw_segments(mq->queue, host->max_hw_segs); 177 blk_queue_max_hw_segments(mq->queue, host->max_hw_segs);
178 blk_queue_max_segment_size(mq->queue, host->max_seg_size); 178 blk_queue_max_segment_size(mq->queue, host->max_seg_size);
179 179
180 mq->sg = kmalloc(sizeof(struct scatterlist) * 180 mq->sg = kzalloc(sizeof(struct scatterlist) *
181 host->max_phys_segs, GFP_KERNEL); 181 host->max_phys_segs, GFP_KERNEL);
182 if (!mq->sg) { 182 if (!mq->sg) {
183 ret = -ENOMEM; 183 ret = -ENOMEM;
diff --git a/drivers/mmc/host/mmc_spi.c b/drivers/mmc/host/mmc_spi.c
index 254b194e7625..71b986b38c55 100644
--- a/drivers/mmc/host/mmc_spi.c
+++ b/drivers/mmc/host/mmc_spi.c
@@ -1280,8 +1280,8 @@ static int mmc_spi_probe(struct spi_device *spi)
1280 if (!host->data) 1280 if (!host->data)
1281 goto fail_nobuf1; 1281 goto fail_nobuf1;
1282 1282
1283 if (spi->master->cdev.dev->dma_mask) { 1283 if (spi->master->dev.parent->dma_mask) {
1284 struct device *dev = spi->master->cdev.dev; 1284 struct device *dev = spi->master->dev.parent;
1285 1285
1286 host->dma_dev = dev; 1286 host->dma_dev = dev;
1287 host->ones_dma = dma_map_single(dev, ones, 1287 host->ones_dma = dma_map_single(dev, ones,
diff --git a/drivers/pcmcia/Kconfig b/drivers/pcmcia/Kconfig
index c0c77f82d051..f201bd673137 100644
--- a/drivers/pcmcia/Kconfig
+++ b/drivers/pcmcia/Kconfig
@@ -2,9 +2,7 @@
2# PCCARD (PCMCIA/CardBus) bus subsystem configuration 2# PCCARD (PCMCIA/CardBus) bus subsystem configuration
3# 3#
4 4
5menu "PCCARD (PCMCIA/CardBus) support" 5menuconfig PCCARD
6
7config PCCARD
8 tristate "PCCard (PCMCIA/CardBus) support" 6 tristate "PCCard (PCMCIA/CardBus) support"
9 depends on HOTPLUG 7 depends on HOTPLUG
10 ---help--- 8 ---help---
@@ -278,5 +276,3 @@ config PCCARD_IODYN
278 bool 276 bool
279 277
280endif # PCCARD 278endif # PCCARD
281
282endmenu
diff --git a/drivers/pcmcia/au1000_xxs1500.c b/drivers/pcmcia/au1000_xxs1500.c
index 01874b0bb03b..ce9d5c44a7b5 100644
--- a/drivers/pcmcia/au1000_xxs1500.c
+++ b/drivers/pcmcia/au1000_xxs1500.c
@@ -50,7 +50,10 @@
50 50
51#include <asm/au1000.h> 51#include <asm/au1000.h>
52#include <asm/au1000_pcmcia.h> 52#include <asm/au1000_pcmcia.h>
53#include <asm/xxs1500.h> 53
54#define PCMCIA_MAX_SOCK 0
55#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK + 1)
56#define PCMCIA_IRQ AU1000_GPIO_4
54 57
55#if 0 58#if 0
56#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args) 59#define DEBUG(x,args...) printk(__FUNCTION__ ": " x,##args)
diff --git a/drivers/pcmcia/cistpl.c b/drivers/pcmcia/cistpl.c
index d154dee76e7f..06a85d7d5aa2 100644
--- a/drivers/pcmcia/cistpl.c
+++ b/drivers/pcmcia/cistpl.c
@@ -25,6 +25,7 @@
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <asm/io.h> 26#include <asm/io.h>
27#include <asm/byteorder.h> 27#include <asm/byteorder.h>
28#include <asm/unaligned.h>
28 29
29#include <pcmcia/cs_types.h> 30#include <pcmcia/cs_types.h>
30#include <pcmcia/ss.h> 31#include <pcmcia/ss.h>
@@ -401,6 +402,15 @@ EXPORT_SYMBOL(pcmcia_replace_cis);
401 402
402======================================================================*/ 403======================================================================*/
403 404
405static inline u16 cis_get_u16(void *ptr)
406{
407 return le16_to_cpu(get_unaligned((__le16 *) ptr));
408}
409static inline u32 cis_get_u32(void *ptr)
410{
411 return le32_to_cpu(get_unaligned((__le32 *) ptr));
412}
413
404typedef struct tuple_flags { 414typedef struct tuple_flags {
405 u_int link_space:4; 415 u_int link_space:4;
406 u_int has_link:1; 416 u_int has_link:1;
@@ -461,7 +471,7 @@ static int follow_link(struct pcmcia_socket *s, tuple_t *tuple)
461 /* Get indirect link from the MFC tuple */ 471 /* Get indirect link from the MFC tuple */
462 read_cis_cache(s, LINK_SPACE(tuple->Flags), 472 read_cis_cache(s, LINK_SPACE(tuple->Flags),
463 tuple->LinkOffset, 5, link); 473 tuple->LinkOffset, 5, link);
464 ofs = le32_to_cpu(*(__le32 *)(link+1)); 474 ofs = cis_get_u32(link + 1);
465 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR); 475 SPACE(tuple->Flags) = (link[0] == CISTPL_MFC_ATTR);
466 /* Move to the next indirect link */ 476 /* Move to the next indirect link */
467 tuple->LinkOffset += 5; 477 tuple->LinkOffset += 5;
@@ -668,10 +678,10 @@ static int parse_checksum(tuple_t *tuple, cistpl_checksum_t *csum)
668 u_char *p; 678 u_char *p;
669 if (tuple->TupleDataLen < 5) 679 if (tuple->TupleDataLen < 5)
670 return CS_BAD_TUPLE; 680 return CS_BAD_TUPLE;
671 p = (u_char *)tuple->TupleData; 681 p = (u_char *) tuple->TupleData;
672 csum->addr = tuple->CISOffset+(short)le16_to_cpu(*(__le16 *)p)-2; 682 csum->addr = tuple->CISOffset + cis_get_u16(p) - 2;
673 csum->len = le16_to_cpu(*(__le16 *)(p + 2)); 683 csum->len = cis_get_u16(p + 2);
674 csum->sum = *(p+4); 684 csum->sum = *(p + 4);
675 return CS_SUCCESS; 685 return CS_SUCCESS;
676} 686}
677 687
@@ -681,7 +691,7 @@ static int parse_longlink(tuple_t *tuple, cistpl_longlink_t *link)
681{ 691{
682 if (tuple->TupleDataLen < 4) 692 if (tuple->TupleDataLen < 4)
683 return CS_BAD_TUPLE; 693 return CS_BAD_TUPLE;
684 link->addr = le32_to_cpu(*(__le32 *)tuple->TupleData); 694 link->addr = cis_get_u32(tuple->TupleData);
685 return CS_SUCCESS; 695 return CS_SUCCESS;
686} 696}
687 697
@@ -700,7 +710,8 @@ static int parse_longlink_mfc(tuple_t *tuple,
700 return CS_BAD_TUPLE; 710 return CS_BAD_TUPLE;
701 for (i = 0; i < link->nfn; i++) { 711 for (i = 0; i < link->nfn; i++) {
702 link->fn[i].space = *p; p++; 712 link->fn[i].space = *p; p++;
703 link->fn[i].addr = le32_to_cpu(*(__le32 *)p); p += 4; 713 link->fn[i].addr = cis_get_u32(p);
714 p += 4;
704 } 715 }
705 return CS_SUCCESS; 716 return CS_SUCCESS;
706} 717}
@@ -787,12 +798,10 @@ static int parse_jedec(tuple_t *tuple, cistpl_jedec_t *jedec)
787 798
788static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m) 799static int parse_manfid(tuple_t *tuple, cistpl_manfid_t *m)
789{ 800{
790 __le16 *p;
791 if (tuple->TupleDataLen < 4) 801 if (tuple->TupleDataLen < 4)
792 return CS_BAD_TUPLE; 802 return CS_BAD_TUPLE;
793 p = (__le16 *)tuple->TupleData; 803 m->manf = cis_get_u16(tuple->TupleData);
794 m->manf = le16_to_cpu(p[0]); 804 m->card = cis_get_u16(tuple->TupleData + 2);
795 m->card = le16_to_cpu(p[1]);
796 return CS_SUCCESS; 805 return CS_SUCCESS;
797} 806}
798 807
@@ -1091,7 +1100,7 @@ static int parse_cftable_entry(tuple_t *tuple,
1091 break; 1100 break;
1092 case 0x20: 1101 case 0x20:
1093 entry->mem.nwin = 1; 1102 entry->mem.nwin = 1;
1094 entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8; 1103 entry->mem.win[0].len = cis_get_u16(p) << 8;
1095 entry->mem.win[0].card_addr = 0; 1104 entry->mem.win[0].card_addr = 0;
1096 entry->mem.win[0].host_addr = 0; 1105 entry->mem.win[0].host_addr = 0;
1097 p += 2; 1106 p += 2;
@@ -1099,9 +1108,8 @@ static int parse_cftable_entry(tuple_t *tuple,
1099 break; 1108 break;
1100 case 0x40: 1109 case 0x40:
1101 entry->mem.nwin = 1; 1110 entry->mem.nwin = 1;
1102 entry->mem.win[0].len = le16_to_cpu(*(__le16 *)p) << 8; 1111 entry->mem.win[0].len = cis_get_u16(p) << 8;
1103 entry->mem.win[0].card_addr = 1112 entry->mem.win[0].card_addr = cis_get_u16(p + 2) << 8;
1104 le16_to_cpu(*(__le16 *)(p+2)) << 8;
1105 entry->mem.win[0].host_addr = 0; 1113 entry->mem.win[0].host_addr = 0;
1106 p += 4; 1114 p += 4;
1107 if (p > q) return CS_BAD_TUPLE; 1115 if (p > q) return CS_BAD_TUPLE;
@@ -1138,7 +1146,7 @@ static int parse_bar(tuple_t *tuple, cistpl_bar_t *bar)
1138 p = (u_char *)tuple->TupleData; 1146 p = (u_char *)tuple->TupleData;
1139 bar->attr = *p; 1147 bar->attr = *p;
1140 p += 2; 1148 p += 2;
1141 bar->size = le32_to_cpu(*(__le32 *)p); 1149 bar->size = cis_get_u32(p);
1142 return CS_SUCCESS; 1150 return CS_SUCCESS;
1143} 1151}
1144 1152
@@ -1151,7 +1159,7 @@ static int parse_config_cb(tuple_t *tuple, cistpl_config_t *config)
1151 return CS_BAD_TUPLE; 1159 return CS_BAD_TUPLE;
1152 config->last_idx = *(++p); 1160 config->last_idx = *(++p);
1153 p++; 1161 p++;
1154 config->base = le32_to_cpu(*(__le32 *)p); 1162 config->base = cis_get_u32(p);
1155 config->subtuples = tuple->TupleDataLen - 6; 1163 config->subtuples = tuple->TupleDataLen - 6;
1156 return CS_SUCCESS; 1164 return CS_SUCCESS;
1157} 1165}
@@ -1267,7 +1275,7 @@ static int parse_vers_2(tuple_t *tuple, cistpl_vers_2_t *v2)
1267 1275
1268 v2->vers = p[0]; 1276 v2->vers = p[0];
1269 v2->comply = p[1]; 1277 v2->comply = p[1];
1270 v2->dindex = le16_to_cpu(*(__le16 *)(p+2)); 1278 v2->dindex = cis_get_u16(p +2 );
1271 v2->vspec8 = p[6]; 1279 v2->vspec8 = p[6];
1272 v2->vspec9 = p[7]; 1280 v2->vspec9 = p[7];
1273 v2->nhdr = p[8]; 1281 v2->nhdr = p[8];
@@ -1308,8 +1316,8 @@ static int parse_format(tuple_t *tuple, cistpl_format_t *fmt)
1308 1316
1309 fmt->type = p[0]; 1317 fmt->type = p[0];
1310 fmt->edc = p[1]; 1318 fmt->edc = p[1];
1311 fmt->offset = le32_to_cpu(*(__le32 *)(p+2)); 1319 fmt->offset = cis_get_u32(p + 2);
1312 fmt->length = le32_to_cpu(*(__le32 *)(p+6)); 1320 fmt->length = cis_get_u32(p + 6);
1313 1321
1314 return CS_SUCCESS; 1322 return CS_SUCCESS;
1315} 1323}
diff --git a/drivers/pcmcia/ds.c b/drivers/pcmcia/ds.c
index 55baa1f0fcbb..7bf78c127898 100644
--- a/drivers/pcmcia/ds.c
+++ b/drivers/pcmcia/ds.c
@@ -23,6 +23,7 @@
23#include <linux/crc32.h> 23#include <linux/crc32.h>
24#include <linux/firmware.h> 24#include <linux/firmware.h>
25#include <linux/kref.h> 25#include <linux/kref.h>
26#include <linux/dma-mapping.h>
26 27
27#define IN_CARD_SERVICES 28#define IN_CARD_SERVICES
28#include <pcmcia/cs_types.h> 29#include <pcmcia/cs_types.h>
@@ -670,6 +671,9 @@ struct pcmcia_device * pcmcia_device_add(struct pcmcia_socket *s, unsigned int f
670 p_dev->dev.bus = &pcmcia_bus_type; 671 p_dev->dev.bus = &pcmcia_bus_type;
671 p_dev->dev.parent = s->dev.parent; 672 p_dev->dev.parent = s->dev.parent;
672 p_dev->dev.release = pcmcia_release_dev; 673 p_dev->dev.release = pcmcia_release_dev;
674 /* by default don't allow DMA */
675 p_dev->dma_mask = DMA_MASK_NONE;
676 p_dev->dev.dma_mask = &p_dev->dma_mask;
673 bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no); 677 bus_id_len = sprintf (p_dev->dev.bus_id, "%d.%d", p_dev->socket->sock, p_dev->device_no);
674 678
675 p_dev->devname = kmalloc(6 + bus_id_len + 1, GFP_KERNEL); 679 p_dev->devname = kmalloc(6 + bus_id_len + 1, GFP_KERNEL);
diff --git a/drivers/pcmcia/pxa2xx_base.c b/drivers/pcmcia/pxa2xx_base.c
index dca9f8549b32..874923fcb2f9 100644
--- a/drivers/pcmcia/pxa2xx_base.c
+++ b/drivers/pcmcia/pxa2xx_base.c
@@ -58,7 +58,7 @@ static inline u_int pxa2xx_mcxx_asst(u_int pcmcia_cycle_ns,
58 u_int mem_clk_10khz) 58 u_int mem_clk_10khz)
59{ 59{
60 u_int code = pcmcia_cycle_ns * mem_clk_10khz; 60 u_int code = pcmcia_cycle_ns * mem_clk_10khz;
61 return (code / 300000) + ((code % 300000) ? 1 : 0) - 1; 61 return (code / 300000) + ((code % 300000) ? 1 : 0) + 1;
62} 62}
63 63
64static inline u_int pxa2xx_mcxx_setup(u_int pcmcia_cycle_ns, 64static inline u_int pxa2xx_mcxx_setup(u_int pcmcia_cycle_ns,
diff --git a/drivers/ps3/ps3av.c b/drivers/ps3/ps3av.c
index 85e21614f868..397f4ce849dc 100644
--- a/drivers/ps3/ps3av.c
+++ b/drivers/ps3/ps3av.c
@@ -23,6 +23,7 @@
23#include <linux/delay.h> 23#include <linux/delay.h>
24#include <linux/notifier.h> 24#include <linux/notifier.h>
25#include <linux/ioctl.h> 25#include <linux/ioctl.h>
26#include <linux/fb.h>
26 27
27#include <asm/firmware.h> 28#include <asm/firmware.h>
28#include <asm/ps3av.h> 29#include <asm/ps3av.h>
@@ -33,6 +34,8 @@
33#define BUFSIZE 4096 /* vuart buf size */ 34#define BUFSIZE 4096 /* vuart buf size */
34#define PS3AV_BUF_SIZE 512 /* max packet size */ 35#define PS3AV_BUF_SIZE 512 /* max packet size */
35 36
37static int safe_mode;
38
36static int timeout = 5000; /* in msec ( 5 sec ) */ 39static int timeout = 5000; /* in msec ( 5 sec ) */
37module_param(timeout, int, 0644); 40module_param(timeout, int, 0644);
38 41
@@ -491,10 +494,10 @@ static int ps3av_set_videomode(void)
491 return 0; 494 return 0;
492} 495}
493 496
494static void ps3av_set_videomode_cont(u32 id, u32 old_id) 497static void ps3av_set_videomode_packet(u32 id)
495{ 498{
496 struct ps3av_pkt_avb_param avb_param; 499 struct ps3av_pkt_avb_param avb_param;
497 int i; 500 unsigned int i;
498 u32 len = 0, av_video_cs; 501 u32 len = 0, av_video_cs;
499 const struct avset_video_mode *video_mode; 502 const struct avset_video_mode *video_mode;
500 int res; 503 int res;
@@ -507,24 +510,6 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
507 ps3av->av_hw_conf.num_of_avmulti; 510 ps3av->av_hw_conf.num_of_avmulti;
508 avb_param.num_of_av_audio_pkt = 0; 511 avb_param.num_of_av_audio_pkt = 0;
509 512
510 /* video signal off */
511 ps3av_set_video_disable_sig();
512
513 /* Retail PS3 product doesn't support this */
514 if (id & PS3AV_MODE_HDCP_OFF) {
515 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF);
516 if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
517 dev_dbg(&ps3av->dev->core, "Not supported\n");
518 else if (res)
519 dev_dbg(&ps3av->dev->core,
520 "ps3av_cmd_av_hdmi_mode failed\n");
521 } else if (old_id & PS3AV_MODE_HDCP_OFF) {
522 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL);
523 if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
524 dev_dbg(&ps3av->dev->core,
525 "ps3av_cmd_av_hdmi_mode failed\n");
526 }
527
528 /* video_pkt */ 513 /* video_pkt */
529 for (i = 0; i < avb_param.num_of_video_pkt; i++) 514 for (i = 0; i < avb_param.num_of_video_pkt; i++)
530 len += ps3av_cmd_set_video_mode(&avb_param.buf[len], 515 len += ps3av_cmd_set_video_mode(&avb_param.buf[len],
@@ -555,6 +540,42 @@ static void ps3av_set_videomode_cont(u32 id, u32 old_id)
555 __func__); 540 __func__);
556 else if (res) 541 else if (res)
557 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n"); 542 dev_dbg(&ps3av->dev->core, "ps3av_cmd_avb_param failed\n");
543}
544
545static void ps3av_set_videomode_cont(u32 id, u32 old_id)
546{
547 static int vesa = 0;
548 int res;
549
550 /* video signal off */
551 ps3av_set_video_disable_sig();
552
553 /*
554 * AV backend needs non-VESA mode setting at least one time
555 * when VESA mode is used.
556 */
557 if (vesa == 0 && (id & PS3AV_MODE_MASK) >= 11) {
558 /* vesa mode */
559 ps3av_set_videomode_packet(2); /* 480P */
560 }
561 vesa = 1;
562
563 /* Retail PS3 product doesn't support this */
564 if (id & PS3AV_MODE_HDCP_OFF) {
565 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_HDCP_OFF);
566 if (res == PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
567 dev_dbg(&ps3av->dev->core, "Not supported\n");
568 else if (res)
569 dev_dbg(&ps3av->dev->core,
570 "ps3av_cmd_av_hdmi_mode failed\n");
571 } else if (old_id & PS3AV_MODE_HDCP_OFF) {
572 res = ps3av_cmd_av_hdmi_mode(PS3AV_CMD_AV_HDMI_MODE_NORMAL);
573 if (res < 0 && res != PS3AV_STATUS_UNSUPPORTED_HDMI_MODE)
574 dev_dbg(&ps3av->dev->core,
575 "ps3av_cmd_av_hdmi_mode failed\n");
576 }
577
578 ps3av_set_videomode_packet(id);
558 579
559 msleep(1500); 580 msleep(1500);
560 /* av video mute */ 581 /* av video mute */
@@ -567,165 +588,251 @@ static void ps3avd(struct work_struct *work)
567 complete(&ps3av->done); 588 complete(&ps3av->done);
568} 589}
569 590
570static int ps3av_vid2table_id(int vid) 591#define SHIFT_50 0
571{ 592#define SHIFT_60 4
572 int i; 593#define SHIFT_VESA 8
573 594
574 for (i = 1; i < ARRAY_SIZE(video_mode_table); i++) 595static const struct {
575 if (video_mode_table[i].vid == vid) 596 unsigned mask : 19;
576 return i; 597 unsigned id : 4;
577 return -1; 598} ps3av_preferred_modes[] = {
578} 599 { .mask = PS3AV_RESBIT_WUXGA << SHIFT_VESA, .id = 13 },
600 { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_60, .id = 5 },
601 { .mask = PS3AV_RESBIT_1920x1080P << SHIFT_50, .id = 10 },
602 { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_60, .id = 4 },
603 { .mask = PS3AV_RESBIT_1920x1080I << SHIFT_50, .id = 9 },
604 { .mask = PS3AV_RESBIT_SXGA << SHIFT_VESA, .id = 12 },
605 { .mask = PS3AV_RESBIT_WXGA << SHIFT_VESA, .id = 11 },
606 { .mask = PS3AV_RESBIT_1280x720P << SHIFT_60, .id = 3 },
607 { .mask = PS3AV_RESBIT_1280x720P << SHIFT_50, .id = 8 },
608 { .mask = PS3AV_RESBIT_720x480P << SHIFT_60, .id = 2 },
609 { .mask = PS3AV_RESBIT_720x576P << SHIFT_50, .id = 7 },
610};
579 611
580static int ps3av_resbit2vid(u32 res_50, u32 res_60) 612static int ps3av_resbit2id(u32 res_50, u32 res_60, u32 res_vesa)
581{ 613{
582 int vid = -1; 614 unsigned int i;
615 u32 res_all;
616
617 /*
618 * We mask off the resolution bits we care about and combine the
619 * results in one bitfield, so make sure there's no overlap
620 */
621 BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 &
622 PS3AV_RES_MASK_60 << SHIFT_60);
623 BUILD_BUG_ON(PS3AV_RES_MASK_50 << SHIFT_50 &
624 PS3AV_RES_MASK_VESA << SHIFT_VESA);
625 BUILD_BUG_ON(PS3AV_RES_MASK_60 << SHIFT_60 &
626 PS3AV_RES_MASK_VESA << SHIFT_VESA);
627 res_all = (res_50 & PS3AV_RES_MASK_50) << SHIFT_50 |
628 (res_60 & PS3AV_RES_MASK_60) << SHIFT_60 |
629 (res_vesa & PS3AV_RES_MASK_VESA) << SHIFT_VESA;
630
631 if (!res_all)
632 return 0;
633
634 for (i = 0; i < ARRAY_SIZE(ps3av_preferred_modes); i++)
635 if (res_all & ps3av_preferred_modes[i].mask)
636 return ps3av_preferred_modes[i].id;
583 637
584 if (res_50 > res_60) { /* if res_50 == res_60, res_60 will be used */ 638 return 0;
585 if (res_50 & PS3AV_RESBIT_1920x1080P)
586 vid = PS3AV_CMD_VIDEO_VID_1080P_50HZ;
587 else if (res_50 & PS3AV_RESBIT_1920x1080I)
588 vid = PS3AV_CMD_VIDEO_VID_1080I_50HZ;
589 else if (res_50 & PS3AV_RESBIT_1280x720P)
590 vid = PS3AV_CMD_VIDEO_VID_720P_50HZ;
591 else if (res_50 & PS3AV_RESBIT_720x576P)
592 vid = PS3AV_CMD_VIDEO_VID_576P;
593 else
594 vid = -1;
595 } else {
596 if (res_60 & PS3AV_RESBIT_1920x1080P)
597 vid = PS3AV_CMD_VIDEO_VID_1080P_60HZ;
598 else if (res_60 & PS3AV_RESBIT_1920x1080I)
599 vid = PS3AV_CMD_VIDEO_VID_1080I_60HZ;
600 else if (res_60 & PS3AV_RESBIT_1280x720P)
601 vid = PS3AV_CMD_VIDEO_VID_720P_60HZ;
602 else if (res_60 & PS3AV_RESBIT_720x480P)
603 vid = PS3AV_CMD_VIDEO_VID_480P;
604 else
605 vid = -1;
606 }
607 return vid;
608} 639}
609 640
610static int ps3av_hdmi_get_vid(struct ps3av_info_monitor *info) 641static int ps3av_hdmi_get_id(struct ps3av_info_monitor *info)
611{ 642{
612 u32 res_50, res_60; 643 int id;
613 int vid = -1;
614 644
615 if (info->monitor_type != PS3AV_MONITOR_TYPE_HDMI) 645 if (safe_mode)
616 return -1; 646 return PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
617 647
618 /* check native resolution */ 648 /* check native resolution */
619 res_50 = info->res_50.native & PS3AV_RES_MASK_50; 649 id = ps3av_resbit2id(info->res_50.native, info->res_60.native,
620 res_60 = info->res_60.native & PS3AV_RES_MASK_60; 650 info->res_vesa.native);
621 if (res_50 || res_60) { 651 if (id) {
622 vid = ps3av_resbit2vid(res_50, res_60); 652 pr_debug("%s: Using native mode %d\n", __func__, id);
623 return vid; 653 return id;
624 } 654 }
625 655
626 /* check resolution */ 656 /* check supported resolutions */
627 res_50 = info->res_50.res_bits & PS3AV_RES_MASK_50; 657 id = ps3av_resbit2id(info->res_50.res_bits, info->res_60.res_bits,
628 res_60 = info->res_60.res_bits & PS3AV_RES_MASK_60; 658 info->res_vesa.res_bits);
629 if (res_50 || res_60) { 659 if (id) {
630 vid = ps3av_resbit2vid(res_50, res_60); 660 pr_debug("%s: Using supported mode %d\n", __func__, id);
631 return vid; 661 return id;
632 } 662 }
633 663
634 if (ps3av->region & PS3AV_REGION_60) 664 if (ps3av->region & PS3AV_REGION_60)
635 vid = PS3AV_DEFAULT_HDMI_VID_REG_60; 665 id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_60;
636 else 666 else
637 vid = PS3AV_DEFAULT_HDMI_VID_REG_50; 667 id = PS3AV_DEFAULT_HDMI_MODE_ID_REG_50;
638 return vid; 668 pr_debug("%s: Using default mode %d\n", __func__, id);
669 return id;
639} 670}
640 671
641static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf, 672static void ps3av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info)
642 int boot)
643{ 673{
644 int i, res, vid = -1, dvi = 0, rgb = 0; 674 const struct ps3av_info_monitor *info = &monitor_info->info;
675 const struct ps3av_info_audio *audio = info->audio;
676 char id[sizeof(info->monitor_id)*3+1];
677 int i;
678
679 pr_debug("Monitor Info: size %u\n", monitor_info->send_hdr.size);
680
681 pr_debug("avport: %02x\n", info->avport);
682 for (i = 0; i < sizeof(info->monitor_id); i++)
683 sprintf(&id[i*3], " %02x", info->monitor_id[i]);
684 pr_debug("monitor_id: %s\n", id);
685 pr_debug("monitor_type: %02x\n", info->monitor_type);
686 pr_debug("monitor_name: %.*s\n", (int)sizeof(info->monitor_name),
687 info->monitor_name);
688
689 /* resolution */
690 pr_debug("resolution_60: bits: %08x native: %08x\n",
691 info->res_60.res_bits, info->res_60.native);
692 pr_debug("resolution_50: bits: %08x native: %08x\n",
693 info->res_50.res_bits, info->res_50.native);
694 pr_debug("resolution_other: bits: %08x native: %08x\n",
695 info->res_other.res_bits, info->res_other.native);
696 pr_debug("resolution_vesa: bits: %08x native: %08x\n",
697 info->res_vesa.res_bits, info->res_vesa.native);
698
699 /* color space */
700 pr_debug("color space rgb: %02x\n", info->cs.rgb);
701 pr_debug("color space yuv444: %02x\n", info->cs.yuv444);
702 pr_debug("color space yuv422: %02x\n", info->cs.yuv422);
703
704 /* color info */
705 pr_debug("color info red: X %04x Y %04x\n", info->color.red_x,
706 info->color.red_y);
707 pr_debug("color info green: X %04x Y %04x\n", info->color.green_x,
708 info->color.green_y);
709 pr_debug("color info blue: X %04x Y %04x\n", info->color.blue_x,
710 info->color.blue_y);
711 pr_debug("color info white: X %04x Y %04x\n", info->color.white_x,
712 info->color.white_y);
713 pr_debug("color info gamma: %08x\n", info->color.gamma);
714
715 /* other info */
716 pr_debug("supported_AI: %02x\n", info->supported_ai);
717 pr_debug("speaker_info: %02x\n", info->speaker_info);
718 pr_debug("num of audio: %02x\n", info->num_of_audio_block);
719
720 /* audio block */
721 for (i = 0; i < info->num_of_audio_block; i++) {
722 pr_debug("audio[%d] type: %02x max_ch: %02x fs: %02x sbit: "
723 "%02x\n",
724 i, audio->type, audio->max_num_of_ch, audio->fs,
725 audio->sbit);
726 audio++;
727 }
728}
729
730static const struct ps3av_monitor_quirk {
731 const char *monitor_name;
732 u32 clear_60, clear_50, clear_vesa;
733} ps3av_monitor_quirks[] = {
734 {
735 .monitor_name = "DELL 2007WFP",
736 .clear_60 = PS3AV_RESBIT_1920x1080I
737 }, {
738 .monitor_name = "L226WTQ",
739 .clear_60 = PS3AV_RESBIT_1920x1080I |
740 PS3AV_RESBIT_1920x1080P
741 }, {
742 .monitor_name = "SyncMaster",
743 .clear_60 = PS3AV_RESBIT_1920x1080I
744 }
745};
746
747static void ps3av_fixup_monitor_info(struct ps3av_info_monitor *info)
748{
749 unsigned int i;
750 const struct ps3av_monitor_quirk *quirk;
751
752 for (i = 0; i < ARRAY_SIZE(ps3av_monitor_quirks); i++) {
753 quirk = &ps3av_monitor_quirks[i];
754 if (!strncmp(info->monitor_name, quirk->monitor_name,
755 sizeof(info->monitor_name))) {
756 pr_info("%s: Applying quirk for %s\n", __func__,
757 quirk->monitor_name);
758 info->res_60.res_bits &= ~quirk->clear_60;
759 info->res_60.native &= ~quirk->clear_60;
760 info->res_50.res_bits &= ~quirk->clear_50;
761 info->res_50.native &= ~quirk->clear_50;
762 info->res_vesa.res_bits &= ~quirk->clear_vesa;
763 info->res_vesa.native &= ~quirk->clear_vesa;
764 break;
765 }
766 }
767}
768
769static int ps3av_auto_videomode(struct ps3av_pkt_av_get_hw_conf *av_hw_conf)
770{
771 int i, res, id = 0, dvi = 0, rgb = 0;
645 struct ps3av_pkt_av_get_monitor_info monitor_info; 772 struct ps3av_pkt_av_get_monitor_info monitor_info;
646 struct ps3av_info_monitor *info; 773 struct ps3av_info_monitor *info;
647 774
648 /* get vid for hdmi */ 775 /* get mode id for hdmi */
649 for (i = 0; i < av_hw_conf->num_of_hdmi; i++) { 776 for (i = 0; i < av_hw_conf->num_of_hdmi && !id; i++) {
650 res = ps3av_cmd_video_get_monitor_info(&monitor_info, 777 res = ps3av_cmd_video_get_monitor_info(&monitor_info,
651 PS3AV_CMD_AVPORT_HDMI_0 + 778 PS3AV_CMD_AVPORT_HDMI_0 +
652 i); 779 i);
653 if (res < 0) 780 if (res < 0)
654 return -1; 781 return -1;
655 782
656 ps3av_cmd_av_monitor_info_dump(&monitor_info); 783 ps3av_monitor_info_dump(&monitor_info);
784
657 info = &monitor_info.info; 785 info = &monitor_info.info;
658 /* check DVI */ 786 ps3av_fixup_monitor_info(info);
659 if (info->monitor_type == PS3AV_MONITOR_TYPE_DVI) { 787
788 switch (info->monitor_type) {
789 case PS3AV_MONITOR_TYPE_DVI:
660 dvi = PS3AV_MODE_DVI; 790 dvi = PS3AV_MODE_DVI;
661 break; 791 /* fall through */
662 } 792 case PS3AV_MONITOR_TYPE_HDMI:
663 /* check HDMI */ 793 id = ps3av_hdmi_get_id(info);
664 vid = ps3av_hdmi_get_vid(info);
665 if (vid != -1) {
666 /* got valid vid */
667 break; 794 break;
668 } 795 }
669 } 796 }
670 797
671 if (dvi) { 798 if (!id) {
672 /* DVI mode */
673 vid = PS3AV_DEFAULT_DVI_VID;
674 } else if (vid == -1) {
675 /* no HDMI interface or HDMI is off */ 799 /* no HDMI interface or HDMI is off */
676 if (ps3av->region & PS3AV_REGION_60) 800 if (ps3av->region & PS3AV_REGION_60)
677 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_60; 801 id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60;
678 else 802 else
679 vid = PS3AV_DEFAULT_AVMULTI_VID_REG_50; 803 id = PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50;
680 if (ps3av->region & PS3AV_REGION_RGB) 804 if (ps3av->region & PS3AV_REGION_RGB)
681 rgb = PS3AV_MODE_RGB; 805 rgb = PS3AV_MODE_RGB;
682 } else if (boot) { 806 pr_debug("%s: Using avmulti mode %d\n", __func__, id);
683 /* HDMI: using DEFAULT HDMI_VID while booting up */
684 info = &monitor_info.info;
685 if (ps3av->region & PS3AV_REGION_60) {
686 if (info->res_60.res_bits & PS3AV_RESBIT_720x480P)
687 vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
688 else if (info->res_50.res_bits & PS3AV_RESBIT_720x576P)
689 vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
690 else {
691 /* default */
692 vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
693 }
694 } else {
695 if (info->res_50.res_bits & PS3AV_RESBIT_720x576P)
696 vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
697 else if (info->res_60.res_bits & PS3AV_RESBIT_720x480P)
698 vid = PS3AV_DEFAULT_HDMI_VID_REG_60;
699 else {
700 /* default */
701 vid = PS3AV_DEFAULT_HDMI_VID_REG_50;
702 }
703 }
704 } 807 }
705 808
706 return (ps3av_vid2table_id(vid) | dvi | rgb); 809 return id | dvi | rgb;
707} 810}
708 811
709static int ps3av_get_hw_conf(struct ps3av *ps3av) 812static int ps3av_get_hw_conf(struct ps3av *ps3av)
710{ 813{
711 int i, j, k, res; 814 int i, j, k, res;
815 const struct ps3av_pkt_av_get_hw_conf *hw_conf;
712 816
713 /* get av_hw_conf */ 817 /* get av_hw_conf */
714 res = ps3av_cmd_av_get_hw_conf(&ps3av->av_hw_conf); 818 res = ps3av_cmd_av_get_hw_conf(&ps3av->av_hw_conf);
715 if (res < 0) 819 if (res < 0)
716 return -1; 820 return -1;
717 821
718 ps3av_cmd_av_hw_conf_dump(&ps3av->av_hw_conf); 822 hw_conf = &ps3av->av_hw_conf;
823 pr_debug("av_h_conf: num of hdmi: %u\n", hw_conf->num_of_hdmi);
824 pr_debug("av_h_conf: num of avmulti: %u\n", hw_conf->num_of_avmulti);
825 pr_debug("av_h_conf: num of spdif: %u\n", hw_conf->num_of_spdif);
719 826
720 for (i = 0; i < PS3AV_HEAD_MAX; i++) 827 for (i = 0; i < PS3AV_HEAD_MAX; i++)
721 ps3av->head[i] = PS3AV_CMD_VIDEO_HEAD_A + i; 828 ps3av->head[i] = PS3AV_CMD_VIDEO_HEAD_A + i;
722 for (i = 0; i < PS3AV_OPT_PORT_MAX; i++) 829 for (i = 0; i < PS3AV_OPT_PORT_MAX; i++)
723 ps3av->opt_port[i] = PS3AV_CMD_AVPORT_SPDIF_0 + i; 830 ps3av->opt_port[i] = PS3AV_CMD_AVPORT_SPDIF_0 + i;
724 for (i = 0; i < ps3av->av_hw_conf.num_of_hdmi; i++) 831 for (i = 0; i < hw_conf->num_of_hdmi; i++)
725 ps3av->av_port[i] = PS3AV_CMD_AVPORT_HDMI_0 + i; 832 ps3av->av_port[i] = PS3AV_CMD_AVPORT_HDMI_0 + i;
726 for (j = 0; j < ps3av->av_hw_conf.num_of_avmulti; j++) 833 for (j = 0; j < hw_conf->num_of_avmulti; j++)
727 ps3av->av_port[i + j] = PS3AV_CMD_AVPORT_AVMULTI_0 + j; 834 ps3av->av_port[i + j] = PS3AV_CMD_AVPORT_AVMULTI_0 + j;
728 for (k = 0; k < ps3av->av_hw_conf.num_of_spdif; k++) 835 for (k = 0; k < hw_conf->num_of_spdif; k++)
729 ps3av->av_port[i + j + k] = PS3AV_CMD_AVPORT_SPDIF_0 + k; 836 ps3av->av_port[i + j + k] = PS3AV_CMD_AVPORT_SPDIF_0 + k;
730 837
731 /* set all audio port */ 838 /* set all audio port */
@@ -738,7 +845,7 @@ static int ps3av_get_hw_conf(struct ps3av *ps3av)
738} 845}
739 846
740/* set mode using id */ 847/* set mode using id */
741int ps3av_set_video_mode(u32 id, int boot) 848int ps3av_set_video_mode(u32 id)
742{ 849{
743 int size; 850 int size;
744 u32 option; 851 u32 option;
@@ -752,7 +859,7 @@ int ps3av_set_video_mode(u32 id, int boot)
752 /* auto mode */ 859 /* auto mode */
753 option = id & ~PS3AV_MODE_MASK; 860 option = id & ~PS3AV_MODE_MASK;
754 if ((id & PS3AV_MODE_MASK) == 0) { 861 if ((id & PS3AV_MODE_MASK) == 0) {
755 id = ps3av_auto_videomode(&ps3av->av_hw_conf, boot); 862 id = ps3av_auto_videomode(&ps3av->av_hw_conf);
756 if (id < 1) { 863 if (id < 1) {
757 printk(KERN_ERR "%s: invalid id :%d\n", __func__, id); 864 printk(KERN_ERR "%s: invalid id :%d\n", __func__, id);
758 return -EINVAL; 865 return -EINVAL;
@@ -772,34 +879,13 @@ int ps3av_set_video_mode(u32 id, int boot)
772 879
773EXPORT_SYMBOL_GPL(ps3av_set_video_mode); 880EXPORT_SYMBOL_GPL(ps3av_set_video_mode);
774 881
775int ps3av_get_auto_mode(int boot) 882int ps3av_get_auto_mode(void)
776{ 883{
777 return ps3av_auto_videomode(&ps3av->av_hw_conf, boot); 884 return ps3av_auto_videomode(&ps3av->av_hw_conf);
778} 885}
779 886
780EXPORT_SYMBOL_GPL(ps3av_get_auto_mode); 887EXPORT_SYMBOL_GPL(ps3av_get_auto_mode);
781 888
782int ps3av_set_mode(u32 id, int boot)
783{
784 int res;
785
786 res = ps3av_set_video_mode(id, boot);
787 if (res)
788 return res;
789
790 res = ps3av_set_audio_mode(PS3AV_CMD_AUDIO_NUM_OF_CH_2,
791 PS3AV_CMD_AUDIO_FS_48K,
792 PS3AV_CMD_AUDIO_WORD_BITS_16,
793 PS3AV_CMD_AUDIO_FORMAT_PCM,
794 PS3AV_CMD_AUDIO_SOURCE_SERIAL);
795 if (res)
796 return res;
797
798 return 0;
799}
800
801EXPORT_SYMBOL_GPL(ps3av_set_mode);
802
803int ps3av_get_mode(void) 889int ps3av_get_mode(void)
804{ 890{
805 return ps3av ? ps3av->ps3av_mode : 0; 891 return ps3av ? ps3av->ps3av_mode : 0;
@@ -941,7 +1027,14 @@ static int ps3av_probe(struct ps3_system_bus_device *dev)
941 res); 1027 res);
942 1028
943 ps3av_get_hw_conf(ps3av); 1029 ps3av_get_hw_conf(ps3av);
944 id = ps3av_auto_videomode(&ps3av->av_hw_conf, 1); 1030
1031#ifdef CONFIG_FB
1032 if (fb_mode_option && !strcmp(fb_mode_option, "safe"))
1033 safe_mode = 1;
1034#endif /* CONFIG_FB */
1035 id = ps3av_auto_videomode(&ps3av->av_hw_conf);
1036 safe_mode = 0;
1037
945 mutex_lock(&ps3av->mutex); 1038 mutex_lock(&ps3av->mutex);
946 ps3av->ps3av_mode = id; 1039 ps3av->ps3av_mode = id;
947 mutex_unlock(&ps3av->mutex); 1040 mutex_unlock(&ps3av->mutex);
diff --git a/drivers/ps3/ps3av_cmd.c b/drivers/ps3/ps3av_cmd.c
index f72f5ddf18e4..7f880c26122f 100644
--- a/drivers/ps3/ps3av_cmd.c
+++ b/drivers/ps3/ps3av_cmd.c
@@ -512,7 +512,6 @@ static const u32 ps3av_ns_table[][5] = {
512static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid) 512static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid)
513{ 513{
514 u32 av_vid, ns_val; 514 u32 av_vid, ns_val;
515 u8 *p = ns;
516 int d; 515 int d;
517 516
518 d = ns_val = 0; 517 d = ns_val = 0;
@@ -551,24 +550,22 @@ static void ps3av_cnv_ns(u8 *ns, u32 fs, u32 video_vid)
551 else 550 else
552 ns_val = ps3av_ns_table[PS3AV_CMD_AUDIO_FS_44K-BASE][d]; 551 ns_val = ps3av_ns_table[PS3AV_CMD_AUDIO_FS_44K-BASE][d];
553 552
554 *p++ = ns_val & 0x000000FF; 553 *ns++ = ns_val & 0x000000FF;
555 *p++ = (ns_val & 0x0000FF00) >> 8; 554 *ns++ = (ns_val & 0x0000FF00) >> 8;
556 *p = (ns_val & 0x00FF0000) >> 16; 555 *ns = (ns_val & 0x00FF0000) >> 16;
557} 556}
558 557
559#undef BASE 558#undef BASE
560 559
561static u8 ps3av_cnv_enable(u32 source, const u8 *enable) 560static u8 ps3av_cnv_enable(u32 source, const u8 *enable)
562{ 561{
563 const u8 *p;
564 u8 ret = 0; 562 u8 ret = 0;
565 563
566 if (source == PS3AV_CMD_AUDIO_SOURCE_SPDIF) { 564 if (source == PS3AV_CMD_AUDIO_SOURCE_SPDIF) {
567 ret = 0x03; 565 ret = 0x03;
568 } else if (source == PS3AV_CMD_AUDIO_SOURCE_SERIAL) { 566 } else if (source == PS3AV_CMD_AUDIO_SOURCE_SERIAL) {
569 p = enable; 567 ret = ((enable[0] << 4) + (enable[1] << 5) + (enable[2] << 6) +
570 ret = ((p[0] << 4) + (p[1] << 5) + (p[2] << 6) + (p[3] << 7)) | 568 (enable[3] << 7)) | 0x01;
571 0x01;
572 } else 569 } else
573 printk(KERN_ERR "%s failed, source:%x\n", __func__, source); 570 printk(KERN_ERR "%s failed, source:%x\n", __func__, source);
574 return ret; 571 return ret;
@@ -576,11 +573,9 @@ static u8 ps3av_cnv_enable(u32 source, const u8 *enable)
576 573
577static u8 ps3av_cnv_fifomap(const u8 *map) 574static u8 ps3av_cnv_fifomap(const u8 *map)
578{ 575{
579 const u8 *p;
580 u8 ret = 0; 576 u8 ret = 0;
581 577
582 p = map; 578 ret = map[0] + (map[1] << 2) + (map[2] << 4) + (map[3] << 6);
583 ret = p[0] + (p[1] << 2) + (p[2] << 4) + (p[3] << 6);
584 return ret; 579 return ret;
585} 580}
586 581
@@ -927,72 +922,6 @@ int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *info,
927 return res; 922 return res;
928} 923}
929 924
930#ifdef PS3AV_DEBUG
931void ps3av_cmd_av_hw_conf_dump(const struct ps3av_pkt_av_get_hw_conf *hw_conf)
932{
933 printk("av_h_conf:num of hdmi:%d\n", hw_conf->num_of_hdmi);
934 printk("av_h_conf:num of avmulti:%d\n", hw_conf->num_of_avmulti);
935 printk("av_h_conf:num of spdif:%d\n", hw_conf->num_of_spdif);
936}
937
938void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info)
939{
940 const struct ps3av_info_monitor *info = &monitor_info->info;
941 const struct ps3av_info_audio *audio = info->audio;
942 int i;
943
944 printk("Monitor Info: size%d\n", monitor_info->send_hdr.size);
945
946 printk("avport:%02x\n", info->avport);
947 printk("monitor_id:");
948 for (i = 0; i < 10; i++)
949 printk("%02x ", info->monitor_id[i]);
950 printk("\nmonitor_type:%02x\n", info->monitor_type);
951 printk("monitor_name:");
952 for (i = 0; i < 16; i++)
953 printk("%c", info->monitor_name[i]);
954
955 /* resolution */
956 printk("\nresolution_60: bits:%08x native:%08x\n",
957 info->res_60.res_bits, info->res_60.native);
958 printk("resolution_50: bits:%08x native:%08x\n",
959 info->res_50.res_bits, info->res_50.native);
960 printk("resolution_other: bits:%08x native:%08x\n",
961 info->res_other.res_bits, info->res_other.native);
962 printk("resolution_vesa: bits:%08x native:%08x\n",
963 info->res_vesa.res_bits, info->res_vesa.native);
964
965 /* color space */
966 printk("color space rgb:%02x\n", info->cs.rgb);
967 printk("color space yuv444:%02x\n", info->cs.yuv444);
968 printk("color space yuv422:%02x\n", info->cs.yuv422);
969
970 /* color info */
971 printk("color info red:X %04x Y %04x\n",
972 info->color.red_x, info->color.red_y);
973 printk("color info green:X %04x Y %04x\n",
974 info->color.green_x, info->color.green_y);
975 printk("color info blue:X %04x Y %04x\n",
976 info->color.blue_x, info->color.blue_y);
977 printk("color info white:X %04x Y %04x\n",
978 info->color.white_x, info->color.white_y);
979 printk("color info gamma: %08x\n", info->color.gamma);
980
981 /* other info */
982 printk("supported_AI:%02x\n", info->supported_ai);
983 printk("speaker_info:%02x\n", info->speaker_info);
984 printk("num of audio:%02x\n", info->num_of_audio_block);
985
986 /* audio block */
987 for (i = 0; i < info->num_of_audio_block; i++) {
988 printk("audio[%d] type:%02x max_ch:%02x fs:%02x sbit:%02x\n",
989 i, audio->type, audio->max_num_of_ch, audio->fs,
990 audio->sbit);
991 audio++;
992 }
993}
994#endif /* PS3AV_DEBUG */
995
996#define PS3AV_AV_LAYOUT_0 (PS3AV_CMD_AV_LAYOUT_32 \ 925#define PS3AV_AV_LAYOUT_0 (PS3AV_CMD_AV_LAYOUT_32 \
997 | PS3AV_CMD_AV_LAYOUT_44 \ 926 | PS3AV_CMD_AV_LAYOUT_44 \
998 | PS3AV_CMD_AV_LAYOUT_48) 927 | PS3AV_CMD_AV_LAYOUT_48)
diff --git a/drivers/rtc/Kconfig b/drivers/rtc/Kconfig
index ff9e35cb308d..6420a90a4a92 100644
--- a/drivers/rtc/Kconfig
+++ b/drivers/rtc/Kconfig
@@ -139,6 +139,17 @@ config RTC_DRV_DS1307
139 This driver can also be built as a module. If so, the module 139 This driver can also be built as a module. If so, the module
140 will be called rtc-ds1307. 140 will be called rtc-ds1307.
141 141
142config RTC_DRV_DS1374
143 tristate "Maxim/Dallas Semiconductor DS1374 Real Time Clock"
144 depends on RTC_CLASS && I2C
145 help
146 If you say yes here you get support for Dallas Semiconductor
147 DS1374 real-time clock chips. If an interrupt is associated
148 with the device, the alarm functionality is supported.
149
150 This driver can also be built as a module. If so, the module
151 will be called rtc-ds1374.
152
142config RTC_DRV_DS1672 153config RTC_DRV_DS1672
143 tristate "Dallas/Maxim DS1672" 154 tristate "Dallas/Maxim DS1672"
144 help 155 help
diff --git a/drivers/rtc/Makefile b/drivers/rtc/Makefile
index d3a33aa2696f..465db4dd50b2 100644
--- a/drivers/rtc/Makefile
+++ b/drivers/rtc/Makefile
@@ -23,6 +23,7 @@ obj-$(CONFIG_RTC_DRV_BFIN) += rtc-bfin.o
23obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o 23obj-$(CONFIG_RTC_DRV_CMOS) += rtc-cmos.o
24obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o 24obj-$(CONFIG_RTC_DRV_DS1216) += rtc-ds1216.o
25obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o 25obj-$(CONFIG_RTC_DRV_DS1307) += rtc-ds1307.o
26obj-$(CONFIG_RTC_DRV_DS1374) += rtc-ds1374.o
26obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o 27obj-$(CONFIG_RTC_DRV_DS1553) += rtc-ds1553.o
27obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o 28obj-$(CONFIG_RTC_DRV_DS1672) += rtc-ds1672.o
28obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o 29obj-$(CONFIG_RTC_DRV_DS1742) += rtc-ds1742.o
diff --git a/drivers/rtc/class.c b/drivers/rtc/class.c
index 10ab3b71ffc6..4dfdf019fccc 100644
--- a/drivers/rtc/class.c
+++ b/drivers/rtc/class.c
@@ -153,6 +153,7 @@ struct rtc_device *rtc_device_register(const char *name, struct device *dev,
153 mutex_init(&rtc->ops_lock); 153 mutex_init(&rtc->ops_lock);
154 spin_lock_init(&rtc->irq_lock); 154 spin_lock_init(&rtc->irq_lock);
155 spin_lock_init(&rtc->irq_task_lock); 155 spin_lock_init(&rtc->irq_task_lock);
156 init_waitqueue_head(&rtc->irq_queue);
156 157
157 strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE); 158 strlcpy(rtc->name, name, RTC_DEVICE_NAME_SIZE);
158 snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id); 159 snprintf(rtc->dev.bus_id, BUS_ID_SIZE, "rtc%d", id);
diff --git a/drivers/rtc/interface.c b/drivers/rtc/interface.c
index ad66c6ecf365..de0da545c7a1 100644
--- a/drivers/rtc/interface.c
+++ b/drivers/rtc/interface.c
@@ -12,6 +12,7 @@
12*/ 12*/
13 13
14#include <linux/rtc.h> 14#include <linux/rtc.h>
15#include <linux/log2.h>
15 16
16int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm) 17int rtc_read_time(struct rtc_device *rtc, struct rtc_time *tm)
17{ 18{
@@ -99,7 +100,7 @@ int rtc_set_mmss(struct rtc_device *rtc, unsigned long secs)
99} 100}
100EXPORT_SYMBOL_GPL(rtc_set_mmss); 101EXPORT_SYMBOL_GPL(rtc_set_mmss);
101 102
102int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) 103static int rtc_read_alarm_internal(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
103{ 104{
104 int err; 105 int err;
105 106
@@ -119,6 +120,87 @@ int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
119 mutex_unlock(&rtc->ops_lock); 120 mutex_unlock(&rtc->ops_lock);
120 return err; 121 return err;
121} 122}
123
124int rtc_read_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
125{
126 int err;
127 struct rtc_time before, now;
128 int first_time = 1;
129
130 /* The lower level RTC driver may not be capable of filling
131 * in all fields of the rtc_time struct (eg. rtc-cmos),
132 * and so might instead return -1 in some fields.
133 * We deal with that here by grabbing a current RTC timestamp
134 * and using values from that for any missing (-1) values.
135 *
136 * But this can be racey, because some fields of the RTC timestamp
137 * may have wrapped in the interval since we read the RTC alarm,
138 * which would lead to us inserting inconsistent values in place
139 * of the -1 fields.
140 *
141 * Reading the alarm and timestamp in the reverse sequence
142 * would have the same race condition, and not solve the issue.
143 *
144 * So, we must first read the RTC timestamp,
145 * then read the RTC alarm value,
146 * and then read a second RTC timestamp.
147 *
148 * If any fields of the second timestamp have changed
149 * when compared with the first timestamp, then we know
150 * our timestamp may be inconsistent with that used by
151 * the low-level rtc_read_alarm_internal() function.
152 *
153 * So, when the two timestamps disagree, we just loop and do
154 * the process again to get a fully consistent set of values.
155 *
156 * This could all instead be done in the lower level driver,
157 * but since more than one lower level RTC implementation needs it,
158 * then it's probably best best to do it here instead of there..
159 */
160
161 /* Get the "before" timestamp */
162 err = rtc_read_time(rtc, &before);
163 if (err < 0)
164 return err;
165 do {
166 if (!first_time)
167 memcpy(&before, &now, sizeof(struct rtc_time));
168 first_time = 0;
169
170 /* get the RTC alarm values, which may be incomplete */
171 err = rtc_read_alarm_internal(rtc, alarm);
172 if (err)
173 return err;
174 if (!alarm->enabled)
175 return 0;
176
177 /* get the "after" timestamp, to detect wrapped fields */
178 err = rtc_read_time(rtc, &now);
179 if (err < 0)
180 return err;
181
182 /* note that tm_sec is a "don't care" value here: */
183 } while ( before.tm_min != now.tm_min
184 || before.tm_hour != now.tm_hour
185 || before.tm_mon != now.tm_mon
186 || before.tm_year != now.tm_year
187 || before.tm_isdst != now.tm_isdst);
188
189 /* Fill in any missing alarm fields using the timestamp */
190 if (alarm->time.tm_sec == -1)
191 alarm->time.tm_sec = now.tm_sec;
192 if (alarm->time.tm_min == -1)
193 alarm->time.tm_min = now.tm_min;
194 if (alarm->time.tm_hour == -1)
195 alarm->time.tm_hour = now.tm_hour;
196 if (alarm->time.tm_mday == -1)
197 alarm->time.tm_mday = now.tm_mday;
198 if (alarm->time.tm_mon == -1)
199 alarm->time.tm_mon = now.tm_mon;
200 if (alarm->time.tm_year == -1)
201 alarm->time.tm_year = now.tm_year;
202 return 0;
203}
122EXPORT_SYMBOL_GPL(rtc_read_alarm); 204EXPORT_SYMBOL_GPL(rtc_read_alarm);
123 205
124int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm) 206int rtc_set_alarm(struct rtc_device *rtc, struct rtc_wkalrm *alarm)
@@ -210,6 +292,10 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
210 if (task == NULL || task->func == NULL) 292 if (task == NULL || task->func == NULL)
211 return -EINVAL; 293 return -EINVAL;
212 294
295 /* Cannot register while the char dev is in use */
296 if (!(mutex_trylock(&rtc->char_lock)))
297 return -EBUSY;
298
213 spin_lock_irq(&rtc->irq_task_lock); 299 spin_lock_irq(&rtc->irq_task_lock);
214 if (rtc->irq_task == NULL) { 300 if (rtc->irq_task == NULL) {
215 rtc->irq_task = task; 301 rtc->irq_task = task;
@@ -217,13 +303,14 @@ int rtc_irq_register(struct rtc_device *rtc, struct rtc_task *task)
217 } 303 }
218 spin_unlock_irq(&rtc->irq_task_lock); 304 spin_unlock_irq(&rtc->irq_task_lock);
219 305
306 mutex_unlock(&rtc->char_lock);
307
220 return retval; 308 return retval;
221} 309}
222EXPORT_SYMBOL_GPL(rtc_irq_register); 310EXPORT_SYMBOL_GPL(rtc_irq_register);
223 311
224void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task) 312void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
225{ 313{
226
227 spin_lock_irq(&rtc->irq_task_lock); 314 spin_lock_irq(&rtc->irq_task_lock);
228 if (rtc->irq_task == task) 315 if (rtc->irq_task == task)
229 rtc->irq_task = NULL; 316 rtc->irq_task = NULL;
@@ -231,6 +318,16 @@ void rtc_irq_unregister(struct rtc_device *rtc, struct rtc_task *task)
231} 318}
232EXPORT_SYMBOL_GPL(rtc_irq_unregister); 319EXPORT_SYMBOL_GPL(rtc_irq_unregister);
233 320
321/**
322 * rtc_irq_set_state - enable/disable 2^N Hz periodic IRQs
323 * @rtc: the rtc device
324 * @task: currently registered with rtc_irq_register()
325 * @enabled: true to enable periodic IRQs
326 * Context: any
327 *
328 * Note that rtc_irq_set_freq() should previously have been used to
329 * specify the desired frequency of periodic IRQ task->func() callbacks.
330 */
234int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled) 331int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled)
235{ 332{
236 int err = 0; 333 int err = 0;
@@ -240,8 +337,10 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled
240 return -ENXIO; 337 return -ENXIO;
241 338
242 spin_lock_irqsave(&rtc->irq_task_lock, flags); 339 spin_lock_irqsave(&rtc->irq_task_lock, flags);
340 if (rtc->irq_task != NULL && task == NULL)
341 err = -EBUSY;
243 if (rtc->irq_task != task) 342 if (rtc->irq_task != task)
244 err = -ENXIO; 343 err = -EACCES;
245 spin_unlock_irqrestore(&rtc->irq_task_lock, flags); 344 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
246 345
247 if (err == 0) 346 if (err == 0)
@@ -251,6 +350,16 @@ int rtc_irq_set_state(struct rtc_device *rtc, struct rtc_task *task, int enabled
251} 350}
252EXPORT_SYMBOL_GPL(rtc_irq_set_state); 351EXPORT_SYMBOL_GPL(rtc_irq_set_state);
253 352
353/**
354 * rtc_irq_set_freq - set 2^N Hz periodic IRQ frequency for IRQ
355 * @rtc: the rtc device
356 * @task: currently registered with rtc_irq_register()
357 * @freq: positive frequency with which task->func() will be called
358 * Context: any
359 *
360 * Note that rtc_irq_set_state() is used to enable or disable the
361 * periodic IRQs.
362 */
254int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq) 363int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
255{ 364{
256 int err = 0; 365 int err = 0;
@@ -259,9 +368,14 @@ int rtc_irq_set_freq(struct rtc_device *rtc, struct rtc_task *task, int freq)
259 if (rtc->ops->irq_set_freq == NULL) 368 if (rtc->ops->irq_set_freq == NULL)
260 return -ENXIO; 369 return -ENXIO;
261 370
371 if (!is_power_of_2(freq))
372 return -EINVAL;
373
262 spin_lock_irqsave(&rtc->irq_task_lock, flags); 374 spin_lock_irqsave(&rtc->irq_task_lock, flags);
375 if (rtc->irq_task != NULL && task == NULL)
376 err = -EBUSY;
263 if (rtc->irq_task != task) 377 if (rtc->irq_task != task)
264 err = -ENXIO; 378 err = -EACCES;
265 spin_unlock_irqrestore(&rtc->irq_task_lock, flags); 379 spin_unlock_irqrestore(&rtc->irq_task_lock, flags);
266 380
267 if (err == 0) { 381 if (err == 0) {
diff --git a/drivers/rtc/rtc-cmos.c b/drivers/rtc/rtc-cmos.c
index 5d760bb6c2cd..e3fe83a23cf7 100644
--- a/drivers/rtc/rtc-cmos.c
+++ b/drivers/rtc/rtc-cmos.c
@@ -246,11 +246,9 @@ static int cmos_irq_set_freq(struct device *dev, int freq)
246 246
247 /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */ 247 /* 0 = no irqs; 1 = 2^15 Hz ... 15 = 2^0 Hz */
248 f = ffs(freq); 248 f = ffs(freq);
249 if (f != 0) { 249 if (f-- > 16)
250 if (f-- > 16 || freq != (1 << f)) 250 return -EINVAL;
251 return -EINVAL; 251 f = 16 - f;
252 f = 16 - f;
253 }
254 252
255 spin_lock_irqsave(&rtc_lock, flags); 253 spin_lock_irqsave(&rtc_lock, flags);
256 CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT); 254 CMOS_WRITE(RTC_REF_CLCK_32KHZ | f, RTC_FREQ_SELECT);
@@ -435,6 +433,19 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
435 if (!ports) 433 if (!ports)
436 return -ENODEV; 434 return -ENODEV;
437 435
436 /* Claim I/O ports ASAP, minimizing conflict with legacy driver.
437 *
438 * REVISIT non-x86 systems may instead use memory space resources
439 * (needing ioremap etc), not i/o space resources like this ...
440 */
441 ports = request_region(ports->start,
442 ports->end + 1 - ports->start,
443 driver_name);
444 if (!ports) {
445 dev_dbg(dev, "i/o registers already in use\n");
446 return -EBUSY;
447 }
448
438 cmos_rtc.irq = rtc_irq; 449 cmos_rtc.irq = rtc_irq;
439 cmos_rtc.iomem = ports; 450 cmos_rtc.iomem = ports;
440 451
@@ -456,24 +467,13 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
456 467
457 cmos_rtc.rtc = rtc_device_register(driver_name, dev, 468 cmos_rtc.rtc = rtc_device_register(driver_name, dev,
458 &cmos_rtc_ops, THIS_MODULE); 469 &cmos_rtc_ops, THIS_MODULE);
459 if (IS_ERR(cmos_rtc.rtc)) 470 if (IS_ERR(cmos_rtc.rtc)) {
460 return PTR_ERR(cmos_rtc.rtc); 471 retval = PTR_ERR(cmos_rtc.rtc);
472 goto cleanup0;
473 }
461 474
462 cmos_rtc.dev = dev; 475 cmos_rtc.dev = dev;
463 dev_set_drvdata(dev, &cmos_rtc); 476 dev_set_drvdata(dev, &cmos_rtc);
464
465 /* platform and pnp busses handle resources incompatibly.
466 *
467 * REVISIT for non-x86 systems we may need to handle io memory
468 * resources: ioremap them, and request_mem_region().
469 */
470 if (is_pnp()) {
471 retval = request_resource(&ioport_resource, ports);
472 if (retval < 0) {
473 dev_dbg(dev, "i/o registers already in use\n");
474 goto cleanup0;
475 }
476 }
477 rename_region(ports, cmos_rtc.rtc->dev.bus_id); 477 rename_region(ports, cmos_rtc.rtc->dev.bus_id);
478 478
479 spin_lock_irq(&rtc_lock); 479 spin_lock_irq(&rtc_lock);
@@ -536,9 +536,10 @@ cmos_do_probe(struct device *dev, struct resource *ports, int rtc_irq)
536 return 0; 536 return 0;
537 537
538cleanup1: 538cleanup1:
539 rename_region(ports, NULL); 539 cmos_rtc.dev = NULL;
540cleanup0:
541 rtc_device_unregister(cmos_rtc.rtc); 540 rtc_device_unregister(cmos_rtc.rtc);
541cleanup0:
542 release_region(ports->start, ports->end + 1 - ports->start);
542 return retval; 543 return retval;
543} 544}
544 545
@@ -557,19 +558,21 @@ static void cmos_do_shutdown(void)
557static void __exit cmos_do_remove(struct device *dev) 558static void __exit cmos_do_remove(struct device *dev)
558{ 559{
559 struct cmos_rtc *cmos = dev_get_drvdata(dev); 560 struct cmos_rtc *cmos = dev_get_drvdata(dev);
561 struct resource *ports;
560 562
561 cmos_do_shutdown(); 563 cmos_do_shutdown();
562 564
563 if (is_pnp())
564 release_resource(cmos->iomem);
565 rename_region(cmos->iomem, NULL);
566
567 if (is_valid_irq(cmos->irq)) 565 if (is_valid_irq(cmos->irq))
568 free_irq(cmos->irq, cmos_rtc.rtc); 566 free_irq(cmos->irq, cmos->rtc);
569 567
570 rtc_device_unregister(cmos_rtc.rtc); 568 rtc_device_unregister(cmos->rtc);
569 cmos->rtc = NULL;
571 570
572 cmos_rtc.dev = NULL; 571 ports = cmos->iomem;
572 release_region(ports->start, ports->end + 1 - ports->start);
573 cmos->iomem = NULL;
574
575 cmos->dev = NULL;
573 dev_set_drvdata(dev, NULL); 576 dev_set_drvdata(dev, NULL);
574} 577}
575 578
@@ -656,7 +659,8 @@ static int cmos_resume(struct device *dev)
656/*----------------------------------------------------------------*/ 659/*----------------------------------------------------------------*/
657 660
658/* The "CMOS" RTC normally lives on the platform_bus. On ACPI systems, 661/* The "CMOS" RTC normally lives on the platform_bus. On ACPI systems,
659 * the device node will always be created as a PNPACPI device. 662 * the device node will always be created as a PNPACPI device. Plus
663 * pre-ACPI PCs probably list it in the PNPBIOS tables.
660 */ 664 */
661 665
662#ifdef CONFIG_PNP 666#ifdef CONFIG_PNP
diff --git a/drivers/rtc/rtc-dev.c b/drivers/rtc/rtc-dev.c
index 005fff3a3508..814583bd2fe7 100644
--- a/drivers/rtc/rtc-dev.c
+++ b/drivers/rtc/rtc-dev.c
@@ -142,7 +142,7 @@ static int set_uie(struct rtc_device *rtc)
142static ssize_t 142static ssize_t
143rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos) 143rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
144{ 144{
145 struct rtc_device *rtc = to_rtc_device(file->private_data); 145 struct rtc_device *rtc = file->private_data;
146 146
147 DECLARE_WAITQUEUE(wait, current); 147 DECLARE_WAITQUEUE(wait, current);
148 unsigned long data; 148 unsigned long data;
@@ -196,7 +196,7 @@ rtc_dev_read(struct file *file, char __user *buf, size_t count, loff_t *ppos)
196 196
197static unsigned int rtc_dev_poll(struct file *file, poll_table *wait) 197static unsigned int rtc_dev_poll(struct file *file, poll_table *wait)
198{ 198{
199 struct rtc_device *rtc = to_rtc_device(file->private_data); 199 struct rtc_device *rtc = file->private_data;
200 unsigned long data; 200 unsigned long data;
201 201
202 poll_wait(file, &rtc->irq_queue, wait); 202 poll_wait(file, &rtc->irq_queue, wait);
@@ -233,22 +233,12 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
233 break; 233 break;
234 234
235 case RTC_PIE_ON: 235 case RTC_PIE_ON:
236 if (!capable(CAP_SYS_RESOURCE)) 236 if (rtc->irq_freq > rtc->max_user_freq &&
237 !capable(CAP_SYS_RESOURCE))
237 return -EACCES; 238 return -EACCES;
238 break; 239 break;
239 } 240 }
240 241
241 /* avoid conflicting IRQ users */
242 if (cmd == RTC_PIE_ON || cmd == RTC_PIE_OFF || cmd == RTC_IRQP_SET) {
243 spin_lock_irq(&rtc->irq_task_lock);
244 if (rtc->irq_task)
245 err = -EBUSY;
246 spin_unlock_irq(&rtc->irq_task_lock);
247
248 if (err < 0)
249 return err;
250 }
251
252 /* try the driver's ioctl interface */ 242 /* try the driver's ioctl interface */
253 if (ops->ioctl) { 243 if (ops->ioctl) {
254 err = ops->ioctl(rtc->dev.parent, cmd, arg); 244 err = ops->ioctl(rtc->dev.parent, cmd, arg);
@@ -338,18 +328,20 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
338 err = rtc_set_time(rtc, &tm); 328 err = rtc_set_time(rtc, &tm);
339 break; 329 break;
340 330
341 case RTC_IRQP_READ: 331 case RTC_PIE_ON:
342 if (ops->irq_set_freq) 332 err = rtc_irq_set_state(rtc, NULL, 1);
343 err = put_user(rtc->irq_freq, (unsigned long __user *)uarg); 333 break;
344 else 334
345 err = -ENOTTY; 335 case RTC_PIE_OFF:
336 err = rtc_irq_set_state(rtc, NULL, 0);
346 break; 337 break;
347 338
348 case RTC_IRQP_SET: 339 case RTC_IRQP_SET:
349 if (ops->irq_set_freq) 340 err = rtc_irq_set_freq(rtc, NULL, arg);
350 err = rtc_irq_set_freq(rtc, rtc->irq_task, arg); 341 break;
351 else 342
352 err = -ENOTTY; 343 case RTC_IRQP_READ:
344 err = put_user(rtc->irq_freq, (unsigned long __user *)uarg);
353 break; 345 break;
354 346
355#if 0 347#if 0
@@ -405,7 +397,7 @@ static int rtc_dev_ioctl(struct inode *inode, struct file *file,
405 397
406static int rtc_dev_release(struct inode *inode, struct file *file) 398static int rtc_dev_release(struct inode *inode, struct file *file)
407{ 399{
408 struct rtc_device *rtc = to_rtc_device(file->private_data); 400 struct rtc_device *rtc = file->private_data;
409 401
410#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL 402#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
411 clear_uie(rtc); 403 clear_uie(rtc);
@@ -419,7 +411,7 @@ static int rtc_dev_release(struct inode *inode, struct file *file)
419 411
420static int rtc_dev_fasync(int fd, struct file *file, int on) 412static int rtc_dev_fasync(int fd, struct file *file, int on)
421{ 413{
422 struct rtc_device *rtc = to_rtc_device(file->private_data); 414 struct rtc_device *rtc = file->private_data;
423 return fasync_helper(fd, file, on, &rtc->async_queue); 415 return fasync_helper(fd, file, on, &rtc->async_queue);
424} 416}
425 417
@@ -449,8 +441,6 @@ void rtc_dev_prepare(struct rtc_device *rtc)
449 rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id); 441 rtc->dev.devt = MKDEV(MAJOR(rtc_devt), rtc->id);
450 442
451 mutex_init(&rtc->char_lock); 443 mutex_init(&rtc->char_lock);
452 spin_lock_init(&rtc->irq_lock);
453 init_waitqueue_head(&rtc->irq_queue);
454#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL 444#ifdef CONFIG_RTC_INTF_DEV_UIE_EMUL
455 INIT_WORK(&rtc->uie_task, rtc_uie_task); 445 INIT_WORK(&rtc->uie_task, rtc_uie_task);
456 setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc); 446 setup_timer(&rtc->uie_timer, rtc_uie_timer, (unsigned long)rtc);
diff --git a/drivers/rtc/rtc-ds1374.c b/drivers/rtc/rtc-ds1374.c
new file mode 100644
index 000000000000..45bda186befc
--- /dev/null
+++ b/drivers/rtc/rtc-ds1374.c
@@ -0,0 +1,449 @@
1/*
2 * RTC client/driver for the Maxim/Dallas DS1374 Real-Time Clock over I2C
3 *
4 * Based on code by Randy Vinson <rvinson@mvista.com>,
5 * which was based on the m41t00.c by Mark Greer <mgreer@mvista.com>.
6 *
7 * Copyright (C) 2006-2007 Freescale Semiconductor
8 *
9 * 2005 (c) MontaVista Software, Inc. This file is licensed under
10 * the terms of the GNU General Public License version 2. This program
11 * is licensed "as is" without any warranty of any kind, whether express
12 * or implied.
13 */
14/*
15 * It would be more efficient to use i2c msgs/i2c_transfer directly but, as
16 * recommened in .../Documentation/i2c/writing-clients section
17 * "Sending and receiving", using SMBus level communication is preferred.
18 */
19
20#include <linux/kernel.h>
21#include <linux/module.h>
22#include <linux/interrupt.h>
23#include <linux/i2c.h>
24#include <linux/rtc.h>
25#include <linux/bcd.h>
26#include <linux/workqueue.h>
27
28#define DS1374_REG_TOD0 0x00 /* Time of Day */
29#define DS1374_REG_TOD1 0x01
30#define DS1374_REG_TOD2 0x02
31#define DS1374_REG_TOD3 0x03
32#define DS1374_REG_WDALM0 0x04 /* Watchdog/Alarm */
33#define DS1374_REG_WDALM1 0x05
34#define DS1374_REG_WDALM2 0x06
35#define DS1374_REG_CR 0x07 /* Control */
36#define DS1374_REG_CR_AIE 0x01 /* Alarm Int. Enable */
37#define DS1374_REG_CR_WDALM 0x20 /* 1=Watchdog, 0=Alarm */
38#define DS1374_REG_CR_WACE 0x40 /* WD/Alarm counter enable */
39#define DS1374_REG_SR 0x08 /* Status */
40#define DS1374_REG_SR_OSF 0x80 /* Oscillator Stop Flag */
41#define DS1374_REG_SR_AF 0x01 /* Alarm Flag */
42#define DS1374_REG_TCR 0x09 /* Trickle Charge */
43
44struct ds1374 {
45 struct i2c_client *client;
46 struct rtc_device *rtc;
47 struct work_struct work;
48
49 /* The mutex protects alarm operations, and prevents a race
50 * between the enable_irq() in the workqueue and the free_irq()
51 * in the remove function.
52 */
53 struct mutex mutex;
54 int exiting;
55};
56
57static struct i2c_driver ds1374_driver;
58
59static int ds1374_read_rtc(struct i2c_client *client, u32 *time,
60 int reg, int nbytes)
61{
62 u8 buf[4];
63 int ret;
64 int i;
65
66 if (nbytes > 4) {
67 WARN_ON(1);
68 return -EINVAL;
69 }
70
71 ret = i2c_smbus_read_i2c_block_data(client, reg, nbytes, buf);
72
73 if (ret < 0)
74 return ret;
75 if (ret < nbytes)
76 return -EIO;
77
78 for (i = nbytes - 1, *time = 0; i >= 0; i--)
79 *time = (*time << 8) | buf[i];
80
81 return 0;
82}
83
84static int ds1374_write_rtc(struct i2c_client *client, u32 time,
85 int reg, int nbytes)
86{
87 u8 buf[4];
88 int i;
89
90 if (nbytes > 4) {
91 WARN_ON(1);
92 return -EINVAL;
93 }
94
95 for (i = 0; i < nbytes; i++) {
96 buf[i] = time & 0xff;
97 time >>= 8;
98 }
99
100 return i2c_smbus_write_i2c_block_data(client, reg, nbytes, buf);
101}
102
103static int ds1374_check_rtc_status(struct i2c_client *client)
104{
105 int ret = 0;
106 int control, stat;
107
108 stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
109 if (stat < 0)
110 return stat;
111
112 if (stat & DS1374_REG_SR_OSF)
113 dev_warn(&client->dev,
114 "oscillator discontinuity flagged, "
115 "time unreliable\n");
116
117 stat &= ~(DS1374_REG_SR_OSF | DS1374_REG_SR_AF);
118
119 ret = i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat);
120 if (ret < 0)
121 return ret;
122
123 /* If the alarm is pending, clear it before requesting
124 * the interrupt, so an interrupt event isn't reported
125 * before everything is initialized.
126 */
127
128 control = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
129 if (control < 0)
130 return control;
131
132 control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE);
133 return i2c_smbus_write_byte_data(client, DS1374_REG_CR, control);
134}
135
136static int ds1374_read_time(struct device *dev, struct rtc_time *time)
137{
138 struct i2c_client *client = to_i2c_client(dev);
139 u32 itime;
140 int ret;
141
142 ret = ds1374_read_rtc(client, &itime, DS1374_REG_TOD0, 4);
143 if (!ret)
144 rtc_time_to_tm(itime, time);
145
146 return ret;
147}
148
149static int ds1374_set_time(struct device *dev, struct rtc_time *time)
150{
151 struct i2c_client *client = to_i2c_client(dev);
152 unsigned long itime;
153
154 rtc_tm_to_time(time, &itime);
155 return ds1374_write_rtc(client, itime, DS1374_REG_TOD0, 4);
156}
157
158/* The ds1374 has a decrementer for an alarm, rather than a comparator.
159 * If the time of day is changed, then the alarm will need to be
160 * reset.
161 */
162static int ds1374_read_alarm(struct device *dev, struct rtc_wkalrm *alarm)
163{
164 struct i2c_client *client = to_i2c_client(dev);
165 struct ds1374 *ds1374 = i2c_get_clientdata(client);
166 u32 now, cur_alarm;
167 int cr, sr;
168 int ret = 0;
169
170 if (client->irq < 0)
171 return -EINVAL;
172
173 mutex_lock(&ds1374->mutex);
174
175 cr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
176 if (ret < 0)
177 goto out;
178
179 sr = ret = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
180 if (ret < 0)
181 goto out;
182
183 ret = ds1374_read_rtc(client, &now, DS1374_REG_TOD0, 4);
184 if (ret)
185 goto out;
186
187 ret = ds1374_read_rtc(client, &cur_alarm, DS1374_REG_WDALM0, 3);
188 if (ret)
189 goto out;
190
191 rtc_time_to_tm(now + cur_alarm, &alarm->time);
192 alarm->enabled = !!(cr & DS1374_REG_CR_WACE);
193 alarm->pending = !!(sr & DS1374_REG_SR_AF);
194
195out:
196 mutex_unlock(&ds1374->mutex);
197 return ret;
198}
199
200static int ds1374_set_alarm(struct device *dev, struct rtc_wkalrm *alarm)
201{
202 struct i2c_client *client = to_i2c_client(dev);
203 struct ds1374 *ds1374 = i2c_get_clientdata(client);
204 struct rtc_time now;
205 unsigned long new_alarm, itime;
206 int cr;
207 int ret = 0;
208
209 if (client->irq < 0)
210 return -EINVAL;
211
212 ret = ds1374_read_time(dev, &now);
213 if (ret < 0)
214 return ret;
215
216 rtc_tm_to_time(&alarm->time, &new_alarm);
217 rtc_tm_to_time(&now, &itime);
218
219 new_alarm -= itime;
220
221 /* This can happen due to races, in addition to dates that are
222 * truly in the past. To avoid requiring the caller to check for
223 * races, dates in the past are assumed to be in the recent past
224 * (i.e. not something that we'd rather the caller know about via
225 * an error), and the alarm is set to go off as soon as possible.
226 */
227 if (new_alarm <= 0)
228 new_alarm = 1;
229
230 mutex_lock(&ds1374->mutex);
231
232 ret = cr = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
233 if (ret < 0)
234 goto out;
235
236 /* Disable any existing alarm before setting the new one
237 * (or lack thereof). */
238 cr &= ~DS1374_REG_CR_WACE;
239
240 ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
241 if (ret < 0)
242 goto out;
243
244 ret = ds1374_write_rtc(client, new_alarm, DS1374_REG_WDALM0, 3);
245 if (ret)
246 goto out;
247
248 if (alarm->enabled) {
249 cr |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
250 cr &= ~DS1374_REG_CR_WDALM;
251
252 ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, cr);
253 }
254
255out:
256 mutex_unlock(&ds1374->mutex);
257 return ret;
258}
259
260static irqreturn_t ds1374_irq(int irq, void *dev_id)
261{
262 struct i2c_client *client = dev_id;
263 struct ds1374 *ds1374 = i2c_get_clientdata(client);
264
265 disable_irq_nosync(irq);
266 schedule_work(&ds1374->work);
267 return IRQ_HANDLED;
268}
269
270static void ds1374_work(struct work_struct *work)
271{
272 struct ds1374 *ds1374 = container_of(work, struct ds1374, work);
273 struct i2c_client *client = ds1374->client;
274 int stat, control;
275
276 mutex_lock(&ds1374->mutex);
277
278 stat = i2c_smbus_read_byte_data(client, DS1374_REG_SR);
279 if (stat < 0)
280 return;
281
282 if (stat & DS1374_REG_SR_AF) {
283 stat &= ~DS1374_REG_SR_AF;
284 i2c_smbus_write_byte_data(client, DS1374_REG_SR, stat);
285
286 control = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
287 if (control < 0)
288 goto out;
289
290 control &= ~(DS1374_REG_CR_WACE | DS1374_REG_CR_AIE);
291 i2c_smbus_write_byte_data(client, DS1374_REG_CR, control);
292
293 /* rtc_update_irq() assumes that it is called
294 * from IRQ-disabled context.
295 */
296 local_irq_disable();
297 rtc_update_irq(ds1374->rtc, 1, RTC_AF | RTC_IRQF);
298 local_irq_enable();
299 }
300
301out:
302 if (!ds1374->exiting)
303 enable_irq(client->irq);
304
305 mutex_unlock(&ds1374->mutex);
306}
307
308static int ds1374_ioctl(struct device *dev, unsigned int cmd, unsigned long arg)
309{
310 struct i2c_client *client = to_i2c_client(dev);
311 struct ds1374 *ds1374 = i2c_get_clientdata(client);
312 int ret = -ENOIOCTLCMD;
313
314 mutex_lock(&ds1374->mutex);
315
316 switch (cmd) {
317 case RTC_AIE_OFF:
318 ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
319 if (ret < 0)
320 goto out;
321
322 ret &= ~DS1374_REG_CR_WACE;
323
324 ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
325 if (ret < 0)
326 goto out;
327
328 break;
329
330 case RTC_AIE_ON:
331 ret = i2c_smbus_read_byte_data(client, DS1374_REG_CR);
332 if (ret < 0)
333 goto out;
334
335 ret |= DS1374_REG_CR_WACE | DS1374_REG_CR_AIE;
336 ret &= ~DS1374_REG_CR_WDALM;
337
338 ret = i2c_smbus_write_byte_data(client, DS1374_REG_CR, ret);
339 if (ret < 0)
340 goto out;
341
342 break;
343 }
344
345out:
346 mutex_unlock(&ds1374->mutex);
347 return ret;
348}
349
350static const struct rtc_class_ops ds1374_rtc_ops = {
351 .read_time = ds1374_read_time,
352 .set_time = ds1374_set_time,
353 .read_alarm = ds1374_read_alarm,
354 .set_alarm = ds1374_set_alarm,
355 .ioctl = ds1374_ioctl,
356};
357
358static int ds1374_probe(struct i2c_client *client)
359{
360 struct ds1374 *ds1374;
361 int ret;
362
363 ds1374 = kzalloc(sizeof(struct ds1374), GFP_KERNEL);
364 if (!ds1374)
365 return -ENOMEM;
366
367 ds1374->client = client;
368 i2c_set_clientdata(client, ds1374);
369
370 INIT_WORK(&ds1374->work, ds1374_work);
371 mutex_init(&ds1374->mutex);
372
373 ret = ds1374_check_rtc_status(client);
374 if (ret)
375 goto out_free;
376
377 if (client->irq >= 0) {
378 ret = request_irq(client->irq, ds1374_irq, 0,
379 "ds1374", client);
380 if (ret) {
381 dev_err(&client->dev, "unable to request IRQ\n");
382 goto out_free;
383 }
384 }
385
386 ds1374->rtc = rtc_device_register(client->name, &client->dev,
387 &ds1374_rtc_ops, THIS_MODULE);
388 if (IS_ERR(ds1374->rtc)) {
389 ret = PTR_ERR(ds1374->rtc);
390 dev_err(&client->dev, "unable to register the class device\n");
391 goto out_irq;
392 }
393
394 return 0;
395
396out_irq:
397 if (client->irq >= 0)
398 free_irq(client->irq, client);
399
400out_free:
401 i2c_set_clientdata(client, NULL);
402 kfree(ds1374);
403 return ret;
404}
405
406static int __devexit ds1374_remove(struct i2c_client *client)
407{
408 struct ds1374 *ds1374 = i2c_get_clientdata(client);
409
410 if (client->irq >= 0) {
411 mutex_lock(&ds1374->mutex);
412 ds1374->exiting = 1;
413 mutex_unlock(&ds1374->mutex);
414
415 free_irq(client->irq, client);
416 flush_scheduled_work();
417 }
418
419 rtc_device_unregister(ds1374->rtc);
420 i2c_set_clientdata(client, NULL);
421 kfree(ds1374);
422 return 0;
423}
424
425static struct i2c_driver ds1374_driver = {
426 .driver = {
427 .name = "rtc-ds1374",
428 .owner = THIS_MODULE,
429 },
430 .probe = ds1374_probe,
431 .remove = __devexit_p(ds1374_remove),
432};
433
434static int __init ds1374_init(void)
435{
436 return i2c_add_driver(&ds1374_driver);
437}
438
439static void __exit ds1374_exit(void)
440{
441 i2c_del_driver(&ds1374_driver);
442}
443
444module_init(ds1374_init);
445module_exit(ds1374_exit);
446
447MODULE_AUTHOR("Scott Wood <scottwood@freescale.com>");
448MODULE_DESCRIPTION("Maxim/Dallas DS1374 RTC Driver");
449MODULE_LICENSE("GPL");
diff --git a/drivers/rtc/rtc-ds1553.c b/drivers/rtc/rtc-ds1553.c
index 5ab3492817d1..bb53c09bad16 100644
--- a/drivers/rtc/rtc-ds1553.c
+++ b/drivers/rtc/rtc-ds1553.c
@@ -395,7 +395,7 @@ static struct platform_driver ds1553_rtc_driver = {
395 .probe = ds1553_rtc_probe, 395 .probe = ds1553_rtc_probe,
396 .remove = __devexit_p(ds1553_rtc_remove), 396 .remove = __devexit_p(ds1553_rtc_remove),
397 .driver = { 397 .driver = {
398 .name = "ds1553", 398 .name = "rtc-ds1553",
399 .owner = THIS_MODULE, 399 .owner = THIS_MODULE,
400 }, 400 },
401}; 401};
diff --git a/drivers/rtc/rtc-ds1742.c b/drivers/rtc/rtc-ds1742.c
index 67291b0f8283..c535b78698e2 100644
--- a/drivers/rtc/rtc-ds1742.c
+++ b/drivers/rtc/rtc-ds1742.c
@@ -251,7 +251,7 @@ static struct platform_driver ds1742_rtc_driver = {
251 .probe = ds1742_rtc_probe, 251 .probe = ds1742_rtc_probe,
252 .remove = __devexit_p(ds1742_rtc_remove), 252 .remove = __devexit_p(ds1742_rtc_remove),
253 .driver = { 253 .driver = {
254 .name = "ds1742", 254 .name = "rtc-ds1742",
255 .owner = THIS_MODULE, 255 .owner = THIS_MODULE,
256 }, 256 },
257}; 257};
diff --git a/drivers/rtc/rtc-pcf8583.c b/drivers/rtc/rtc-pcf8583.c
index d48b03374586..556d0e7da35b 100644
--- a/drivers/rtc/rtc-pcf8583.c
+++ b/drivers/rtc/rtc-pcf8583.c
@@ -332,6 +332,9 @@ static int pcf8583_probe(struct i2c_adapter *adap, int addr, int kind)
332 } 332 }
333 }; 333 };
334 334
335 if (!i2c_check_functionality(adap, I2C_FUNC_I2C))
336 return 0;
337
335 pcf = kzalloc(sizeof(*pcf), GFP_KERNEL); 338 pcf = kzalloc(sizeof(*pcf), GFP_KERNEL);
336 if (!pcf) 339 if (!pcf)
337 return -ENOMEM; 340 return -ENOMEM;
diff --git a/drivers/rtc/rtc-sysfs.c b/drivers/rtc/rtc-sysfs.c
index 69df94b44841..6cad0841f3c4 100644
--- a/drivers/rtc/rtc-sysfs.c
+++ b/drivers/rtc/rtc-sysfs.c
@@ -73,11 +73,35 @@ rtc_sysfs_show_since_epoch(struct device *dev, struct device_attribute *attr,
73 return retval; 73 return retval;
74} 74}
75 75
76static ssize_t
77rtc_sysfs_show_max_user_freq(struct device *dev, struct device_attribute *attr,
78 char *buf)
79{
80 return sprintf(buf, "%d\n", to_rtc_device(dev)->max_user_freq);
81}
82
83static ssize_t
84rtc_sysfs_set_max_user_freq(struct device *dev, struct device_attribute *attr,
85 const char *buf, size_t n)
86{
87 struct rtc_device *rtc = to_rtc_device(dev);
88 unsigned long val = simple_strtoul(buf, NULL, 0);
89
90 if (val >= 4096 || val == 0)
91 return -EINVAL;
92
93 rtc->max_user_freq = (int)val;
94
95 return n;
96}
97
76static struct device_attribute rtc_attrs[] = { 98static struct device_attribute rtc_attrs[] = {
77 __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL), 99 __ATTR(name, S_IRUGO, rtc_sysfs_show_name, NULL),
78 __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL), 100 __ATTR(date, S_IRUGO, rtc_sysfs_show_date, NULL),
79 __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL), 101 __ATTR(time, S_IRUGO, rtc_sysfs_show_time, NULL),
80 __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL), 102 __ATTR(since_epoch, S_IRUGO, rtc_sysfs_show_since_epoch, NULL),
103 __ATTR(max_user_freq, S_IRUGO | S_IWUSR, rtc_sysfs_show_max_user_freq,
104 rtc_sysfs_set_max_user_freq),
81 { }, 105 { },
82}; 106};
83 107
diff --git a/drivers/s390/scsi/zfcp_def.h b/drivers/s390/scsi/zfcp_def.h
index 16e5563e0c65..57cac7008e0b 100644
--- a/drivers/s390/scsi/zfcp_def.h
+++ b/drivers/s390/scsi/zfcp_def.h
@@ -34,6 +34,7 @@
34#include <linux/slab.h> 34#include <linux/slab.h>
35#include <linux/mempool.h> 35#include <linux/mempool.h>
36#include <linux/syscalls.h> 36#include <linux/syscalls.h>
37#include <linux/scatterlist.h>
37#include <linux/ioctl.h> 38#include <linux/ioctl.h>
38#include <scsi/scsi.h> 39#include <scsi/scsi.h>
39#include <scsi/scsi_tcq.h> 40#include <scsi/scsi_tcq.h>
diff --git a/drivers/s390/scsi/zfcp_qdio.c b/drivers/s390/scsi/zfcp_qdio.c
index 3f105fdcf239..51d92b196ee7 100644
--- a/drivers/s390/scsi/zfcp_qdio.c
+++ b/drivers/s390/scsi/zfcp_qdio.c
@@ -590,7 +590,7 @@ zfcp_qdio_sbals_from_segment(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
590 */ 590 */
591int 591int
592zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype, 592zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
593 struct scatterlist *sg, int sg_count, int max_sbals) 593 struct scatterlist *sgl, int sg_count, int max_sbals)
594{ 594{
595 int sg_index; 595 int sg_index;
596 struct scatterlist *sg_segment; 596 struct scatterlist *sg_segment;
@@ -606,9 +606,7 @@ zfcp_qdio_sbals_from_sg(struct zfcp_fsf_req *fsf_req, unsigned long sbtype,
606 sbale->flags |= sbtype; 606 sbale->flags |= sbtype;
607 607
608 /* process all segements of scatter-gather list */ 608 /* process all segements of scatter-gather list */
609 for (sg_index = 0, sg_segment = sg, bytes = 0; 609 for_each_sg(sgl, sg_segment, sg_count, sg_index) {
610 sg_index < sg_count;
611 sg_index++, sg_segment++) {
612 retval = zfcp_qdio_sbals_from_segment( 610 retval = zfcp_qdio_sbals_from_segment(
613 fsf_req, 611 fsf_req,
614 sbtype, 612 sbtype,
diff --git a/drivers/scsi/3w-9xxx.c b/drivers/scsi/3w-9xxx.c
index efd9d8d3a890..fb14014ee16e 100644
--- a/drivers/scsi/3w-9xxx.c
+++ b/drivers/scsi/3w-9xxx.c
@@ -1990,6 +1990,7 @@ static struct scsi_host_template driver_template = {
1990 .max_sectors = TW_MAX_SECTORS, 1990 .max_sectors = TW_MAX_SECTORS,
1991 .cmd_per_lun = TW_MAX_CMDS_PER_LUN, 1991 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
1992 .use_clustering = ENABLE_CLUSTERING, 1992 .use_clustering = ENABLE_CLUSTERING,
1993 .use_sg_chaining = ENABLE_SG_CHAINING,
1993 .shost_attrs = twa_host_attrs, 1994 .shost_attrs = twa_host_attrs,
1994 .emulated = 1 1995 .emulated = 1
1995}; 1996};
diff --git a/drivers/scsi/3w-xxxx.c b/drivers/scsi/3w-xxxx.c
index c7995fc216e8..a64153b96034 100644
--- a/drivers/scsi/3w-xxxx.c
+++ b/drivers/scsi/3w-xxxx.c
@@ -2261,6 +2261,7 @@ static struct scsi_host_template driver_template = {
2261 .max_sectors = TW_MAX_SECTORS, 2261 .max_sectors = TW_MAX_SECTORS,
2262 .cmd_per_lun = TW_MAX_CMDS_PER_LUN, 2262 .cmd_per_lun = TW_MAX_CMDS_PER_LUN,
2263 .use_clustering = ENABLE_CLUSTERING, 2263 .use_clustering = ENABLE_CLUSTERING,
2264 .use_sg_chaining = ENABLE_SG_CHAINING,
2264 .shost_attrs = tw_host_attrs, 2265 .shost_attrs = tw_host_attrs,
2265 .emulated = 1 2266 .emulated = 1
2266}; 2267};
diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c
index 9b206176f717..49e1ffa4b2ff 100644
--- a/drivers/scsi/BusLogic.c
+++ b/drivers/scsi/BusLogic.c
@@ -3575,6 +3575,7 @@ static struct scsi_host_template Bus_Logic_template = {
3575 .unchecked_isa_dma = 1, 3575 .unchecked_isa_dma = 1,
3576 .max_sectors = 128, 3576 .max_sectors = 128,
3577 .use_clustering = ENABLE_CLUSTERING, 3577 .use_clustering = ENABLE_CLUSTERING,
3578 .use_sg_chaining = ENABLE_SG_CHAINING,
3578}; 3579};
3579 3580
3580/* 3581/*
diff --git a/drivers/scsi/NCR53c406a.c b/drivers/scsi/NCR53c406a.c
index eda8c48f6be7..3168a1794849 100644
--- a/drivers/scsi/NCR53c406a.c
+++ b/drivers/scsi/NCR53c406a.c
@@ -1066,7 +1066,8 @@ static struct scsi_host_template driver_template =
1066 .sg_tablesize = 32 /*SG_ALL*/ /*SG_NONE*/, 1066 .sg_tablesize = 32 /*SG_ALL*/ /*SG_NONE*/,
1067 .cmd_per_lun = 1 /* commands per lun */, 1067 .cmd_per_lun = 1 /* commands per lun */,
1068 .unchecked_isa_dma = 1 /* unchecked_isa_dma */, 1068 .unchecked_isa_dma = 1 /* unchecked_isa_dma */,
1069 .use_clustering = ENABLE_CLUSTERING 1069 .use_clustering = ENABLE_CLUSTERING,
1070 .use_sg_chaining = ENABLE_SG_CHAINING,
1070}; 1071};
1071 1072
1072#include "scsi_module.c" 1073#include "scsi_module.c"
diff --git a/drivers/scsi/a100u2w.c b/drivers/scsi/a100u2w.c
index f608d4a1d6da..d3a6d15fb77a 100644
--- a/drivers/scsi/a100u2w.c
+++ b/drivers/scsi/a100u2w.c
@@ -1071,6 +1071,7 @@ static struct scsi_host_template inia100_template = {
1071 .sg_tablesize = SG_ALL, 1071 .sg_tablesize = SG_ALL,
1072 .cmd_per_lun = 1, 1072 .cmd_per_lun = 1,
1073 .use_clustering = ENABLE_CLUSTERING, 1073 .use_clustering = ENABLE_CLUSTERING,
1074 .use_sg_chaining = ENABLE_SG_CHAINING,
1074}; 1075};
1075 1076
1076static int __devinit inia100_probe_one(struct pci_dev *pdev, 1077static int __devinit inia100_probe_one(struct pci_dev *pdev,
diff --git a/drivers/scsi/aacraid/linit.c b/drivers/scsi/aacraid/linit.c
index a7f42a17b5c7..038980be763d 100644
--- a/drivers/scsi/aacraid/linit.c
+++ b/drivers/scsi/aacraid/linit.c
@@ -944,6 +944,7 @@ static struct scsi_host_template aac_driver_template = {
944 .cmd_per_lun = AAC_NUM_IO_FIB, 944 .cmd_per_lun = AAC_NUM_IO_FIB,
945#endif 945#endif
946 .use_clustering = ENABLE_CLUSTERING, 946 .use_clustering = ENABLE_CLUSTERING,
947 .use_sg_chaining = ENABLE_SG_CHAINING,
947 .emulated = 1, 948 .emulated = 1,
948}; 949};
949 950
diff --git a/drivers/scsi/aha1542.c b/drivers/scsi/aha1542.c
index cbbfbc9f3e0f..961a1882cb7e 100644
--- a/drivers/scsi/aha1542.c
+++ b/drivers/scsi/aha1542.c
@@ -61,15 +61,15 @@ static void BAD_DMA(void *address, unsigned int length)
61} 61}
62 62
63static void BAD_SG_DMA(Scsi_Cmnd * SCpnt, 63static void BAD_SG_DMA(Scsi_Cmnd * SCpnt,
64 struct scatterlist *sgpnt, 64 struct scatterlist *sgp,
65 int nseg, 65 int nseg,
66 int badseg) 66 int badseg)
67{ 67{
68 printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%llx length %u\n", 68 printk(KERN_CRIT "sgpnt[%d:%d] page %p/0x%llx length %u\n",
69 badseg, nseg, 69 badseg, nseg,
70 page_address(sgpnt[badseg].page) + sgpnt[badseg].offset, 70 page_address(sgp->page) + sgp->offset,
71 (unsigned long long)SCSI_SG_PA(&sgpnt[badseg]), 71 (unsigned long long)SCSI_SG_PA(sgp),
72 sgpnt[badseg].length); 72 sgp->length);
73 73
74 /* 74 /*
75 * Not safe to continue. 75 * Not safe to continue.
@@ -691,7 +691,7 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
691 memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen); 691 memcpy(ccb[mbo].cdb, cmd, ccb[mbo].cdblen);
692 692
693 if (SCpnt->use_sg) { 693 if (SCpnt->use_sg) {
694 struct scatterlist *sgpnt; 694 struct scatterlist *sg;
695 struct chain *cptr; 695 struct chain *cptr;
696#ifdef DEBUG 696#ifdef DEBUG
697 unsigned char *ptr; 697 unsigned char *ptr;
@@ -699,23 +699,21 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
699 int i; 699 int i;
700 ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */ 700 ccb[mbo].op = 2; /* SCSI Initiator Command w/scatter-gather */
701 SCpnt->host_scribble = kmalloc(512, GFP_KERNEL | GFP_DMA); 701 SCpnt->host_scribble = kmalloc(512, GFP_KERNEL | GFP_DMA);
702 sgpnt = (struct scatterlist *) SCpnt->request_buffer;
703 cptr = (struct chain *) SCpnt->host_scribble; 702 cptr = (struct chain *) SCpnt->host_scribble;
704 if (cptr == NULL) { 703 if (cptr == NULL) {
705 /* free the claimed mailbox slot */ 704 /* free the claimed mailbox slot */
706 HOSTDATA(SCpnt->device->host)->SCint[mbo] = NULL; 705 HOSTDATA(SCpnt->device->host)->SCint[mbo] = NULL;
707 return SCSI_MLQUEUE_HOST_BUSY; 706 return SCSI_MLQUEUE_HOST_BUSY;
708 } 707 }
709 for (i = 0; i < SCpnt->use_sg; i++) { 708 scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
710 if (sgpnt[i].length == 0 || SCpnt->use_sg > 16 || 709 if (sg->length == 0 || SCpnt->use_sg > 16 ||
711 (((int) sgpnt[i].offset) & 1) || (sgpnt[i].length & 1)) { 710 (((int) sg->offset) & 1) || (sg->length & 1)) {
712 unsigned char *ptr; 711 unsigned char *ptr;
713 printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i); 712 printk(KERN_CRIT "Bad segment list supplied to aha1542.c (%d, %d)\n", SCpnt->use_sg, i);
714 for (i = 0; i < SCpnt->use_sg; i++) { 713 scsi_for_each_sg(SCpnt, sg, SCpnt->use_sg, i) {
715 printk(KERN_CRIT "%d: %p %d\n", i, 714 printk(KERN_CRIT "%d: %p %d\n", i,
716 (page_address(sgpnt[i].page) + 715 (page_address(sg->page) +
717 sgpnt[i].offset), 716 sg->offset), sg->length);
718 sgpnt[i].length);
719 }; 717 };
720 printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr); 718 printk(KERN_CRIT "cptr %x: ", (unsigned int) cptr);
721 ptr = (unsigned char *) &cptr[i]; 719 ptr = (unsigned char *) &cptr[i];
@@ -723,10 +721,10 @@ static int aha1542_queuecommand(Scsi_Cmnd * SCpnt, void (*done) (Scsi_Cmnd *))
723 printk("%02x ", ptr[i]); 721 printk("%02x ", ptr[i]);
724 panic("Foooooooood fight!"); 722 panic("Foooooooood fight!");
725 }; 723 };
726 any2scsi(cptr[i].dataptr, SCSI_SG_PA(&sgpnt[i])); 724 any2scsi(cptr[i].dataptr, SCSI_SG_PA(sg));
727 if (SCSI_SG_PA(&sgpnt[i]) + sgpnt[i].length - 1 > ISA_DMA_THRESHOLD) 725 if (SCSI_SG_PA(sg) + sg->length - 1 > ISA_DMA_THRESHOLD)
728 BAD_SG_DMA(SCpnt, sgpnt, SCpnt->use_sg, i); 726 BAD_SG_DMA(SCpnt, sg, SCpnt->use_sg, i);
729 any2scsi(cptr[i].datalen, sgpnt[i].length); 727 any2scsi(cptr[i].datalen, sg->length);
730 }; 728 };
731 any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain)); 729 any2scsi(ccb[mbo].datalen, SCpnt->use_sg * sizeof(struct chain));
732 any2scsi(ccb[mbo].dataptr, SCSI_BUF_PA(cptr)); 730 any2scsi(ccb[mbo].dataptr, SCSI_BUF_PA(cptr));
diff --git a/drivers/scsi/aha1740.c b/drivers/scsi/aha1740.c
index e4a4f3a965d9..f6722fd46008 100644
--- a/drivers/scsi/aha1740.c
+++ b/drivers/scsi/aha1740.c
@@ -563,6 +563,7 @@ static struct scsi_host_template aha1740_template = {
563 .sg_tablesize = AHA1740_SCATTER, 563 .sg_tablesize = AHA1740_SCATTER,
564 .cmd_per_lun = AHA1740_CMDLUN, 564 .cmd_per_lun = AHA1740_CMDLUN,
565 .use_clustering = ENABLE_CLUSTERING, 565 .use_clustering = ENABLE_CLUSTERING,
566 .use_sg_chaining = ENABLE_SG_CHAINING,
566 .eh_abort_handler = aha1740_eh_abort_handler, 567 .eh_abort_handler = aha1740_eh_abort_handler,
567}; 568};
568 569
diff --git a/drivers/scsi/aic7xxx/aic79xx_osm.c b/drivers/scsi/aic7xxx/aic79xx_osm.c
index a055a96e3ad3..42c0f14a262c 100644
--- a/drivers/scsi/aic7xxx/aic79xx_osm.c
+++ b/drivers/scsi/aic7xxx/aic79xx_osm.c
@@ -766,6 +766,7 @@ struct scsi_host_template aic79xx_driver_template = {
766 .max_sectors = 8192, 766 .max_sectors = 8192,
767 .cmd_per_lun = 2, 767 .cmd_per_lun = 2,
768 .use_clustering = ENABLE_CLUSTERING, 768 .use_clustering = ENABLE_CLUSTERING,
769 .use_sg_chaining = ENABLE_SG_CHAINING,
769 .slave_alloc = ahd_linux_slave_alloc, 770 .slave_alloc = ahd_linux_slave_alloc,
770 .slave_configure = ahd_linux_slave_configure, 771 .slave_configure = ahd_linux_slave_configure,
771 .target_alloc = ahd_linux_target_alloc, 772 .target_alloc = ahd_linux_target_alloc,
diff --git a/drivers/scsi/aic7xxx/aic7xxx_osm.c b/drivers/scsi/aic7xxx/aic7xxx_osm.c
index 2e9c38f2e8a6..7770befbf50c 100644
--- a/drivers/scsi/aic7xxx/aic7xxx_osm.c
+++ b/drivers/scsi/aic7xxx/aic7xxx_osm.c
@@ -747,6 +747,7 @@ struct scsi_host_template aic7xxx_driver_template = {
747 .max_sectors = 8192, 747 .max_sectors = 8192,
748 .cmd_per_lun = 2, 748 .cmd_per_lun = 2,
749 .use_clustering = ENABLE_CLUSTERING, 749 .use_clustering = ENABLE_CLUSTERING,
750 .use_sg_chaining = ENABLE_SG_CHAINING,
750 .slave_alloc = ahc_linux_slave_alloc, 751 .slave_alloc = ahc_linux_slave_alloc,
751 .slave_configure = ahc_linux_slave_configure, 752 .slave_configure = ahc_linux_slave_configure,
752 .target_alloc = ahc_linux_target_alloc, 753 .target_alloc = ahc_linux_target_alloc,
diff --git a/drivers/scsi/aic7xxx_old.c b/drivers/scsi/aic7xxx_old.c
index 1a71b0236c97..4025608d6964 100644
--- a/drivers/scsi/aic7xxx_old.c
+++ b/drivers/scsi/aic7xxx_old.c
@@ -11142,6 +11142,7 @@ static struct scsi_host_template driver_template = {
11142 .max_sectors = 2048, 11142 .max_sectors = 2048,
11143 .cmd_per_lun = 3, 11143 .cmd_per_lun = 3,
11144 .use_clustering = ENABLE_CLUSTERING, 11144 .use_clustering = ENABLE_CLUSTERING,
11145 .use_sg_chaining = ENABLE_SG_CHAINING,
11145}; 11146};
11146 11147
11147#include "scsi_module.c" 11148#include "scsi_module.c"
diff --git a/drivers/scsi/aic94xx/aic94xx_task.c b/drivers/scsi/aic94xx/aic94xx_task.c
index f2b23e01401a..ee0a98bffcd4 100644
--- a/drivers/scsi/aic94xx/aic94xx_task.c
+++ b/drivers/scsi/aic94xx/aic94xx_task.c
@@ -94,7 +94,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
94 res = -ENOMEM; 94 res = -ENOMEM;
95 goto err_unmap; 95 goto err_unmap;
96 } 96 }
97 for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) { 97 for_each_sg(task->scatter, sc, num_sg, i) {
98 struct sg_el *sg = 98 struct sg_el *sg =
99 &((struct sg_el *)ascb->sg_arr->vaddr)[i]; 99 &((struct sg_el *)ascb->sg_arr->vaddr)[i];
100 sg->bus_addr = cpu_to_le64((u64)sg_dma_address(sc)); 100 sg->bus_addr = cpu_to_le64((u64)sg_dma_address(sc));
@@ -103,7 +103,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
103 sg->flags |= ASD_SG_EL_LIST_EOL; 103 sg->flags |= ASD_SG_EL_LIST_EOL;
104 } 104 }
105 105
106 for (sc = task->scatter, i = 0; i < 2; i++, sc++) { 106 for_each_sg(task->scatter, sc, 2, i) {
107 sg_arr[i].bus_addr = 107 sg_arr[i].bus_addr =
108 cpu_to_le64((u64)sg_dma_address(sc)); 108 cpu_to_le64((u64)sg_dma_address(sc));
109 sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc)); 109 sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
@@ -115,7 +115,7 @@ static inline int asd_map_scatterlist(struct sas_task *task,
115 sg_arr[2].bus_addr=cpu_to_le64((u64)ascb->sg_arr->dma_handle); 115 sg_arr[2].bus_addr=cpu_to_le64((u64)ascb->sg_arr->dma_handle);
116 } else { 116 } else {
117 int i; 117 int i;
118 for (sc = task->scatter, i = 0; i < num_sg; i++, sc++) { 118 for_each_sg(task->scatter, sc, num_sg, i) {
119 sg_arr[i].bus_addr = 119 sg_arr[i].bus_addr =
120 cpu_to_le64((u64)sg_dma_address(sc)); 120 cpu_to_le64((u64)sg_dma_address(sc));
121 sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc)); 121 sg_arr[i].size = cpu_to_le32((u32)sg_dma_len(sc));
diff --git a/drivers/scsi/arcmsr/arcmsr_hba.c b/drivers/scsi/arcmsr/arcmsr_hba.c
index cfcf40159eab..f81777586b8f 100644
--- a/drivers/scsi/arcmsr/arcmsr_hba.c
+++ b/drivers/scsi/arcmsr/arcmsr_hba.c
@@ -122,6 +122,7 @@ static struct scsi_host_template arcmsr_scsi_host_template = {
122 .max_sectors = ARCMSR_MAX_XFER_SECTORS, 122 .max_sectors = ARCMSR_MAX_XFER_SECTORS,
123 .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN, 123 .cmd_per_lun = ARCMSR_MAX_CMD_PERLUN,
124 .use_clustering = ENABLE_CLUSTERING, 124 .use_clustering = ENABLE_CLUSTERING,
125 .use_sg_chaining = ENABLE_SG_CHAINING,
125 .shost_attrs = arcmsr_host_attrs, 126 .shost_attrs = arcmsr_host_attrs,
126}; 127};
127#ifdef CONFIG_SCSI_ARCMSR_AER 128#ifdef CONFIG_SCSI_ARCMSR_AER
diff --git a/drivers/scsi/dc395x.c b/drivers/scsi/dc395x.c
index 1591824cf4b3..fd42d4789202 100644
--- a/drivers/scsi/dc395x.c
+++ b/drivers/scsi/dc395x.c
@@ -4765,6 +4765,7 @@ static struct scsi_host_template dc395x_driver_template = {
4765 .eh_bus_reset_handler = dc395x_eh_bus_reset, 4765 .eh_bus_reset_handler = dc395x_eh_bus_reset,
4766 .unchecked_isa_dma = 0, 4766 .unchecked_isa_dma = 0,
4767 .use_clustering = DISABLE_CLUSTERING, 4767 .use_clustering = DISABLE_CLUSTERING,
4768 .use_sg_chaining = ENABLE_SG_CHAINING,
4768}; 4769};
4769 4770
4770 4771
diff --git a/drivers/scsi/dpt_i2o.c b/drivers/scsi/dpt_i2o.c
index bea9d659af15..8258506ba7d7 100644
--- a/drivers/scsi/dpt_i2o.c
+++ b/drivers/scsi/dpt_i2o.c
@@ -3295,6 +3295,7 @@ static struct scsi_host_template adpt_template = {
3295 .this_id = 7, 3295 .this_id = 7,
3296 .cmd_per_lun = 1, 3296 .cmd_per_lun = 1,
3297 .use_clustering = ENABLE_CLUSTERING, 3297 .use_clustering = ENABLE_CLUSTERING,
3298 .use_sg_chaining = ENABLE_SG_CHAINING,
3298}; 3299};
3299 3300
3300static s32 adpt_scsi_register(adpt_hba* pHba) 3301static s32 adpt_scsi_register(adpt_hba* pHba)
diff --git a/drivers/scsi/eata.c b/drivers/scsi/eata.c
index ec2233114bc9..7ead5210de96 100644
--- a/drivers/scsi/eata.c
+++ b/drivers/scsi/eata.c
@@ -523,7 +523,8 @@ static struct scsi_host_template driver_template = {
523 .slave_configure = eata2x_slave_configure, 523 .slave_configure = eata2x_slave_configure,
524 .this_id = 7, 524 .this_id = 7,
525 .unchecked_isa_dma = 1, 525 .unchecked_isa_dma = 1,
526 .use_clustering = ENABLE_CLUSTERING 526 .use_clustering = ENABLE_CLUSTERING,
527 .use_sg_chaining = ENABLE_SG_CHAINING,
527}; 528};
528 529
529#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD) 530#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
diff --git a/drivers/scsi/hosts.c b/drivers/scsi/hosts.c
index adc9559cb6f4..112ab6abe62b 100644
--- a/drivers/scsi/hosts.c
+++ b/drivers/scsi/hosts.c
@@ -343,6 +343,7 @@ struct Scsi_Host *scsi_host_alloc(struct scsi_host_template *sht, int privsize)
343 shost->use_clustering = sht->use_clustering; 343 shost->use_clustering = sht->use_clustering;
344 shost->ordered_tag = sht->ordered_tag; 344 shost->ordered_tag = sht->ordered_tag;
345 shost->active_mode = sht->supported_mode; 345 shost->active_mode = sht->supported_mode;
346 shost->use_sg_chaining = sht->use_sg_chaining;
346 347
347 if (sht->max_host_blocked) 348 if (sht->max_host_blocked)
348 shost->max_host_blocked = sht->max_host_blocked; 349 shost->max_host_blocked = sht->max_host_blocked;
diff --git a/drivers/scsi/hptiop.c b/drivers/scsi/hptiop.c
index 8b384fa7f048..8515054cdf70 100644
--- a/drivers/scsi/hptiop.c
+++ b/drivers/scsi/hptiop.c
@@ -655,6 +655,7 @@ static struct scsi_host_template driver_template = {
655 .unchecked_isa_dma = 0, 655 .unchecked_isa_dma = 0,
656 .emulated = 0, 656 .emulated = 0,
657 .use_clustering = ENABLE_CLUSTERING, 657 .use_clustering = ENABLE_CLUSTERING,
658 .use_sg_chaining = ENABLE_SG_CHAINING,
658 .proc_name = driver_name, 659 .proc_name = driver_name,
659 .shost_attrs = hptiop_attrs, 660 .shost_attrs = hptiop_attrs,
660 .this_id = -1, 661 .this_id = -1,
diff --git a/drivers/scsi/ibmmca.c b/drivers/scsi/ibmmca.c
index 1a924e9b0271..714e6273a70d 100644
--- a/drivers/scsi/ibmmca.c
+++ b/drivers/scsi/ibmmca.c
@@ -1501,6 +1501,7 @@ static struct scsi_host_template ibmmca_driver_template = {
1501 .sg_tablesize = 16, 1501 .sg_tablesize = 16,
1502 .cmd_per_lun = 1, 1502 .cmd_per_lun = 1,
1503 .use_clustering = ENABLE_CLUSTERING, 1503 .use_clustering = ENABLE_CLUSTERING,
1504 .use_sg_chaining = ENABLE_SG_CHAINING,
1504}; 1505};
1505 1506
1506static int ibmmca_probe(struct device *dev) 1507static int ibmmca_probe(struct device *dev)
diff --git a/drivers/scsi/ibmvscsi/ibmvscsi.c b/drivers/scsi/ibmvscsi/ibmvscsi.c
index cda0cc3d182f..22d91ee173c5 100644
--- a/drivers/scsi/ibmvscsi/ibmvscsi.c
+++ b/drivers/scsi/ibmvscsi/ibmvscsi.c
@@ -1548,6 +1548,7 @@ static struct scsi_host_template driver_template = {
1548 .this_id = -1, 1548 .this_id = -1,
1549 .sg_tablesize = SG_ALL, 1549 .sg_tablesize = SG_ALL,
1550 .use_clustering = ENABLE_CLUSTERING, 1550 .use_clustering = ENABLE_CLUSTERING,
1551 .use_sg_chaining = ENABLE_SG_CHAINING,
1551 .shost_attrs = ibmvscsi_attrs, 1552 .shost_attrs = ibmvscsi_attrs,
1552}; 1553};
1553 1554
diff --git a/drivers/scsi/ide-scsi.c b/drivers/scsi/ide-scsi.c
index d81bb076a15a..d297f64cd432 100644
--- a/drivers/scsi/ide-scsi.c
+++ b/drivers/scsi/ide-scsi.c
@@ -70,6 +70,7 @@ typedef struct idescsi_pc_s {
70 u8 *buffer; /* Data buffer */ 70 u8 *buffer; /* Data buffer */
71 u8 *current_position; /* Pointer into the above buffer */ 71 u8 *current_position; /* Pointer into the above buffer */
72 struct scatterlist *sg; /* Scatter gather table */ 72 struct scatterlist *sg; /* Scatter gather table */
73 struct scatterlist *last_sg; /* Last sg element */
73 int b_count; /* Bytes transferred from current entry */ 74 int b_count; /* Bytes transferred from current entry */
74 struct scsi_cmnd *scsi_cmd; /* SCSI command */ 75 struct scsi_cmnd *scsi_cmd; /* SCSI command */
75 void (*done)(struct scsi_cmnd *); /* Scsi completion routine */ 76 void (*done)(struct scsi_cmnd *); /* Scsi completion routine */
@@ -173,12 +174,6 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
173 char *buf; 174 char *buf;
174 175
175 while (bcount) { 176 while (bcount) {
176 if (pc->sg - scsi_sglist(pc->scsi_cmd) >
177 scsi_sg_count(pc->scsi_cmd)) {
178 printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
179 idescsi_discard_data (drive, bcount);
180 return;
181 }
182 count = min(pc->sg->length - pc->b_count, bcount); 177 count = min(pc->sg->length - pc->b_count, bcount);
183 if (PageHighMem(pc->sg->page)) { 178 if (PageHighMem(pc->sg->page)) {
184 unsigned long flags; 179 unsigned long flags;
@@ -197,10 +192,17 @@ static void idescsi_input_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigne
197 } 192 }
198 bcount -= count; pc->b_count += count; 193 bcount -= count; pc->b_count += count;
199 if (pc->b_count == pc->sg->length) { 194 if (pc->b_count == pc->sg->length) {
200 pc->sg++; 195 if (pc->sg == pc->last_sg)
196 break;
197 pc->sg = sg_next(pc->sg);
201 pc->b_count = 0; 198 pc->b_count = 0;
202 } 199 }
203 } 200 }
201
202 if (bcount) {
203 printk (KERN_ERR "ide-scsi: scatter gather table too small, discarding data\n");
204 idescsi_discard_data (drive, bcount);
205 }
204} 206}
205 207
206static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount) 208static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsigned int bcount)
@@ -209,12 +211,6 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
209 char *buf; 211 char *buf;
210 212
211 while (bcount) { 213 while (bcount) {
212 if (pc->sg - scsi_sglist(pc->scsi_cmd) >
213 scsi_sg_count(pc->scsi_cmd)) {
214 printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
215 idescsi_output_zeros (drive, bcount);
216 return;
217 }
218 count = min(pc->sg->length - pc->b_count, bcount); 214 count = min(pc->sg->length - pc->b_count, bcount);
219 if (PageHighMem(pc->sg->page)) { 215 if (PageHighMem(pc->sg->page)) {
220 unsigned long flags; 216 unsigned long flags;
@@ -233,10 +229,17 @@ static void idescsi_output_buffers (ide_drive_t *drive, idescsi_pc_t *pc, unsign
233 } 229 }
234 bcount -= count; pc->b_count += count; 230 bcount -= count; pc->b_count += count;
235 if (pc->b_count == pc->sg->length) { 231 if (pc->b_count == pc->sg->length) {
236 pc->sg++; 232 if (pc->sg == pc->last_sg)
233 break;
234 pc->sg = sg_next(pc->sg);
237 pc->b_count = 0; 235 pc->b_count = 0;
238 } 236 }
239 } 237 }
238
239 if (bcount) {
240 printk (KERN_ERR "ide-scsi: scatter gather table too small, padding with zeros\n");
241 idescsi_output_zeros (drive, bcount);
242 }
240} 243}
241 244
242static void hexdump(u8 *x, int len) 245static void hexdump(u8 *x, int len)
@@ -804,6 +807,7 @@ static int idescsi_queue (struct scsi_cmnd *cmd,
804 memcpy (pc->c, cmd->cmnd, cmd->cmd_len); 807 memcpy (pc->c, cmd->cmnd, cmd->cmd_len);
805 pc->buffer = NULL; 808 pc->buffer = NULL;
806 pc->sg = scsi_sglist(cmd); 809 pc->sg = scsi_sglist(cmd);
810 pc->last_sg = sg_last(pc->sg, cmd->use_sg);
807 pc->b_count = 0; 811 pc->b_count = 0;
808 pc->request_transfer = pc->buffer_size = scsi_bufflen(cmd); 812 pc->request_transfer = pc->buffer_size = scsi_bufflen(cmd);
809 pc->scsi_cmd = cmd; 813 pc->scsi_cmd = cmd;
diff --git a/drivers/scsi/initio.c b/drivers/scsi/initio.c
index d9dfb69ae031..22d40fd5845b 100644
--- a/drivers/scsi/initio.c
+++ b/drivers/scsi/initio.c
@@ -2831,6 +2831,7 @@ static struct scsi_host_template initio_template = {
2831 .sg_tablesize = SG_ALL, 2831 .sg_tablesize = SG_ALL,
2832 .cmd_per_lun = 1, 2832 .cmd_per_lun = 1,
2833 .use_clustering = ENABLE_CLUSTERING, 2833 .use_clustering = ENABLE_CLUSTERING,
2834 .use_sg_chaining = ENABLE_SG_CHAINING,
2834}; 2835};
2835 2836
2836static int initio_probe_one(struct pci_dev *pdev, 2837static int initio_probe_one(struct pci_dev *pdev,
diff --git a/drivers/scsi/ips.c b/drivers/scsi/ips.c
index 2ed099e2c20d..edaac2714c5a 100644
--- a/drivers/scsi/ips.c
+++ b/drivers/scsi/ips.c
@@ -3252,7 +3252,7 @@ ips_done(ips_ha_t * ha, ips_scb_t * scb)
3252 */ 3252 */
3253 if ((scb->breakup) || (scb->sg_break)) { 3253 if ((scb->breakup) || (scb->sg_break)) {
3254 struct scatterlist *sg; 3254 struct scatterlist *sg;
3255 int sg_dma_index, ips_sg_index = 0; 3255 int i, sg_dma_index, ips_sg_index = 0;
3256 3256
3257 /* we had a data breakup */ 3257 /* we had a data breakup */
3258 scb->data_len = 0; 3258 scb->data_len = 0;
@@ -3261,20 +3261,22 @@ ips_done(ips_ha_t * ha, ips_scb_t * scb)
3261 3261
3262 /* Spin forward to last dma chunk */ 3262 /* Spin forward to last dma chunk */
3263 sg_dma_index = scb->breakup; 3263 sg_dma_index = scb->breakup;
3264 for (i = 0; i < scb->breakup; i++)
3265 sg = sg_next(sg);
3264 3266
3265 /* Take care of possible partial on last chunk */ 3267 /* Take care of possible partial on last chunk */
3266 ips_fill_scb_sg_single(ha, 3268 ips_fill_scb_sg_single(ha,
3267 sg_dma_address(&sg[sg_dma_index]), 3269 sg_dma_address(sg),
3268 scb, ips_sg_index++, 3270 scb, ips_sg_index++,
3269 sg_dma_len(&sg[sg_dma_index])); 3271 sg_dma_len(sg));
3270 3272
3271 for (; sg_dma_index < scsi_sg_count(scb->scsi_cmd); 3273 for (; sg_dma_index < scsi_sg_count(scb->scsi_cmd);
3272 sg_dma_index++) { 3274 sg_dma_index++, sg = sg_next(sg)) {
3273 if (ips_fill_scb_sg_single 3275 if (ips_fill_scb_sg_single
3274 (ha, 3276 (ha,
3275 sg_dma_address(&sg[sg_dma_index]), 3277 sg_dma_address(sg),
3276 scb, ips_sg_index++, 3278 scb, ips_sg_index++,
3277 sg_dma_len(&sg[sg_dma_index])) < 0) 3279 sg_dma_len(sg)) < 0)
3278 break; 3280 break;
3279 } 3281 }
3280 3282
diff --git a/drivers/scsi/lpfc/lpfc_scsi.c b/drivers/scsi/lpfc/lpfc_scsi.c
index cd674938ccd5..c0755565fae9 100644
--- a/drivers/scsi/lpfc/lpfc_scsi.c
+++ b/drivers/scsi/lpfc/lpfc_scsi.c
@@ -1438,6 +1438,7 @@ struct scsi_host_template lpfc_template = {
1438 .scan_finished = lpfc_scan_finished, 1438 .scan_finished = lpfc_scan_finished,
1439 .this_id = -1, 1439 .this_id = -1,
1440 .sg_tablesize = LPFC_SG_SEG_CNT, 1440 .sg_tablesize = LPFC_SG_SEG_CNT,
1441 .use_sg_chaining = ENABLE_SG_CHAINING,
1441 .cmd_per_lun = LPFC_CMD_PER_LUN, 1442 .cmd_per_lun = LPFC_CMD_PER_LUN,
1442 .use_clustering = ENABLE_CLUSTERING, 1443 .use_clustering = ENABLE_CLUSTERING,
1443 .shost_attrs = lpfc_hba_attrs, 1444 .shost_attrs = lpfc_hba_attrs,
@@ -1460,6 +1461,7 @@ struct scsi_host_template lpfc_vport_template = {
1460 .sg_tablesize = LPFC_SG_SEG_CNT, 1461 .sg_tablesize = LPFC_SG_SEG_CNT,
1461 .cmd_per_lun = LPFC_CMD_PER_LUN, 1462 .cmd_per_lun = LPFC_CMD_PER_LUN,
1462 .use_clustering = ENABLE_CLUSTERING, 1463 .use_clustering = ENABLE_CLUSTERING,
1464 .use_sg_chaining = ENABLE_SG_CHAINING,
1463 .shost_attrs = lpfc_vport_attrs, 1465 .shost_attrs = lpfc_vport_attrs,
1464 .max_sectors = 0xFFFF, 1466 .max_sectors = 0xFFFF,
1465}; 1467};
diff --git a/drivers/scsi/mac53c94.c b/drivers/scsi/mac53c94.c
index b12ad7c7c673..a035001f4438 100644
--- a/drivers/scsi/mac53c94.c
+++ b/drivers/scsi/mac53c94.c
@@ -402,6 +402,7 @@ static struct scsi_host_template mac53c94_template = {
402 .sg_tablesize = SG_ALL, 402 .sg_tablesize = SG_ALL,
403 .cmd_per_lun = 1, 403 .cmd_per_lun = 1,
404 .use_clustering = DISABLE_CLUSTERING, 404 .use_clustering = DISABLE_CLUSTERING,
405 .use_sg_chaining = ENABLE_SG_CHAINING,
405}; 406};
406 407
407static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match) 408static int mac53c94_probe(struct macio_dev *mdev, const struct of_device_id *match)
diff --git a/drivers/scsi/mac_scsi.c b/drivers/scsi/mac_scsi.c
index cdbcaa5ad6cf..abe2bda6ac37 100644
--- a/drivers/scsi/mac_scsi.c
+++ b/drivers/scsi/mac_scsi.c
@@ -53,6 +53,11 @@
53#include "scsi.h" 53#include "scsi.h"
54#include <scsi/scsi_host.h> 54#include <scsi/scsi_host.h>
55#include "mac_scsi.h" 55#include "mac_scsi.h"
56
57/* These control the behaviour of the generic 5380 core */
58#define AUTOSENSE
59#define PSEUDO_DMA
60
56#include "NCR5380.h" 61#include "NCR5380.h"
57 62
58#if 0 63#if 0
@@ -571,10 +576,6 @@ static int macscsi_pwrite (struct Scsi_Host *instance,
571} 576}
572 577
573 578
574/* These control the behaviour of the generic 5380 core */
575#define AUTOSENSE
576#define PSEUDO_DMA
577
578#include "NCR5380.c" 579#include "NCR5380.c"
579 580
580static struct scsi_host_template driver_template = { 581static struct scsi_host_template driver_template = {
diff --git a/drivers/scsi/megaraid.c b/drivers/scsi/megaraid.c
index e7e11f282c8f..10d1aff9938a 100644
--- a/drivers/scsi/megaraid.c
+++ b/drivers/scsi/megaraid.c
@@ -4492,6 +4492,7 @@ static struct scsi_host_template megaraid_template = {
4492 .sg_tablesize = MAX_SGLIST, 4492 .sg_tablesize = MAX_SGLIST,
4493 .cmd_per_lun = DEF_CMD_PER_LUN, 4493 .cmd_per_lun = DEF_CMD_PER_LUN,
4494 .use_clustering = ENABLE_CLUSTERING, 4494 .use_clustering = ENABLE_CLUSTERING,
4495 .use_sg_chaining = ENABLE_SG_CHAINING,
4495 .eh_abort_handler = megaraid_abort, 4496 .eh_abort_handler = megaraid_abort,
4496 .eh_device_reset_handler = megaraid_reset, 4497 .eh_device_reset_handler = megaraid_reset,
4497 .eh_bus_reset_handler = megaraid_reset, 4498 .eh_bus_reset_handler = megaraid_reset,
diff --git a/drivers/scsi/megaraid/megaraid_mbox.c b/drivers/scsi/megaraid/megaraid_mbox.c
index c6a53dccc16a..e4e4c6a39ed6 100644
--- a/drivers/scsi/megaraid/megaraid_mbox.c
+++ b/drivers/scsi/megaraid/megaraid_mbox.c
@@ -361,6 +361,7 @@ static struct scsi_host_template megaraid_template_g = {
361 .eh_host_reset_handler = megaraid_reset_handler, 361 .eh_host_reset_handler = megaraid_reset_handler,
362 .change_queue_depth = megaraid_change_queue_depth, 362 .change_queue_depth = megaraid_change_queue_depth,
363 .use_clustering = ENABLE_CLUSTERING, 363 .use_clustering = ENABLE_CLUSTERING,
364 .use_sg_chaining = ENABLE_SG_CHAINING,
364 .sdev_attrs = megaraid_sdev_attrs, 365 .sdev_attrs = megaraid_sdev_attrs,
365 .shost_attrs = megaraid_shost_attrs, 366 .shost_attrs = megaraid_shost_attrs,
366}; 367};
diff --git a/drivers/scsi/megaraid/megaraid_sas.c b/drivers/scsi/megaraid/megaraid_sas.c
index ebb948c016bb..e3c5c5282203 100644
--- a/drivers/scsi/megaraid/megaraid_sas.c
+++ b/drivers/scsi/megaraid/megaraid_sas.c
@@ -1110,6 +1110,7 @@ static struct scsi_host_template megasas_template = {
1110 .eh_timed_out = megasas_reset_timer, 1110 .eh_timed_out = megasas_reset_timer,
1111 .bios_param = megasas_bios_param, 1111 .bios_param = megasas_bios_param,
1112 .use_clustering = ENABLE_CLUSTERING, 1112 .use_clustering = ENABLE_CLUSTERING,
1113 .use_sg_chaining = ENABLE_SG_CHAINING,
1113}; 1114};
1114 1115
1115/** 1116/**
diff --git a/drivers/scsi/mesh.c b/drivers/scsi/mesh.c
index 651d09b08f2a..7470ff39ab22 100644
--- a/drivers/scsi/mesh.c
+++ b/drivers/scsi/mesh.c
@@ -1843,6 +1843,7 @@ static struct scsi_host_template mesh_template = {
1843 .sg_tablesize = SG_ALL, 1843 .sg_tablesize = SG_ALL,
1844 .cmd_per_lun = 2, 1844 .cmd_per_lun = 2,
1845 .use_clustering = DISABLE_CLUSTERING, 1845 .use_clustering = DISABLE_CLUSTERING,
1846 .use_sg_chaining = ENABLE_SG_CHAINING,
1846}; 1847};
1847 1848
1848static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match) 1849static int mesh_probe(struct macio_dev *mdev, const struct of_device_id *match)
diff --git a/drivers/scsi/nsp32.c b/drivers/scsi/nsp32.c
index 7fed35372150..28161dc95e0d 100644
--- a/drivers/scsi/nsp32.c
+++ b/drivers/scsi/nsp32.c
@@ -281,6 +281,7 @@ static struct scsi_host_template nsp32_template = {
281 .cmd_per_lun = 1, 281 .cmd_per_lun = 1,
282 .this_id = NSP32_HOST_SCSIID, 282 .this_id = NSP32_HOST_SCSIID,
283 .use_clustering = DISABLE_CLUSTERING, 283 .use_clustering = DISABLE_CLUSTERING,
284 .use_sg_chaining = ENABLE_SG_CHAINING,
284 .eh_abort_handler = nsp32_eh_abort, 285 .eh_abort_handler = nsp32_eh_abort,
285 .eh_bus_reset_handler = nsp32_eh_bus_reset, 286 .eh_bus_reset_handler = nsp32_eh_bus_reset,
286 .eh_host_reset_handler = nsp32_eh_host_reset, 287 .eh_host_reset_handler = nsp32_eh_host_reset,
diff --git a/drivers/scsi/pcmcia/sym53c500_cs.c b/drivers/scsi/pcmcia/sym53c500_cs.c
index 961839ecfe86..190e2a7d7067 100644
--- a/drivers/scsi/pcmcia/sym53c500_cs.c
+++ b/drivers/scsi/pcmcia/sym53c500_cs.c
@@ -694,6 +694,7 @@ static struct scsi_host_template sym53c500_driver_template = {
694 .sg_tablesize = 32, 694 .sg_tablesize = 32,
695 .cmd_per_lun = 1, 695 .cmd_per_lun = 1,
696 .use_clustering = ENABLE_CLUSTERING, 696 .use_clustering = ENABLE_CLUSTERING,
697 .use_sg_chaining = ENABLE_SG_CHAINING,
697 .shost_attrs = SYM53C500_shost_attrs 698 .shost_attrs = SYM53C500_shost_attrs
698}; 699};
699 700
diff --git a/drivers/scsi/qla1280.c b/drivers/scsi/qla1280.c
index fba8aa8a81b5..76089cf55f4e 100644
--- a/drivers/scsi/qla1280.c
+++ b/drivers/scsi/qla1280.c
@@ -2775,7 +2775,7 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
2775 struct device_reg __iomem *reg = ha->iobase; 2775 struct device_reg __iomem *reg = ha->iobase;
2776 struct scsi_cmnd *cmd = sp->cmd; 2776 struct scsi_cmnd *cmd = sp->cmd;
2777 cmd_a64_entry_t *pkt; 2777 cmd_a64_entry_t *pkt;
2778 struct scatterlist *sg = NULL; 2778 struct scatterlist *sg = NULL, *s;
2779 __le32 *dword_ptr; 2779 __le32 *dword_ptr;
2780 dma_addr_t dma_handle; 2780 dma_addr_t dma_handle;
2781 int status = 0; 2781 int status = 0;
@@ -2889,13 +2889,16 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
2889 * Load data segments. 2889 * Load data segments.
2890 */ 2890 */
2891 if (seg_cnt) { /* If data transfer. */ 2891 if (seg_cnt) { /* If data transfer. */
2892 int remseg = seg_cnt;
2892 /* Setup packet address segment pointer. */ 2893 /* Setup packet address segment pointer. */
2893 dword_ptr = (u32 *)&pkt->dseg_0_address; 2894 dword_ptr = (u32 *)&pkt->dseg_0_address;
2894 2895
2895 if (cmd->use_sg) { /* If scatter gather */ 2896 if (cmd->use_sg) { /* If scatter gather */
2896 /* Load command entry data segments. */ 2897 /* Load command entry data segments. */
2897 for (cnt = 0; cnt < 2 && seg_cnt; cnt++, seg_cnt--) { 2898 for_each_sg(sg, s, seg_cnt, cnt) {
2898 dma_handle = sg_dma_address(sg); 2899 if (cnt == 2)
2900 break;
2901 dma_handle = sg_dma_address(s);
2899#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) 2902#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
2900 if (ha->flags.use_pci_vchannel) 2903 if (ha->flags.use_pci_vchannel)
2901 sn_pci_set_vchan(ha->pdev, 2904 sn_pci_set_vchan(ha->pdev,
@@ -2906,12 +2909,12 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
2906 cpu_to_le32(pci_dma_lo32(dma_handle)); 2909 cpu_to_le32(pci_dma_lo32(dma_handle));
2907 *dword_ptr++ = 2910 *dword_ptr++ =
2908 cpu_to_le32(pci_dma_hi32(dma_handle)); 2911 cpu_to_le32(pci_dma_hi32(dma_handle));
2909 *dword_ptr++ = cpu_to_le32(sg_dma_len(sg)); 2912 *dword_ptr++ = cpu_to_le32(sg_dma_len(s));
2910 sg++;
2911 dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n", 2913 dprintk(3, "S/G Segment phys_addr=%x %x, len=0x%x\n",
2912 cpu_to_le32(pci_dma_hi32(dma_handle)), 2914 cpu_to_le32(pci_dma_hi32(dma_handle)),
2913 cpu_to_le32(pci_dma_lo32(dma_handle)), 2915 cpu_to_le32(pci_dma_lo32(dma_handle)),
2914 cpu_to_le32(sg_dma_len(sg))); 2916 cpu_to_le32(sg_dma_len(sg_next(s))));
2917 remseg--;
2915 } 2918 }
2916 dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather " 2919 dprintk(5, "qla1280_64bit_start_scsi: Scatter/gather "
2917 "command packet data - b %i, t %i, l %i \n", 2920 "command packet data - b %i, t %i, l %i \n",
@@ -2926,7 +2929,9 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
2926 dprintk(3, "S/G Building Continuation...seg_cnt=0x%x " 2929 dprintk(3, "S/G Building Continuation...seg_cnt=0x%x "
2927 "remains\n", seg_cnt); 2930 "remains\n", seg_cnt);
2928 2931
2929 while (seg_cnt > 0) { 2932 while (remseg > 0) {
2933 /* Update sg start */
2934 sg = s;
2930 /* Adjust ring index. */ 2935 /* Adjust ring index. */
2931 ha->req_ring_index++; 2936 ha->req_ring_index++;
2932 if (ha->req_ring_index == REQUEST_ENTRY_CNT) { 2937 if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
@@ -2952,9 +2957,10 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
2952 (u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address; 2957 (u32 *)&((struct cont_a64_entry *) pkt)->dseg_0_address;
2953 2958
2954 /* Load continuation entry data segments. */ 2959 /* Load continuation entry data segments. */
2955 for (cnt = 0; cnt < 5 && seg_cnt; 2960 for_each_sg(sg, s, remseg, cnt) {
2956 cnt++, seg_cnt--) { 2961 if (cnt == 5)
2957 dma_handle = sg_dma_address(sg); 2962 break;
2963 dma_handle = sg_dma_address(s);
2958#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2) 2964#if defined(CONFIG_IA64_GENERIC) || defined(CONFIG_IA64_SGI_SN2)
2959 if (ha->flags.use_pci_vchannel) 2965 if (ha->flags.use_pci_vchannel)
2960 sn_pci_set_vchan(ha->pdev, 2966 sn_pci_set_vchan(ha->pdev,
@@ -2966,13 +2972,13 @@ qla1280_64bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
2966 *dword_ptr++ = 2972 *dword_ptr++ =
2967 cpu_to_le32(pci_dma_hi32(dma_handle)); 2973 cpu_to_le32(pci_dma_hi32(dma_handle));
2968 *dword_ptr++ = 2974 *dword_ptr++ =
2969 cpu_to_le32(sg_dma_len(sg)); 2975 cpu_to_le32(sg_dma_len(s));
2970 dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n", 2976 dprintk(3, "S/G Segment Cont. phys_addr=%x %x, len=0x%x\n",
2971 cpu_to_le32(pci_dma_hi32(dma_handle)), 2977 cpu_to_le32(pci_dma_hi32(dma_handle)),
2972 cpu_to_le32(pci_dma_lo32(dma_handle)), 2978 cpu_to_le32(pci_dma_lo32(dma_handle)),
2973 cpu_to_le32(sg_dma_len(sg))); 2979 cpu_to_le32(sg_dma_len(s)));
2974 sg++;
2975 } 2980 }
2981 remseg -= cnt;
2976 dprintk(5, "qla1280_64bit_start_scsi: " 2982 dprintk(5, "qla1280_64bit_start_scsi: "
2977 "continuation packet data - b %i, t " 2983 "continuation packet data - b %i, t "
2978 "%i, l %i \n", SCSI_BUS_32(cmd), 2984 "%i, l %i \n", SCSI_BUS_32(cmd),
@@ -3062,7 +3068,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
3062 struct device_reg __iomem *reg = ha->iobase; 3068 struct device_reg __iomem *reg = ha->iobase;
3063 struct scsi_cmnd *cmd = sp->cmd; 3069 struct scsi_cmnd *cmd = sp->cmd;
3064 struct cmd_entry *pkt; 3070 struct cmd_entry *pkt;
3065 struct scatterlist *sg = NULL; 3071 struct scatterlist *sg = NULL, *s;
3066 __le32 *dword_ptr; 3072 __le32 *dword_ptr;
3067 int status = 0; 3073 int status = 0;
3068 int cnt; 3074 int cnt;
@@ -3188,6 +3194,7 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
3188 * Load data segments. 3194 * Load data segments.
3189 */ 3195 */
3190 if (seg_cnt) { 3196 if (seg_cnt) {
3197 int remseg = seg_cnt;
3191 /* Setup packet address segment pointer. */ 3198 /* Setup packet address segment pointer. */
3192 dword_ptr = &pkt->dseg_0_address; 3199 dword_ptr = &pkt->dseg_0_address;
3193 3200
@@ -3196,22 +3203,25 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
3196 qla1280_dump_buffer(1, (char *)sg, 4 * 16); 3203 qla1280_dump_buffer(1, (char *)sg, 4 * 16);
3197 3204
3198 /* Load command entry data segments. */ 3205 /* Load command entry data segments. */
3199 for (cnt = 0; cnt < 4 && seg_cnt; cnt++, seg_cnt--) { 3206 for_each_sg(sg, s, seg_cnt, cnt) {
3207 if (cnt == 4)
3208 break;
3200 *dword_ptr++ = 3209 *dword_ptr++ =
3201 cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); 3210 cpu_to_le32(pci_dma_lo32(sg_dma_address(s)));
3202 *dword_ptr++ = 3211 *dword_ptr++ = cpu_to_le32(sg_dma_len(s));
3203 cpu_to_le32(sg_dma_len(sg));
3204 dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n", 3212 dprintk(3, "S/G Segment phys_addr=0x%lx, len=0x%x\n",
3205 (pci_dma_lo32(sg_dma_address(sg))), 3213 (pci_dma_lo32(sg_dma_address(s))),
3206 (sg_dma_len(sg))); 3214 (sg_dma_len(s)));
3207 sg++; 3215 remseg--;
3208 } 3216 }
3209 /* 3217 /*
3210 * Build continuation packets. 3218 * Build continuation packets.
3211 */ 3219 */
3212 dprintk(3, "S/G Building Continuation" 3220 dprintk(3, "S/G Building Continuation"
3213 "...seg_cnt=0x%x remains\n", seg_cnt); 3221 "...seg_cnt=0x%x remains\n", seg_cnt);
3214 while (seg_cnt > 0) { 3222 while (remseg > 0) {
3223 /* Continue from end point */
3224 sg = s;
3215 /* Adjust ring index. */ 3225 /* Adjust ring index. */
3216 ha->req_ring_index++; 3226 ha->req_ring_index++;
3217 if (ha->req_ring_index == REQUEST_ENTRY_CNT) { 3227 if (ha->req_ring_index == REQUEST_ENTRY_CNT) {
@@ -3239,19 +3249,20 @@ qla1280_32bit_start_scsi(struct scsi_qla_host *ha, struct srb * sp)
3239 &((struct cont_entry *) pkt)->dseg_0_address; 3249 &((struct cont_entry *) pkt)->dseg_0_address;
3240 3250
3241 /* Load continuation entry data segments. */ 3251 /* Load continuation entry data segments. */
3242 for (cnt = 0; cnt < 7 && seg_cnt; 3252 for_each_sg(sg, s, remseg, cnt) {
3243 cnt++, seg_cnt--) { 3253 if (cnt == 7)
3254 break;
3244 *dword_ptr++ = 3255 *dword_ptr++ =
3245 cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))); 3256 cpu_to_le32(pci_dma_lo32(sg_dma_address(s)));
3246 *dword_ptr++ = 3257 *dword_ptr++ =
3247 cpu_to_le32(sg_dma_len(sg)); 3258 cpu_to_le32(sg_dma_len(s));
3248 dprintk(1, 3259 dprintk(1,
3249 "S/G Segment Cont. phys_addr=0x%x, " 3260 "S/G Segment Cont. phys_addr=0x%x, "
3250 "len=0x%x\n", 3261 "len=0x%x\n",
3251 cpu_to_le32(pci_dma_lo32(sg_dma_address(sg))), 3262 cpu_to_le32(pci_dma_lo32(sg_dma_address(s))),
3252 cpu_to_le32(sg_dma_len(sg))); 3263 cpu_to_le32(sg_dma_len(s)));
3253 sg++;
3254 } 3264 }
3265 remseg -= cnt;
3255 dprintk(5, "qla1280_32bit_start_scsi: " 3266 dprintk(5, "qla1280_32bit_start_scsi: "
3256 "continuation packet data - " 3267 "continuation packet data - "
3257 "scsi(%i:%i:%i)\n", SCSI_BUS_32(cmd), 3268 "scsi(%i:%i:%i)\n", SCSI_BUS_32(cmd),
@@ -4248,6 +4259,7 @@ static struct scsi_host_template qla1280_driver_template = {
4248 .sg_tablesize = SG_ALL, 4259 .sg_tablesize = SG_ALL,
4249 .cmd_per_lun = 1, 4260 .cmd_per_lun = 1,
4250 .use_clustering = ENABLE_CLUSTERING, 4261 .use_clustering = ENABLE_CLUSTERING,
4262 .use_sg_chaining = ENABLE_SG_CHAINING,
4251}; 4263};
4252 4264
4253 4265
diff --git a/drivers/scsi/qla2xxx/qla_os.c b/drivers/scsi/qla2xxx/qla_os.c
index a6bb8d0ecf13..0351d380c2d7 100644
--- a/drivers/scsi/qla2xxx/qla_os.c
+++ b/drivers/scsi/qla2xxx/qla_os.c
@@ -132,6 +132,7 @@ struct scsi_host_template qla2x00_driver_template = {
132 .this_id = -1, 132 .this_id = -1,
133 .cmd_per_lun = 3, 133 .cmd_per_lun = 3,
134 .use_clustering = ENABLE_CLUSTERING, 134 .use_clustering = ENABLE_CLUSTERING,
135 .use_sg_chaining = ENABLE_SG_CHAINING,
135 .sg_tablesize = SG_ALL, 136 .sg_tablesize = SG_ALL,
136 137
137 /* 138 /*
@@ -163,6 +164,7 @@ struct scsi_host_template qla24xx_driver_template = {
163 .this_id = -1, 164 .this_id = -1,
164 .cmd_per_lun = 3, 165 .cmd_per_lun = 3,
165 .use_clustering = ENABLE_CLUSTERING, 166 .use_clustering = ENABLE_CLUSTERING,
167 .use_sg_chaining = ENABLE_SG_CHAINING,
166 .sg_tablesize = SG_ALL, 168 .sg_tablesize = SG_ALL,
167 169
168 .max_sectors = 0xFFFF, 170 .max_sectors = 0xFFFF,
diff --git a/drivers/scsi/qla4xxx/ql4_os.c b/drivers/scsi/qla4xxx/ql4_os.c
index b1d565c12c5b..03b68d4f3bd0 100644
--- a/drivers/scsi/qla4xxx/ql4_os.c
+++ b/drivers/scsi/qla4xxx/ql4_os.c
@@ -94,6 +94,7 @@ static struct scsi_host_template qla4xxx_driver_template = {
94 .this_id = -1, 94 .this_id = -1,
95 .cmd_per_lun = 3, 95 .cmd_per_lun = 3,
96 .use_clustering = ENABLE_CLUSTERING, 96 .use_clustering = ENABLE_CLUSTERING,
97 .use_sg_chaining = ENABLE_SG_CHAINING,
97 .sg_tablesize = SG_ALL, 98 .sg_tablesize = SG_ALL,
98 99
99 .max_sectors = 0xFFFF, 100 .max_sectors = 0xFFFF,
diff --git a/drivers/scsi/qlogicfas.c b/drivers/scsi/qlogicfas.c
index 1e874f1fb5c6..1769f965eedf 100644
--- a/drivers/scsi/qlogicfas.c
+++ b/drivers/scsi/qlogicfas.c
@@ -197,6 +197,7 @@ static struct scsi_host_template qlogicfas_driver_template = {
197 .sg_tablesize = SG_ALL, 197 .sg_tablesize = SG_ALL,
198 .cmd_per_lun = 1, 198 .cmd_per_lun = 1,
199 .use_clustering = DISABLE_CLUSTERING, 199 .use_clustering = DISABLE_CLUSTERING,
200 .use_sg_chaining = ENABLE_SG_CHAINING,
200}; 201};
201 202
202static __init int qlogicfas_init(void) 203static __init int qlogicfas_init(void)
diff --git a/drivers/scsi/qlogicpti.c b/drivers/scsi/qlogicpti.c
index e93f80316a19..7a2e7986b038 100644
--- a/drivers/scsi/qlogicpti.c
+++ b/drivers/scsi/qlogicpti.c
@@ -868,7 +868,7 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
868 struct qlogicpti *qpti, u_int in_ptr, u_int out_ptr) 868 struct qlogicpti *qpti, u_int in_ptr, u_int out_ptr)
869{ 869{
870 struct dataseg *ds; 870 struct dataseg *ds;
871 struct scatterlist *sg; 871 struct scatterlist *sg, *s;
872 int i, n; 872 int i, n;
873 873
874 if (Cmnd->use_sg) { 874 if (Cmnd->use_sg) {
@@ -884,11 +884,12 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
884 n = sg_count; 884 n = sg_count;
885 if (n > 4) 885 if (n > 4)
886 n = 4; 886 n = 4;
887 for (i = 0; i < n; i++, sg++) { 887 for_each_sg(sg, s, n, i) {
888 ds[i].d_base = sg_dma_address(sg); 888 ds[i].d_base = sg_dma_address(s);
889 ds[i].d_count = sg_dma_len(sg); 889 ds[i].d_count = sg_dma_len(s);
890 } 890 }
891 sg_count -= 4; 891 sg_count -= 4;
892 sg = s;
892 while (sg_count > 0) { 893 while (sg_count > 0) {
893 struct Continuation_Entry *cont; 894 struct Continuation_Entry *cont;
894 895
@@ -907,9 +908,9 @@ static inline int load_cmd(struct scsi_cmnd *Cmnd, struct Command_Entry *cmd,
907 n = sg_count; 908 n = sg_count;
908 if (n > 7) 909 if (n > 7)
909 n = 7; 910 n = 7;
910 for (i = 0; i < n; i++, sg++) { 911 for_each_sg(sg, s, n, i) {
911 ds[i].d_base = sg_dma_address(sg); 912 ds[i].d_base = sg_dma_address(s);
912 ds[i].d_count = sg_dma_len(sg); 913 ds[i].d_count = sg_dma_len(s);
913 } 914 }
914 sg_count -= n; 915 sg_count -= n;
915 } 916 }
diff --git a/drivers/scsi/scsi_debug.c b/drivers/scsi/scsi_debug.c
index 4947dfe625a6..72ee4c9cfb1a 100644
--- a/drivers/scsi/scsi_debug.c
+++ b/drivers/scsi/scsi_debug.c
@@ -38,6 +38,7 @@
38#include <linux/proc_fs.h> 38#include <linux/proc_fs.h>
39#include <linux/vmalloc.h> 39#include <linux/vmalloc.h>
40#include <linux/moduleparam.h> 40#include <linux/moduleparam.h>
41#include <linux/scatterlist.h>
41 42
42#include <linux/blkdev.h> 43#include <linux/blkdev.h>
43#include "scsi.h" 44#include "scsi.h"
@@ -600,7 +601,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
600 int k, req_len, act_len, len, active; 601 int k, req_len, act_len, len, active;
601 void * kaddr; 602 void * kaddr;
602 void * kaddr_off; 603 void * kaddr_off;
603 struct scatterlist * sgpnt; 604 struct scatterlist * sg;
604 605
605 if (0 == scp->request_bufflen) 606 if (0 == scp->request_bufflen)
606 return 0; 607 return 0;
@@ -619,16 +620,16 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
619 scp->resid = req_len - act_len; 620 scp->resid = req_len - act_len;
620 return 0; 621 return 0;
621 } 622 }
622 sgpnt = (struct scatterlist *)scp->request_buffer;
623 active = 1; 623 active = 1;
624 for (k = 0, req_len = 0, act_len = 0; k < scp->use_sg; ++k, ++sgpnt) { 624 req_len = act_len = 0;
625 scsi_for_each_sg(scp, sg, scp->use_sg, k) {
625 if (active) { 626 if (active) {
626 kaddr = (unsigned char *) 627 kaddr = (unsigned char *)
627 kmap_atomic(sgpnt->page, KM_USER0); 628 kmap_atomic(sg->page, KM_USER0);
628 if (NULL == kaddr) 629 if (NULL == kaddr)
629 return (DID_ERROR << 16); 630 return (DID_ERROR << 16);
630 kaddr_off = (unsigned char *)kaddr + sgpnt->offset; 631 kaddr_off = (unsigned char *)kaddr + sg->offset;
631 len = sgpnt->length; 632 len = sg->length;
632 if ((req_len + len) > arr_len) { 633 if ((req_len + len) > arr_len) {
633 active = 0; 634 active = 0;
634 len = arr_len - req_len; 635 len = arr_len - req_len;
@@ -637,7 +638,7 @@ static int fill_from_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
637 kunmap_atomic(kaddr, KM_USER0); 638 kunmap_atomic(kaddr, KM_USER0);
638 act_len += len; 639 act_len += len;
639 } 640 }
640 req_len += sgpnt->length; 641 req_len += sg->length;
641 } 642 }
642 if (scp->resid) 643 if (scp->resid)
643 scp->resid -= act_len; 644 scp->resid -= act_len;
@@ -653,7 +654,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
653 int k, req_len, len, fin; 654 int k, req_len, len, fin;
654 void * kaddr; 655 void * kaddr;
655 void * kaddr_off; 656 void * kaddr_off;
656 struct scatterlist * sgpnt; 657 struct scatterlist * sg;
657 658
658 if (0 == scp->request_bufflen) 659 if (0 == scp->request_bufflen)
659 return 0; 660 return 0;
@@ -668,13 +669,14 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
668 memcpy(arr, scp->request_buffer, len); 669 memcpy(arr, scp->request_buffer, len);
669 return len; 670 return len;
670 } 671 }
671 sgpnt = (struct scatterlist *)scp->request_buffer; 672 sg = scsi_sglist(scp);
672 for (k = 0, req_len = 0, fin = 0; k < scp->use_sg; ++k, ++sgpnt) { 673 req_len = fin = 0;
673 kaddr = (unsigned char *)kmap_atomic(sgpnt->page, KM_USER0); 674 for (k = 0; k < scp->use_sg; ++k, sg = sg_next(sg)) {
675 kaddr = (unsigned char *)kmap_atomic(sg->page, KM_USER0);
674 if (NULL == kaddr) 676 if (NULL == kaddr)
675 return -1; 677 return -1;
676 kaddr_off = (unsigned char *)kaddr + sgpnt->offset; 678 kaddr_off = (unsigned char *)kaddr + sg->offset;
677 len = sgpnt->length; 679 len = sg->length;
678 if ((req_len + len) > max_arr_len) { 680 if ((req_len + len) > max_arr_len) {
679 len = max_arr_len - req_len; 681 len = max_arr_len - req_len;
680 fin = 1; 682 fin = 1;
@@ -683,7 +685,7 @@ static int fetch_to_dev_buffer(struct scsi_cmnd * scp, unsigned char * arr,
683 kunmap_atomic(kaddr, KM_USER0); 685 kunmap_atomic(kaddr, KM_USER0);
684 if (fin) 686 if (fin)
685 return req_len + len; 687 return req_len + len;
686 req_len += sgpnt->length; 688 req_len += sg->length;
687 } 689 }
688 return req_len; 690 return req_len;
689} 691}
diff --git a/drivers/scsi/scsi_lib.c b/drivers/scsi/scsi_lib.c
index 207f1aa08869..aac8a02cbe80 100644
--- a/drivers/scsi/scsi_lib.c
+++ b/drivers/scsi/scsi_lib.c
@@ -17,6 +17,7 @@
17#include <linux/pci.h> 17#include <linux/pci.h>
18#include <linux/delay.h> 18#include <linux/delay.h>
19#include <linux/hardirq.h> 19#include <linux/hardirq.h>
20#include <linux/scatterlist.h>
20 21
21#include <scsi/scsi.h> 22#include <scsi/scsi.h>
22#include <scsi/scsi_cmnd.h> 23#include <scsi/scsi_cmnd.h>
@@ -33,35 +34,34 @@
33#define SG_MEMPOOL_NR ARRAY_SIZE(scsi_sg_pools) 34#define SG_MEMPOOL_NR ARRAY_SIZE(scsi_sg_pools)
34#define SG_MEMPOOL_SIZE 2 35#define SG_MEMPOOL_SIZE 2
35 36
37/*
38 * The maximum number of SG segments that we will put inside a scatterlist
39 * (unless chaining is used). Should ideally fit inside a single page, to
40 * avoid a higher order allocation.
41 */
42#define SCSI_MAX_SG_SEGMENTS 128
43
36struct scsi_host_sg_pool { 44struct scsi_host_sg_pool {
37 size_t size; 45 size_t size;
38 char *name; 46 char *name;
39 struct kmem_cache *slab; 47 struct kmem_cache *slab;
40 mempool_t *pool; 48 mempool_t *pool;
41}; 49};
42 50
43#if (SCSI_MAX_PHYS_SEGMENTS < 32) 51#define SP(x) { x, "sgpool-" #x }
44#error SCSI_MAX_PHYS_SEGMENTS is too small
45#endif
46
47#define SP(x) { x, "sgpool-" #x }
48static struct scsi_host_sg_pool scsi_sg_pools[] = { 52static struct scsi_host_sg_pool scsi_sg_pools[] = {
49 SP(8), 53 SP(8),
50 SP(16), 54 SP(16),
55#if (SCSI_MAX_SG_SEGMENTS > 16)
51 SP(32), 56 SP(32),
52#if (SCSI_MAX_PHYS_SEGMENTS > 32) 57#if (SCSI_MAX_SG_SEGMENTS > 32)
53 SP(64), 58 SP(64),
54#if (SCSI_MAX_PHYS_SEGMENTS > 64) 59#if (SCSI_MAX_SG_SEGMENTS > 64)
55 SP(128), 60 SP(128),
56#if (SCSI_MAX_PHYS_SEGMENTS > 128)
57 SP(256),
58#if (SCSI_MAX_PHYS_SEGMENTS > 256)
59#error SCSI_MAX_PHYS_SEGMENTS is too large
60#endif
61#endif 61#endif
62#endif 62#endif
63#endif 63#endif
64}; 64};
65#undef SP 65#undef SP
66 66
67static void scsi_run_queue(struct request_queue *q); 67static void scsi_run_queue(struct request_queue *q);
@@ -289,14 +289,16 @@ static int scsi_req_map_sg(struct request *rq, struct scatterlist *sgl,
289 struct request_queue *q = rq->q; 289 struct request_queue *q = rq->q;
290 int nr_pages = (bufflen + sgl[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT; 290 int nr_pages = (bufflen + sgl[0].offset + PAGE_SIZE - 1) >> PAGE_SHIFT;
291 unsigned int data_len = bufflen, len, bytes, off; 291 unsigned int data_len = bufflen, len, bytes, off;
292 struct scatterlist *sg;
292 struct page *page; 293 struct page *page;
293 struct bio *bio = NULL; 294 struct bio *bio = NULL;
294 int i, err, nr_vecs = 0; 295 int i, err, nr_vecs = 0;
295 296
296 for (i = 0; i < nsegs; i++) { 297 for_each_sg(sgl, sg, nsegs, i) {
297 page = sgl[i].page; 298 page = sg->page;
298 off = sgl[i].offset; 299 off = sg->offset;
299 len = sgl[i].length; 300 len = sg->length;
301 data_len += len;
300 302
301 while (len > 0 && data_len > 0) { 303 while (len > 0 && data_len > 0) {
302 /* 304 /*
@@ -695,56 +697,170 @@ static struct scsi_cmnd *scsi_end_request(struct scsi_cmnd *cmd, int uptodate,
695 return NULL; 697 return NULL;
696} 698}
697 699
698struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask) 700/*
699{ 701 * Like SCSI_MAX_SG_SEGMENTS, but for archs that have sg chaining. This limit
700 struct scsi_host_sg_pool *sgp; 702 * is totally arbitrary, a setting of 2048 will get you at least 8mb ios.
701 struct scatterlist *sgl; 703 */
704#define SCSI_MAX_SG_CHAIN_SEGMENTS 2048
702 705
703 BUG_ON(!cmd->use_sg); 706static inline unsigned int scsi_sgtable_index(unsigned short nents)
707{
708 unsigned int index;
704 709
705 switch (cmd->use_sg) { 710 switch (nents) {
706 case 1 ... 8: 711 case 1 ... 8:
707 cmd->sglist_len = 0; 712 index = 0;
708 break; 713 break;
709 case 9 ... 16: 714 case 9 ... 16:
710 cmd->sglist_len = 1; 715 index = 1;
711 break; 716 break;
717#if (SCSI_MAX_SG_SEGMENTS > 16)
712 case 17 ... 32: 718 case 17 ... 32:
713 cmd->sglist_len = 2; 719 index = 2;
714 break; 720 break;
715#if (SCSI_MAX_PHYS_SEGMENTS > 32) 721#if (SCSI_MAX_SG_SEGMENTS > 32)
716 case 33 ... 64: 722 case 33 ... 64:
717 cmd->sglist_len = 3; 723 index = 3;
718 break; 724 break;
719#if (SCSI_MAX_PHYS_SEGMENTS > 64) 725#if (SCSI_MAX_SG_SEGMENTS > 64)
720 case 65 ... 128: 726 case 65 ... 128:
721 cmd->sglist_len = 4; 727 index = 4;
722 break;
723#if (SCSI_MAX_PHYS_SEGMENTS > 128)
724 case 129 ... 256:
725 cmd->sglist_len = 5;
726 break; 728 break;
727#endif 729#endif
728#endif 730#endif
729#endif 731#endif
730 default: 732 default:
731 return NULL; 733 printk(KERN_ERR "scsi: bad segment count=%d\n", nents);
734 BUG();
732 } 735 }
733 736
734 sgp = scsi_sg_pools + cmd->sglist_len; 737 return index;
735 sgl = mempool_alloc(sgp->pool, gfp_mask); 738}
736 return sgl; 739
740struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *cmd, gfp_t gfp_mask)
741{
742 struct scsi_host_sg_pool *sgp;
743 struct scatterlist *sgl, *prev, *ret;
744 unsigned int index;
745 int this, left;
746
747 BUG_ON(!cmd->use_sg);
748
749 left = cmd->use_sg;
750 ret = prev = NULL;
751 do {
752 this = left;
753 if (this > SCSI_MAX_SG_SEGMENTS) {
754 this = SCSI_MAX_SG_SEGMENTS - 1;
755 index = SG_MEMPOOL_NR - 1;
756 } else
757 index = scsi_sgtable_index(this);
758
759 left -= this;
760
761 sgp = scsi_sg_pools + index;
762
763 sgl = mempool_alloc(sgp->pool, gfp_mask);
764 if (unlikely(!sgl))
765 goto enomem;
766
767 memset(sgl, 0, sizeof(*sgl) * sgp->size);
768
769 /*
770 * first loop through, set initial index and return value
771 */
772 if (!ret)
773 ret = sgl;
774
775 /*
776 * chain previous sglist, if any. we know the previous
777 * sglist must be the biggest one, or we would not have
778 * ended up doing another loop.
779 */
780 if (prev)
781 sg_chain(prev, SCSI_MAX_SG_SEGMENTS, sgl);
782
783 /*
784 * don't allow subsequent mempool allocs to sleep, it would
785 * violate the mempool principle.
786 */
787 gfp_mask &= ~__GFP_WAIT;
788 gfp_mask |= __GFP_HIGH;
789 prev = sgl;
790 } while (left);
791
792 /*
793 * ->use_sg may get modified after dma mapping has potentially
794 * shrunk the number of segments, so keep a copy of it for free.
795 */
796 cmd->__use_sg = cmd->use_sg;
797 return ret;
798enomem:
799 if (ret) {
800 /*
801 * Free entries chained off ret. Since we were trying to
802 * allocate another sglist, we know that all entries are of
803 * the max size.
804 */
805 sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
806 prev = ret;
807 ret = &ret[SCSI_MAX_SG_SEGMENTS - 1];
808
809 while ((sgl = sg_chain_ptr(ret)) != NULL) {
810 ret = &sgl[SCSI_MAX_SG_SEGMENTS - 1];
811 mempool_free(sgl, sgp->pool);
812 }
813
814 mempool_free(prev, sgp->pool);
815 }
816 return NULL;
737} 817}
738 818
739EXPORT_SYMBOL(scsi_alloc_sgtable); 819EXPORT_SYMBOL(scsi_alloc_sgtable);
740 820
741void scsi_free_sgtable(struct scatterlist *sgl, int index) 821void scsi_free_sgtable(struct scsi_cmnd *cmd)
742{ 822{
823 struct scatterlist *sgl = cmd->request_buffer;
743 struct scsi_host_sg_pool *sgp; 824 struct scsi_host_sg_pool *sgp;
744 825
745 BUG_ON(index >= SG_MEMPOOL_NR); 826 /*
827 * if this is the biggest size sglist, check if we have
828 * chained parts we need to free
829 */
830 if (cmd->__use_sg > SCSI_MAX_SG_SEGMENTS) {
831 unsigned short this, left;
832 struct scatterlist *next;
833 unsigned int index;
834
835 left = cmd->__use_sg - (SCSI_MAX_SG_SEGMENTS - 1);
836 next = sg_chain_ptr(&sgl[SCSI_MAX_SG_SEGMENTS - 1]);
837 while (left && next) {
838 sgl = next;
839 this = left;
840 if (this > SCSI_MAX_SG_SEGMENTS) {
841 this = SCSI_MAX_SG_SEGMENTS - 1;
842 index = SG_MEMPOOL_NR - 1;
843 } else
844 index = scsi_sgtable_index(this);
845
846 left -= this;
847
848 sgp = scsi_sg_pools + index;
849
850 if (left)
851 next = sg_chain_ptr(&sgl[sgp->size - 1]);
852
853 mempool_free(sgl, sgp->pool);
854 }
855
856 /*
857 * Restore original, will be freed below
858 */
859 sgl = cmd->request_buffer;
860 sgp = scsi_sg_pools + SG_MEMPOOL_NR - 1;
861 } else
862 sgp = scsi_sg_pools + scsi_sgtable_index(cmd->__use_sg);
746 863
747 sgp = scsi_sg_pools + index;
748 mempool_free(sgl, sgp->pool); 864 mempool_free(sgl, sgp->pool);
749} 865}
750 866
@@ -770,7 +886,7 @@ EXPORT_SYMBOL(scsi_free_sgtable);
770static void scsi_release_buffers(struct scsi_cmnd *cmd) 886static void scsi_release_buffers(struct scsi_cmnd *cmd)
771{ 887{
772 if (cmd->use_sg) 888 if (cmd->use_sg)
773 scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); 889 scsi_free_sgtable(cmd);
774 890
775 /* 891 /*
776 * Zero these out. They now point to freed memory, and it is 892 * Zero these out. They now point to freed memory, and it is
@@ -984,7 +1100,6 @@ void scsi_io_completion(struct scsi_cmnd *cmd, unsigned int good_bytes)
984static int scsi_init_io(struct scsi_cmnd *cmd) 1100static int scsi_init_io(struct scsi_cmnd *cmd)
985{ 1101{
986 struct request *req = cmd->request; 1102 struct request *req = cmd->request;
987 struct scatterlist *sgpnt;
988 int count; 1103 int count;
989 1104
990 /* 1105 /*
@@ -997,14 +1112,13 @@ static int scsi_init_io(struct scsi_cmnd *cmd)
997 /* 1112 /*
998 * If sg table allocation fails, requeue request later. 1113 * If sg table allocation fails, requeue request later.
999 */ 1114 */
1000 sgpnt = scsi_alloc_sgtable(cmd, GFP_ATOMIC); 1115 cmd->request_buffer = scsi_alloc_sgtable(cmd, GFP_ATOMIC);
1001 if (unlikely(!sgpnt)) { 1116 if (unlikely(!cmd->request_buffer)) {
1002 scsi_unprep_request(req); 1117 scsi_unprep_request(req);
1003 return BLKPREP_DEFER; 1118 return BLKPREP_DEFER;
1004 } 1119 }
1005 1120
1006 req->buffer = NULL; 1121 req->buffer = NULL;
1007 cmd->request_buffer = (char *) sgpnt;
1008 if (blk_pc_request(req)) 1122 if (blk_pc_request(req))
1009 cmd->request_bufflen = req->data_len; 1123 cmd->request_bufflen = req->data_len;
1010 else 1124 else
@@ -1529,8 +1643,25 @@ struct request_queue *__scsi_alloc_queue(struct Scsi_Host *shost,
1529 if (!q) 1643 if (!q)
1530 return NULL; 1644 return NULL;
1531 1645
1646 /*
1647 * this limit is imposed by hardware restrictions
1648 */
1532 blk_queue_max_hw_segments(q, shost->sg_tablesize); 1649 blk_queue_max_hw_segments(q, shost->sg_tablesize);
1533 blk_queue_max_phys_segments(q, SCSI_MAX_PHYS_SEGMENTS); 1650
1651 /*
1652 * In the future, sg chaining support will be mandatory and this
1653 * ifdef can then go away. Right now we don't have all archs
1654 * converted, so better keep it safe.
1655 */
1656#ifdef ARCH_HAS_SG_CHAIN
1657 if (shost->use_sg_chaining)
1658 blk_queue_max_phys_segments(q, SCSI_MAX_SG_CHAIN_SEGMENTS);
1659 else
1660 blk_queue_max_phys_segments(q, SCSI_MAX_SG_SEGMENTS);
1661#else
1662 blk_queue_max_phys_segments(q, SCSI_MAX_SG_SEGMENTS);
1663#endif
1664
1534 blk_queue_max_sectors(q, shost->max_sectors); 1665 blk_queue_max_sectors(q, shost->max_sectors);
1535 blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost)); 1666 blk_queue_bounce_limit(q, scsi_calculate_bounce_limit(shost));
1536 blk_queue_segment_boundary(q, shost->dma_boundary); 1667 blk_queue_segment_boundary(q, shost->dma_boundary);
@@ -2193,18 +2324,19 @@ EXPORT_SYMBOL_GPL(scsi_target_unblock);
2193 * 2324 *
2194 * Returns virtual address of the start of the mapped page 2325 * Returns virtual address of the start of the mapped page
2195 */ 2326 */
2196void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count, 2327void *scsi_kmap_atomic_sg(struct scatterlist *sgl, int sg_count,
2197 size_t *offset, size_t *len) 2328 size_t *offset, size_t *len)
2198{ 2329{
2199 int i; 2330 int i;
2200 size_t sg_len = 0, len_complete = 0; 2331 size_t sg_len = 0, len_complete = 0;
2332 struct scatterlist *sg;
2201 struct page *page; 2333 struct page *page;
2202 2334
2203 WARN_ON(!irqs_disabled()); 2335 WARN_ON(!irqs_disabled());
2204 2336
2205 for (i = 0; i < sg_count; i++) { 2337 for_each_sg(sgl, sg, sg_count, i) {
2206 len_complete = sg_len; /* Complete sg-entries */ 2338 len_complete = sg_len; /* Complete sg-entries */
2207 sg_len += sg[i].length; 2339 sg_len += sg->length;
2208 if (sg_len > *offset) 2340 if (sg_len > *offset)
2209 break; 2341 break;
2210 } 2342 }
@@ -2218,10 +2350,10 @@ void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
2218 } 2350 }
2219 2351
2220 /* Offset starting from the beginning of first page in this sg-entry */ 2352 /* Offset starting from the beginning of first page in this sg-entry */
2221 *offset = *offset - len_complete + sg[i].offset; 2353 *offset = *offset - len_complete + sg->offset;
2222 2354
2223 /* Assumption: contiguous pages can be accessed as "page + i" */ 2355 /* Assumption: contiguous pages can be accessed as "page + i" */
2224 page = nth_page(sg[i].page, (*offset >> PAGE_SHIFT)); 2356 page = nth_page(sg->page, (*offset >> PAGE_SHIFT));
2225 *offset &= ~PAGE_MASK; 2357 *offset &= ~PAGE_MASK;
2226 2358
2227 /* Bytes in this sg-entry from *offset to the end of the page */ 2359 /* Bytes in this sg-entry from *offset to the end of the page */
diff --git a/drivers/scsi/scsi_tgt_lib.c b/drivers/scsi/scsi_tgt_lib.c
index 66c692ffa305..a91761c3645f 100644
--- a/drivers/scsi/scsi_tgt_lib.c
+++ b/drivers/scsi/scsi_tgt_lib.c
@@ -332,7 +332,7 @@ static void scsi_tgt_cmd_done(struct scsi_cmnd *cmd)
332 scsi_tgt_uspace_send_status(cmd, tcmd->itn_id, tcmd->tag); 332 scsi_tgt_uspace_send_status(cmd, tcmd->itn_id, tcmd->tag);
333 333
334 if (cmd->request_buffer) 334 if (cmd->request_buffer)
335 scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); 335 scsi_free_sgtable(cmd);
336 336
337 queue_work(scsi_tgtd, &tcmd->work); 337 queue_work(scsi_tgtd, &tcmd->work);
338} 338}
@@ -373,7 +373,7 @@ static int scsi_tgt_init_cmd(struct scsi_cmnd *cmd, gfp_t gfp_mask)
373 } 373 }
374 374
375 eprintk("cmd %p cnt %d\n", cmd, cmd->use_sg); 375 eprintk("cmd %p cnt %d\n", cmd, cmd->use_sg);
376 scsi_free_sgtable(cmd->request_buffer, cmd->sglist_len); 376 scsi_free_sgtable(cmd);
377 return -EINVAL; 377 return -EINVAL;
378} 378}
379 379
diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c
index 0a3a528212c2..69f542c4923c 100644
--- a/drivers/scsi/sd.c
+++ b/drivers/scsi/sd.c
@@ -826,27 +826,6 @@ static int sd_sync_cache(struct scsi_disk *sdkp)
826 return 0; 826 return 0;
827} 827}
828 828
829static int sd_issue_flush(struct request_queue *q, struct gendisk *disk,
830 sector_t *error_sector)
831{
832 int ret = 0;
833 struct scsi_device *sdp = q->queuedata;
834 struct scsi_disk *sdkp;
835
836 if (sdp->sdev_state != SDEV_RUNNING)
837 return -ENXIO;
838
839 sdkp = scsi_disk_get_from_dev(&sdp->sdev_gendev);
840
841 if (!sdkp)
842 return -ENODEV;
843
844 if (sdkp->WCE)
845 ret = sd_sync_cache(sdkp);
846 scsi_disk_put(sdkp);
847 return ret;
848}
849
850static void sd_prepare_flush(struct request_queue *q, struct request *rq) 829static void sd_prepare_flush(struct request_queue *q, struct request *rq)
851{ 830{
852 memset(rq->cmd, 0, sizeof(rq->cmd)); 831 memset(rq->cmd, 0, sizeof(rq->cmd));
@@ -1697,7 +1676,6 @@ static int sd_probe(struct device *dev)
1697 sd_revalidate_disk(gd); 1676 sd_revalidate_disk(gd);
1698 1677
1699 blk_queue_prep_rq(sdp->request_queue, sd_prep_fn); 1678 blk_queue_prep_rq(sdp->request_queue, sd_prep_fn);
1700 blk_queue_issue_flush_fn(sdp->request_queue, sd_issue_flush);
1701 1679
1702 gd->driverfs_dev = &sdp->sdev_gendev; 1680 gd->driverfs_dev = &sdp->sdev_gendev;
1703 gd->flags = GENHD_FL_DRIVERFS; 1681 gd->flags = GENHD_FL_DRIVERFS;
diff --git a/drivers/scsi/sg.c b/drivers/scsi/sg.c
index f6f5fc7d0cee..7238b2dfc497 100644
--- a/drivers/scsi/sg.c
+++ b/drivers/scsi/sg.c
@@ -1165,7 +1165,7 @@ sg_vma_nopage(struct vm_area_struct *vma, unsigned long addr, int *type)
1165 sg = rsv_schp->buffer; 1165 sg = rsv_schp->buffer;
1166 sa = vma->vm_start; 1166 sa = vma->vm_start;
1167 for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end); 1167 for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
1168 ++k, ++sg) { 1168 ++k, sg = sg_next(sg)) {
1169 len = vma->vm_end - sa; 1169 len = vma->vm_end - sa;
1170 len = (len < sg->length) ? len : sg->length; 1170 len = (len < sg->length) ? len : sg->length;
1171 if (offset < len) { 1171 if (offset < len) {
@@ -1209,7 +1209,7 @@ sg_mmap(struct file *filp, struct vm_area_struct *vma)
1209 sa = vma->vm_start; 1209 sa = vma->vm_start;
1210 sg = rsv_schp->buffer; 1210 sg = rsv_schp->buffer;
1211 for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end); 1211 for (k = 0; (k < rsv_schp->k_use_sg) && (sa < vma->vm_end);
1212 ++k, ++sg) { 1212 ++k, sg = sg_next(sg)) {
1213 len = vma->vm_end - sa; 1213 len = vma->vm_end - sa;
1214 len = (len < sg->length) ? len : sg->length; 1214 len = (len < sg->length) ? len : sg->length;
1215 sa += len; 1215 sa += len;
@@ -1840,7 +1840,7 @@ sg_build_indirect(Sg_scatter_hold * schp, Sg_fd * sfp, int buff_size)
1840 } 1840 }
1841 for (k = 0, sg = schp->buffer, rem_sz = blk_size; 1841 for (k = 0, sg = schp->buffer, rem_sz = blk_size;
1842 (rem_sz > 0) && (k < mx_sc_elems); 1842 (rem_sz > 0) && (k < mx_sc_elems);
1843 ++k, rem_sz -= ret_sz, ++sg) { 1843 ++k, rem_sz -= ret_sz, sg = sg_next(sg)) {
1844 1844
1845 num = (rem_sz > scatter_elem_sz_prev) ? 1845 num = (rem_sz > scatter_elem_sz_prev) ?
1846 scatter_elem_sz_prev : rem_sz; 1846 scatter_elem_sz_prev : rem_sz;
@@ -1913,7 +1913,7 @@ sg_write_xfer(Sg_request * srp)
1913 if (res) 1913 if (res)
1914 return res; 1914 return res;
1915 1915
1916 for (; p; ++sg, ksglen = sg->length, 1916 for (; p; sg = sg_next(sg), ksglen = sg->length,
1917 p = page_address(sg->page)) { 1917 p = page_address(sg->page)) {
1918 if (usglen <= 0) 1918 if (usglen <= 0)
1919 break; 1919 break;
@@ -1992,7 +1992,7 @@ sg_remove_scat(Sg_scatter_hold * schp)
1992 int k; 1992 int k;
1993 1993
1994 for (k = 0; (k < schp->k_use_sg) && sg->page; 1994 for (k = 0; (k < schp->k_use_sg) && sg->page;
1995 ++k, ++sg) { 1995 ++k, sg = sg_next(sg)) {
1996 SCSI_LOG_TIMEOUT(5, printk( 1996 SCSI_LOG_TIMEOUT(5, printk(
1997 "sg_remove_scat: k=%d, pg=0x%p, len=%d\n", 1997 "sg_remove_scat: k=%d, pg=0x%p, len=%d\n",
1998 k, sg->page, sg->length)); 1998 k, sg->page, sg->length));
@@ -2045,7 +2045,7 @@ sg_read_xfer(Sg_request * srp)
2045 if (res) 2045 if (res)
2046 return res; 2046 return res;
2047 2047
2048 for (; p; ++sg, ksglen = sg->length, 2048 for (; p; sg = sg_next(sg), ksglen = sg->length,
2049 p = page_address(sg->page)) { 2049 p = page_address(sg->page)) {
2050 if (usglen <= 0) 2050 if (usglen <= 0)
2051 break; 2051 break;
@@ -2092,7 +2092,7 @@ sg_read_oxfer(Sg_request * srp, char __user *outp, int num_read_xfer)
2092 if ((!outp) || (num_read_xfer <= 0)) 2092 if ((!outp) || (num_read_xfer <= 0))
2093 return 0; 2093 return 0;
2094 2094
2095 for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, ++sg) { 2095 for (k = 0; (k < schp->k_use_sg) && sg->page; ++k, sg = sg_next(sg)) {
2096 num = sg->length; 2096 num = sg->length;
2097 if (num > num_read_xfer) { 2097 if (num > num_read_xfer) {
2098 if (__copy_to_user(outp, page_address(sg->page), 2098 if (__copy_to_user(outp, page_address(sg->page),
@@ -2142,7 +2142,7 @@ sg_link_reserve(Sg_fd * sfp, Sg_request * srp, int size)
2142 SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size)); 2142 SCSI_LOG_TIMEOUT(4, printk("sg_link_reserve: size=%d\n", size));
2143 rem = size; 2143 rem = size;
2144 2144
2145 for (k = 0; k < rsv_schp->k_use_sg; ++k, ++sg) { 2145 for (k = 0; k < rsv_schp->k_use_sg; ++k, sg = sg_next(sg)) {
2146 num = sg->length; 2146 num = sg->length;
2147 if (rem <= num) { 2147 if (rem <= num) {
2148 sfp->save_scat_len = num; 2148 sfp->save_scat_len = num;
diff --git a/drivers/scsi/stex.c b/drivers/scsi/stex.c
index 72f6d8015358..e3fab3a6aed7 100644
--- a/drivers/scsi/stex.c
+++ b/drivers/scsi/stex.c
@@ -1123,6 +1123,7 @@ static struct scsi_host_template driver_template = {
1123 .this_id = -1, 1123 .this_id = -1,
1124 .sg_tablesize = ST_MAX_SG, 1124 .sg_tablesize = ST_MAX_SG,
1125 .cmd_per_lun = ST_CMD_PER_LUN, 1125 .cmd_per_lun = ST_CMD_PER_LUN,
1126 .use_sg_chaining = ENABLE_SG_CHAINING,
1126}; 1127};
1127 1128
1128static int stex_set_dma_mask(struct pci_dev * pdev) 1129static int stex_set_dma_mask(struct pci_dev * pdev)
diff --git a/drivers/scsi/sym53c416.c b/drivers/scsi/sym53c416.c
index 92bfaeafe30d..8befab7e9839 100644
--- a/drivers/scsi/sym53c416.c
+++ b/drivers/scsi/sym53c416.c
@@ -854,5 +854,6 @@ static struct scsi_host_template driver_template = {
854 .cmd_per_lun = 1, 854 .cmd_per_lun = 1,
855 .unchecked_isa_dma = 1, 855 .unchecked_isa_dma = 1,
856 .use_clustering = ENABLE_CLUSTERING, 856 .use_clustering = ENABLE_CLUSTERING,
857 .use_sg_chaining = ENABLE_SG_CHAINING,
857}; 858};
858#include "scsi_module.c" 859#include "scsi_module.c"
diff --git a/drivers/scsi/sym53c8xx_2/sym_glue.c b/drivers/scsi/sym53c8xx_2/sym_glue.c
index 3db22325ea2c..db03c4c8ec1e 100644
--- a/drivers/scsi/sym53c8xx_2/sym_glue.c
+++ b/drivers/scsi/sym53c8xx_2/sym_glue.c
@@ -1808,6 +1808,7 @@ static struct scsi_host_template sym2_template = {
1808 .eh_host_reset_handler = sym53c8xx_eh_host_reset_handler, 1808 .eh_host_reset_handler = sym53c8xx_eh_host_reset_handler,
1809 .this_id = 7, 1809 .this_id = 7,
1810 .use_clustering = ENABLE_CLUSTERING, 1810 .use_clustering = ENABLE_CLUSTERING,
1811 .use_sg_chaining = ENABLE_SG_CHAINING,
1811 .max_sectors = 0xFFFF, 1812 .max_sectors = 0xFFFF,
1812#ifdef SYM_LINUX_PROC_INFO_SUPPORT 1813#ifdef SYM_LINUX_PROC_INFO_SUPPORT
1813 .proc_info = sym53c8xx_proc_info, 1814 .proc_info = sym53c8xx_proc_info,
diff --git a/drivers/scsi/u14-34f.c b/drivers/scsi/u14-34f.c
index fc9f51818e8f..7edd6ceb13b2 100644
--- a/drivers/scsi/u14-34f.c
+++ b/drivers/scsi/u14-34f.c
@@ -450,7 +450,8 @@ static struct scsi_host_template driver_template = {
450 .slave_configure = u14_34f_slave_configure, 450 .slave_configure = u14_34f_slave_configure,
451 .this_id = 7, 451 .this_id = 7,
452 .unchecked_isa_dma = 1, 452 .unchecked_isa_dma = 1,
453 .use_clustering = ENABLE_CLUSTERING 453 .use_clustering = ENABLE_CLUSTERING,
454 .use_sg_chaining = ENABLE_SG_CHAINING,
454 }; 455 };
455 456
456#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD) 457#if !defined(__BIG_ENDIAN_BITFIELD) && !defined(__LITTLE_ENDIAN_BITFIELD)
diff --git a/drivers/scsi/ultrastor.c b/drivers/scsi/ultrastor.c
index c08235d5afc9..ea72bbeb8f9d 100644
--- a/drivers/scsi/ultrastor.c
+++ b/drivers/scsi/ultrastor.c
@@ -1197,5 +1197,6 @@ static struct scsi_host_template driver_template = {
1197 .cmd_per_lun = ULTRASTOR_MAX_CMDS_PER_LUN, 1197 .cmd_per_lun = ULTRASTOR_MAX_CMDS_PER_LUN,
1198 .unchecked_isa_dma = 1, 1198 .unchecked_isa_dma = 1,
1199 .use_clustering = ENABLE_CLUSTERING, 1199 .use_clustering = ENABLE_CLUSTERING,
1200 .use_sg_chaining = ENABLE_SG_CHAINING,
1200}; 1201};
1201#include "scsi_module.c" 1202#include "scsi_module.c"
diff --git a/drivers/scsi/wd7000.c b/drivers/scsi/wd7000.c
index d6fd4259c56b..255c611e78b8 100644
--- a/drivers/scsi/wd7000.c
+++ b/drivers/scsi/wd7000.c
@@ -1671,6 +1671,7 @@ static struct scsi_host_template driver_template = {
1671 .cmd_per_lun = 1, 1671 .cmd_per_lun = 1,
1672 .unchecked_isa_dma = 1, 1672 .unchecked_isa_dma = 1,
1673 .use_clustering = ENABLE_CLUSTERING, 1673 .use_clustering = ENABLE_CLUSTERING,
1674 .use_sg_chaining = ENABLE_SG_CHAINING,
1674}; 1675};
1675 1676
1676#include "scsi_module.c" 1677#include "scsi_module.c"
diff --git a/drivers/serial/8250_pci.c b/drivers/serial/8250_pci.c
index 1ea1ed82c352..0e357562ce9e 100644
--- a/drivers/serial/8250_pci.c
+++ b/drivers/serial/8250_pci.c
@@ -1036,6 +1036,7 @@ enum pci_board_num_t {
1036 pbn_b0_2_115200, 1036 pbn_b0_2_115200,
1037 pbn_b0_4_115200, 1037 pbn_b0_4_115200,
1038 pbn_b0_5_115200, 1038 pbn_b0_5_115200,
1039 pbn_b0_8_115200,
1039 1040
1040 pbn_b0_1_921600, 1041 pbn_b0_1_921600,
1041 pbn_b0_2_921600, 1042 pbn_b0_2_921600,
@@ -1172,6 +1173,12 @@ static struct pciserial_board pci_boards[] __devinitdata = {
1172 .base_baud = 115200, 1173 .base_baud = 115200,
1173 .uart_offset = 8, 1174 .uart_offset = 8,
1174 }, 1175 },
1176 [pbn_b0_8_115200] = {
1177 .flags = FL_BASE0,
1178 .num_ports = 8,
1179 .base_baud = 115200,
1180 .uart_offset = 8,
1181 },
1175 1182
1176 [pbn_b0_1_921600] = { 1183 [pbn_b0_1_921600] = {
1177 .flags = FL_BASE0, 1184 .flags = FL_BASE0,
@@ -2566,6 +2573,119 @@ static struct pci_device_id serial_pci_tbl[] = {
2566 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030, 2573 { PCI_VENDOR_ID_PLX, PCI_DEVICE_ID_PLX_9030,
2567 PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8, 2574 PCI_SUBVENDOR_ID_PERLE, PCI_SUBDEVICE_ID_PCI_RAS8,
2568 0, 0, pbn_b2_8_921600 }, 2575 0, 0, pbn_b2_8_921600 },
2576
2577 /*
2578 * Mainpine series cards: Fairly standard layout but fools
2579 * parts of the autodetect in some cases and uses otherwise
2580 * unmatched communications subclasses in the PCI Express case
2581 */
2582
2583 { /* RockForceDUO */
2584 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2585 PCI_VENDOR_ID_MAINPINE, 0x0200,
2586 0, 0, pbn_b0_2_115200 },
2587 { /* RockForceQUATRO */
2588 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2589 PCI_VENDOR_ID_MAINPINE, 0x0300,
2590 0, 0, pbn_b0_4_115200 },
2591 { /* RockForceDUO+ */
2592 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2593 PCI_VENDOR_ID_MAINPINE, 0x0400,
2594 0, 0, pbn_b0_2_115200 },
2595 { /* RockForceQUATRO+ */
2596 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2597 PCI_VENDOR_ID_MAINPINE, 0x0500,
2598 0, 0, pbn_b0_4_115200 },
2599 { /* RockForce+ */
2600 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2601 PCI_VENDOR_ID_MAINPINE, 0x0600,
2602 0, 0, pbn_b0_2_115200 },
2603 { /* RockForce+ */
2604 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2605 PCI_VENDOR_ID_MAINPINE, 0x0700,
2606 0, 0, pbn_b0_4_115200 },
2607 { /* RockForceOCTO+ */
2608 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2609 PCI_VENDOR_ID_MAINPINE, 0x0800,
2610 0, 0, pbn_b0_8_115200 },
2611 { /* RockForceDUO+ */
2612 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2613 PCI_VENDOR_ID_MAINPINE, 0x0C00,
2614 0, 0, pbn_b0_2_115200 },
2615 { /* RockForceQUARTRO+ */
2616 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2617 PCI_VENDOR_ID_MAINPINE, 0x0D00,
2618 0, 0, pbn_b0_4_115200 },
2619 { /* RockForceOCTO+ */
2620 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2621 PCI_VENDOR_ID_MAINPINE, 0x1D00,
2622 0, 0, pbn_b0_8_115200 },
2623 { /* RockForceD1 */
2624 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2625 PCI_VENDOR_ID_MAINPINE, 0x2000,
2626 0, 0, pbn_b0_1_115200 },
2627 { /* RockForceF1 */
2628 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2629 PCI_VENDOR_ID_MAINPINE, 0x2100,
2630 0, 0, pbn_b0_1_115200 },
2631 { /* RockForceD2 */
2632 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2633 PCI_VENDOR_ID_MAINPINE, 0x2200,
2634 0, 0, pbn_b0_2_115200 },
2635 { /* RockForceF2 */
2636 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2637 PCI_VENDOR_ID_MAINPINE, 0x2300,
2638 0, 0, pbn_b0_2_115200 },
2639 { /* RockForceD4 */
2640 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2641 PCI_VENDOR_ID_MAINPINE, 0x2400,
2642 0, 0, pbn_b0_4_115200 },
2643 { /* RockForceF4 */
2644 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2645 PCI_VENDOR_ID_MAINPINE, 0x2500,
2646 0, 0, pbn_b0_4_115200 },
2647 { /* RockForceD8 */
2648 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2649 PCI_VENDOR_ID_MAINPINE, 0x2600,
2650 0, 0, pbn_b0_8_115200 },
2651 { /* RockForceF8 */
2652 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2653 PCI_VENDOR_ID_MAINPINE, 0x2700,
2654 0, 0, pbn_b0_8_115200 },
2655 { /* IQ Express D1 */
2656 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2657 PCI_VENDOR_ID_MAINPINE, 0x3000,
2658 0, 0, pbn_b0_1_115200 },
2659 { /* IQ Express F1 */
2660 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2661 PCI_VENDOR_ID_MAINPINE, 0x3100,
2662 0, 0, pbn_b0_1_115200 },
2663 { /* IQ Express D2 */
2664 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2665 PCI_VENDOR_ID_MAINPINE, 0x3200,
2666 0, 0, pbn_b0_2_115200 },
2667 { /* IQ Express F2 */
2668 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2669 PCI_VENDOR_ID_MAINPINE, 0x3300,
2670 0, 0, pbn_b0_2_115200 },
2671 { /* IQ Express D4 */
2672 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2673 PCI_VENDOR_ID_MAINPINE, 0x3400,
2674 0, 0, pbn_b0_4_115200 },
2675 { /* IQ Express F4 */
2676 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2677 PCI_VENDOR_ID_MAINPINE, 0x3500,
2678 0, 0, pbn_b0_4_115200 },
2679 { /* IQ Express D8 */
2680 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2681 PCI_VENDOR_ID_MAINPINE, 0x3C00,
2682 0, 0, pbn_b0_8_115200 },
2683 { /* IQ Express F8 */
2684 PCI_VENDOR_ID_MAINPINE, PCI_DEVICE_ID_MAINPINE_PBRIDGE,
2685 PCI_VENDOR_ID_MAINPINE, 0x3D00,
2686 0, 0, pbn_b0_8_115200 },
2687
2688
2569 /* 2689 /*
2570 * PA Semi PA6T-1682M on-chip UART 2690 * PA Semi PA6T-1682M on-chip UART
2571 */ 2691 */
diff --git a/drivers/serial/8250_pnp.c b/drivers/serial/8250_pnp.c
index 301c8c0be9d7..926f58a674a1 100644
--- a/drivers/serial/8250_pnp.c
+++ b/drivers/serial/8250_pnp.c
@@ -327,6 +327,8 @@ static const struct pnp_device_id pnp_dev_table[] = {
327 { "WACF004", 0 }, 327 { "WACF004", 0 },
328 { "WACF005", 0 }, 328 { "WACF005", 0 },
329 { "WACF006", 0 }, 329 { "WACF006", 0 },
330 { "WACF007", 0 },
331 { "WACF008", 0 },
330 /* Compaq touchscreen */ 332 /* Compaq touchscreen */
331 { "FPI2002", 0 }, 333 { "FPI2002", 0 },
332 /* Fujitsu Stylistic touchscreens */ 334 /* Fujitsu Stylistic touchscreens */
diff --git a/drivers/serial/crisv10.c b/drivers/serial/crisv10.c
index 312bef6bd583..7e8724d3571f 100644
--- a/drivers/serial/crisv10.c
+++ b/drivers/serial/crisv10.c
@@ -514,6 +514,8 @@ struct tty_driver *serial_driver;
514 * TTY_THRESHOLD_THROTTLE/UNTHROTTLE=128 514 * TTY_THRESHOLD_THROTTLE/UNTHROTTLE=128
515 * BUF_SIZE can't be > 128 515 * BUF_SIZE can't be > 128
516 */ 516 */
517#define CRIS_BUF_SIZE 512
518
517/* Currently 16 descriptors x 128 bytes = 2048 bytes */ 519/* Currently 16 descriptors x 128 bytes = 2048 bytes */
518#define SERIAL_DESCR_BUF_SIZE 256 520#define SERIAL_DESCR_BUF_SIZE 256
519 521
@@ -2497,55 +2499,18 @@ static void flush_to_flip_buffer(struct e100_serial *info)
2497 return; 2499 return;
2498 } 2500 }
2499 2501
2500 length = tty->flip.count; 2502 while ((buffer = info->first_recv_buffer) != NULL) {
2501 /* Don't flip more than the ldisc has room for.
2502 * The return value from ldisc.receive_room(tty) - might not be up to
2503 * date, the previous flip of up to TTY_FLIPBUF_SIZE might be on the
2504 * processed and not accounted for yet.
2505 * Since we use DMA, 1 SERIAL_DESCR_BUF_SIZE could be on the way.
2506 * Lets buffer data here and let flow control take care of it.
2507 * Since we normally flip large chunks, the ldisc don't react
2508 * with throttle until too late if we flip to much.
2509 */
2510 max_flip_size = tty->ldisc.receive_room(tty);
2511 if (max_flip_size < 0)
2512 max_flip_size = 0;
2513 if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */
2514 length + info->recv_cnt + /* We have this queued */
2515 2*SERIAL_DESCR_BUF_SIZE + /* This could be on the way */
2516 TTY_THRESHOLD_THROTTLE)) { /* Some slack */
2517 /* check TTY_THROTTLED first so it indicates our state */
2518 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) {
2519 DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles room %lu\n", max_flip_size));
2520 rs_throttle(tty);
2521 }
2522#if 0
2523 else if (max_flip_size <= (TTY_FLIPBUF_SIZE + /* Maybe not accounted for */
2524 length + info->recv_cnt + /* We have this queued */
2525 SERIAL_DESCR_BUF_SIZE + /* This could be on the way */
2526 TTY_THRESHOLD_THROTTLE)) { /* Some slack */
2527 DFLOW(DEBUG_LOG(info->line,"flush_to_flip throttles again! %lu\n", max_flip_size));
2528 rs_throttle(tty);
2529 }
2530#endif
2531 }
2532
2533 if (max_flip_size > TTY_FLIPBUF_SIZE)
2534 max_flip_size = TTY_FLIPBUF_SIZE;
2535
2536 while ((buffer = info->first_recv_buffer) && length < max_flip_size) {
2537 unsigned int count = buffer->length; 2503 unsigned int count = buffer->length;
2538 2504
2539 if (length + count > max_flip_size) 2505 count = tty_buffer_request_room(tty, count);
2540 count = max_flip_size - length; 2506 if (count == 0) /* Throttle ?? */
2507 break;
2541 2508
2542 memcpy(tty->flip.char_buf_ptr + length, buffer->buffer, count); 2509 if (count > 1)
2543 memset(tty->flip.flag_buf_ptr + length, TTY_NORMAL, count); 2510 tty_insert_flip_strings(tty, buffer->buffer, count - 1);
2544 tty->flip.flag_buf_ptr[length] = buffer->error; 2511 tty_insert_flip_char(tty, buffer->buffer[count-1], buffer->error);
2545 2512
2546 length += count;
2547 info->recv_cnt -= count; 2513 info->recv_cnt -= count;
2548 DFLIP(DEBUG_LOG(info->line,"flip: %i\n", length));
2549 2514
2550 if (count == buffer->length) { 2515 if (count == buffer->length) {
2551 info->first_recv_buffer = buffer->next; 2516 info->first_recv_buffer = buffer->next;
@@ -2560,14 +2525,6 @@ static void flush_to_flip_buffer(struct e100_serial *info)
2560 if (!info->first_recv_buffer) 2525 if (!info->first_recv_buffer)
2561 info->last_recv_buffer = NULL; 2526 info->last_recv_buffer = NULL;
2562 2527
2563 tty->flip.count = length;
2564 DFLIP(if (tty->ldisc.chars_in_buffer(tty) > 3500) {
2565 DEBUG_LOG(info->line, "ldisc %lu\n",
2566 tty->ldisc.chars_in_buffer(tty));
2567 DEBUG_LOG(info->line, "flip.count %lu\n",
2568 tty->flip.count);
2569 }
2570 );
2571 restore_flags(flags); 2528 restore_flags(flags);
2572 2529
2573 DFLIP( 2530 DFLIP(
@@ -2722,17 +2679,17 @@ struct e100_serial * handle_ser_rx_interrupt_no_dma(struct e100_serial *info)
2722 printk("!NO TTY!\n"); 2679 printk("!NO TTY!\n");
2723 return info; 2680 return info;
2724 } 2681 }
2725 if (tty->flip.count >= TTY_FLIPBUF_SIZE - TTY_THRESHOLD_THROTTLE) { 2682 if (tty->flip.count >= CRIS_BUF_SIZE - TTY_THRESHOLD_THROTTLE) {
2726 /* check TTY_THROTTLED first so it indicates our state */ 2683 /* check TTY_THROTTLED first so it indicates our state */
2727 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) { 2684 if (!test_and_set_bit(TTY_THROTTLED, &tty->flags)) {
2728 DFLOW(DEBUG_LOG(info->line, "rs_throttle flip.count: %i\n", tty->flip.count)); 2685 DFLOW(DEBUG_LOG(info->line, "rs_throttle flip.count: %i\n", tty->flip.count));
2729 rs_throttle(tty); 2686 rs_throttle(tty);
2730 } 2687 }
2731 } 2688 }
2732 if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 2689 if (tty->flip.count >= CRIS_BUF_SIZE) {
2733 DEBUG_LOG(info->line, "force FLIP! %i\n", tty->flip.count); 2690 DEBUG_LOG(info->line, "force FLIP! %i\n", tty->flip.count);
2734 tty->flip.work.func((void *) tty); 2691 tty->flip.work.func((void *) tty);
2735 if (tty->flip.count >= TTY_FLIPBUF_SIZE) { 2692 if (tty->flip.count >= CRIS_BUF_SIZE) {
2736 DEBUG_LOG(info->line, "FLIP FULL! %i\n", tty->flip.count); 2693 DEBUG_LOG(info->line, "FLIP FULL! %i\n", tty->flip.count);
2737 return info; /* if TTY_DONT_FLIP is set */ 2694 return info; /* if TTY_DONT_FLIP is set */
2738 } 2695 }
diff --git a/drivers/serial/m32r_sio.c b/drivers/serial/m32r_sio.c
index 6e09c8b395e8..348ee2c19b58 100644
--- a/drivers/serial/m32r_sio.c
+++ b/drivers/serial/m32r_sio.c
@@ -539,7 +539,7 @@ static void serial_do_unlink(struct irq_info *i, struct uart_sio_port *up)
539static int serial_link_irq_chain(struct uart_sio_port *up) 539static int serial_link_irq_chain(struct uart_sio_port *up)
540{ 540{
541 struct irq_info *i = irq_lists + up->port.irq; 541 struct irq_info *i = irq_lists + up->port.irq;
542 int ret, irq_flags = up->port.flags & UPF_SHARE_IRQ ? IRQF_SHARED : 0; 542 int ret, irq_flags = 0;
543 543
544 spin_lock_irq(&i->lock); 544 spin_lock_irq(&i->lock);
545 545
diff --git a/drivers/serial/m32r_sio.h b/drivers/serial/m32r_sio.h
index 849f1b2c2531..e9b7e11793b1 100644
--- a/drivers/serial/m32r_sio.h
+++ b/drivers/serial/m32r_sio.h
@@ -46,9 +46,3 @@ struct old_serial_port {
46#define PROBE_ANY (~0) 46#define PROBE_ANY (~0)
47 47
48#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8) 48#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
49
50#ifdef CONFIG_SERIAL_SIO_SHARE_IRQ
51#define M32R_SIO_SHARE_IRQS 1
52#else
53#define M32R_SIO_SHARE_IRQS 0
54#endif
diff --git a/drivers/serial/serial_core.c b/drivers/serial/serial_core.c
index a3bd3a3f41f3..68aa4da01865 100644
--- a/drivers/serial/serial_core.c
+++ b/drivers/serial/serial_core.c
@@ -1938,9 +1938,24 @@ static void uart_change_pm(struct uart_state *state, int pm_state)
1938 } 1938 }
1939} 1939}
1940 1940
1941struct uart_match {
1942 struct uart_port *port;
1943 struct uart_driver *driver;
1944};
1945
1946static int serial_match_port(struct device *dev, void *data)
1947{
1948 struct uart_match *match = data;
1949 dev_t devt = MKDEV(match->driver->major, match->driver->minor) + match->port->line;
1950
1951 return dev->devt == devt; /* Actually, only one tty per port */
1952}
1953
1941int uart_suspend_port(struct uart_driver *drv, struct uart_port *port) 1954int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
1942{ 1955{
1943 struct uart_state *state = drv->state + port->line; 1956 struct uart_state *state = drv->state + port->line;
1957 struct device *tty_dev;
1958 struct uart_match match = {port, drv};
1944 1959
1945 mutex_lock(&state->mutex); 1960 mutex_lock(&state->mutex);
1946 1961
@@ -1951,6 +1966,15 @@ int uart_suspend_port(struct uart_driver *drv, struct uart_port *port)
1951 } 1966 }
1952#endif 1967#endif
1953 1968
1969 tty_dev = device_find_child(port->dev, &match, serial_match_port);
1970 if (device_may_wakeup(tty_dev)) {
1971 enable_irq_wake(port->irq);
1972 put_device(tty_dev);
1973 mutex_unlock(&state->mutex);
1974 return 0;
1975 }
1976 port->suspended = 1;
1977
1954 if (state->info && state->info->flags & UIF_INITIALIZED) { 1978 if (state->info && state->info->flags & UIF_INITIALIZED) {
1955 const struct uart_ops *ops = port->ops; 1979 const struct uart_ops *ops = port->ops;
1956 1980
@@ -1999,6 +2023,13 @@ int uart_resume_port(struct uart_driver *drv, struct uart_port *port)
1999 } 2023 }
2000#endif 2024#endif
2001 2025
2026 if (!port->suspended) {
2027 disable_irq_wake(port->irq);
2028 mutex_unlock(&state->mutex);
2029 return 0;
2030 }
2031 port->suspended = 0;
2032
2002 uart_change_pm(state, 0); 2033 uart_change_pm(state, 0);
2003 2034
2004 /* 2035 /*
@@ -2278,6 +2309,7 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
2278{ 2309{
2279 struct uart_state *state; 2310 struct uart_state *state;
2280 int ret = 0; 2311 int ret = 0;
2312 struct device *tty_dev;
2281 2313
2282 BUG_ON(in_interrupt()); 2314 BUG_ON(in_interrupt());
2283 2315
@@ -2314,7 +2346,13 @@ int uart_add_one_port(struct uart_driver *drv, struct uart_port *port)
2314 * Register the port whether it's detected or not. This allows 2346 * Register the port whether it's detected or not. This allows
2315 * setserial to be used to alter this ports parameters. 2347 * setserial to be used to alter this ports parameters.
2316 */ 2348 */
2317 tty_register_device(drv->tty_driver, port->line, port->dev); 2349 tty_dev = tty_register_device(drv->tty_driver, port->line, port->dev);
2350 if (likely(!IS_ERR(tty_dev))) {
2351 device_can_wakeup(tty_dev) = 1;
2352 device_set_wakeup_enable(tty_dev, 0);
2353 } else
2354 printk(KERN_ERR "Cannot register tty device on line %d\n",
2355 port->line);
2318 2356
2319 /* 2357 /*
2320 * Ensure UPF_DEAD is not set. 2358 * Ensure UPF_DEAD is not set.
diff --git a/drivers/serial/serial_cs.c b/drivers/serial/serial_cs.c
index 7c8d78fbbbfb..5afcb2fa7cd3 100644
--- a/drivers/serial/serial_cs.c
+++ b/drivers/serial/serial_cs.c
@@ -911,6 +911,7 @@ static struct pcmcia_device_id serial_ids[] = {
911 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"), 911 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0175, 0x0000, "DP83903.cis"),
912 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"), 912 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x0035, "3CXEM556.cis"),
913 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"), 913 PCMCIA_MFC_DEVICE_CIS_MANF_CARD(1, 0x0101, 0x003d, "3CXEM556.cis"),
914 PCMCIA_DEVICE_CIS_PROD_ID12("Sierra Wireless", "AC850", 0xd85f6206, 0x42a2c018, "SW_8xx_SER.cis"), /* Sierra Wireless AC850 3G Network Adapter R1 */
914 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */ 915 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0x0710, "SW_7xx_SER.cis"), /* Sierra Wireless AC710/AC750 GPRS Network Adapter R1 */
915 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */ 916 PCMCIA_DEVICE_CIS_MANF_CARD(0x0192, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- pre update */
916 PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */ 917 PCMCIA_DEVICE_CIS_MANF_CARD(0x013f, 0xa555, "SW_555_SER.cis"), /* Sierra Aircard 555 CDMA 1xrtt Modem -- post update */
diff --git a/drivers/serial/serial_txx9.c b/drivers/serial/serial_txx9.c
index 0930e2a85514..6846a6c38b6d 100644
--- a/drivers/serial/serial_txx9.c
+++ b/drivers/serial/serial_txx9.c
@@ -25,19 +25,15 @@
25#include <linux/ioport.h> 25#include <linux/ioport.h>
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/console.h> 27#include <linux/console.h>
28#include <linux/sysrq.h>
29#include <linux/delay.h> 28#include <linux/delay.h>
30#include <linux/platform_device.h> 29#include <linux/platform_device.h>
31#include <linux/pci.h> 30#include <linux/pci.h>
32#include <linux/tty.h>
33#include <linux/tty_flip.h>
34#include <linux/serial_core.h> 31#include <linux/serial_core.h>
35#include <linux/serial.h> 32#include <linux/serial.h>
36#include <linux/mutex.h>
37 33
38#include <asm/io.h> 34#include <asm/io.h>
39 35
40static char *serial_version = "1.10"; 36static char *serial_version = "1.11";
41static char *serial_name = "TX39/49 Serial driver"; 37static char *serial_name = "TX39/49 Serial driver";
42 38
43#define PASS_LIMIT 256 39#define PASS_LIMIT 256
@@ -68,8 +64,6 @@ static char *serial_name = "TX39/49 Serial driver";
68 */ 64 */
69#define UART_NR CONFIG_SERIAL_TXX9_NR_UARTS 65#define UART_NR CONFIG_SERIAL_TXX9_NR_UARTS
70 66
71#define HIGH_BITS_OFFSET ((sizeof(long)-sizeof(int))*8)
72
73struct uart_txx9_port { 67struct uart_txx9_port {
74 struct uart_port port; 68 struct uart_port port;
75 /* No additional info for now */ 69 /* No additional info for now */
@@ -756,21 +750,6 @@ static void serial_txx9_config_port(struct uart_port *port, int uflags)
756 serial_txx9_initialize(port); 750 serial_txx9_initialize(port);
757} 751}
758 752
759static int
760serial_txx9_verify_port(struct uart_port *port, struct serial_struct *ser)
761{
762 unsigned long new_port = ser->port;
763 if (HIGH_BITS_OFFSET)
764 new_port += (unsigned long)ser->port_high << HIGH_BITS_OFFSET;
765 if (ser->type != port->type ||
766 ser->irq != port->irq ||
767 ser->io_type != port->iotype ||
768 new_port != port->iobase ||
769 (unsigned long)ser->iomem_base != port->mapbase)
770 return -EINVAL;
771 return 0;
772}
773
774static const char * 753static const char *
775serial_txx9_type(struct uart_port *port) 754serial_txx9_type(struct uart_port *port)
776{ 755{
@@ -794,7 +773,6 @@ static struct uart_ops serial_txx9_pops = {
794 .release_port = serial_txx9_release_port, 773 .release_port = serial_txx9_release_port,
795 .request_port = serial_txx9_request_port, 774 .request_port = serial_txx9_request_port,
796 .config_port = serial_txx9_config_port, 775 .config_port = serial_txx9_config_port,
797 .verify_port = serial_txx9_verify_port,
798}; 776};
799 777
800static struct uart_txx9_port serial_txx9_ports[UART_NR]; 778static struct uart_txx9_port serial_txx9_ports[UART_NR];
@@ -950,7 +928,8 @@ int __init early_serial_txx9_setup(struct uart_port *port)
950 928
951 serial_txx9_ports[port->line].port = *port; 929 serial_txx9_ports[port->line].port = *port;
952 serial_txx9_ports[port->line].port.ops = &serial_txx9_pops; 930 serial_txx9_ports[port->line].port.ops = &serial_txx9_pops;
953 serial_txx9_ports[port->line].port.flags |= UPF_BOOT_AUTOCONF; 931 serial_txx9_ports[port->line].port.flags |=
932 UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
954 return 0; 933 return 0;
955} 934}
956 935
@@ -995,7 +974,8 @@ static int __devinit serial_txx9_register_port(struct uart_port *port)
995 uart->port.irq = port->irq; 974 uart->port.irq = port->irq;
996 uart->port.uartclk = port->uartclk; 975 uart->port.uartclk = port->uartclk;
997 uart->port.iotype = port->iotype; 976 uart->port.iotype = port->iotype;
998 uart->port.flags = port->flags | UPF_BOOT_AUTOCONF; 977 uart->port.flags = port->flags
978 | UPF_BOOT_AUTOCONF | UPF_FIXED_PORT;
999 uart->port.mapbase = port->mapbase; 979 uart->port.mapbase = port->mapbase;
1000 if (port->dev) 980 if (port->dev)
1001 uart->port.dev = port->dev; 981 uart->port.dev = port->dev;
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index b91571122daa..a77ede598d34 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -124,16 +124,17 @@ config SPI_MPC52xx_PSC
124 Controller in master SPI mode. 124 Controller in master SPI mode.
125 125
126config SPI_MPC83xx 126config SPI_MPC83xx
127 tristate "Freescale MPC83xx SPI controller" 127 tristate "Freescale MPC83xx/QUICC Engine SPI controller"
128 depends on SPI_MASTER && PPC_83xx && EXPERIMENTAL 128 depends on SPI_MASTER && (PPC_83xx || QUICC_ENGINE) && EXPERIMENTAL
129 select SPI_BITBANG 129 select SPI_BITBANG
130 help 130 help
131 This enables using the Freescale MPC83xx SPI controller in master 131 This enables using the Freescale MPC83xx and QUICC Engine SPI
132 mode. 132 controllers in master mode.
133 133
134 Note, this driver uniquely supports the SPI controller on the MPC83xx 134 Note, this driver uniquely supports the SPI controller on the MPC83xx
135 family of PowerPC processors. The MPC83xx uses a simple set of shift 135 family of PowerPC processors, plus processors with QUICC Engine
136 registers for data (opposed to the CPM based descriptor model). 136 technology. This driver uses a simple set of shift registers for data
137 (opposed to the CPM based descriptor model).
137 138
138config SPI_OMAP_UWIRE 139config SPI_OMAP_UWIRE
139 tristate "OMAP1 MicroWire" 140 tristate "OMAP1 MicroWire"
diff --git a/drivers/spi/atmel_spi.c b/drivers/spi/atmel_spi.c
index b0469749310a..0d342dcdd302 100644
--- a/drivers/spi/atmel_spi.c
+++ b/drivers/spi/atmel_spi.c
@@ -211,7 +211,7 @@ static void atmel_spi_next_message(struct spi_master *master)
211 msg = list_entry(as->queue.next, struct spi_message, queue); 211 msg = list_entry(as->queue.next, struct spi_message, queue);
212 spi = msg->spi; 212 spi = msg->spi;
213 213
214 dev_dbg(master->cdev.dev, "start message %p for %s\n", 214 dev_dbg(master->dev.parent, "start message %p for %s\n",
215 msg, spi->dev.bus_id); 215 msg, spi->dev.bus_id);
216 216
217 /* select chip if it's not still active */ 217 /* select chip if it's not still active */
@@ -266,10 +266,10 @@ static void atmel_spi_dma_unmap_xfer(struct spi_master *master,
266 struct spi_transfer *xfer) 266 struct spi_transfer *xfer)
267{ 267{
268 if (xfer->tx_dma != INVALID_DMA_ADDRESS) 268 if (xfer->tx_dma != INVALID_DMA_ADDRESS)
269 dma_unmap_single(master->cdev.dev, xfer->tx_dma, 269 dma_unmap_single(master->dev.parent, xfer->tx_dma,
270 xfer->len, DMA_TO_DEVICE); 270 xfer->len, DMA_TO_DEVICE);
271 if (xfer->rx_dma != INVALID_DMA_ADDRESS) 271 if (xfer->rx_dma != INVALID_DMA_ADDRESS)
272 dma_unmap_single(master->cdev.dev, xfer->rx_dma, 272 dma_unmap_single(master->dev.parent, xfer->rx_dma,
273 xfer->len, DMA_FROM_DEVICE); 273 xfer->len, DMA_FROM_DEVICE);
274} 274}
275 275
@@ -285,7 +285,7 @@ atmel_spi_msg_done(struct spi_master *master, struct atmel_spi *as,
285 list_del(&msg->queue); 285 list_del(&msg->queue);
286 msg->status = status; 286 msg->status = status;
287 287
288 dev_dbg(master->cdev.dev, 288 dev_dbg(master->dev.parent,
289 "xfer complete: %u bytes transferred\n", 289 "xfer complete: %u bytes transferred\n",
290 msg->actual_length); 290 msg->actual_length);
291 291
@@ -348,7 +348,7 @@ atmel_spi_interrupt(int irq, void *dev_id)
348 if (xfer->delay_usecs) 348 if (xfer->delay_usecs)
349 udelay(xfer->delay_usecs); 349 udelay(xfer->delay_usecs);
350 350
351 dev_warn(master->cdev.dev, "fifo overrun (%u/%u remaining)\n", 351 dev_warn(master->dev.parent, "fifo overrun (%u/%u remaining)\n",
352 spi_readl(as, TCR), spi_readl(as, RCR)); 352 spi_readl(as, TCR), spi_readl(as, RCR));
353 353
354 /* 354 /*
@@ -363,7 +363,7 @@ atmel_spi_interrupt(int irq, void *dev_id)
363 if (spi_readl(as, SR) & SPI_BIT(TXEMPTY)) 363 if (spi_readl(as, SR) & SPI_BIT(TXEMPTY))
364 break; 364 break;
365 if (!timeout) 365 if (!timeout)
366 dev_warn(master->cdev.dev, 366 dev_warn(master->dev.parent,
367 "timeout waiting for TXEMPTY"); 367 "timeout waiting for TXEMPTY");
368 while (spi_readl(as, SR) & SPI_BIT(RDRF)) 368 while (spi_readl(as, SR) & SPI_BIT(RDRF))
369 spi_readl(as, RDR); 369 spi_readl(as, RDR);
@@ -526,7 +526,7 @@ static int atmel_spi_transfer(struct spi_device *spi, struct spi_message *msg)
526 struct atmel_spi *as; 526 struct atmel_spi *as;
527 struct spi_transfer *xfer; 527 struct spi_transfer *xfer;
528 unsigned long flags; 528 unsigned long flags;
529 struct device *controller = spi->master->cdev.dev; 529 struct device *controller = spi->master->dev.parent;
530 530
531 as = spi_master_get_devdata(spi->master); 531 as = spi_master_get_devdata(spi->master);
532 532
diff --git a/drivers/spi/mpc52xx_psc_spi.c b/drivers/spi/mpc52xx_psc_spi.c
index d2a4b2bdb07b..e9aba932f217 100644
--- a/drivers/spi/mpc52xx_psc_spi.c
+++ b/drivers/spi/mpc52xx_psc_spi.c
@@ -503,7 +503,7 @@ static int __init mpc52xx_psc_spi_do_probe(struct device *dev, u32 regaddr,
503 INIT_LIST_HEAD(&mps->queue); 503 INIT_LIST_HEAD(&mps->queue);
504 504
505 mps->workqueue = create_singlethread_workqueue( 505 mps->workqueue = create_singlethread_workqueue(
506 master->cdev.dev->bus_id); 506 master->dev.parent->bus_id);
507 if (mps->workqueue == NULL) { 507 if (mps->workqueue == NULL) {
508 ret = -EBUSY; 508 ret = -EBUSY;
509 goto free_irq; 509 goto free_irq;
diff --git a/drivers/spi/omap2_mcspi.c b/drivers/spi/omap2_mcspi.c
index 6b357cdb9ea3..3cdab131c4a9 100644
--- a/drivers/spi/omap2_mcspi.c
+++ b/drivers/spi/omap2_mcspi.c
@@ -645,7 +645,7 @@ static int omap2_mcspi_setup(struct spi_device *spi)
645 645
646 clk_enable(mcspi->ick); 646 clk_enable(mcspi->ick);
647 clk_enable(mcspi->fck); 647 clk_enable(mcspi->fck);
648 ret = omap2_mcspi_setup_transfer(spi, NULL); 648 ret = omap2_mcspi_setup_transfer(spi, NULL);
649 clk_disable(mcspi->fck); 649 clk_disable(mcspi->fck);
650 clk_disable(mcspi->ick); 650 clk_disable(mcspi->ick);
651 651
@@ -693,7 +693,6 @@ static void omap2_mcspi_work(struct work_struct *work)
693 struct spi_device *spi; 693 struct spi_device *spi;
694 struct spi_transfer *t = NULL; 694 struct spi_transfer *t = NULL;
695 int cs_active = 0; 695 int cs_active = 0;
696 struct omap2_mcspi_device_config *conf;
697 struct omap2_mcspi_cs *cs; 696 struct omap2_mcspi_cs *cs;
698 int par_override = 0; 697 int par_override = 0;
699 int status = 0; 698 int status = 0;
@@ -706,7 +705,6 @@ static void omap2_mcspi_work(struct work_struct *work)
706 spin_unlock_irq(&mcspi->lock); 705 spin_unlock_irq(&mcspi->lock);
707 706
708 spi = m->spi; 707 spi = m->spi;
709 conf = spi->controller_data;
710 cs = spi->controller_state; 708 cs = spi->controller_state;
711 709
712 omap2_mcspi_set_enable(spi, 1); 710 omap2_mcspi_set_enable(spi, 1);
diff --git a/drivers/spi/omap_uwire.c b/drivers/spi/omap_uwire.c
index d275c615a73e..8245b5153f30 100644
--- a/drivers/spi/omap_uwire.c
+++ b/drivers/spi/omap_uwire.c
@@ -481,7 +481,7 @@ static void uwire_off(struct uwire_spi *uwire)
481 spi_master_put(uwire->bitbang.master); 481 spi_master_put(uwire->bitbang.master);
482} 482}
483 483
484static int uwire_probe(struct platform_device *pdev) 484static int __init uwire_probe(struct platform_device *pdev)
485{ 485{
486 struct spi_master *master; 486 struct spi_master *master;
487 struct uwire_spi *uwire; 487 struct uwire_spi *uwire;
@@ -525,7 +525,7 @@ static int uwire_probe(struct platform_device *pdev)
525 return status; 525 return status;
526} 526}
527 527
528static int uwire_remove(struct platform_device *pdev) 528static int __exit uwire_remove(struct platform_device *pdev)
529{ 529{
530 struct uwire_spi *uwire = dev_get_drvdata(&pdev->dev); 530 struct uwire_spi *uwire = dev_get_drvdata(&pdev->dev);
531 int status; 531 int status;
@@ -543,8 +543,7 @@ static struct platform_driver uwire_driver = {
543 .bus = &platform_bus_type, 543 .bus = &platform_bus_type,
544 .owner = THIS_MODULE, 544 .owner = THIS_MODULE,
545 }, 545 },
546 .probe = uwire_probe, 546 .remove = __exit_p(uwire_remove),
547 .remove = uwire_remove,
548 // suspend ... unuse ck 547 // suspend ... unuse ck
549 // resume ... use ck 548 // resume ... use ck
550}; 549};
@@ -566,7 +565,7 @@ static int __init omap_uwire_init(void)
566 omap_writel(val | 0x00AAA000, OMAP730_IO_CONF_9); 565 omap_writel(val | 0x00AAA000, OMAP730_IO_CONF_9);
567 } 566 }
568 567
569 return platform_driver_register(&uwire_driver); 568 return platform_driver_probe(&uwire_driver, uwire_probe);
570} 569}
571 570
572static void __exit omap_uwire_exit(void) 571static void __exit omap_uwire_exit(void)
diff --git a/drivers/spi/pxa2xx_spi.c b/drivers/spi/pxa2xx_spi.c
index e51311b2da0b..5f3d808cbc29 100644
--- a/drivers/spi/pxa2xx_spi.c
+++ b/drivers/spi/pxa2xx_spi.c
@@ -26,7 +26,6 @@
26#include <linux/dma-mapping.h> 26#include <linux/dma-mapping.h>
27#include <linux/spi/spi.h> 27#include <linux/spi/spi.h>
28#include <linux/workqueue.h> 28#include <linux/workqueue.h>
29#include <linux/errno.h>
30#include <linux/delay.h> 29#include <linux/delay.h>
31 30
32#include <asm/io.h> 31#include <asm/io.h>
@@ -1230,7 +1229,7 @@ static void cleanup(struct spi_device *spi)
1230 kfree(chip); 1229 kfree(chip);
1231} 1230}
1232 1231
1233static int init_queue(struct driver_data *drv_data) 1232static int __init init_queue(struct driver_data *drv_data)
1234{ 1233{
1235 INIT_LIST_HEAD(&drv_data->queue); 1234 INIT_LIST_HEAD(&drv_data->queue);
1236 spin_lock_init(&drv_data->lock); 1235 spin_lock_init(&drv_data->lock);
@@ -1243,7 +1242,7 @@ static int init_queue(struct driver_data *drv_data)
1243 1242
1244 INIT_WORK(&drv_data->pump_messages, pump_messages); 1243 INIT_WORK(&drv_data->pump_messages, pump_messages);
1245 drv_data->workqueue = create_singlethread_workqueue( 1244 drv_data->workqueue = create_singlethread_workqueue(
1246 drv_data->master->cdev.dev->bus_id); 1245 drv_data->master->dev.parent->bus_id);
1247 if (drv_data->workqueue == NULL) 1246 if (drv_data->workqueue == NULL)
1248 return -EBUSY; 1247 return -EBUSY;
1249 1248
@@ -1318,7 +1317,7 @@ static int destroy_queue(struct driver_data *drv_data)
1318 return 0; 1317 return 0;
1319} 1318}
1320 1319
1321static int pxa2xx_spi_probe(struct platform_device *pdev) 1320static int __init pxa2xx_spi_probe(struct platform_device *pdev)
1322{ 1321{
1323 struct device *dev = &pdev->dev; 1322 struct device *dev = &pdev->dev;
1324 struct pxa2xx_spi_master *platform_info; 1323 struct pxa2xx_spi_master *platform_info;
@@ -1622,8 +1621,7 @@ static struct platform_driver driver = {
1622 .bus = &platform_bus_type, 1621 .bus = &platform_bus_type,
1623 .owner = THIS_MODULE, 1622 .owner = THIS_MODULE,
1624 }, 1623 },
1625 .probe = pxa2xx_spi_probe, 1624 .remove = pxa2xx_spi_remove,
1626 .remove = __devexit_p(pxa2xx_spi_remove),
1627 .shutdown = pxa2xx_spi_shutdown, 1625 .shutdown = pxa2xx_spi_shutdown,
1628 .suspend = pxa2xx_spi_suspend, 1626 .suspend = pxa2xx_spi_suspend,
1629 .resume = pxa2xx_spi_resume, 1627 .resume = pxa2xx_spi_resume,
@@ -1631,9 +1629,7 @@ static struct platform_driver driver = {
1631 1629
1632static int __init pxa2xx_spi_init(void) 1630static int __init pxa2xx_spi_init(void)
1633{ 1631{
1634 platform_driver_register(&driver); 1632 return platform_driver_probe(&driver, pxa2xx_spi_probe);
1635
1636 return 0;
1637} 1633}
1638module_init(pxa2xx_spi_init); 1634module_init(pxa2xx_spi_init);
1639 1635
diff --git a/drivers/spi/spi.c b/drivers/spi/spi.c
index bcb8dd5fb0b4..89769ce16f88 100644
--- a/drivers/spi/spi.c
+++ b/drivers/spi/spi.c
@@ -204,7 +204,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
204 struct spi_board_info *chip) 204 struct spi_board_info *chip)
205{ 205{
206 struct spi_device *proxy; 206 struct spi_device *proxy;
207 struct device *dev = master->cdev.dev; 207 struct device *dev = master->dev.parent;
208 int status; 208 int status;
209 209
210 /* NOTE: caller did any chip->bus_num checks necessary. 210 /* NOTE: caller did any chip->bus_num checks necessary.
@@ -239,7 +239,7 @@ struct spi_device *spi_new_device(struct spi_master *master,
239 proxy->modalias = chip->modalias; 239 proxy->modalias = chip->modalias;
240 240
241 snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id, 241 snprintf(proxy->dev.bus_id, sizeof proxy->dev.bus_id,
242 "%s.%u", master->cdev.class_id, 242 "%s.%u", master->dev.bus_id,
243 chip->chip_select); 243 chip->chip_select);
244 proxy->dev.parent = dev; 244 proxy->dev.parent = dev;
245 proxy->dev.bus = &spi_bus_type; 245 proxy->dev.bus = &spi_bus_type;
@@ -338,18 +338,18 @@ static void scan_boardinfo(struct spi_master *master)
338 338
339/*-------------------------------------------------------------------------*/ 339/*-------------------------------------------------------------------------*/
340 340
341static void spi_master_release(struct class_device *cdev) 341static void spi_master_release(struct device *dev)
342{ 342{
343 struct spi_master *master; 343 struct spi_master *master;
344 344
345 master = container_of(cdev, struct spi_master, cdev); 345 master = container_of(dev, struct spi_master, dev);
346 kfree(master); 346 kfree(master);
347} 347}
348 348
349static struct class spi_master_class = { 349static struct class spi_master_class = {
350 .name = "spi_master", 350 .name = "spi_master",
351 .owner = THIS_MODULE, 351 .owner = THIS_MODULE,
352 .release = spi_master_release, 352 .dev_release = spi_master_release,
353}; 353};
354 354
355 355
@@ -357,7 +357,7 @@ static struct class spi_master_class = {
357 * spi_alloc_master - allocate SPI master controller 357 * spi_alloc_master - allocate SPI master controller
358 * @dev: the controller, possibly using the platform_bus 358 * @dev: the controller, possibly using the platform_bus
359 * @size: how much zeroed driver-private data to allocate; the pointer to this 359 * @size: how much zeroed driver-private data to allocate; the pointer to this
360 * memory is in the class_data field of the returned class_device, 360 * memory is in the driver_data field of the returned device,
361 * accessible with spi_master_get_devdata(). 361 * accessible with spi_master_get_devdata().
362 * Context: can sleep 362 * Context: can sleep
363 * 363 *
@@ -383,9 +383,9 @@ struct spi_master *spi_alloc_master(struct device *dev, unsigned size)
383 if (!master) 383 if (!master)
384 return NULL; 384 return NULL;
385 385
386 class_device_initialize(&master->cdev); 386 device_initialize(&master->dev);
387 master->cdev.class = &spi_master_class; 387 master->dev.class = &spi_master_class;
388 master->cdev.dev = get_device(dev); 388 master->dev.parent = get_device(dev);
389 spi_master_set_devdata(master, &master[1]); 389 spi_master_set_devdata(master, &master[1]);
390 390
391 return master; 391 return master;
@@ -415,7 +415,7 @@ EXPORT_SYMBOL_GPL(spi_alloc_master);
415int spi_register_master(struct spi_master *master) 415int spi_register_master(struct spi_master *master)
416{ 416{
417 static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1); 417 static atomic_t dyn_bus_id = ATOMIC_INIT((1<<15) - 1);
418 struct device *dev = master->cdev.dev; 418 struct device *dev = master->dev.parent;
419 int status = -ENODEV; 419 int status = -ENODEV;
420 int dynamic = 0; 420 int dynamic = 0;
421 421
@@ -440,12 +440,12 @@ int spi_register_master(struct spi_master *master)
440 /* register the device, then userspace will see it. 440 /* register the device, then userspace will see it.
441 * registration fails if the bus ID is in use. 441 * registration fails if the bus ID is in use.
442 */ 442 */
443 snprintf(master->cdev.class_id, sizeof master->cdev.class_id, 443 snprintf(master->dev.bus_id, sizeof master->dev.bus_id,
444 "spi%u", master->bus_num); 444 "spi%u", master->bus_num);
445 status = class_device_add(&master->cdev); 445 status = device_add(&master->dev);
446 if (status < 0) 446 if (status < 0)
447 goto done; 447 goto done;
448 dev_dbg(dev, "registered master %s%s\n", master->cdev.class_id, 448 dev_dbg(dev, "registered master %s%s\n", master->dev.bus_id,
449 dynamic ? " (dynamic)" : ""); 449 dynamic ? " (dynamic)" : "");
450 450
451 /* populate children from any spi device tables */ 451 /* populate children from any spi device tables */
@@ -478,8 +478,8 @@ void spi_unregister_master(struct spi_master *master)
478{ 478{
479 int dummy; 479 int dummy;
480 480
481 dummy = device_for_each_child(master->cdev.dev, NULL, __unregister); 481 dummy = device_for_each_child(master->dev.parent, NULL, __unregister);
482 class_device_unregister(&master->cdev); 482 device_unregister(&master->dev);
483} 483}
484EXPORT_SYMBOL_GPL(spi_unregister_master); 484EXPORT_SYMBOL_GPL(spi_unregister_master);
485 485
@@ -495,13 +495,13 @@ EXPORT_SYMBOL_GPL(spi_unregister_master);
495 */ 495 */
496struct spi_master *spi_busnum_to_master(u16 bus_num) 496struct spi_master *spi_busnum_to_master(u16 bus_num)
497{ 497{
498 struct class_device *cdev; 498 struct device *dev;
499 struct spi_master *master = NULL; 499 struct spi_master *master = NULL;
500 struct spi_master *m; 500 struct spi_master *m;
501 501
502 down(&spi_master_class.sem); 502 down(&spi_master_class.sem);
503 list_for_each_entry(cdev, &spi_master_class.children, node) { 503 list_for_each_entry(dev, &spi_master_class.children, node) {
504 m = container_of(cdev, struct spi_master, cdev); 504 m = container_of(dev, struct spi_master, dev);
505 if (m->bus_num == bus_num) { 505 if (m->bus_num == bus_num) {
506 master = spi_master_get(m); 506 master = spi_master_get(m);
507 break; 507 break;
diff --git a/drivers/spi/spi_bfin5xx.c b/drivers/spi/spi_bfin5xx.c
index f540ed77a102..6cb71d74738f 100644
--- a/drivers/spi/spi_bfin5xx.c
+++ b/drivers/spi/spi_bfin5xx.c
@@ -39,7 +39,6 @@
39#include <linux/dma-mapping.h> 39#include <linux/dma-mapping.h>
40#include <linux/spi/spi.h> 40#include <linux/spi/spi.h>
41#include <linux/workqueue.h> 41#include <linux/workqueue.h>
42#include <linux/errno.h>
43#include <linux/delay.h> 42#include <linux/delay.h>
44 43
45#include <asm/io.h> 44#include <asm/io.h>
@@ -1107,7 +1106,7 @@ static inline int init_queue(struct driver_data *drv_data)
1107 /* init messages workqueue */ 1106 /* init messages workqueue */
1108 INIT_WORK(&drv_data->pump_messages, pump_messages); 1107 INIT_WORK(&drv_data->pump_messages, pump_messages);
1109 drv_data->workqueue = 1108 drv_data->workqueue =
1110 create_singlethread_workqueue(drv_data->master->cdev.dev->bus_id); 1109 create_singlethread_workqueue(drv_data->master->dev.parent->bus_id);
1111 if (drv_data->workqueue == NULL) 1110 if (drv_data->workqueue == NULL)
1112 return -EBUSY; 1111 return -EBUSY;
1113 1112
diff --git a/drivers/spi/spi_bitbang.c b/drivers/spi/spi_bitbang.c
index 0c85c984ccb4..81639c6be1c7 100644
--- a/drivers/spi/spi_bitbang.c
+++ b/drivers/spi/spi_bitbang.c
@@ -472,7 +472,7 @@ int spi_bitbang_start(struct spi_bitbang *bitbang)
472 /* this task is the only thing to touch the SPI bits */ 472 /* this task is the only thing to touch the SPI bits */
473 bitbang->busy = 0; 473 bitbang->busy = 0;
474 bitbang->workqueue = create_singlethread_workqueue( 474 bitbang->workqueue = create_singlethread_workqueue(
475 bitbang->master->cdev.dev->bus_id); 475 bitbang->master->dev.parent->bus_id);
476 if (bitbang->workqueue == NULL) { 476 if (bitbang->workqueue == NULL) {
477 status = -EBUSY; 477 status = -EBUSY;
478 goto err1; 478 goto err1;
diff --git a/drivers/spi/spi_imx.c b/drivers/spi/spi_imx.c
index bd9177f51de9..3b4650ae6f1a 100644
--- a/drivers/spi/spi_imx.c
+++ b/drivers/spi/spi_imx.c
@@ -1361,7 +1361,7 @@ static void cleanup(struct spi_device *spi)
1361 kfree(spi_get_ctldata(spi)); 1361 kfree(spi_get_ctldata(spi));
1362} 1362}
1363 1363
1364static int init_queue(struct driver_data *drv_data) 1364static int __init init_queue(struct driver_data *drv_data)
1365{ 1365{
1366 INIT_LIST_HEAD(&drv_data->queue); 1366 INIT_LIST_HEAD(&drv_data->queue);
1367 spin_lock_init(&drv_data->lock); 1367 spin_lock_init(&drv_data->lock);
@@ -1374,7 +1374,7 @@ static int init_queue(struct driver_data *drv_data)
1374 1374
1375 INIT_WORK(&drv_data->work, pump_messages); 1375 INIT_WORK(&drv_data->work, pump_messages);
1376 drv_data->workqueue = create_singlethread_workqueue( 1376 drv_data->workqueue = create_singlethread_workqueue(
1377 drv_data->master->cdev.dev->bus_id); 1377 drv_data->master->dev.parent->bus_id);
1378 if (drv_data->workqueue == NULL) 1378 if (drv_data->workqueue == NULL)
1379 return -EBUSY; 1379 return -EBUSY;
1380 1380
@@ -1444,7 +1444,7 @@ static int destroy_queue(struct driver_data *drv_data)
1444 return 0; 1444 return 0;
1445} 1445}
1446 1446
1447static int spi_imx_probe(struct platform_device *pdev) 1447static int __init spi_imx_probe(struct platform_device *pdev)
1448{ 1448{
1449 struct device *dev = &pdev->dev; 1449 struct device *dev = &pdev->dev;
1450 struct spi_imx_master *platform_info; 1450 struct spi_imx_master *platform_info;
@@ -1622,7 +1622,7 @@ err_no_mem:
1622 return status; 1622 return status;
1623} 1623}
1624 1624
1625static int __devexit spi_imx_remove(struct platform_device *pdev) 1625static int __exit spi_imx_remove(struct platform_device *pdev)
1626{ 1626{
1627 struct driver_data *drv_data = platform_get_drvdata(pdev); 1627 struct driver_data *drv_data = platform_get_drvdata(pdev);
1628 int irq; 1628 int irq;
@@ -1739,8 +1739,7 @@ static struct platform_driver driver = {
1739 .bus = &platform_bus_type, 1739 .bus = &platform_bus_type,
1740 .owner = THIS_MODULE, 1740 .owner = THIS_MODULE,
1741 }, 1741 },
1742 .probe = spi_imx_probe, 1742 .remove = __exit_p(spi_imx_remove),
1743 .remove = __devexit_p(spi_imx_remove),
1744 .shutdown = spi_imx_shutdown, 1743 .shutdown = spi_imx_shutdown,
1745 .suspend = spi_imx_suspend, 1744 .suspend = spi_imx_suspend,
1746 .resume = spi_imx_resume, 1745 .resume = spi_imx_resume,
@@ -1748,7 +1747,7 @@ static struct platform_driver driver = {
1748 1747
1749static int __init spi_imx_init(void) 1748static int __init spi_imx_init(void)
1750{ 1749{
1751 return platform_driver_register(&driver); 1750 return platform_driver_probe(&driver, spi_imx_probe);
1752} 1751}
1753module_init(spi_imx_init); 1752module_init(spi_imx_init);
1754 1753
diff --git a/drivers/spi/spi_lm70llp.c b/drivers/spi/spi_lm70llp.c
index 4ea68ac16115..39d8d8ad65c0 100644
--- a/drivers/spi/spi_lm70llp.c
+++ b/drivers/spi/spi_lm70llp.c
@@ -82,7 +82,7 @@ struct spi_lm70llp {
82 struct pardevice *pd; 82 struct pardevice *pd;
83 struct spi_device *spidev_lm70; 83 struct spi_device *spidev_lm70;
84 struct spi_board_info info; 84 struct spi_board_info info;
85 struct class_device *cdev; 85 //struct device *dev;
86}; 86};
87 87
88/* REVISIT : ugly global ; provides "exclusive open" facility */ 88/* REVISIT : ugly global ; provides "exclusive open" facility */
diff --git a/drivers/spi/spi_mpc83xx.c b/drivers/spi/spi_mpc83xx.c
index 32cda77b31cd..4580b9cf625d 100644
--- a/drivers/spi/spi_mpc83xx.c
+++ b/drivers/spi/spi_mpc83xx.c
@@ -511,7 +511,7 @@ err:
511 return ret; 511 return ret;
512} 512}
513 513
514static int __devexit mpc83xx_spi_remove(struct platform_device *dev) 514static int __exit mpc83xx_spi_remove(struct platform_device *dev)
515{ 515{
516 struct mpc83xx_spi *mpc83xx_spi; 516 struct mpc83xx_spi *mpc83xx_spi;
517 struct spi_master *master; 517 struct spi_master *master;
@@ -529,8 +529,7 @@ static int __devexit mpc83xx_spi_remove(struct platform_device *dev)
529 529
530MODULE_ALIAS("mpc83xx_spi"); /* for platform bus hotplug */ 530MODULE_ALIAS("mpc83xx_spi"); /* for platform bus hotplug */
531static struct platform_driver mpc83xx_spi_driver = { 531static struct platform_driver mpc83xx_spi_driver = {
532 .probe = mpc83xx_spi_probe, 532 .remove = __exit_p(mpc83xx_spi_remove),
533 .remove = __devexit_p(mpc83xx_spi_remove),
534 .driver = { 533 .driver = {
535 .name = "mpc83xx_spi", 534 .name = "mpc83xx_spi",
536 }, 535 },
@@ -538,7 +537,7 @@ static struct platform_driver mpc83xx_spi_driver = {
538 537
539static int __init mpc83xx_spi_init(void) 538static int __init mpc83xx_spi_init(void)
540{ 539{
541 return platform_driver_register(&mpc83xx_spi_driver); 540 return platform_driver_probe(&mpc83xx_spi_driver, mpc83xx_spi_probe);
542} 541}
543 542
544static void __exit mpc83xx_spi_exit(void) 543static void __exit mpc83xx_spi_exit(void)
diff --git a/drivers/spi/spi_s3c24xx.c b/drivers/spi/spi_s3c24xx.c
index e9b683f7d7b3..89d6685a5ca4 100644
--- a/drivers/spi/spi_s3c24xx.c
+++ b/drivers/spi/spi_s3c24xx.c
@@ -233,7 +233,7 @@ static irqreturn_t s3c24xx_spi_irq(int irq, void *dev)
233 return IRQ_HANDLED; 233 return IRQ_HANDLED;
234} 234}
235 235
236static int s3c24xx_spi_probe(struct platform_device *pdev) 236static int __init s3c24xx_spi_probe(struct platform_device *pdev)
237{ 237{
238 struct s3c24xx_spi *hw; 238 struct s3c24xx_spi *hw;
239 struct spi_master *master; 239 struct spi_master *master;
@@ -382,7 +382,7 @@ static int s3c24xx_spi_probe(struct platform_device *pdev)
382 return err; 382 return err;
383} 383}
384 384
385static int s3c24xx_spi_remove(struct platform_device *dev) 385static int __exit s3c24xx_spi_remove(struct platform_device *dev)
386{ 386{
387 struct s3c24xx_spi *hw = platform_get_drvdata(dev); 387 struct s3c24xx_spi *hw = platform_get_drvdata(dev);
388 388
@@ -429,8 +429,7 @@ static int s3c24xx_spi_resume(struct platform_device *pdev)
429 429
430MODULE_ALIAS("s3c2410_spi"); /* for platform bus hotplug */ 430MODULE_ALIAS("s3c2410_spi"); /* for platform bus hotplug */
431static struct platform_driver s3c24xx_spidrv = { 431static struct platform_driver s3c24xx_spidrv = {
432 .probe = s3c24xx_spi_probe, 432 .remove = __exit_p(s3c24xx_spi_remove),
433 .remove = s3c24xx_spi_remove,
434 .suspend = s3c24xx_spi_suspend, 433 .suspend = s3c24xx_spi_suspend,
435 .resume = s3c24xx_spi_resume, 434 .resume = s3c24xx_spi_resume,
436 .driver = { 435 .driver = {
@@ -441,7 +440,7 @@ static struct platform_driver s3c24xx_spidrv = {
441 440
442static int __init s3c24xx_spi_init(void) 441static int __init s3c24xx_spi_init(void)
443{ 442{
444 return platform_driver_register(&s3c24xx_spidrv); 443 return platform_driver_probe(&s3c24xx_spidrv, s3c24xx_spi_probe);
445} 444}
446 445
447static void __exit s3c24xx_spi_exit(void) 446static void __exit s3c24xx_spi_exit(void)
diff --git a/drivers/spi/spi_txx9.c b/drivers/spi/spi_txx9.c
index b7f4bb239eaf..cc5094f37dd3 100644
--- a/drivers/spi/spi_txx9.c
+++ b/drivers/spi/spi_txx9.c
@@ -400,7 +400,7 @@ static int __init txx9spi_probe(struct platform_device *dev)
400 goto exit; 400 goto exit;
401 } 401 }
402 402
403 c->workqueue = create_singlethread_workqueue(master->cdev.dev->bus_id); 403 c->workqueue = create_singlethread_workqueue(master->dev.parent->bus_id);
404 if (!c->workqueue) 404 if (!c->workqueue)
405 goto exit; 405 goto exit;
406 c->last_chipselect = -1; 406 c->last_chipselect = -1;
diff --git a/drivers/usb/core/hub.c b/drivers/usb/core/hub.c
index d20cb545a6e4..60a8f55a0cc7 100644
--- a/drivers/usb/core/hub.c
+++ b/drivers/usb/core/hub.c
@@ -1407,7 +1407,11 @@ fail:
1407 1407
1408 1408
1409/** 1409/**
1410 * Similar to usb_disconnect() 1410 * usb_deauthorize_device - deauthorize a device (usbcore-internal)
1411 * @usb_dev: USB device
1412 *
1413 * Move the USB device to a very basic state where interfaces are disabled
1414 * and the device is in fact unconfigured and unusable.
1411 * 1415 *
1412 * We share a lock (that we have) with device_del(), so we need to 1416 * We share a lock (that we have) with device_del(), so we need to
1413 * defer its call. 1417 * defer its call.
diff --git a/drivers/usb/misc/sisusbvga/sisusb_con.c b/drivers/usb/misc/sisusbvga/sisusb_con.c
index 43722e5a49d1..b624320df903 100644
--- a/drivers/usb/misc/sisusbvga/sisusb_con.c
+++ b/drivers/usb/misc/sisusbvga/sisusb_con.c
@@ -1042,7 +1042,8 @@ sisusbcon_set_origin(struct vc_data *c)
1042 1042
1043/* Interface routine */ 1043/* Interface routine */
1044static int 1044static int
1045sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows) 1045sisusbcon_resize(struct vc_data *c, unsigned int newcols, unsigned int newrows,
1046 unsigned int user)
1046{ 1047{
1047 struct sisusb_usb_data *sisusb; 1048 struct sisusb_usb_data *sisusb;
1048 int fh; 1049 int fh;
diff --git a/drivers/usb/storage/alauda.c b/drivers/usb/storage/alauda.c
index 4d3cbb12b713..8d3711a7ff06 100644
--- a/drivers/usb/storage/alauda.c
+++ b/drivers/usb/storage/alauda.c
@@ -798,12 +798,13 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
798{ 798{
799 unsigned char *buffer; 799 unsigned char *buffer;
800 u16 lba, max_lba; 800 u16 lba, max_lba;
801 unsigned int page, len, index, offset; 801 unsigned int page, len, offset;
802 unsigned int blockshift = MEDIA_INFO(us).blockshift; 802 unsigned int blockshift = MEDIA_INFO(us).blockshift;
803 unsigned int pageshift = MEDIA_INFO(us).pageshift; 803 unsigned int pageshift = MEDIA_INFO(us).pageshift;
804 unsigned int blocksize = MEDIA_INFO(us).blocksize; 804 unsigned int blocksize = MEDIA_INFO(us).blocksize;
805 unsigned int pagesize = MEDIA_INFO(us).pagesize; 805 unsigned int pagesize = MEDIA_INFO(us).pagesize;
806 unsigned int uzonesize = MEDIA_INFO(us).uzonesize; 806 unsigned int uzonesize = MEDIA_INFO(us).uzonesize;
807 struct scatterlist *sg;
807 int result; 808 int result;
808 809
809 /* 810 /*
@@ -827,7 +828,8 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
827 max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift); 828 max_lba = MEDIA_INFO(us).capacity >> (blockshift + pageshift);
828 829
829 result = USB_STOR_TRANSPORT_GOOD; 830 result = USB_STOR_TRANSPORT_GOOD;
830 index = offset = 0; 831 offset = 0;
832 sg = NULL;
831 833
832 while (sectors > 0) { 834 while (sectors > 0) {
833 unsigned int zone = lba / uzonesize; /* integer division */ 835 unsigned int zone = lba / uzonesize; /* integer division */
@@ -873,7 +875,7 @@ static int alauda_read_data(struct us_data *us, unsigned long address,
873 875
874 /* Store the data in the transfer buffer */ 876 /* Store the data in the transfer buffer */
875 usb_stor_access_xfer_buf(buffer, len, us->srb, 877 usb_stor_access_xfer_buf(buffer, len, us->srb,
876 &index, &offset, TO_XFER_BUF); 878 &sg, &offset, TO_XFER_BUF);
877 879
878 page = 0; 880 page = 0;
879 lba++; 881 lba++;
@@ -891,11 +893,12 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
891 unsigned int sectors) 893 unsigned int sectors)
892{ 894{
893 unsigned char *buffer, *blockbuffer; 895 unsigned char *buffer, *blockbuffer;
894 unsigned int page, len, index, offset; 896 unsigned int page, len, offset;
895 unsigned int blockshift = MEDIA_INFO(us).blockshift; 897 unsigned int blockshift = MEDIA_INFO(us).blockshift;
896 unsigned int pageshift = MEDIA_INFO(us).pageshift; 898 unsigned int pageshift = MEDIA_INFO(us).pageshift;
897 unsigned int blocksize = MEDIA_INFO(us).blocksize; 899 unsigned int blocksize = MEDIA_INFO(us).blocksize;
898 unsigned int pagesize = MEDIA_INFO(us).pagesize; 900 unsigned int pagesize = MEDIA_INFO(us).pagesize;
901 struct scatterlist *sg;
899 u16 lba, max_lba; 902 u16 lba, max_lba;
900 int result; 903 int result;
901 904
@@ -929,7 +932,8 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
929 max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift); 932 max_lba = MEDIA_INFO(us).capacity >> (pageshift + blockshift);
930 933
931 result = USB_STOR_TRANSPORT_GOOD; 934 result = USB_STOR_TRANSPORT_GOOD;
932 index = offset = 0; 935 offset = 0;
936 sg = NULL;
933 937
934 while (sectors > 0) { 938 while (sectors > 0) {
935 /* Write as many sectors as possible in this block */ 939 /* Write as many sectors as possible in this block */
@@ -946,7 +950,7 @@ static int alauda_write_data(struct us_data *us, unsigned long address,
946 950
947 /* Get the data from the transfer buffer */ 951 /* Get the data from the transfer buffer */
948 usb_stor_access_xfer_buf(buffer, len, us->srb, 952 usb_stor_access_xfer_buf(buffer, len, us->srb,
949 &index, &offset, FROM_XFER_BUF); 953 &sg, &offset, FROM_XFER_BUF);
950 954
951 result = alauda_write_lba(us, lba, page, pages, buffer, 955 result = alauda_write_lba(us, lba, page, pages, buffer,
952 blockbuffer); 956 blockbuffer);
diff --git a/drivers/usb/storage/datafab.c b/drivers/usb/storage/datafab.c
index c87ad1bae1d6..579e9f52053a 100644
--- a/drivers/usb/storage/datafab.c
+++ b/drivers/usb/storage/datafab.c
@@ -98,7 +98,8 @@ static int datafab_read_data(struct us_data *us,
98 unsigned char thistime; 98 unsigned char thistime;
99 unsigned int totallen, alloclen; 99 unsigned int totallen, alloclen;
100 int len, result; 100 int len, result;
101 unsigned int sg_idx = 0, sg_offset = 0; 101 unsigned int sg_offset = 0;
102 struct scatterlist *sg = NULL;
102 103
103 // we're working in LBA mode. according to the ATA spec, 104 // we're working in LBA mode. according to the ATA spec,
104 // we can support up to 28-bit addressing. I don't know if Datafab 105 // we can support up to 28-bit addressing. I don't know if Datafab
@@ -155,7 +156,7 @@ static int datafab_read_data(struct us_data *us,
155 156
156 // Store the data in the transfer buffer 157 // Store the data in the transfer buffer
157 usb_stor_access_xfer_buf(buffer, len, us->srb, 158 usb_stor_access_xfer_buf(buffer, len, us->srb,
158 &sg_idx, &sg_offset, TO_XFER_BUF); 159 &sg, &sg_offset, TO_XFER_BUF);
159 160
160 sector += thistime; 161 sector += thistime;
161 totallen -= len; 162 totallen -= len;
@@ -181,7 +182,8 @@ static int datafab_write_data(struct us_data *us,
181 unsigned char thistime; 182 unsigned char thistime;
182 unsigned int totallen, alloclen; 183 unsigned int totallen, alloclen;
183 int len, result; 184 int len, result;
184 unsigned int sg_idx = 0, sg_offset = 0; 185 unsigned int sg_offset = 0;
186 struct scatterlist *sg = NULL;
185 187
186 // we're working in LBA mode. according to the ATA spec, 188 // we're working in LBA mode. according to the ATA spec,
187 // we can support up to 28-bit addressing. I don't know if Datafab 189 // we can support up to 28-bit addressing. I don't know if Datafab
@@ -217,7 +219,7 @@ static int datafab_write_data(struct us_data *us,
217 219
218 // Get the data from the transfer buffer 220 // Get the data from the transfer buffer
219 usb_stor_access_xfer_buf(buffer, len, us->srb, 221 usb_stor_access_xfer_buf(buffer, len, us->srb,
220 &sg_idx, &sg_offset, FROM_XFER_BUF); 222 &sg, &sg_offset, FROM_XFER_BUF);
221 223
222 command[0] = 0; 224 command[0] = 0;
223 command[1] = thistime; 225 command[1] = thistime;
diff --git a/drivers/usb/storage/jumpshot.c b/drivers/usb/storage/jumpshot.c
index 003fcf545888..61097cbb1585 100644
--- a/drivers/usb/storage/jumpshot.c
+++ b/drivers/usb/storage/jumpshot.c
@@ -119,7 +119,8 @@ static int jumpshot_read_data(struct us_data *us,
119 unsigned char thistime; 119 unsigned char thistime;
120 unsigned int totallen, alloclen; 120 unsigned int totallen, alloclen;
121 int len, result; 121 int len, result;
122 unsigned int sg_idx = 0, sg_offset = 0; 122 unsigned int sg_offset = 0;
123 struct scatterlist *sg = NULL;
123 124
124 // we're working in LBA mode. according to the ATA spec, 125 // we're working in LBA mode. according to the ATA spec,
125 // we can support up to 28-bit addressing. I don't know if Jumpshot 126 // we can support up to 28-bit addressing. I don't know if Jumpshot
@@ -170,7 +171,7 @@ static int jumpshot_read_data(struct us_data *us,
170 171
171 // Store the data in the transfer buffer 172 // Store the data in the transfer buffer
172 usb_stor_access_xfer_buf(buffer, len, us->srb, 173 usb_stor_access_xfer_buf(buffer, len, us->srb,
173 &sg_idx, &sg_offset, TO_XFER_BUF); 174 &sg, &sg_offset, TO_XFER_BUF);
174 175
175 sector += thistime; 176 sector += thistime;
176 totallen -= len; 177 totallen -= len;
@@ -195,7 +196,8 @@ static int jumpshot_write_data(struct us_data *us,
195 unsigned char thistime; 196 unsigned char thistime;
196 unsigned int totallen, alloclen; 197 unsigned int totallen, alloclen;
197 int len, result, waitcount; 198 int len, result, waitcount;
198 unsigned int sg_idx = 0, sg_offset = 0; 199 unsigned int sg_offset = 0;
200 struct scatterlist *sg = NULL;
199 201
200 // we're working in LBA mode. according to the ATA spec, 202 // we're working in LBA mode. according to the ATA spec,
201 // we can support up to 28-bit addressing. I don't know if Jumpshot 203 // we can support up to 28-bit addressing. I don't know if Jumpshot
@@ -225,7 +227,7 @@ static int jumpshot_write_data(struct us_data *us,
225 227
226 // Get the data from the transfer buffer 228 // Get the data from the transfer buffer
227 usb_stor_access_xfer_buf(buffer, len, us->srb, 229 usb_stor_access_xfer_buf(buffer, len, us->srb,
228 &sg_idx, &sg_offset, FROM_XFER_BUF); 230 &sg, &sg_offset, FROM_XFER_BUF);
229 231
230 command[0] = 0; 232 command[0] = 0;
231 command[1] = thistime; 233 command[1] = thistime;
diff --git a/drivers/usb/storage/protocol.c b/drivers/usb/storage/protocol.c
index 9ad30428d2dd..cc8f7c52c729 100644
--- a/drivers/usb/storage/protocol.c
+++ b/drivers/usb/storage/protocol.c
@@ -157,7 +157,7 @@ void usb_stor_transparent_scsi_command(struct scsi_cmnd *srb,
157 * pick up from where this one left off. */ 157 * pick up from where this one left off. */
158 158
159unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, 159unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
160 unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, 160 unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **sgptr,
161 unsigned int *offset, enum xfer_buf_dir dir) 161 unsigned int *offset, enum xfer_buf_dir dir)
162{ 162{
163 unsigned int cnt; 163 unsigned int cnt;
@@ -184,16 +184,17 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
184 * located in high memory -- then kmap() will map it to a temporary 184 * located in high memory -- then kmap() will map it to a temporary
185 * position in the kernel's virtual address space. */ 185 * position in the kernel's virtual address space. */
186 } else { 186 } else {
187 struct scatterlist *sg = 187 struct scatterlist *sg = *sgptr;
188 (struct scatterlist *) srb->request_buffer 188
189 + *index; 189 if (!sg)
190 sg = (struct scatterlist *) srb->request_buffer;
190 191
191 /* This loop handles a single s-g list entry, which may 192 /* This loop handles a single s-g list entry, which may
192 * include multiple pages. Find the initial page structure 193 * include multiple pages. Find the initial page structure
193 * and the starting offset within the page, and update 194 * and the starting offset within the page, and update
194 * the *offset and *index values for the next loop. */ 195 * the *offset and *index values for the next loop. */
195 cnt = 0; 196 cnt = 0;
196 while (cnt < buflen && *index < srb->use_sg) { 197 while (cnt < buflen) {
197 struct page *page = sg->page + 198 struct page *page = sg->page +
198 ((sg->offset + *offset) >> PAGE_SHIFT); 199 ((sg->offset + *offset) >> PAGE_SHIFT);
199 unsigned int poff = 200 unsigned int poff =
@@ -209,8 +210,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
209 210
210 /* Transfer continues to next s-g entry */ 211 /* Transfer continues to next s-g entry */
211 *offset = 0; 212 *offset = 0;
212 ++*index; 213 sg = sg_next(sg);
213 ++sg;
214 } 214 }
215 215
216 /* Transfer the data for all the pages in this 216 /* Transfer the data for all the pages in this
@@ -234,6 +234,7 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
234 sglen -= plen; 234 sglen -= plen;
235 } 235 }
236 } 236 }
237 *sgptr = sg;
237 } 238 }
238 239
239 /* Return the amount actually transferred */ 240 /* Return the amount actually transferred */
@@ -245,9 +246,10 @@ unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
245void usb_stor_set_xfer_buf(unsigned char *buffer, 246void usb_stor_set_xfer_buf(unsigned char *buffer,
246 unsigned int buflen, struct scsi_cmnd *srb) 247 unsigned int buflen, struct scsi_cmnd *srb)
247{ 248{
248 unsigned int index = 0, offset = 0; 249 unsigned int offset = 0;
250 struct scatterlist *sg = NULL;
249 251
250 usb_stor_access_xfer_buf(buffer, buflen, srb, &index, &offset, 252 usb_stor_access_xfer_buf(buffer, buflen, srb, &sg, &offset,
251 TO_XFER_BUF); 253 TO_XFER_BUF);
252 if (buflen < srb->request_bufflen) 254 if (buflen < srb->request_bufflen)
253 srb->resid = srb->request_bufflen - buflen; 255 srb->resid = srb->request_bufflen - buflen;
diff --git a/drivers/usb/storage/protocol.h b/drivers/usb/storage/protocol.h
index 845bed4b8031..8737a36891ca 100644
--- a/drivers/usb/storage/protocol.h
+++ b/drivers/usb/storage/protocol.h
@@ -52,7 +52,7 @@ extern void usb_stor_transparent_scsi_command(struct scsi_cmnd*,
52enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF}; 52enum xfer_buf_dir {TO_XFER_BUF, FROM_XFER_BUF};
53 53
54extern unsigned int usb_stor_access_xfer_buf(unsigned char *buffer, 54extern unsigned int usb_stor_access_xfer_buf(unsigned char *buffer,
55 unsigned int buflen, struct scsi_cmnd *srb, unsigned int *index, 55 unsigned int buflen, struct scsi_cmnd *srb, struct scatterlist **,
56 unsigned int *offset, enum xfer_buf_dir dir); 56 unsigned int *offset, enum xfer_buf_dir dir);
57 57
58extern void usb_stor_set_xfer_buf(unsigned char *buffer, 58extern void usb_stor_set_xfer_buf(unsigned char *buffer,
diff --git a/drivers/usb/storage/sddr09.c b/drivers/usb/storage/sddr09.c
index b2ed2a3e6fca..b12202c5da2d 100644
--- a/drivers/usb/storage/sddr09.c
+++ b/drivers/usb/storage/sddr09.c
@@ -705,7 +705,8 @@ sddr09_read_data(struct us_data *us,
705 unsigned char *buffer; 705 unsigned char *buffer;
706 unsigned int lba, maxlba, pba; 706 unsigned int lba, maxlba, pba;
707 unsigned int page, pages; 707 unsigned int page, pages;
708 unsigned int len, index, offset; 708 unsigned int len, offset;
709 struct scatterlist *sg;
709 int result; 710 int result;
710 711
711 // Figure out the initial LBA and page 712 // Figure out the initial LBA and page
@@ -730,7 +731,8 @@ sddr09_read_data(struct us_data *us,
730 // contiguous LBA's. Another exercise left to the student. 731 // contiguous LBA's. Another exercise left to the student.
731 732
732 result = 0; 733 result = 0;
733 index = offset = 0; 734 offset = 0;
735 sg = NULL;
734 736
735 while (sectors > 0) { 737 while (sectors > 0) {
736 738
@@ -777,7 +779,7 @@ sddr09_read_data(struct us_data *us,
777 779
778 // Store the data in the transfer buffer 780 // Store the data in the transfer buffer
779 usb_stor_access_xfer_buf(buffer, len, us->srb, 781 usb_stor_access_xfer_buf(buffer, len, us->srb,
780 &index, &offset, TO_XFER_BUF); 782 &sg, &offset, TO_XFER_BUF);
781 783
782 page = 0; 784 page = 0;
783 lba++; 785 lba++;
@@ -931,7 +933,8 @@ sddr09_write_data(struct us_data *us,
931 unsigned int pagelen, blocklen; 933 unsigned int pagelen, blocklen;
932 unsigned char *blockbuffer; 934 unsigned char *blockbuffer;
933 unsigned char *buffer; 935 unsigned char *buffer;
934 unsigned int len, index, offset; 936 unsigned int len, offset;
937 struct scatterlist *sg;
935 int result; 938 int result;
936 939
937 // Figure out the initial LBA and page 940 // Figure out the initial LBA and page
@@ -968,7 +971,8 @@ sddr09_write_data(struct us_data *us,
968 } 971 }
969 972
970 result = 0; 973 result = 0;
971 index = offset = 0; 974 offset = 0;
975 sg = NULL;
972 976
973 while (sectors > 0) { 977 while (sectors > 0) {
974 978
@@ -987,7 +991,7 @@ sddr09_write_data(struct us_data *us,
987 991
988 // Get the data from the transfer buffer 992 // Get the data from the transfer buffer
989 usb_stor_access_xfer_buf(buffer, len, us->srb, 993 usb_stor_access_xfer_buf(buffer, len, us->srb,
990 &index, &offset, FROM_XFER_BUF); 994 &sg, &offset, FROM_XFER_BUF);
991 995
992 result = sddr09_write_lba(us, lba, page, pages, 996 result = sddr09_write_lba(us, lba, page, pages,
993 buffer, blockbuffer); 997 buffer, blockbuffer);
diff --git a/drivers/usb/storage/sddr55.c b/drivers/usb/storage/sddr55.c
index 0b1b5b59ca7b..d43a3415e12f 100644
--- a/drivers/usb/storage/sddr55.c
+++ b/drivers/usb/storage/sddr55.c
@@ -167,7 +167,8 @@ static int sddr55_read_data(struct us_data *us,
167 unsigned long address; 167 unsigned long address;
168 168
169 unsigned short pages; 169 unsigned short pages;
170 unsigned int len, index, offset; 170 unsigned int len, offset;
171 struct scatterlist *sg;
171 172
172 // Since we only read in one block at a time, we have to create 173 // Since we only read in one block at a time, we have to create
173 // a bounce buffer and move the data a piece at a time between the 174 // a bounce buffer and move the data a piece at a time between the
@@ -178,7 +179,8 @@ static int sddr55_read_data(struct us_data *us,
178 buffer = kmalloc(len, GFP_NOIO); 179 buffer = kmalloc(len, GFP_NOIO);
179 if (buffer == NULL) 180 if (buffer == NULL)
180 return USB_STOR_TRANSPORT_ERROR; /* out of memory */ 181 return USB_STOR_TRANSPORT_ERROR; /* out of memory */
181 index = offset = 0; 182 offset = 0;
183 sg = NULL;
182 184
183 while (sectors>0) { 185 while (sectors>0) {
184 186
@@ -255,7 +257,7 @@ static int sddr55_read_data(struct us_data *us,
255 257
256 // Store the data in the transfer buffer 258 // Store the data in the transfer buffer
257 usb_stor_access_xfer_buf(buffer, len, us->srb, 259 usb_stor_access_xfer_buf(buffer, len, us->srb,
258 &index, &offset, TO_XFER_BUF); 260 &sg, &offset, TO_XFER_BUF);
259 261
260 page = 0; 262 page = 0;
261 lba++; 263 lba++;
@@ -287,7 +289,8 @@ static int sddr55_write_data(struct us_data *us,
287 289
288 unsigned short pages; 290 unsigned short pages;
289 int i; 291 int i;
290 unsigned int len, index, offset; 292 unsigned int len, offset;
293 struct scatterlist *sg;
291 294
292 /* check if we are allowed to write */ 295 /* check if we are allowed to write */
293 if (info->read_only || info->force_read_only) { 296 if (info->read_only || info->force_read_only) {
@@ -304,7 +307,8 @@ static int sddr55_write_data(struct us_data *us,
304 buffer = kmalloc(len, GFP_NOIO); 307 buffer = kmalloc(len, GFP_NOIO);
305 if (buffer == NULL) 308 if (buffer == NULL)
306 return USB_STOR_TRANSPORT_ERROR; 309 return USB_STOR_TRANSPORT_ERROR;
307 index = offset = 0; 310 offset = 0;
311 sg = NULL;
308 312
309 while (sectors > 0) { 313 while (sectors > 0) {
310 314
@@ -322,7 +326,7 @@ static int sddr55_write_data(struct us_data *us,
322 326
323 // Get the data from the transfer buffer 327 // Get the data from the transfer buffer
324 usb_stor_access_xfer_buf(buffer, len, us->srb, 328 usb_stor_access_xfer_buf(buffer, len, us->srb,
325 &index, &offset, FROM_XFER_BUF); 329 &sg, &offset, FROM_XFER_BUF);
326 330
327 US_DEBUGP("Write %02X pages, to PBA %04X" 331 US_DEBUGP("Write %02X pages, to PBA %04X"
328 " (LBA %04X) page %02X\n", 332 " (LBA %04X) page %02X\n",
diff --git a/drivers/usb/storage/shuttle_usbat.c b/drivers/usb/storage/shuttle_usbat.c
index 17ca4d73577b..cb22a9ad1694 100644
--- a/drivers/usb/storage/shuttle_usbat.c
+++ b/drivers/usb/storage/shuttle_usbat.c
@@ -993,7 +993,8 @@ static int usbat_flash_read_data(struct us_data *us,
993 unsigned char thistime; 993 unsigned char thistime;
994 unsigned int totallen, alloclen; 994 unsigned int totallen, alloclen;
995 int len, result; 995 int len, result;
996 unsigned int sg_idx = 0, sg_offset = 0; 996 unsigned int sg_offset = 0;
997 struct scatterlist *sg = NULL;
997 998
998 result = usbat_flash_check_media(us, info); 999 result = usbat_flash_check_media(us, info);
999 if (result != USB_STOR_TRANSPORT_GOOD) 1000 if (result != USB_STOR_TRANSPORT_GOOD)
@@ -1047,7 +1048,7 @@ static int usbat_flash_read_data(struct us_data *us,
1047 1048
1048 /* Store the data in the transfer buffer */ 1049 /* Store the data in the transfer buffer */
1049 usb_stor_access_xfer_buf(buffer, len, us->srb, 1050 usb_stor_access_xfer_buf(buffer, len, us->srb,
1050 &sg_idx, &sg_offset, TO_XFER_BUF); 1051 &sg, &sg_offset, TO_XFER_BUF);
1051 1052
1052 sector += thistime; 1053 sector += thistime;
1053 totallen -= len; 1054 totallen -= len;
@@ -1083,7 +1084,8 @@ static int usbat_flash_write_data(struct us_data *us,
1083 unsigned char thistime; 1084 unsigned char thistime;
1084 unsigned int totallen, alloclen; 1085 unsigned int totallen, alloclen;
1085 int len, result; 1086 int len, result;
1086 unsigned int sg_idx = 0, sg_offset = 0; 1087 unsigned int sg_offset = 0;
1088 struct scatterlist *sg = NULL;
1087 1089
1088 result = usbat_flash_check_media(us, info); 1090 result = usbat_flash_check_media(us, info);
1089 if (result != USB_STOR_TRANSPORT_GOOD) 1091 if (result != USB_STOR_TRANSPORT_GOOD)
@@ -1122,7 +1124,7 @@ static int usbat_flash_write_data(struct us_data *us,
1122 1124
1123 /* Get the data from the transfer buffer */ 1125 /* Get the data from the transfer buffer */
1124 usb_stor_access_xfer_buf(buffer, len, us->srb, 1126 usb_stor_access_xfer_buf(buffer, len, us->srb,
1125 &sg_idx, &sg_offset, FROM_XFER_BUF); 1127 &sg, &sg_offset, FROM_XFER_BUF);
1126 1128
1127 /* ATA command 0x30 (WRITE SECTORS) */ 1129 /* ATA command 0x30 (WRITE SECTORS) */
1128 usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30); 1130 usbat_pack_ata_sector_cmd(command, thistime, sector, 0x30);
@@ -1162,8 +1164,8 @@ static int usbat_hp8200e_handle_read10(struct us_data *us,
1162 unsigned char *buffer; 1164 unsigned char *buffer;
1163 unsigned int len; 1165 unsigned int len;
1164 unsigned int sector; 1166 unsigned int sector;
1165 unsigned int sg_segment = 0;
1166 unsigned int sg_offset = 0; 1167 unsigned int sg_offset = 0;
1168 struct scatterlist *sg = NULL;
1167 1169
1168 US_DEBUGP("handle_read10: transfersize %d\n", 1170 US_DEBUGP("handle_read10: transfersize %d\n",
1169 srb->transfersize); 1171 srb->transfersize);
@@ -1220,9 +1222,6 @@ static int usbat_hp8200e_handle_read10(struct us_data *us,
1220 sector |= short_pack(data[7+5], data[7+4]); 1222 sector |= short_pack(data[7+5], data[7+4]);
1221 transferred = 0; 1223 transferred = 0;
1222 1224
1223 sg_segment = 0; /* for keeping track of where we are in */
1224 sg_offset = 0; /* the scatter/gather list */
1225
1226 while (transferred != srb->request_bufflen) { 1225 while (transferred != srb->request_bufflen) {
1227 1226
1228 if (len > srb->request_bufflen - transferred) 1227 if (len > srb->request_bufflen - transferred)
@@ -1255,7 +1254,7 @@ static int usbat_hp8200e_handle_read10(struct us_data *us,
1255 1254
1256 /* Store the data in the transfer buffer */ 1255 /* Store the data in the transfer buffer */
1257 usb_stor_access_xfer_buf(buffer, len, srb, 1256 usb_stor_access_xfer_buf(buffer, len, srb,
1258 &sg_segment, &sg_offset, TO_XFER_BUF); 1257 &sg, &sg_offset, TO_XFER_BUF);
1259 1258
1260 /* Update the amount transferred and the sector number */ 1259 /* Update the amount transferred and the sector number */
1261 1260
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 5216c11d4dec..efe474e2cc3b 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -5,8 +5,9 @@
5menu "Graphics support" 5menu "Graphics support"
6 depends on HAS_IOMEM 6 depends on HAS_IOMEM
7 7
8source "drivers/video/backlight/Kconfig" 8source "drivers/char/agp/Kconfig"
9source "drivers/video/display/Kconfig" 9
10source "drivers/char/drm/Kconfig"
10 11
11config VGASTATE 12config VGASTATE
12 tristate 13 tristate
@@ -19,7 +20,7 @@ config VIDEO_OUTPUT_CONTROL
19 This framework adds support for low-level control of the video 20 This framework adds support for low-level control of the video
20 output switch. 21 output switch.
21 22
22config FB 23menuconfig FB
23 tristate "Support for frame buffer devices" 24 tristate "Support for frame buffer devices"
24 ---help--- 25 ---help---
25 The frame buffer device provides an abstraction for the graphics 26 The frame buffer device provides an abstraction for the graphics
@@ -103,6 +104,15 @@ config FB_CFB_IMAGEBLIT
103 blitting. This is used by drivers that don't provide their own 104 blitting. This is used by drivers that don't provide their own
104 (accelerated) version. 105 (accelerated) version.
105 106
107config FB_CFB_REV_PIXELS_IN_BYTE
108 bool
109 depends on FB
110 default n
111 ---help---
112 Allow generic frame-buffer functions to work on displays with 1, 2
113 and 4 bits per pixel depths which has opposite order of pixels in
114 byte order to bytes in long order.
115
106config FB_SYS_FILLRECT 116config FB_SYS_FILLRECT
107 tristate 117 tristate
108 depends on FB 118 depends on FB
@@ -535,6 +545,15 @@ config FB_VGA16
535 To compile this driver as a module, choose M here: the 545 To compile this driver as a module, choose M here: the
536 module will be called vga16fb. 546 module will be called vga16fb.
537 547
548config FB_BF54X_LQ043
549 tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)"
550 depends on FB && (BF54x)
551 select FB_CFB_FILLRECT
552 select FB_CFB_COPYAREA
553 select FB_CFB_IMAGEBLIT
554 help
555 This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD
556
538config FB_STI 557config FB_STI
539 tristate "HP STI frame buffer device support" 558 tristate "HP STI frame buffer device support"
540 depends on FB && PARISC 559 depends on FB && PARISC
@@ -592,6 +611,24 @@ config FB_TGA
592 611
593 Say Y if you have one of those. 612 Say Y if you have one of those.
594 613
614config FB_UVESA
615 tristate "Userspace VESA VGA graphics support"
616 depends on FB && CONNECTOR
617 select FB_CFB_FILLRECT
618 select FB_CFB_COPYAREA
619 select FB_CFB_IMAGEBLIT
620 select FB_MODE_HELPERS
621 help
622 This is the frame buffer driver for generic VBE 2.0 compliant
623 graphic cards. It can also take advantage of VBE 3.0 features,
624 such as refresh rate adjustment.
625
626 This driver generally provides more features than vesafb but
627 requires a userspace helper application called 'v86d'. See
628 <file:Documentation/fb/uvesafb.txt> for more information.
629
630 If unsure, say N.
631
595config FB_VESA 632config FB_VESA
596 bool "VESA VGA graphics support" 633 bool "VESA VGA graphics support"
597 depends on (FB = y) && X86 634 depends on (FB = y) && X86
@@ -1625,7 +1662,7 @@ config FB_PMAG_BA
1625 1662
1626config FB_PMAGB_B 1663config FB_PMAGB_B
1627 tristate "PMAGB-B TURBOchannel framebuffer support" 1664 tristate "PMAGB-B TURBOchannel framebuffer support"
1628 depends on TC 1665 depends on FB && TC
1629 select FB_CFB_FILLRECT 1666 select FB_CFB_FILLRECT
1630 select FB_CFB_COPYAREA 1667 select FB_CFB_COPYAREA
1631 select FB_CFB_IMAGEBLIT 1668 select FB_CFB_IMAGEBLIT
@@ -1793,7 +1830,7 @@ config FB_PNX4008_DUM_RGB
1793 1830
1794config FB_IBM_GXT4500 1831config FB_IBM_GXT4500
1795 tristate "Framebuffer support for IBM GXT4500P adaptor" 1832 tristate "Framebuffer support for IBM GXT4500P adaptor"
1796 depends on PPC 1833 depends on FB && PPC
1797 select FB_CFB_FILLRECT 1834 select FB_CFB_FILLRECT
1798 select FB_CFB_COPYAREA 1835 select FB_CFB_COPYAREA
1799 select FB_CFB_IMAGEBLIT 1836 select FB_CFB_IMAGEBLIT
@@ -1833,10 +1870,6 @@ config FB_XILINX
1833 framebuffer. ML300 carries a 640*480 LCD display on the board, 1870 framebuffer. ML300 carries a 640*480 LCD display on the board,
1834 ML403 uses a standard DB15 VGA connector. 1871 ML403 uses a standard DB15 VGA connector.
1835 1872
1836if ARCH_OMAP
1837 source "drivers/video/omap/Kconfig"
1838endif
1839
1840config FB_VIRTUAL 1873config FB_VIRTUAL
1841 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)" 1874 tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
1842 depends on FB 1875 depends on FB
@@ -1860,6 +1893,13 @@ config FB_VIRTUAL
1860 1893
1861 If unsure, say N. 1894 If unsure, say N.
1862 1895
1896if ARCH_OMAP
1897 source "drivers/video/omap/Kconfig"
1898endif
1899
1900source "drivers/video/backlight/Kconfig"
1901source "drivers/video/display/Kconfig"
1902
1863if VT 1903if VT
1864 source "drivers/video/console/Kconfig" 1904 source "drivers/video/console/Kconfig"
1865endif 1905endif
@@ -1869,4 +1909,3 @@ if FB || SGI_NEWPORT_CONSOLE
1869endif 1909endif
1870 1910
1871endmenu 1911endmenu
1872
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 06eec7b182b7..59d6c45a910d 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -115,10 +115,12 @@ obj-$(CONFIG_FB_XILINX) += xilinxfb.o
115obj-$(CONFIG_FB_OMAP) += omap/ 115obj-$(CONFIG_FB_OMAP) += omap/
116 116
117# Platform or fallback drivers go here 117# Platform or fallback drivers go here
118obj-$(CONFIG_FB_UVESA) += uvesafb.o
118obj-$(CONFIG_FB_VESA) += vesafb.o 119obj-$(CONFIG_FB_VESA) += vesafb.o
119obj-$(CONFIG_FB_IMAC) += imacfb.o 120obj-$(CONFIG_FB_IMAC) += imacfb.o
120obj-$(CONFIG_FB_VGA16) += vga16fb.o 121obj-$(CONFIG_FB_VGA16) += vga16fb.o
121obj-$(CONFIG_FB_OF) += offb.o 122obj-$(CONFIG_FB_OF) += offb.o
123obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
122 124
123# the test framebuffer is last 125# the test framebuffer is last
124obj-$(CONFIG_FB_VIRTUAL) += vfb.o 126obj-$(CONFIG_FB_VIRTUAL) += vfb.o
diff --git a/drivers/video/amifb.c b/drivers/video/amifb.c
index 1a849b870bcc..f2e243c353f9 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/amifb.c
@@ -52,7 +52,7 @@
52#include <linux/init.h> 52#include <linux/init.h>
53#include <linux/ioport.h> 53#include <linux/ioport.h>
54 54
55#include <asm/uaccess.h> 55#include <linux/uaccess.h>
56#include <asm/system.h> 56#include <asm/system.h>
57#include <asm/irq.h> 57#include <asm/irq.h>
58#include <asm/amigahw.h> 58#include <asm/amigahw.h>
diff --git a/drivers/video/arcfb.c b/drivers/video/arcfb.c
index db15baca3f7b..c3431691c9f2 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/arcfb.c
@@ -48,7 +48,7 @@
48#include <linux/arcfb.h> 48#include <linux/arcfb.h>
49#include <linux/platform_device.h> 49#include <linux/platform_device.h>
50 50
51#include <asm/uaccess.h> 51#include <linux/uaccess.h>
52 52
53#define floor8(a) (a&(~0x07)) 53#define floor8(a) (a&(~0x07))
54#define floorXres(a,xres) (a&(~(xres - 1))) 54#define floorXres(a,xres) (a&(~(xres - 1)))
diff --git a/drivers/video/atafb.c b/drivers/video/atafb.c
index 0038a0541c7e..5d4fbaa53a6c 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/atafb.c
@@ -58,7 +58,7 @@
58#include <linux/interrupt.h> 58#include <linux/interrupt.h>
59 59
60#include <asm/setup.h> 60#include <asm/setup.h>
61#include <asm/uaccess.h> 61#include <linux/uaccess.h>
62#include <asm/pgtable.h> 62#include <asm/pgtable.h>
63#include <asm/irq.h> 63#include <asm/irq.h>
64#include <asm/io.h> 64#include <asm/io.h>
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/aty/ati_ids.h
index dca2eb8f2dde..3e9d28bcd9f8 100644
--- a/drivers/video/aty/ati_ids.h
+++ b/drivers/video/aty/ati_ids.h
@@ -188,6 +188,7 @@
188#define PCI_CHIP_MACH64VT 0x5654 188#define PCI_CHIP_MACH64VT 0x5654
189#define PCI_CHIP_MACH64VU 0x5655 189#define PCI_CHIP_MACH64VU 0x5655
190#define PCI_CHIP_MACH64VV 0x5656 190#define PCI_CHIP_MACH64VV 0x5656
191#define PCI_CHIP_RC410_5A62 0x5A62
191#define PCI_CHIP_RS300_5834 0x5834 192#define PCI_CHIP_RS300_5834 0x5834
192#define PCI_CHIP_RS300_5835 0x5835 193#define PCI_CHIP_RS300_5835 0x5835
193#define PCI_CHIP_RS300_5836 0x5836 194#define PCI_CHIP_RS300_5836 0x5836
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/aty/aty128fb.c
index cfcbe37d2d70..cbd3308b6690 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/aty/aty128fb.c
@@ -56,7 +56,7 @@
56#include <linux/vmalloc.h> 56#include <linux/vmalloc.h>
57#include <linux/delay.h> 57#include <linux/delay.h>
58#include <linux/interrupt.h> 58#include <linux/interrupt.h>
59#include <asm/uaccess.h> 59#include <linux/uaccess.h>
60#include <linux/fb.h> 60#include <linux/fb.h>
61#include <linux/init.h> 61#include <linux/init.h>
62#include <linux/pci.h> 62#include <linux/pci.h>
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/aty/atyfb.h
index dc62f8e282b4..7691e73823d3 100644
--- a/drivers/video/aty/atyfb.h
+++ b/drivers/video/aty/atyfb.h
@@ -126,6 +126,7 @@ union aty_pll {
126 */ 126 */
127 127
128struct atyfb_par { 128struct atyfb_par {
129 u32 pseudo_palette[16];
129 struct { u8 red, green, blue; } palette[256]; 130 struct { u8 red, green, blue; } palette[256];
130 const struct aty_dac_ops *dac_ops; 131 const struct aty_dac_ops *dac_ops;
131 const struct aty_pll_ops *pll_ops; 132 const struct aty_pll_ops *pll_ops;
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/aty/atyfb_base.c
index bc6f0096aa04..abe0c435a664 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/aty/atyfb_base.c
@@ -68,7 +68,7 @@
68#include <linux/backlight.h> 68#include <linux/backlight.h>
69 69
70#include <asm/io.h> 70#include <asm/io.h>
71#include <asm/uaccess.h> 71#include <linux/uaccess.h>
72 72
73#include <video/mach64.h> 73#include <video/mach64.h>
74#include "atyfb.h" 74#include "atyfb.h"
@@ -541,8 +541,6 @@ static char ram_off[] __devinitdata = "OFF";
541#endif /* CONFIG_FB_ATY_CT */ 541#endif /* CONFIG_FB_ATY_CT */
542 542
543 543
544static u32 pseudo_palette[16];
545
546#ifdef CONFIG_FB_ATY_GX 544#ifdef CONFIG_FB_ATY_GX
547static char *aty_gx_ram[8] __devinitdata = { 545static char *aty_gx_ram[8] __devinitdata = {
548 ram_dram, ram_vram, ram_vram, ram_dram, 546 ram_dram, ram_vram, ram_vram, ram_dram,
@@ -2577,7 +2575,7 @@ static int __devinit aty_init(struct fb_info *info)
2577#endif 2575#endif
2578 2576
2579 info->fbops = &atyfb_ops; 2577 info->fbops = &atyfb_ops;
2580 info->pseudo_palette = pseudo_palette; 2578 info->pseudo_palette = par->pseudo_palette;
2581 info->flags = FBINFO_DEFAULT | 2579 info->flags = FBINFO_DEFAULT |
2582 FBINFO_HWACCEL_IMAGEBLIT | 2580 FBINFO_HWACCEL_IMAGEBLIT |
2583 FBINFO_HWACCEL_FILLRECT | 2581 FBINFO_HWACCEL_FILLRECT |
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/aty/mach64_cursor.c
index fe2c6ad01a8d..faf95da8fcbc 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/aty/mach64_cursor.c
@@ -8,7 +8,6 @@
8#include <linux/string.h> 8#include <linux/string.h>
9 9
10#include <asm/io.h> 10#include <asm/io.h>
11#include <asm/uaccess.h>
12 11
13#ifdef __sparc__ 12#ifdef __sparc__
14#include <asm/fbio.h> 13#include <asm/fbio.h>
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/aty/radeon_base.c
index 4b747bdaeea6..1e32b3d13f2e 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/aty/radeon_base.c
@@ -69,7 +69,7 @@
69#include <linux/device.h> 69#include <linux/device.h>
70 70
71#include <asm/io.h> 71#include <asm/io.h>
72#include <asm/uaccess.h> 72#include <linux/uaccess.h>
73 73
74#ifdef CONFIG_PPC_OF 74#ifdef CONFIG_PPC_OF
75 75
@@ -145,6 +145,8 @@ static struct pci_device_id radeonfb_pci_table[] = {
145 /* 9000/Pro */ 145 /* 9000/Pro */
146 CHIP_DEF(PCI_CHIP_RV250_If, RV250, CHIP_HAS_CRTC2), 146 CHIP_DEF(PCI_CHIP_RV250_If, RV250, CHIP_HAS_CRTC2),
147 CHIP_DEF(PCI_CHIP_RV250_Ig, RV250, CHIP_HAS_CRTC2), 147 CHIP_DEF(PCI_CHIP_RV250_Ig, RV250, CHIP_HAS_CRTC2),
148
149 CHIP_DEF(PCI_CHIP_RC410_5A62, RC410, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
148 /* Mobility 9100 IGP (U3) */ 150 /* Mobility 9100 IGP (U3) */
149 CHIP_DEF(PCI_CHIP_RS300_5835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), 151 CHIP_DEF(PCI_CHIP_RS300_5835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
150 CHIP_DEF(PCI_CHIP_RS350_7835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY), 152 CHIP_DEF(PCI_CHIP_RS350_7835, RS300, CHIP_HAS_CRTC2 | CHIP_IS_IGP | CHIP_IS_MOBILITY),
@@ -1999,6 +2001,7 @@ static void radeon_identify_vram(struct radeonfb_info *rinfo)
1999 if ((rinfo->family == CHIP_FAMILY_RS100) || 2001 if ((rinfo->family == CHIP_FAMILY_RS100) ||
2000 (rinfo->family == CHIP_FAMILY_RS200) || 2002 (rinfo->family == CHIP_FAMILY_RS200) ||
2001 (rinfo->family == CHIP_FAMILY_RS300) || 2003 (rinfo->family == CHIP_FAMILY_RS300) ||
2004 (rinfo->family == CHIP_FAMILY_RC410) ||
2002 (rinfo->family == CHIP_FAMILY_RS480) ) { 2005 (rinfo->family == CHIP_FAMILY_RS480) ) {
2003 u32 tom = INREG(NB_TOM); 2006 u32 tom = INREG(NB_TOM);
2004 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024); 2007 tmp = ((((tom >> 16) - (tom & 0xffff) + 1) << 6) * 1024);
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/aty/radeonfb.h
index 7c922c7b460b..5eac1ce52e72 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/aty/radeonfb.h
@@ -48,6 +48,7 @@ enum radeon_family {
48 CHIP_FAMILY_RV350, 48 CHIP_FAMILY_RV350,
49 CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */ 49 CHIP_FAMILY_RV380, /* RV370/RV380/M22/M24 */
50 CHIP_FAMILY_R420, /* R420/R423/M18 */ 50 CHIP_FAMILY_R420, /* R420/R423/M18 */
51 CHIP_FAMILY_RC410,
51 CHIP_FAMILY_RS480, 52 CHIP_FAMILY_RS480,
52 CHIP_FAMILY_LAST, 53 CHIP_FAMILY_LAST,
53}; 54};
@@ -66,7 +67,8 @@ enum radeon_family {
66 ((rinfo)->family == CHIP_FAMILY_R350) || \ 67 ((rinfo)->family == CHIP_FAMILY_R350) || \
67 ((rinfo)->family == CHIP_FAMILY_RV380) || \ 68 ((rinfo)->family == CHIP_FAMILY_RV380) || \
68 ((rinfo)->family == CHIP_FAMILY_R420) || \ 69 ((rinfo)->family == CHIP_FAMILY_R420) || \
69 ((rinfo)->family == CHIP_FAMILY_RS480) ) 70 ((rinfo)->family == CHIP_FAMILY_RC410) || \
71 ((rinfo)->family == CHIP_FAMILY_RS480))
70 72
71/* 73/*
72 * Chip flags 74 * Chip flags
diff --git a/drivers/video/backlight/cr_bllcd.c b/drivers/video/backlight/cr_bllcd.c
index 92e201e81fbd..26add8898605 100644
--- a/drivers/video/backlight/cr_bllcd.c
+++ b/drivers/video/backlight/cr_bllcd.c
@@ -36,7 +36,6 @@
36#include <linux/backlight.h> 36#include <linux/backlight.h>
37#include <linux/lcd.h> 37#include <linux/lcd.h>
38#include <linux/pci.h> 38#include <linux/pci.h>
39#include <asm/uaccess.h>
40 39
41/* The LVDS- and panel power controls sits on the 40/* The LVDS- and panel power controls sits on the
42 * GPIO port of the ISA bridge. 41 * GPIO port of the ISA bridge.
diff --git a/drivers/video/backlight/progear_bl.c b/drivers/video/backlight/progear_bl.c
index 836ab4df0ef2..15fb4d58b5bc 100644
--- a/drivers/video/backlight/progear_bl.c
+++ b/drivers/video/backlight/progear_bl.c
@@ -23,7 +23,6 @@
23#include <linux/fb.h> 23#include <linux/fb.h>
24#include <linux/backlight.h> 24#include <linux/backlight.h>
25#include <linux/pci.h> 25#include <linux/pci.h>
26#include <asm/uaccess.h>
27 26
28#define PMU_LPCR 0xB0 27#define PMU_LPCR 0xB0
29#define SB_MPS1 0x61 28#define SB_MPS1 0x61
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/bf54x-lq043fb.c
new file mode 100644
index 000000000000..74d11c318987
--- /dev/null
+++ b/drivers/video/bf54x-lq043fb.c
@@ -0,0 +1,786 @@
1/*
2 * File: drivers/video/bf54x-lq043.c
3 * Based on:
4 * Author: Michael Hennerich <hennerich@blackfin.uclinux.org>
5 *
6 * Created:
7 * Description: ADSP-BF54x Framebufer driver
8 *
9 *
10 * Modified:
11 * Copyright 2004-2007 Analog Devices Inc.
12 *
13 * Bugs: Enter bugs at http://blackfin.uclinux.org/
14 *
15 * This program is free software; you can redistribute it and/or modify
16 * it under the terms of the GNU General Public License as published by
17 * the Free Software Foundation; either version 2 of the License, or
18 * (at your option) any later version.
19 *
20 * This program is distributed in the hope that it will be useful,
21 * but WITHOUT ANY WARRANTY; without even the implied warranty of
22 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 * GNU General Public License for more details.
24 *
25 * You should have received a copy of the GNU General Public License
26 * along with this program; if not, see the file COPYING, or write
27 * to the Free Software Foundation, Inc.,
28 * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
29 */
30
31#include <linux/module.h>
32#include <linux/kernel.h>
33#include <linux/errno.h>
34#include <linux/string.h>
35#include <linux/mm.h>
36#include <linux/tty.h>
37#include <linux/slab.h>
38#include <linux/delay.h>
39#include <linux/fb.h>
40#include <linux/ioport.h>
41#include <linux/init.h>
42#include <linux/types.h>
43#include <linux/interrupt.h>
44#include <linux/sched.h>
45#include <linux/timer.h>
46#include <linux/device.h>
47#include <linux/backlight.h>
48#include <linux/lcd.h>
49#include <linux/spinlock.h>
50#include <linux/dma-mapping.h>
51#include <linux/platform_device.h>
52
53#include <asm/blackfin.h>
54#include <asm/irq.h>
55#include <asm/dpmc.h>
56#include <asm/dma-mapping.h>
57#include <asm/dma.h>
58#include <asm/gpio.h>
59#include <asm/portmux.h>
60
61#include <asm/mach/bf54x-lq043.h>
62
63#define NO_BL_SUPPORT
64
65#define DRIVER_NAME "bf54x-lq043"
66static char driver_name[] = DRIVER_NAME;
67
68#define BFIN_LCD_NBR_PALETTE_ENTRIES 256
69
70#define EPPI0_18 {P_PPI0_CLK, P_PPI0_FS1, P_PPI0_FS2, P_PPI0_D0, P_PPI0_D1, P_PPI0_D2, P_PPI0_D3, \
71 P_PPI0_D4, P_PPI0_D5, P_PPI0_D6, P_PPI0_D7, P_PPI0_D8, P_PPI0_D9, P_PPI0_D10, \
72 P_PPI0_D11, P_PPI0_D12, P_PPI0_D13, P_PPI0_D14, P_PPI0_D15, P_PPI0_D16, P_PPI0_D17, 0}
73
74#define EPPI0_24 {P_PPI0_D18, P_PPI0_D19, P_PPI0_D20, P_PPI0_D21, P_PPI0_D22, P_PPI0_D23, 0}
75
76struct bfin_bf54xfb_info {
77 struct fb_info *fb;
78 struct device *dev;
79
80 struct bfin_bf54xfb_mach_info *mach_info;
81
82 unsigned char *fb_buffer; /* RGB Buffer */
83
84 dma_addr_t dma_handle;
85 int lq043_mmap;
86 int lq043_open_cnt;
87 int irq;
88 spinlock_t lock; /* lock */
89};
90
91static int nocursor;
92module_param(nocursor, int, 0644);
93MODULE_PARM_DESC(nocursor, "cursor enable/disable");
94
95static int outp_rgb666;
96module_param(outp_rgb666, int, 0);
97MODULE_PARM_DESC(outp_rgb666, "Output 18-bit RGB666");
98
99#define LCD_X_RES 480 /*Horizontal Resolution */
100#define LCD_Y_RES 272 /* Vertical Resolution */
101
102#define LCD_BPP 24 /* Bit Per Pixel */
103#define DMA_BUS_SIZE 32
104
105/* -- Horizontal synchronizing --
106 *
107 * Timing characteristics taken from the SHARP LQ043T1DG01 datasheet
108 * (LCY-W-06602A Page 9 of 22)
109 *
110 * Clock Frequency 1/Tc Min 7.83 Typ 9.00 Max 9.26 MHz
111 *
112 * Period TH - 525 - Clock
113 * Pulse width THp - 41 - Clock
114 * Horizontal period THd - 480 - Clock
115 * Back porch THb - 2 - Clock
116 * Front porch THf - 2 - Clock
117 *
118 * -- Vertical synchronizing --
119 * Period TV - 286 - Line
120 * Pulse width TVp - 10 - Line
121 * Vertical period TVd - 272 - Line
122 * Back porch TVb - 2 - Line
123 * Front porch TVf - 2 - Line
124 */
125
126#define LCD_CLK (8*1000*1000) /* 8MHz */
127
128/* # active data to transfer after Horizontal Delay clock */
129#define EPPI_HCOUNT LCD_X_RES
130
131/* # active lines to transfer after Vertical Delay clock */
132#define EPPI_VCOUNT LCD_Y_RES
133
134/* Samples per Line = 480 (active data) + 45 (padding) */
135#define EPPI_LINE 525
136
137/* Lines per Frame = 272 (active data) + 14 (padding) */
138#define EPPI_FRAME 286
139
140/* FS1 (Hsync) Width (Typical)*/
141#define EPPI_FS1W_HBL 41
142
143/* FS1 (Hsync) Period (Typical) */
144#define EPPI_FS1P_AVPL EPPI_LINE
145
146/* Horizontal Delay clock after assertion of Hsync (Typical) */
147#define EPPI_HDELAY 43
148
149/* FS2 (Vsync) Width = FS1 (Hsync) Period * 10 */
150#define EPPI_FS2W_LVB (EPPI_LINE * 10)
151
152 /* FS2 (Vsync) Period = FS1 (Hsync) Period * Lines per Frame */
153#define EPPI_FS2P_LAVF (EPPI_LINE * EPPI_FRAME)
154
155/* Vertical Delay after assertion of Vsync (2 Lines) */
156#define EPPI_VDELAY 12
157
158#define EPPI_CLIP 0xFF00FF00
159
160/* EPPI Control register configuration value for RGB out
161 * - EPPI as Output
162 * GP 2 frame sync mode,
163 * Internal Clock generation disabled, Internal FS generation enabled,
164 * Receives samples on EPPI_CLK raising edge, Transmits samples on EPPI_CLK falling edge,
165 * FS1 & FS2 are active high,
166 * DLEN = 6 (24 bits for RGB888 out) or 5 (18 bits for RGB666 out)
167 * DMA Unpacking disabled when RGB Formating is enabled, otherwise DMA unpacking enabled
168 * Swapping Enabled,
169 * One (DMA) Channel Mode,
170 * RGB Formatting Enabled for RGB666 output, disabled for RGB888 output
171 * Regular watermark - when FIFO is 100% full,
172 * Urgent watermark - when FIFO is 75% full
173 */
174
175#define EPPI_CONTROL (0x20136E2E | SWAPEN)
176
177static inline u16 get_eppi_clkdiv(u32 target_ppi_clk)
178{
179 u32 sclk = get_sclk();
180
181 /* EPPI_CLK = (SCLK) / (2 * (EPPI_CLKDIV[15:0] + 1)) */
182
183 return (((sclk / target_ppi_clk) / 2) - 1);
184}
185
186static void config_ppi(struct bfin_bf54xfb_info *fbi)
187{
188
189 u16 eppi_clkdiv = get_eppi_clkdiv(LCD_CLK);
190
191 bfin_write_EPPI0_FS1W_HBL(EPPI_FS1W_HBL);
192 bfin_write_EPPI0_FS1P_AVPL(EPPI_FS1P_AVPL);
193 bfin_write_EPPI0_FS2W_LVB(EPPI_FS2W_LVB);
194 bfin_write_EPPI0_FS2P_LAVF(EPPI_FS2P_LAVF);
195 bfin_write_EPPI0_CLIP(EPPI_CLIP);
196
197 bfin_write_EPPI0_FRAME(EPPI_FRAME);
198 bfin_write_EPPI0_LINE(EPPI_LINE);
199
200 bfin_write_EPPI0_HCOUNT(EPPI_HCOUNT);
201 bfin_write_EPPI0_HDELAY(EPPI_HDELAY);
202 bfin_write_EPPI0_VCOUNT(EPPI_VCOUNT);
203 bfin_write_EPPI0_VDELAY(EPPI_VDELAY);
204
205 bfin_write_EPPI0_CLKDIV(eppi_clkdiv);
206
207/*
208 * DLEN = 6 (24 bits for RGB888 out) or 5 (18 bits for RGB666 out)
209 * RGB Formatting Enabled for RGB666 output, disabled for RGB888 output
210 */
211 if (outp_rgb666)
212 bfin_write_EPPI0_CONTROL((EPPI_CONTROL & ~DLENGTH) | DLEN_18 |
213 RGB_FMT_EN);
214 else
215 bfin_write_EPPI0_CONTROL(((EPPI_CONTROL & ~DLENGTH) | DLEN_24) &
216 ~RGB_FMT_EN);
217
218
219}
220
221static int config_dma(struct bfin_bf54xfb_info *fbi)
222{
223
224 set_dma_config(CH_EPPI0,
225 set_bfin_dma_config(DIR_READ, DMA_FLOW_AUTO,
226 INTR_DISABLE, DIMENSION_2D,
227 DATA_SIZE_32));
228 set_dma_x_count(CH_EPPI0, (LCD_X_RES * LCD_BPP) / DMA_BUS_SIZE);
229 set_dma_x_modify(CH_EPPI0, DMA_BUS_SIZE / 8);
230 set_dma_y_count(CH_EPPI0, LCD_Y_RES);
231 set_dma_y_modify(CH_EPPI0, DMA_BUS_SIZE / 8);
232 set_dma_start_addr(CH_EPPI0, (unsigned long)fbi->fb_buffer);
233
234 return 0;
235}
236
237static int request_ports(struct bfin_bf54xfb_info *fbi)
238{
239
240 u16 eppi_req_18[] = EPPI0_18;
241 u16 disp = fbi->mach_info->disp;
242
243 if (gpio_request(disp, NULL)) {
244 printk(KERN_ERR "Requesting GPIO %d faild\n", disp);
245 return -EFAULT;
246 }
247
248 if (peripheral_request_list(eppi_req_18, DRIVER_NAME)) {
249 printk(KERN_ERR "Requesting Peripherals faild\n");
250 gpio_free(disp);
251 return -EFAULT;
252 }
253
254 if (!outp_rgb666) {
255
256 u16 eppi_req_24[] = EPPI0_24;
257
258 if (peripheral_request_list(eppi_req_24, DRIVER_NAME)) {
259 printk(KERN_ERR "Requesting Peripherals faild\n");
260 peripheral_free_list(eppi_req_18);
261 gpio_free(disp);
262 return -EFAULT;
263 }
264 }
265
266 gpio_direction_output(disp);
267 gpio_set_value(disp, 1);
268
269 return 0;
270}
271
272static void free_ports(struct bfin_bf54xfb_info *fbi)
273{
274
275 u16 eppi_req_18[] = EPPI0_18;
276
277 gpio_free(fbi->mach_info->disp);
278
279 peripheral_free_list(eppi_req_18);
280
281 if (!outp_rgb666) {
282 u16 eppi_req_24[] = EPPI0_24;
283 peripheral_free_list(eppi_req_24);
284 }
285}
286
287static int bfin_bf54x_fb_open(struct fb_info *info, int user)
288{
289 struct bfin_bf54xfb_info *fbi = info->par;
290
291 spin_lock(&fbi->lock);
292 fbi->lq043_open_cnt++;
293
294 if (fbi->lq043_open_cnt <= 1) {
295
296 bfin_write_EPPI0_CONTROL(0);
297 SSYNC();
298
299 config_dma(fbi);
300 config_ppi(fbi);
301
302 /* start dma */
303 enable_dma(CH_EPPI0);
304 bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN);
305 }
306
307 spin_unlock(&fbi->lock);
308
309 return 0;
310}
311
312static int bfin_bf54x_fb_release(struct fb_info *info, int user)
313{
314 struct bfin_bf54xfb_info *fbi = info->par;
315
316 spin_lock(&fbi->lock);
317
318 fbi->lq043_open_cnt--;
319 fbi->lq043_mmap = 0;
320
321 if (fbi->lq043_open_cnt <= 0) {
322
323 bfin_write_EPPI0_CONTROL(0);
324 SSYNC();
325 disable_dma(CH_EPPI0);
326 memset(fbi->fb_buffer, 0, info->fix.smem_len);
327 }
328
329 spin_unlock(&fbi->lock);
330
331 return 0;
332}
333
334static int bfin_bf54x_fb_check_var(struct fb_var_screeninfo *var,
335 struct fb_info *info)
336{
337
338 if (var->bits_per_pixel != LCD_BPP) {
339 pr_debug("%s: depth not supported: %u BPP\n", __FUNCTION__,
340 var->bits_per_pixel);
341 return -EINVAL;
342 }
343
344 if (info->var.xres != var->xres || info->var.yres != var->yres ||
345 info->var.xres_virtual != var->xres_virtual ||
346 info->var.yres_virtual != var->yres_virtual) {
347 pr_debug("%s: Resolution not supported: X%u x Y%u \n",
348 __FUNCTION__, var->xres, var->yres);
349 return -EINVAL;
350 }
351
352 /*
353 * Memory limit
354 */
355
356 if ((info->fix.line_length * var->yres_virtual) > info->fix.smem_len) {
357 pr_debug("%s: Memory Limit requested yres_virtual = %u\n",
358 __FUNCTION__, var->yres_virtual);
359 return -ENOMEM;
360 }
361
362 return 0;
363}
364
365static int bfin_bf54x_fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
366{
367
368 struct bfin_bf54xfb_info *fbi = info->par;
369
370 if (fbi->lq043_mmap)
371 return -1;
372
373 spin_lock(&fbi->lock);
374 fbi->lq043_mmap = 1;
375 spin_unlock(&fbi->lock);
376
377 vma->vm_start = (unsigned long)(fbi->fb_buffer);
378
379 vma->vm_end = vma->vm_start + info->fix.smem_len;
380 /* For those who don't understand how mmap works, go read
381 * Documentation/nommu-mmap.txt.
382 * For those that do, you will know that the VM_MAYSHARE flag
383 * must be set in the vma->vm_flags structure on noMMU
384 * Other flags can be set, and are documented in
385 * include/linux/mm.h
386 */
387 vma->vm_flags |= VM_MAYSHARE;
388
389 return 0;
390}
391
392int bfin_bf54x_fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
393{
394 if (nocursor)
395 return 0;
396 else
397 return -EINVAL; /* just to force soft_cursor() call */
398}
399
400static int bfin_bf54x_fb_setcolreg(u_int regno, u_int red, u_int green,
401 u_int blue, u_int transp,
402 struct fb_info *info)
403{
404 if (regno >= BFIN_LCD_NBR_PALETTE_ENTRIES)
405 return -EINVAL;
406
407 if (info->var.grayscale) {
408 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
409 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
410 }
411
412 if (info->fix.visual == FB_VISUAL_TRUECOLOR) {
413
414 u32 value;
415 /* Place color in the pseudopalette */
416 if (regno > 16)
417 return -EINVAL;
418
419 red >>= (16 - info->var.red.length);
420 green >>= (16 - info->var.green.length);
421 blue >>= (16 - info->var.blue.length);
422
423 value = (red << info->var.red.offset) |
424 (green << info->var.green.offset) |
425 (blue << info->var.blue.offset);
426 value &= 0xFFFFFF;
427
428 ((u32 *) (info->pseudo_palette))[regno] = value;
429
430 }
431
432 return 0;
433}
434
435static struct fb_ops bfin_bf54x_fb_ops = {
436 .owner = THIS_MODULE,
437 .fb_open = bfin_bf54x_fb_open,
438 .fb_release = bfin_bf54x_fb_release,
439 .fb_check_var = bfin_bf54x_fb_check_var,
440 .fb_fillrect = cfb_fillrect,
441 .fb_copyarea = cfb_copyarea,
442 .fb_imageblit = cfb_imageblit,
443 .fb_mmap = bfin_bf54x_fb_mmap,
444 .fb_cursor = bfin_bf54x_fb_cursor,
445 .fb_setcolreg = bfin_bf54x_fb_setcolreg,
446};
447
448#ifndef NO_BL_SUPPORT
449static int bl_get_brightness(struct backlight_device *bd)
450{
451 return 0;
452}
453
454static struct backlight_ops bfin_lq043fb_bl_ops = {
455 .get_brightness = bl_get_brightness,
456};
457
458static struct backlight_device *bl_dev;
459
460static int bfin_lcd_get_power(struct lcd_device *dev)
461{
462 return 0;
463}
464
465static int bfin_lcd_set_power(struct lcd_device *dev, int power)
466{
467 return 0;
468}
469
470static int bfin_lcd_get_contrast(struct lcd_device *dev)
471{
472 return 0;
473}
474
475static int bfin_lcd_set_contrast(struct lcd_device *dev, int contrast)
476{
477
478 return 0;
479}
480
481static int bfin_lcd_check_fb(struct fb_info *fi)
482{
483 if (!fi || (fi == &bfin_bf54x_fb))
484 return 1;
485 return 0;
486}
487
488static struct lcd_ops bfin_lcd_ops = {
489 .get_power = bfin_lcd_get_power,
490 .set_power = bfin_lcd_set_power,
491 .get_contrast = bfin_lcd_get_contrast,
492 .set_contrast = bfin_lcd_set_contrast,
493 .check_fb = bfin_lcd_check_fb,
494};
495
496static struct lcd_device *lcd_dev;
497#endif
498
499static irqreturn_t bfin_bf54x_irq_error(int irq, void *dev_id)
500{
501
502 /*struct bfin_bf54xfb_info *info = (struct bfin_bf54xfb_info *)dev_id;*/
503
504 u16 status = bfin_read_EPPI0_STATUS();
505
506 bfin_write_EPPI0_STATUS(0xFFFF);
507
508 if (status) {
509 bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() & ~EPPI_EN);
510 disable_dma(CH_EPPI0);
511
512 /* start dma */
513 enable_dma(CH_EPPI0);
514 bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN);
515 bfin_write_EPPI0_STATUS(0xFFFF);
516 }
517
518 return IRQ_HANDLED;
519}
520
521static int __init bfin_bf54x_probe(struct platform_device *pdev)
522{
523 struct bfin_bf54xfb_info *info;
524 struct fb_info *fbinfo;
525 int ret;
526
527 printk(KERN_INFO DRIVER_NAME ": FrameBuffer initializing...\n");
528
529 if (request_dma(CH_EPPI0, "CH_EPPI0") < 0) {
530 printk(KERN_ERR DRIVER_NAME
531 ": couldn't request CH_EPPI0 DMA\n");
532 ret = -EFAULT;
533 goto out1;
534 }
535
536 fbinfo =
537 framebuffer_alloc(sizeof(struct bfin_bf54xfb_info), &pdev->dev);
538 if (!fbinfo) {
539 ret = -ENOMEM;
540 goto out2;
541 }
542
543 info = fbinfo->par;
544 info->fb = fbinfo;
545 info->dev = &pdev->dev;
546
547 platform_set_drvdata(pdev, fbinfo);
548
549 strcpy(fbinfo->fix.id, driver_name);
550
551 info->mach_info = pdev->dev.platform_data;
552
553 if (info->mach_info == NULL) {
554 dev_err(&pdev->dev,
555 "no platform data for lcd, cannot attach\n");
556 ret = -EINVAL;
557 goto out3;
558 }
559
560 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
561 fbinfo->fix.type_aux = 0;
562 fbinfo->fix.xpanstep = 0;
563 fbinfo->fix.ypanstep = 0;
564 fbinfo->fix.ywrapstep = 0;
565 fbinfo->fix.accel = FB_ACCEL_NONE;
566 fbinfo->fix.visual = FB_VISUAL_TRUECOLOR;
567
568 fbinfo->var.nonstd = 0;
569 fbinfo->var.activate = FB_ACTIVATE_NOW;
570 fbinfo->var.height = info->mach_info->height;
571 fbinfo->var.width = info->mach_info->width;
572 fbinfo->var.accel_flags = 0;
573 fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
574
575 fbinfo->fbops = &bfin_bf54x_fb_ops;
576 fbinfo->flags = FBINFO_FLAG_DEFAULT;
577
578 fbinfo->var.xres = info->mach_info->xres.defval;
579 fbinfo->var.xres_virtual = info->mach_info->xres.defval;
580 fbinfo->var.yres = info->mach_info->yres.defval;
581 fbinfo->var.yres_virtual = info->mach_info->yres.defval;
582 fbinfo->var.bits_per_pixel = info->mach_info->bpp.defval;
583
584 fbinfo->var.upper_margin = 0;
585 fbinfo->var.lower_margin = 0;
586 fbinfo->var.vsync_len = 0;
587
588 fbinfo->var.left_margin = 0;
589 fbinfo->var.right_margin = 0;
590 fbinfo->var.hsync_len = 0;
591
592 fbinfo->var.red.offset = 16;
593 fbinfo->var.green.offset = 8;
594 fbinfo->var.blue.offset = 0;
595 fbinfo->var.transp.offset = 0;
596 fbinfo->var.red.length = 8;
597 fbinfo->var.green.length = 8;
598 fbinfo->var.blue.length = 8;
599 fbinfo->var.transp.length = 0;
600 fbinfo->fix.smem_len = info->mach_info->xres.max *
601 info->mach_info->yres.max * info->mach_info->bpp.max / 8;
602
603 fbinfo->fix.line_length = fbinfo->var.xres_virtual *
604 fbinfo->var.bits_per_pixel / 8;
605
606 info->fb_buffer =
607 dma_alloc_coherent(NULL, fbinfo->fix.smem_len, &info->dma_handle,
608 GFP_KERNEL);
609
610 if (NULL == info->fb_buffer) {
611 printk(KERN_ERR DRIVER_NAME
612 ": couldn't allocate dma buffer.\n");
613 ret = -ENOMEM;
614 goto out3;
615 }
616
617 memset(info->fb_buffer, 0, fbinfo->fix.smem_len);
618
619 fbinfo->screen_base = (void *)info->fb_buffer;
620 fbinfo->fix.smem_start = (int)info->fb_buffer;
621
622 fbinfo->fbops = &bfin_bf54x_fb_ops;
623
624 fbinfo->pseudo_palette = kmalloc(sizeof(u32) * 16, GFP_KERNEL);
625 if (!fbinfo->pseudo_palette) {
626 printk(KERN_ERR DRIVER_NAME
627 "Fail to allocate pseudo_palette\n");
628
629 ret = -ENOMEM;
630 goto out4;
631 }
632
633 memset(fbinfo->pseudo_palette, 0, sizeof(u32) * 16);
634
635 if (fb_alloc_cmap(&fbinfo->cmap, BFIN_LCD_NBR_PALETTE_ENTRIES, 0)
636 < 0) {
637 printk(KERN_ERR DRIVER_NAME
638 "Fail to allocate colormap (%d entries)\n",
639 BFIN_LCD_NBR_PALETTE_ENTRIES);
640 ret = -EFAULT;
641 goto out5;
642 }
643
644 if (request_ports(info)) {
645 printk(KERN_ERR DRIVER_NAME ": couldn't request gpio port.\n");
646 ret = -EFAULT;
647 goto out6;
648 }
649
650 info->irq = platform_get_irq(pdev, 0);
651 if (info->irq < 0) {
652 ret = -EINVAL;
653 goto out7;
654 }
655
656 if (request_irq(info->irq, (void *)bfin_bf54x_irq_error, IRQF_DISABLED,
657 "PPI ERROR", info) < 0) {
658 printk(KERN_ERR DRIVER_NAME
659 ": unable to request PPI ERROR IRQ\n");
660 ret = -EFAULT;
661 goto out7;
662 }
663
664 if (register_framebuffer(fbinfo) < 0) {
665 printk(KERN_ERR DRIVER_NAME
666 ": unable to register framebuffer.\n");
667 ret = -EINVAL;
668 goto out8;
669 }
670#ifndef NO_BL_SUPPORT
671 bl_dev =
672 backlight_device_register("bf54x-bl", NULL, NULL,
673 &bfin_lq043fb_bl_ops);
674 bl_dev->props.max_brightness = 255;
675
676 lcd_dev = lcd_device_register(DRIVER_NAME, NULL, &bfin_lcd_ops);
677 lcd_dev->props.max_contrast = 255, printk(KERN_INFO "Done.\n");
678#endif
679
680 return 0;
681
682out8:
683 free_irq(info->irq, info);
684out7:
685 free_ports(info);
686out6:
687 fb_dealloc_cmap(&fbinfo->cmap);
688out5:
689 kfree(fbinfo->pseudo_palette);
690out4:
691 dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
692 info->dma_handle);
693out3:
694 framebuffer_release(fbinfo);
695out2:
696 free_dma(CH_EPPI0);
697out1:
698 platform_set_drvdata(pdev, NULL);
699
700 return ret;
701}
702
703static int bfin_bf54x_remove(struct platform_device *pdev)
704{
705
706 struct fb_info *fbinfo = platform_get_drvdata(pdev);
707 struct bfin_bf54xfb_info *info = fbinfo->par;
708
709 free_dma(CH_EPPI0);
710 free_irq(info->irq, info);
711
712 if (info->fb_buffer != NULL)
713 dma_free_coherent(NULL, fbinfo->fix.smem_len, info->fb_buffer,
714 info->dma_handle);
715
716 kfree(fbinfo->pseudo_palette);
717 fb_dealloc_cmap(&fbinfo->cmap);
718
719#ifndef NO_BL_SUPPORT
720 lcd_device_unregister(lcd_dev);
721 backlight_device_unregister(bl_dev);
722#endif
723
724 unregister_framebuffer(fbinfo);
725
726 free_ports(info);
727
728 printk(KERN_INFO DRIVER_NAME ": Unregister LCD driver.\n");
729
730 return 0;
731}
732
733#ifdef CONFIG_PM
734static int bfin_bf54x_suspend(struct platform_device *pdev, pm_message_t state)
735{
736 struct fb_info *fbinfo = platform_get_drvdata(pdev);
737 struct bfin_bf54xfb_info *info = fbinfo->par;
738
739 bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() & ~EPPI_EN);
740 disable_dma(CH_EPPI0);
741 bfin_write_EPPI0_STATUS(0xFFFF);
742
743 return 0;
744}
745
746static int bfin_bf54x_resume(struct platform_device *pdev)
747{
748 struct fb_info *fbinfo = platform_get_drvdata(pdev);
749 struct bfin_bf54xfb_info *info = fbinfo->par;
750
751 enable_dma(CH_EPPI0);
752 bfin_write_EPPI0_CONTROL(bfin_read_EPPI0_CONTROL() | EPPI_EN);
753
754 return 0;
755}
756#else
757#define bfin_bf54x_suspend NULL
758#define bfin_bf54x_resume NULL
759#endif
760
761static struct platform_driver bfin_bf54x_driver = {
762 .probe = bfin_bf54x_probe,
763 .remove = bfin_bf54x_remove,
764 .suspend = bfin_bf54x_suspend,
765 .resume = bfin_bf54x_resume,
766 .driver = {
767 .name = DRIVER_NAME,
768 .owner = THIS_MODULE,
769 },
770};
771
772static int __devinit bfin_bf54x_driver_init(void)
773{
774 return platform_driver_register(&bfin_bf54x_driver);
775}
776
777static void __exit bfin_bf54x_driver_cleanup(void)
778{
779 platform_driver_unregister(&bfin_bf54x_driver);
780}
781
782MODULE_DESCRIPTION("Blackfin BF54x TFT LCD Driver");
783MODULE_LICENSE("GPL");
784
785module_init(bfin_bf54x_driver_init);
786module_exit(bfin_bf54x_driver_cleanup);
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/cfbcopyarea.c
index 032210f45be3..b07e419b12d2 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/cfbcopyarea.c
@@ -45,14 +45,14 @@
45 45
46static void 46static void
47bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src, 47bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src,
48 int src_idx, int bits, unsigned n) 48 int src_idx, int bits, unsigned n, u32 bswapmask)
49{ 49{
50 unsigned long first, last; 50 unsigned long first, last;
51 int const shift = dst_idx-src_idx; 51 int const shift = dst_idx-src_idx;
52 int left, right; 52 int left, right;
53 53
54 first = FB_SHIFT_HIGH(~0UL, dst_idx); 54 first = fb_shifted_pixels_mask_long(dst_idx, bswapmask);
55 last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); 55 last = ~fb_shifted_pixels_mask_long((dst_idx+n) % bits, bswapmask);
56 56
57 if (!shift) { 57 if (!shift) {
58 // Same alignment for source and dest 58 // Same alignment for source and dest
@@ -94,29 +94,34 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
94 FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst); 94 FB_WRITEL( comp( FB_READL(src), FB_READL(dst), last), dst);
95 } 95 }
96 } else { 96 } else {
97 /* Different alignment for source and dest */
97 unsigned long d0, d1; 98 unsigned long d0, d1;
98 int m; 99 int m;
99 // Different alignment for source and dest
100 100
101 right = shift & (bits - 1); 101 right = shift & (bits - 1);
102 left = -shift & (bits - 1); 102 left = -shift & (bits - 1);
103 bswapmask &= shift;
103 104
104 if (dst_idx+n <= bits) { 105 if (dst_idx+n <= bits) {
105 // Single destination word 106 // Single destination word
106 if (last) 107 if (last)
107 first &= last; 108 first &= last;
109 d0 = FB_READL(src);
110 d0 = fb_rev_pixels_in_long(d0, bswapmask);
108 if (shift > 0) { 111 if (shift > 0) {
109 // Single source word 112 // Single source word
110 FB_WRITEL( comp( FB_READL(src) >> right, FB_READL(dst), first), dst); 113 d0 >>= right;
111 } else if (src_idx+n <= bits) { 114 } else if (src_idx+n <= bits) {
112 // Single source word 115 // Single source word
113 FB_WRITEL( comp(FB_READL(src) << left, FB_READL(dst), first), dst); 116 d0 <<= left;;
114 } else { 117 } else {
115 // 2 source words 118 // 2 source words
116 d0 = FB_READL(src++); 119 d1 = FB_READL(src + 1);
117 d1 = FB_READL(src); 120 d1 = fb_rev_pixels_in_long(d1, bswapmask);
118 FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), first), dst); 121 d0 = d0<<left | d1>>right;
119 } 122 }
123 d0 = fb_rev_pixels_in_long(d0, bswapmask);
124 FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
120 } else { 125 } else {
121 // Multiple destination words 126 // Multiple destination words
122 /** We must always remember the last value read, because in case 127 /** We must always remember the last value read, because in case
@@ -125,25 +130,31 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
125 overlap with the current long from SRC. We store this value in 130 overlap with the current long from SRC. We store this value in
126 'd0'. */ 131 'd0'. */
127 d0 = FB_READL(src++); 132 d0 = FB_READL(src++);
133 d0 = fb_rev_pixels_in_long(d0, bswapmask);
128 // Leading bits 134 // Leading bits
129 if (shift > 0) { 135 if (shift > 0) {
130 // Single source word 136 // Single source word
131 FB_WRITEL( comp(d0 >> right, FB_READL(dst), first), dst); 137 d1 = d0;
138 d0 >>= right;
132 dst++; 139 dst++;
133 n -= bits - dst_idx; 140 n -= bits - dst_idx;
134 } else { 141 } else {
135 // 2 source words 142 // 2 source words
136 d1 = FB_READL(src++); 143 d1 = FB_READL(src++);
137 FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), first), dst); 144 d1 = fb_rev_pixels_in_long(d1, bswapmask);
138 d0 = d1; 145
146 d0 = d0<<left | d1>>right;
139 dst++; 147 dst++;
140 n -= bits - dst_idx; 148 n -= bits - dst_idx;
141 } 149 }
150 d0 = fb_rev_pixels_in_long(d0, bswapmask);
151 FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
152 d0 = d1;
142 153
143 // Main chunk 154 // Main chunk
144 m = n % bits; 155 m = n % bits;
145 n /= bits; 156 n /= bits;
146 while (n >= 4) { 157 while ((n >= 4) && !bswapmask) {
147 d1 = FB_READL(src++); 158 d1 = FB_READL(src++);
148 FB_WRITEL(d0 << left | d1 >> right, dst++); 159 FB_WRITEL(d0 << left | d1 >> right, dst++);
149 d0 = d1; 160 d0 = d1;
@@ -160,7 +171,10 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
160 } 171 }
161 while (n--) { 172 while (n--) {
162 d1 = FB_READL(src++); 173 d1 = FB_READL(src++);
163 FB_WRITEL(d0 << left | d1 >> right, dst++); 174 d1 = fb_rev_pixels_in_long(d1, bswapmask);
175 d0 = d0 << left | d1 >> right;
176 d0 = fb_rev_pixels_in_long(d0, bswapmask);
177 FB_WRITEL(d0, dst++);
164 d0 = d1; 178 d0 = d1;
165 } 179 }
166 180
@@ -168,12 +182,16 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
168 if (last) { 182 if (last) {
169 if (m <= right) { 183 if (m <= right) {
170 // Single source word 184 // Single source word
171 FB_WRITEL( comp(d0 << left, FB_READL(dst), last), dst); 185 d0 <<= left;
172 } else { 186 } else {
173 // 2 source words 187 // 2 source words
174 d1 = FB_READL(src); 188 d1 = FB_READL(src);
175 FB_WRITEL( comp(d0<<left | d1>>right, FB_READL(dst), last), dst); 189 d1 = fb_rev_pixels_in_long(d1,
190 bswapmask);
191 d0 = d0<<left | d1>>right;
176 } 192 }
193 d0 = fb_rev_pixels_in_long(d0, bswapmask);
194 FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
177 } 195 }
178 } 196 }
179 } 197 }
@@ -185,7 +203,7 @@ bitcpy(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src
185 203
186static void 204static void
187bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src, 205bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem *src,
188 int src_idx, int bits, unsigned n) 206 int src_idx, int bits, unsigned n, u32 bswapmask)
189{ 207{
190 unsigned long first, last; 208 unsigned long first, last;
191 int shift; 209 int shift;
@@ -203,8 +221,8 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
203 221
204 shift = dst_idx-src_idx; 222 shift = dst_idx-src_idx;
205 223
206 first = FB_SHIFT_LOW(~0UL, bits - 1 - dst_idx); 224 first = fb_shifted_pixels_mask_long(bits - 1 - dst_idx, bswapmask);
207 last = ~(FB_SHIFT_LOW(~0UL, bits - 1 - ((dst_idx-n) % bits))); 225 last = ~fb_shifted_pixels_mask_long(bits - 1 - ((dst_idx-n) % bits), bswapmask);
208 226
209 if (!shift) { 227 if (!shift) {
210 // Same alignment for source and dest 228 // Same alignment for source and dest
@@ -247,24 +265,32 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
247 } 265 }
248 } else { 266 } else {
249 // Different alignment for source and dest 267 // Different alignment for source and dest
268 unsigned long d0, d1;
269 int m;
250 270
251 int const left = -shift & (bits-1); 271 int const left = -shift & (bits-1);
252 int const right = shift & (bits-1); 272 int const right = shift & (bits-1);
273 bswapmask &= shift;
253 274
254 if ((unsigned long)dst_idx+1 >= n) { 275 if ((unsigned long)dst_idx+1 >= n) {
255 // Single destination word 276 // Single destination word
256 if (last) 277 if (last)
257 first &= last; 278 first &= last;
279 d0 = FB_READL(src);
258 if (shift < 0) { 280 if (shift < 0) {
259 // Single source word 281 // Single source word
260 FB_WRITEL( comp( FB_READL(src)<<left, FB_READL(dst), first), dst); 282 d0 <<= left;
261 } else if (1+(unsigned long)src_idx >= n) { 283 } else if (1+(unsigned long)src_idx >= n) {
262 // Single source word 284 // Single source word
263 FB_WRITEL( comp( FB_READL(src)>>right, FB_READL(dst), first), dst); 285 d0 >>= right;
264 } else { 286 } else {
265 // 2 source words 287 // 2 source words
266 FB_WRITEL( comp( (FB_READL(src)>>right | FB_READL(src-1)<<left), FB_READL(dst), first), dst); 288 d1 = FB_READL(src - 1);
289 d1 = fb_rev_pixels_in_long(d1, bswapmask);
290 d0 = d0>>right | d1<<left;
267 } 291 }
292 d0 = fb_rev_pixels_in_long(d0, bswapmask);
293 FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
268 } else { 294 } else {
269 // Multiple destination words 295 // Multiple destination words
270 /** We must always remember the last value read, because in case 296 /** We must always remember the last value read, because in case
@@ -272,27 +298,30 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
272 1bpp), we always collect one full long for DST and that might 298 1bpp), we always collect one full long for DST and that might
273 overlap with the current long from SRC. We store this value in 299 overlap with the current long from SRC. We store this value in
274 'd0'. */ 300 'd0'. */
275 unsigned long d0, d1;
276 int m;
277 301
278 d0 = FB_READL(src--); 302 d0 = FB_READL(src--);
303 d0 = fb_rev_pixels_in_long(d0, bswapmask);
279 // Leading bits 304 // Leading bits
280 if (shift < 0) { 305 if (shift < 0) {
281 // Single source word 306 // Single source word
282 FB_WRITEL( comp( (d0 << left), FB_READL(dst), first), dst); 307 d1 = d0;
308 d0 <<= left;
283 } else { 309 } else {
284 // 2 source words 310 // 2 source words
285 d1 = FB_READL(src--); 311 d1 = FB_READL(src--);
286 FB_WRITEL( comp( (d0>>right | d1<<left), FB_READL(dst), first), dst); 312 d1 = fb_rev_pixels_in_long(d1, bswapmask);
287 d0 = d1; 313 d0 = d0>>right | d1<<left;
288 } 314 }
315 d0 = fb_rev_pixels_in_long(d0, bswapmask);
316 FB_WRITEL(comp(d0, FB_READL(dst), first), dst);
317 d0 = d1;
289 dst--; 318 dst--;
290 n -= dst_idx+1; 319 n -= dst_idx+1;
291 320
292 // Main chunk 321 // Main chunk
293 m = n % bits; 322 m = n % bits;
294 n /= bits; 323 n /= bits;
295 while (n >= 4) { 324 while ((n >= 4) && !bswapmask) {
296 d1 = FB_READL(src--); 325 d1 = FB_READL(src--);
297 FB_WRITEL(d0 >> right | d1 << left, dst--); 326 FB_WRITEL(d0 >> right | d1 << left, dst--);
298 d0 = d1; 327 d0 = d1;
@@ -309,7 +338,10 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
309 } 338 }
310 while (n--) { 339 while (n--) {
311 d1 = FB_READL(src--); 340 d1 = FB_READL(src--);
312 FB_WRITEL(d0 >> right | d1 << left, dst--); 341 d1 = fb_rev_pixels_in_long(d1, bswapmask);
342 d0 = d0 >> right | d1 << left;
343 d0 = fb_rev_pixels_in_long(d0, bswapmask);
344 FB_WRITEL(d0, dst--);
313 d0 = d1; 345 d0 = d1;
314 } 346 }
315 347
@@ -317,12 +349,16 @@ bitcpy_rev(unsigned long __iomem *dst, int dst_idx, const unsigned long __iomem
317 if (last) { 349 if (last) {
318 if (m <= left) { 350 if (m <= left) {
319 // Single source word 351 // Single source word
320 FB_WRITEL( comp(d0 >> right, FB_READL(dst), last), dst); 352 d0 >>= right;
321 } else { 353 } else {
322 // 2 source words 354 // 2 source words
323 d1 = FB_READL(src); 355 d1 = FB_READL(src);
324 FB_WRITEL( comp(d0>>right | d1<<left, FB_READL(dst), last), dst); 356 d1 = fb_rev_pixels_in_long(d1,
357 bswapmask);
358 d0 = d0>>right | d1<<left;
325 } 359 }
360 d0 = fb_rev_pixels_in_long(d0, bswapmask);
361 FB_WRITEL(comp(d0, FB_READL(dst), last), dst);
326 } 362 }
327 } 363 }
328 } 364 }
@@ -336,6 +372,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
336 unsigned long __iomem *dst = NULL, *src = NULL; 372 unsigned long __iomem *dst = NULL, *src = NULL;
337 int bits = BITS_PER_LONG, bytes = bits >> 3; 373 int bits = BITS_PER_LONG, bytes = bits >> 3;
338 int dst_idx = 0, src_idx = 0, rev_copy = 0; 374 int dst_idx = 0, src_idx = 0, rev_copy = 0;
375 u32 bswapmask = fb_compute_bswapmask(p);
339 376
340 if (p->state != FBINFO_STATE_RUNNING) 377 if (p->state != FBINFO_STATE_RUNNING)
341 return; 378 return;
@@ -368,7 +405,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
368 src += src_idx >> (ffs(bits) - 1); 405 src += src_idx >> (ffs(bits) - 1);
369 src_idx &= (bytes - 1); 406 src_idx &= (bytes - 1);
370 bitcpy_rev(dst, dst_idx, src, src_idx, bits, 407 bitcpy_rev(dst, dst_idx, src, src_idx, bits,
371 width*p->var.bits_per_pixel); 408 width*p->var.bits_per_pixel, bswapmask);
372 } 409 }
373 } else { 410 } else {
374 while (height--) { 411 while (height--) {
@@ -377,7 +414,7 @@ void cfb_copyarea(struct fb_info *p, const struct fb_copyarea *area)
377 src += src_idx >> (ffs(bits) - 1); 414 src += src_idx >> (ffs(bits) - 1);
378 src_idx &= (bytes - 1); 415 src_idx &= (bytes - 1);
379 bitcpy(dst, dst_idx, src, src_idx, bits, 416 bitcpy(dst, dst_idx, src, src_idx, bits,
380 width*p->var.bits_per_pixel); 417 width*p->var.bits_per_pixel, bswapmask);
381 dst_idx += bits_per_line; 418 dst_idx += bits_per_line;
382 src_idx += bits_per_line; 419 src_idx += bits_per_line;
383 } 420 }
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/cfbfillrect.c
index 71623b4f8ca2..23d70a12e4da 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/cfbfillrect.c
@@ -36,15 +36,16 @@
36 */ 36 */
37 37
38static void 38static void
39bitfill_aligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat, unsigned n, int bits) 39bitfill_aligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
40 unsigned n, int bits, u32 bswapmask)
40{ 41{
41 unsigned long first, last; 42 unsigned long first, last;
42 43
43 if (!n) 44 if (!n)
44 return; 45 return;
45 46
46 first = FB_SHIFT_HIGH(~0UL, dst_idx); 47 first = fb_shifted_pixels_mask_long(dst_idx, bswapmask);
47 last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); 48 last = ~fb_shifted_pixels_mask_long((dst_idx+n) % bits, bswapmask);
48 49
49 if (dst_idx+n <= bits) { 50 if (dst_idx+n <= bits) {
50 // Single word 51 // Single word
@@ -146,7 +147,8 @@ bitfill_unaligned(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
146 * Aligned pattern invert using 32/64-bit memory accesses 147 * Aligned pattern invert using 32/64-bit memory accesses
147 */ 148 */
148static void 149static void
149bitfill_aligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat, unsigned n, int bits) 150bitfill_aligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
151 unsigned n, int bits, u32 bswapmask)
150{ 152{
151 unsigned long val = pat, dat; 153 unsigned long val = pat, dat;
152 unsigned long first, last; 154 unsigned long first, last;
@@ -154,8 +156,8 @@ bitfill_aligned_rev(unsigned long __iomem *dst, int dst_idx, unsigned long pat,
154 if (!n) 156 if (!n)
155 return; 157 return;
156 158
157 first = FB_SHIFT_HIGH(~0UL, dst_idx); 159 first = fb_shifted_pixels_mask_long(dst_idx, bswapmask);
158 last = ~(FB_SHIFT_HIGH(~0UL, (dst_idx+n) % bits)); 160 last = ~fb_shifted_pixels_mask_long((dst_idx+n) % bits, bswapmask);
159 161
160 if (dst_idx+n <= bits) { 162 if (dst_idx+n <= bits) {
161 // Single word 163 // Single word
@@ -303,8 +305,10 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
303 if (p->fbops->fb_sync) 305 if (p->fbops->fb_sync)
304 p->fbops->fb_sync(p); 306 p->fbops->fb_sync(p);
305 if (!left) { 307 if (!left) {
308 u32 bswapmask = fb_compute_bswapmask(p);
306 void (*fill_op32)(unsigned long __iomem *dst, int dst_idx, 309 void (*fill_op32)(unsigned long __iomem *dst, int dst_idx,
307 unsigned long pat, unsigned n, int bits) = NULL; 310 unsigned long pat, unsigned n, int bits,
311 u32 bswapmask) = NULL;
308 312
309 switch (rect->rop) { 313 switch (rect->rop) {
310 case ROP_XOR: 314 case ROP_XOR:
@@ -321,7 +325,7 @@ void cfb_fillrect(struct fb_info *p, const struct fb_fillrect *rect)
321 while (height--) { 325 while (height--) {
322 dst += dst_idx >> (ffs(bits) - 1); 326 dst += dst_idx >> (ffs(bits) - 1);
323 dst_idx &= (bits - 1); 327 dst_idx &= (bits - 1);
324 fill_op32(dst, dst_idx, pat, width*bpp, bits); 328 fill_op32(dst, dst_idx, pat, width*bpp, bits, bswapmask);
325 dst_idx += p->fix.line_length*8; 329 dst_idx += p->fix.line_length*8;
326 } 330 }
327 } else { 331 } else {
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/cfbimgblt.c
index 261004473c8e..f598907b42ad 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/cfbimgblt.c
@@ -33,6 +33,7 @@
33#include <linux/string.h> 33#include <linux/string.h>
34#include <linux/fb.h> 34#include <linux/fb.h>
35#include <asm/types.h> 35#include <asm/types.h>
36#include "fb_draw.h"
36 37
37#define DEBUG 38#define DEBUG
38 39
@@ -87,6 +88,7 @@ static inline void color_imageblit(const struct fb_image *image,
87 u32 null_bits = 32 - bpp; 88 u32 null_bits = 32 - bpp;
88 u32 *palette = (u32 *) p->pseudo_palette; 89 u32 *palette = (u32 *) p->pseudo_palette;
89 const u8 *src = image->data; 90 const u8 *src = image->data;
91 u32 bswapmask = fb_compute_bswapmask(p);
90 92
91 dst2 = (u32 __iomem *) dst1; 93 dst2 = (u32 __iomem *) dst1;
92 for (i = image->height; i--; ) { 94 for (i = image->height; i--; ) {
@@ -96,7 +98,7 @@ static inline void color_imageblit(const struct fb_image *image,
96 val = 0; 98 val = 0;
97 99
98 if (start_index) { 100 if (start_index) {
99 u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0, start_index)); 101 u32 start_mask = ~fb_shifted_pixels_mask_u32(start_index, bswapmask);
100 val = FB_READL(dst) & start_mask; 102 val = FB_READL(dst) & start_mask;
101 shift = start_index; 103 shift = start_index;
102 } 104 }
@@ -107,7 +109,7 @@ static inline void color_imageblit(const struct fb_image *image,
107 else 109 else
108 color = *src; 110 color = *src;
109 color <<= FB_LEFT_POS(bpp); 111 color <<= FB_LEFT_POS(bpp);
110 val |= FB_SHIFT_HIGH(color, shift); 112 val |= FB_SHIFT_HIGH(color, shift ^ bswapmask);
111 if (shift >= null_bits) { 113 if (shift >= null_bits) {
112 FB_WRITEL(val, dst++); 114 FB_WRITEL(val, dst++);
113 115
@@ -119,7 +121,7 @@ static inline void color_imageblit(const struct fb_image *image,
119 src++; 121 src++;
120 } 122 }
121 if (shift) { 123 if (shift) {
122 u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift); 124 u32 end_mask = fb_shifted_pixels_mask_u32(shift, bswapmask);
123 125
124 FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); 126 FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
125 } 127 }
@@ -147,7 +149,8 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
147 u32 spitch = (image->width+7)/8; 149 u32 spitch = (image->width+7)/8;
148 const u8 *src = image->data, *s; 150 const u8 *src = image->data, *s;
149 u32 i, j, l; 151 u32 i, j, l;
150 152 u32 bswapmask = fb_compute_bswapmask(p);
153
151 dst2 = (u32 __iomem *) dst1; 154 dst2 = (u32 __iomem *) dst1;
152 fgcolor <<= FB_LEFT_POS(bpp); 155 fgcolor <<= FB_LEFT_POS(bpp);
153 bgcolor <<= FB_LEFT_POS(bpp); 156 bgcolor <<= FB_LEFT_POS(bpp);
@@ -161,7 +164,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
161 164
162 /* write leading bits */ 165 /* write leading bits */
163 if (start_index) { 166 if (start_index) {
164 u32 start_mask = ~(FB_SHIFT_HIGH(~(u32)0,start_index)); 167 u32 start_mask = ~fb_shifted_pixels_mask_u32(start_index, bswapmask);
165 val = FB_READL(dst) & start_mask; 168 val = FB_READL(dst) & start_mask;
166 shift = start_index; 169 shift = start_index;
167 } 170 }
@@ -169,7 +172,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
169 while (j--) { 172 while (j--) {
170 l--; 173 l--;
171 color = (*s & (1 << l)) ? fgcolor : bgcolor; 174 color = (*s & (1 << l)) ? fgcolor : bgcolor;
172 val |= FB_SHIFT_HIGH(color, shift); 175 val |= FB_SHIFT_HIGH(color, shift ^ bswapmask);
173 176
174 /* Did the bitshift spill bits to the next long? */ 177 /* Did the bitshift spill bits to the next long? */
175 if (shift >= null_bits) { 178 if (shift >= null_bits) {
@@ -184,7 +187,7 @@ static inline void slow_imageblit(const struct fb_image *image, struct fb_info *
184 187
185 /* write trailing bits */ 188 /* write trailing bits */
186 if (shift) { 189 if (shift) {
187 u32 end_mask = FB_SHIFT_HIGH(~(u32)0, shift); 190 u32 end_mask = fb_shifted_pixels_mask_u32(shift, bswapmask);
188 191
189 FB_WRITEL((FB_READL(dst) & end_mask) | val, dst); 192 FB_WRITEL((FB_READL(dst) & end_mask) | val, dst);
190 } 193 }
diff --git a/drivers/video/cirrusfb.c b/drivers/video/cirrusfb.c
index 8269d704ab2a..ce22bf5de350 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/cirrusfb.c
@@ -45,7 +45,6 @@
45#include <linux/delay.h> 45#include <linux/delay.h>
46#include <linux/fb.h> 46#include <linux/fb.h>
47#include <linux/init.h> 47#include <linux/init.h>
48#include <linux/selection.h>
49#include <asm/pgtable.h> 48#include <asm/pgtable.h>
50 49
51#ifdef CONFIG_ZORRO 50#ifdef CONFIG_ZORRO
@@ -59,14 +58,13 @@
59#endif 58#endif
60#ifdef CONFIG_PPC_PREP 59#ifdef CONFIG_PPC_PREP
61#include <asm/machdep.h> 60#include <asm/machdep.h>
62#define isPReP (machine_is(prep)) 61#define isPReP machine_is(prep)
63#else 62#else
64#define isPReP 0 63#define isPReP 0
65#endif 64#endif
66 65
67#include "video/vga.h" 66#include <video/vga.h>
68#include "video/cirrus.h" 67#include <video/cirrus.h>
69
70 68
71/***************************************************************** 69/*****************************************************************
72 * 70 *
@@ -82,7 +80,8 @@
82 80
83/* debug output */ 81/* debug output */
84#ifdef CIRRUSFB_DEBUG 82#ifdef CIRRUSFB_DEBUG
85#define DPRINTK(fmt, args...) printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args) 83#define DPRINTK(fmt, args...) \
84 printk(KERN_DEBUG "%s: " fmt, __FUNCTION__ , ## args)
86#else 85#else
87#define DPRINTK(fmt, args...) 86#define DPRINTK(fmt, args...)
88#endif 87#endif
@@ -90,19 +89,15 @@
90/* debugging assertions */ 89/* debugging assertions */
91#ifndef CIRRUSFB_NDEBUG 90#ifndef CIRRUSFB_NDEBUG
92#define assert(expr) \ 91#define assert(expr) \
93 if(!(expr)) { \ 92 if (!(expr)) { \
94 printk( "Assertion failed! %s,%s,%s,line=%d\n",\ 93 printk("Assertion failed! %s,%s,%s,line=%d\n", \
95 #expr,__FILE__,__FUNCTION__,__LINE__); \ 94 #expr, __FILE__, __FUNCTION__, __LINE__); \
96 } 95 }
97#else 96#else
98#define assert(expr) 97#define assert(expr)
99#endif 98#endif
100 99
101#define MB_ (1024*1024) 100#define MB_ (1024 * 1024)
102#define KB_ (1024)
103
104#define MAX_NUM_BOARDS 7
105
106 101
107/***************************************************************** 102/*****************************************************************
108 * 103 *
@@ -111,7 +106,7 @@
111 */ 106 */
112 107
113/* board types */ 108/* board types */
114typedef enum { 109enum cirrus_board {
115 BT_NONE = 0, 110 BT_NONE = 0,
116 BT_SD64, 111 BT_SD64,
117 BT_PICCOLO, 112 BT_PICCOLO,
@@ -121,13 +116,12 @@ typedef enum {
121 BT_ALPINE, /* GD543x/4x */ 116 BT_ALPINE, /* GD543x/4x */
122 BT_GD5480, 117 BT_GD5480,
123 BT_LAGUNA, /* GD546x */ 118 BT_LAGUNA, /* GD546x */
124} cirrusfb_board_t; 119};
125
126 120
127/* 121/*
128 * per-board-type information, used for enumerating and abstracting 122 * per-board-type information, used for enumerating and abstracting
129 * chip-specific information 123 * chip-specific information
130 * NOTE: MUST be in the same order as cirrusfb_board_t in order to 124 * NOTE: MUST be in the same order as enum cirrus_board in order to
131 * use direct indexing on this array 125 * use direct indexing on this array
132 * NOTE: '__initdata' cannot be used as some of this info 126 * NOTE: '__initdata' cannot be used as some of this info
133 * is required at runtime. Maybe separate into an init-only and 127 * is required at runtime. Maybe separate into an init-only and
@@ -139,7 +133,8 @@ static const struct cirrusfb_board_info_rec {
139 /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */ 133 /* for 1/4bpp, 8bpp 15/16bpp, 24bpp, 32bpp - numbers from xorg code */
140 bool init_sr07 : 1; /* init SR07 during init_vgachip() */ 134 bool init_sr07 : 1; /* init SR07 during init_vgachip() */
141 bool init_sr1f : 1; /* write SR1F during init_vgachip() */ 135 bool init_sr1f : 1; /* write SR1F during init_vgachip() */
142 bool scrn_start_bit19 : 1; /* construct bit 19 of screen start address */ 136 /* construct bit 19 of screen start address */
137 bool scrn_start_bit19 : 1;
143 138
144 /* initial SR07 value, then for each mode */ 139 /* initial SR07 value, then for each mode */
145 unsigned char sr07; 140 unsigned char sr07;
@@ -261,30 +256,28 @@ static const struct cirrusfb_board_info_rec {
261 } 256 }
262}; 257};
263 258
264
265#ifdef CONFIG_PCI 259#ifdef CONFIG_PCI
266#define CHIP(id, btype) \ 260#define CHIP(id, btype) \
267 { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) } 261 { PCI_VENDOR_ID_CIRRUS, id, PCI_ANY_ID, PCI_ANY_ID, 0, 0, (btype) }
268 262
269static struct pci_device_id cirrusfb_pci_table[] = { 263static struct pci_device_id cirrusfb_pci_table[] = {
270 CHIP( PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE ), 264 CHIP(PCI_DEVICE_ID_CIRRUS_5436, BT_ALPINE),
271 CHIP( PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE ), 265 CHIP(PCI_DEVICE_ID_CIRRUS_5434_8, BT_ALPINE),
272 CHIP( PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE ), 266 CHIP(PCI_DEVICE_ID_CIRRUS_5434_4, BT_ALPINE),
273 CHIP( PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE ), /* GD-5440 is same id */ 267 CHIP(PCI_DEVICE_ID_CIRRUS_5430, BT_ALPINE), /* GD-5440 is same id */
274 CHIP( PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE ), 268 CHIP(PCI_DEVICE_ID_CIRRUS_7543, BT_ALPINE),
275 CHIP( PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE ), 269 CHIP(PCI_DEVICE_ID_CIRRUS_7548, BT_ALPINE),
276 CHIP( PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480 ), /* MacPicasso likely */ 270 CHIP(PCI_DEVICE_ID_CIRRUS_5480, BT_GD5480), /* MacPicasso likely */
277 CHIP( PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4 ), /* Picasso 4 is 5446 */ 271 CHIP(PCI_DEVICE_ID_CIRRUS_5446, BT_PICASSO4), /* Picasso 4 is 5446 */
278 CHIP( PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA ), /* CL Laguna */ 272 CHIP(PCI_DEVICE_ID_CIRRUS_5462, BT_LAGUNA), /* CL Laguna */
279 CHIP( PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA ), /* CL Laguna 3D */ 273 CHIP(PCI_DEVICE_ID_CIRRUS_5464, BT_LAGUNA), /* CL Laguna 3D */
280 CHIP( PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA ), /* CL Laguna 3DA*/ 274 CHIP(PCI_DEVICE_ID_CIRRUS_5465, BT_LAGUNA), /* CL Laguna 3DA*/
281 { 0, } 275 { 0, }
282}; 276};
283MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table); 277MODULE_DEVICE_TABLE(pci, cirrusfb_pci_table);
284#undef CHIP 278#undef CHIP
285#endif /* CONFIG_PCI */ 279#endif /* CONFIG_PCI */
286 280
287
288#ifdef CONFIG_ZORRO 281#ifdef CONFIG_ZORRO
289static const struct zorro_device_id cirrusfb_zorro_table[] = { 282static const struct zorro_device_id cirrusfb_zorro_table[] = {
290 { 283 {
@@ -294,7 +287,7 @@ static const struct zorro_device_id cirrusfb_zorro_table[] = {
294 .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM, 287 .id = ZORRO_PROD_HELFRICH_PICCOLO_RAM,
295 .driver_data = BT_PICCOLO, 288 .driver_data = BT_PICCOLO,
296 }, { 289 }, {
297 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM, 290 .id = ZORRO_PROD_VILLAGE_TRONIC_PICASSO_II_II_PLUS_RAM,
298 .driver_data = BT_PICASSO, 291 .driver_data = BT_PICASSO,
299 }, { 292 }, {
300 .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM, 293 .id = ZORRO_PROD_GVP_EGS_28_24_SPECTRUM_RAM,
@@ -333,12 +326,7 @@ static const struct {
333}; 326};
334#endif /* CONFIG_ZORRO */ 327#endif /* CONFIG_ZORRO */
335 328
336
337struct cirrusfb_regs { 329struct cirrusfb_regs {
338 __u32 line_length; /* in BYTES! */
339 __u32 visual;
340 __u32 type;
341
342 long freq; 330 long freq;
343 long nom; 331 long nom;
344 long den; 332 long den;
@@ -364,37 +352,23 @@ struct cirrusfb_regs {
364 long VertBlankEnd; 352 long VertBlankEnd;
365}; 353};
366 354
367
368
369#ifdef CIRRUSFB_DEBUG 355#ifdef CIRRUSFB_DEBUG
370typedef enum { 356enum cirrusfb_dbg_reg_class {
371 CRT, 357 CRT,
372 SEQ 358 SEQ
373} cirrusfb_dbg_reg_class_t; 359};
374#endif /* CIRRUSFB_DEBUG */ 360#endif /* CIRRUSFB_DEBUG */
375
376
377
378 361
379/* info about board */ 362/* info about board */
380struct cirrusfb_info { 363struct cirrusfb_info {
381 struct fb_info *info;
382
383 u8 __iomem *fbmem;
384 u8 __iomem *regbase; 364 u8 __iomem *regbase;
385 u8 __iomem *mem; 365 enum cirrus_board btype;
386 unsigned long size;
387 cirrusfb_board_t btype;
388 unsigned char SFR; /* Shadow of special function register */ 366 unsigned char SFR; /* Shadow of special function register */
389 367
390 unsigned long fbmem_phys;
391 unsigned long fbregs_phys;
392
393 struct cirrusfb_regs currentmode; 368 struct cirrusfb_regs currentmode;
394 int blank_mode; 369 int blank_mode;
395 370
396 u32 pseudo_palette[16]; 371 u32 pseudo_palette[16];
397 struct { u8 red, green, blue, pad; } palette[256];
398 372
399#ifdef CONFIG_ZORRO 373#ifdef CONFIG_ZORRO
400 struct zorro_dev *zdev; 374 struct zorro_dev *zdev;
@@ -402,12 +376,11 @@ struct cirrusfb_info {
402#ifdef CONFIG_PCI 376#ifdef CONFIG_PCI
403 struct pci_dev *pdev; 377 struct pci_dev *pdev;
404#endif 378#endif
405 void (*unmap)(struct cirrusfb_info *cinfo); 379 void (*unmap)(struct fb_info *info);
406}; 380};
407 381
408
409static unsigned cirrusfb_def_mode = 1; 382static unsigned cirrusfb_def_mode = 1;
410static int noaccel = 0; 383static int noaccel;
411 384
412/* 385/*
413 * Predefined Video Modes 386 * Predefined Video Modes
@@ -441,7 +414,7 @@ static const struct {
441 .lower_margin = 8, 414 .lower_margin = 8,
442 .hsync_len = 96, 415 .hsync_len = 96,
443 .vsync_len = 4, 416 .vsync_len = 4,
444 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 417 .sync = FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
445 .vmode = FB_VMODE_NONINTERLACED 418 .vmode = FB_VMODE_NONINTERLACED
446 } 419 }
447 }, { 420 }, {
@@ -502,27 +475,29 @@ static const struct {
502/****************************************************************************/ 475/****************************************************************************/
503/**** BEGIN PROTOTYPES ******************************************************/ 476/**** BEGIN PROTOTYPES ******************************************************/
504 477
505
506/*--- Interface used by the world ------------------------------------------*/ 478/*--- Interface used by the world ------------------------------------------*/
507static int cirrusfb_init (void); 479static int cirrusfb_init(void);
508#ifndef MODULE 480#ifndef MODULE
509static int cirrusfb_setup (char *options); 481static int cirrusfb_setup(char *options);
510#endif 482#endif
511 483
512static int cirrusfb_open (struct fb_info *info, int user); 484static int cirrusfb_open(struct fb_info *info, int user);
513static int cirrusfb_release (struct fb_info *info, int user); 485static int cirrusfb_release(struct fb_info *info, int user);
514static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green, 486static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
515 unsigned blue, unsigned transp, 487 unsigned blue, unsigned transp,
516 struct fb_info *info); 488 struct fb_info *info);
517static int cirrusfb_check_var (struct fb_var_screeninfo *var, 489static int cirrusfb_check_var(struct fb_var_screeninfo *var,
518 struct fb_info *info); 490 struct fb_info *info);
519static int cirrusfb_set_par (struct fb_info *info); 491static int cirrusfb_set_par(struct fb_info *info);
520static int cirrusfb_pan_display (struct fb_var_screeninfo *var, 492static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
521 struct fb_info *info); 493 struct fb_info *info);
522static int cirrusfb_blank (int blank_mode, struct fb_info *info); 494static int cirrusfb_blank(int blank_mode, struct fb_info *info);
523static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region); 495static void cirrusfb_fillrect(struct fb_info *info,
524static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area); 496 const struct fb_fillrect *region);
525static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image); 497static void cirrusfb_copyarea(struct fb_info *info,
498 const struct fb_copyarea *area);
499static void cirrusfb_imageblit(struct fb_info *info,
500 const struct fb_image *image);
526 501
527/* function table of the above functions */ 502/* function table of the above functions */
528static struct fb_ops cirrusfb_ops = { 503static struct fb_ops cirrusfb_ops = {
@@ -540,68 +515,68 @@ static struct fb_ops cirrusfb_ops = {
540}; 515};
541 516
542/*--- Hardware Specific Routines -------------------------------------------*/ 517/*--- Hardware Specific Routines -------------------------------------------*/
543static int cirrusfb_decode_var (const struct fb_var_screeninfo *var, 518static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
544 struct cirrusfb_regs *regs, 519 struct cirrusfb_regs *regs,
545 const struct fb_info *info); 520 struct fb_info *info);
546/*--- Internal routines ----------------------------------------------------*/ 521/*--- Internal routines ----------------------------------------------------*/
547static void init_vgachip (struct cirrusfb_info *cinfo); 522static void init_vgachip(struct fb_info *info);
548static void switch_monitor (struct cirrusfb_info *cinfo, int on); 523static void switch_monitor(struct cirrusfb_info *cinfo, int on);
549static void WGen (const struct cirrusfb_info *cinfo, 524static void WGen(const struct cirrusfb_info *cinfo,
550 int regnum, unsigned char val); 525 int regnum, unsigned char val);
551static unsigned char RGen (const struct cirrusfb_info *cinfo, int regnum); 526static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum);
552static void AttrOn (const struct cirrusfb_info *cinfo); 527static void AttrOn(const struct cirrusfb_info *cinfo);
553static void WHDR (const struct cirrusfb_info *cinfo, unsigned char val); 528static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val);
554static void WSFR (struct cirrusfb_info *cinfo, unsigned char val); 529static void WSFR(struct cirrusfb_info *cinfo, unsigned char val);
555static void WSFR2 (struct cirrusfb_info *cinfo, unsigned char val); 530static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val);
556static void WClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red, 531static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum,
557 unsigned char green, 532 unsigned char red, unsigned char green, unsigned char blue);
558 unsigned char blue);
559#if 0 533#if 0
560static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red, 534static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum,
561 unsigned char *green, 535 unsigned char *red, unsigned char *green,
562 unsigned char *blue); 536 unsigned char *blue);
563#endif 537#endif
564static void cirrusfb_WaitBLT (u8 __iomem *regbase); 538static void cirrusfb_WaitBLT(u8 __iomem *regbase);
565static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel, 539static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
566 u_short curx, u_short cury, 540 u_short curx, u_short cury,
567 u_short destx, u_short desty, 541 u_short destx, u_short desty,
568 u_short width, u_short height, 542 u_short width, u_short height,
569 u_short line_length); 543 u_short line_length);
570static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel, 544static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
571 u_short x, u_short y, 545 u_short x, u_short y,
572 u_short width, u_short height, 546 u_short width, u_short height,
573 u_char color, u_short line_length); 547 u_char color, u_short line_length);
574 548
575static void bestclock (long freq, long *best, 549static void bestclock(long freq, long *best,
576 long *nom, long *den, 550 long *nom, long *den,
577 long *div, long maxfreq); 551 long *div, long maxfreq);
578 552
579#ifdef CIRRUSFB_DEBUG 553#ifdef CIRRUSFB_DEBUG
580static void cirrusfb_dump (void); 554static void cirrusfb_dump(void);
581static void cirrusfb_dbg_reg_dump (caddr_t regbase); 555static void cirrusfb_dbg_reg_dump(caddr_t regbase);
582static void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_class,...); 556static void cirrusfb_dbg_print_regs(caddr_t regbase,
583static void cirrusfb_dbg_print_byte (const char *name, unsigned char val); 557 enum cirrusfb_dbg_reg_class reg_class, ...);
558static void cirrusfb_dbg_print_byte(const char *name, unsigned char val);
584#endif /* CIRRUSFB_DEBUG */ 559#endif /* CIRRUSFB_DEBUG */
585 560
586/*** END PROTOTYPES ********************************************************/ 561/*** END PROTOTYPES ********************************************************/
587/*****************************************************************************/ 562/*****************************************************************************/
588/*** BEGIN Interface Used by the World ***************************************/ 563/*** BEGIN Interface Used by the World ***************************************/
589 564
590static int opencount = 0; 565static int opencount;
591 566
592/*--- Open /dev/fbx ---------------------------------------------------------*/ 567/*--- Open /dev/fbx ---------------------------------------------------------*/
593static int cirrusfb_open (struct fb_info *info, int user) 568static int cirrusfb_open(struct fb_info *info, int user)
594{ 569{
595 if (opencount++ == 0) 570 if (opencount++ == 0)
596 switch_monitor (info->par, 1); 571 switch_monitor(info->par, 1);
597 return 0; 572 return 0;
598} 573}
599 574
600/*--- Close /dev/fbx --------------------------------------------------------*/ 575/*--- Close /dev/fbx --------------------------------------------------------*/
601static int cirrusfb_release (struct fb_info *info, int user) 576static int cirrusfb_release(struct fb_info *info, int user)
602{ 577{
603 if (--opencount == 0) 578 if (--opencount == 0)
604 switch_monitor (info->par, 0); 579 switch_monitor(info->par, 0);
605 return 0; 580 return 0;
606} 581}
607 582
@@ -610,11 +585,11 @@ static int cirrusfb_release (struct fb_info *info, int user)
610/**** BEGIN Hardware specific Routines **************************************/ 585/**** BEGIN Hardware specific Routines **************************************/
611 586
612/* Get a good MCLK value */ 587/* Get a good MCLK value */
613static long cirrusfb_get_mclk (long freq, int bpp, long *div) 588static long cirrusfb_get_mclk(long freq, int bpp, long *div)
614{ 589{
615 long mclk; 590 long mclk;
616 591
617 assert (div != NULL); 592 assert(div != NULL);
618 593
619 /* Calculate MCLK, in case VCLK is high enough to require > 50MHz. 594 /* Calculate MCLK, in case VCLK is high enough to require > 50MHz.
620 * Assume a 64-bit data path for now. The formula is: 595 * Assume a 64-bit data path for now. The formula is:
@@ -624,23 +599,23 @@ static long cirrusfb_get_mclk (long freq, int bpp, long *div)
624 mclk = (mclk * 12) / 10; 599 mclk = (mclk * 12) / 10;
625 if (mclk < 50000) 600 if (mclk < 50000)
626 mclk = 50000; 601 mclk = 50000;
627 DPRINTK ("Use MCLK of %ld kHz\n", mclk); 602 DPRINTK("Use MCLK of %ld kHz\n", mclk);
628 603
629 /* Calculate value for SR1F. Multiply by 2 so we can round up. */ 604 /* Calculate value for SR1F. Multiply by 2 so we can round up. */
630 mclk = ((mclk * 16) / 14318); 605 mclk = ((mclk * 16) / 14318);
631 mclk = (mclk + 1) / 2; 606 mclk = (mclk + 1) / 2;
632 DPRINTK ("Set SR1F[5:0] to 0x%lx\n", mclk); 607 DPRINTK("Set SR1F[5:0] to 0x%lx\n", mclk);
633 608
634 /* Determine if we should use MCLK instead of VCLK, and if so, what we 609 /* Determine if we should use MCLK instead of VCLK, and if so, what we
635 * should divide it by to get VCLK */ 610 * should divide it by to get VCLK */
636 switch (freq) { 611 switch (freq) {
637 case 24751 ... 25249: 612 case 24751 ... 25249:
638 *div = 2; 613 *div = 2;
639 DPRINTK ("Using VCLK = MCLK/2\n"); 614 DPRINTK("Using VCLK = MCLK/2\n");
640 break; 615 break;
641 case 49501 ... 50499: 616 case 49501 ... 50499:
642 *div = 1; 617 *div = 1;
643 DPRINTK ("Using VCLK = MCLK\n"); 618 DPRINTK("Using VCLK = MCLK\n");
644 break; 619 break;
645 default: 620 default:
646 *div = 0; 621 *div = 0;
@@ -653,7 +628,6 @@ static long cirrusfb_get_mclk (long freq, int bpp, long *div)
653static int cirrusfb_check_var(struct fb_var_screeninfo *var, 628static int cirrusfb_check_var(struct fb_var_screeninfo *var,
654 struct fb_info *info) 629 struct fb_info *info)
655{ 630{
656 struct cirrusfb_info *cinfo = info->par;
657 int nom, den; /* translyting from pixels->bytes */ 631 int nom, den; /* translyting from pixels->bytes */
658 int yres, i; 632 int yres, i;
659 static struct { int xres, yres; } modes[] = 633 static struct { int xres, yres; } modes[] =
@@ -665,63 +639,55 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
665 { -1, -1 } }; 639 { -1, -1 } };
666 640
667 switch (var->bits_per_pixel) { 641 switch (var->bits_per_pixel) {
668 case 0 ... 1: 642 case 1:
669 var->bits_per_pixel = 1;
670 nom = 4; 643 nom = 4;
671 den = 8; 644 den = 8;
672 break; /* 8 pixel per byte, only 1/4th of mem usable */ 645 break; /* 8 pixel per byte, only 1/4th of mem usable */
673 case 2 ... 8: 646 case 8:
674 var->bits_per_pixel = 8; 647 case 16:
675 nom = 1; 648 case 24:
649 case 32:
650 nom = var->bits_per_pixel / 8;
676 den = 1; 651 den = 1;
677 break; /* 1 pixel == 1 byte */ 652 break; /* 1 pixel == 1 byte */
678 case 9 ... 16:
679 var->bits_per_pixel = 16;
680 nom = 2;
681 den = 1;
682 break; /* 2 bytes per pixel */
683 case 17 ... 24:
684 var->bits_per_pixel = 24;
685 nom = 3;
686 den = 1;
687 break; /* 3 bytes per pixel */
688 case 25 ... 32:
689 var->bits_per_pixel = 32;
690 nom = 4;
691 den = 1;
692 break; /* 4 bytes per pixel */
693 default: 653 default:
694 printk ("cirrusfb: mode %dx%dx%d rejected...color depth not supported.\n", 654 printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
655 "color depth not supported.\n",
695 var->xres, var->yres, var->bits_per_pixel); 656 var->xres, var->yres, var->bits_per_pixel);
696 DPRINTK ("EXIT - EINVAL error\n"); 657 DPRINTK("EXIT - EINVAL error\n");
697 return -EINVAL; 658 return -EINVAL;
698 } 659 }
699 660
700 if (var->xres * nom / den * var->yres > cinfo->size) { 661 if (var->xres * nom / den * var->yres > info->screen_size) {
701 printk ("cirrusfb: mode %dx%dx%d rejected...resolution too high to fit into video memory!\n", 662 printk(KERN_ERR "cirrusfb: mode %dx%dx%d rejected..."
663 "resolution too high to fit into video memory!\n",
702 var->xres, var->yres, var->bits_per_pixel); 664 var->xres, var->yres, var->bits_per_pixel);
703 DPRINTK ("EXIT - EINVAL error\n"); 665 DPRINTK("EXIT - EINVAL error\n");
704 return -EINVAL; 666 return -EINVAL;
705 } 667 }
706 668
707 /* use highest possible virtual resolution */ 669 /* use highest possible virtual resolution */
708 if (var->xres_virtual == -1 && 670 if (var->xres_virtual == -1 &&
709 var->yres_virtual == -1) { 671 var->yres_virtual == -1) {
710 printk ("cirrusfb: using maximum available virtual resolution\n"); 672 printk(KERN_INFO
673 "cirrusfb: using maximum available virtual resolution\n");
711 for (i = 0; modes[i].xres != -1; i++) { 674 for (i = 0; modes[i].xres != -1; i++) {
712 if (modes[i].xres * nom / den * modes[i].yres < cinfo->size / 2) 675 int size = modes[i].xres * nom / den * modes[i].yres;
676 if (size < info->screen_size / 2)
713 break; 677 break;
714 } 678 }
715 if (modes[i].xres == -1) { 679 if (modes[i].xres == -1) {
716 printk ("cirrusfb: could not find a virtual resolution that fits into video memory!!\n"); 680 printk(KERN_ERR "cirrusfb: could not find a virtual "
717 DPRINTK ("EXIT - EINVAL error\n"); 681 "resolution that fits into video memory!!\n");
682 DPRINTK("EXIT - EINVAL error\n");
718 return -EINVAL; 683 return -EINVAL;
719 } 684 }
720 var->xres_virtual = modes[i].xres; 685 var->xres_virtual = modes[i].xres;
721 var->yres_virtual = modes[i].yres; 686 var->yres_virtual = modes[i].yres;
722 687
723 printk ("cirrusfb: virtual resolution set to maximum of %dx%d\n", 688 printk(KERN_INFO "cirrusfb: virtual resolution set to "
724 var->xres_virtual, var->yres_virtual); 689 "maximum of %dx%d\n", var->xres_virtual,
690 var->yres_virtual);
725 } 691 }
726 692
727 if (var->xres_virtual < var->xres) 693 if (var->xres_virtual < var->xres)
@@ -744,23 +710,19 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
744 case 1: 710 case 1:
745 var->red.offset = 0; 711 var->red.offset = 0;
746 var->red.length = 1; 712 var->red.length = 1;
747 var->green.offset = 0; 713 var->green = var->red;
748 var->green.length = 1; 714 var->blue = var->red;
749 var->blue.offset = 0;
750 var->blue.length = 1;
751 break; 715 break;
752 716
753 case 8: 717 case 8:
754 var->red.offset = 0; 718 var->red.offset = 0;
755 var->red.length = 6; 719 var->red.length = 6;
756 var->green.offset = 0; 720 var->green = var->red;
757 var->green.length = 6; 721 var->blue = var->red;
758 var->blue.offset = 0;
759 var->blue.length = 6;
760 break; 722 break;
761 723
762 case 16: 724 case 16:
763 if(isPReP) { 725 if (isPReP) {
764 var->red.offset = 2; 726 var->red.offset = 2;
765 var->green.offset = -3; 727 var->green.offset = -3;
766 var->blue.offset = 8; 728 var->blue.offset = 8;
@@ -775,22 +737,8 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
775 break; 737 break;
776 738
777 case 24: 739 case 24:
778 if(isPReP) {
779 var->red.offset = 8;
780 var->green.offset = 16;
781 var->blue.offset = 24;
782 } else {
783 var->red.offset = 16;
784 var->green.offset = 8;
785 var->blue.offset = 0;
786 }
787 var->red.length = 8;
788 var->green.length = 8;
789 var->blue.length = 8;
790 break;
791
792 case 32: 740 case 32:
793 if(isPReP) { 741 if (isPReP) {
794 var->red.offset = 8; 742 var->red.offset = 8;
795 var->green.offset = 16; 743 var->green.offset = 16;
796 var->blue.offset = 24; 744 var->blue.offset = 24;
@@ -825,54 +773,42 @@ static int cirrusfb_check_var(struct fb_var_screeninfo *var,
825 yres = (yres + 1) / 2; 773 yres = (yres + 1) / 2;
826 774
827 if (yres >= 1280) { 775 if (yres >= 1280) {
828 printk (KERN_WARNING "cirrusfb: ERROR: VerticalTotal >= 1280; special treatment required! (TODO)\n"); 776 printk(KERN_ERR "cirrusfb: ERROR: VerticalTotal >= 1280; "
829 DPRINTK ("EXIT - EINVAL error\n"); 777 "special treatment required! (TODO)\n");
778 DPRINTK("EXIT - EINVAL error\n");
830 return -EINVAL; 779 return -EINVAL;
831 } 780 }
832 781
833 return 0; 782 return 0;
834} 783}
835 784
836static int cirrusfb_decode_var (const struct fb_var_screeninfo *var, 785static int cirrusfb_decode_var(const struct fb_var_screeninfo *var,
837 struct cirrusfb_regs *regs, 786 struct cirrusfb_regs *regs,
838 const struct fb_info *info) 787 struct fb_info *info)
839{ 788{
840 long freq; 789 long freq;
841 long maxclock; 790 long maxclock;
842 int maxclockidx = 0; 791 int maxclockidx = var->bits_per_pixel >> 3;
843 struct cirrusfb_info *cinfo = info->par; 792 struct cirrusfb_info *cinfo = info->par;
844 int xres, hfront, hsync, hback; 793 int xres, hfront, hsync, hback;
845 int yres, vfront, vsync, vback; 794 int yres, vfront, vsync, vback;
846 795
847 switch(var->bits_per_pixel) { 796 switch (var->bits_per_pixel) {
848 case 1: 797 case 1:
849 regs->line_length = var->xres_virtual / 8; 798 info->fix.line_length = var->xres_virtual / 8;
850 regs->visual = FB_VISUAL_MONO10; 799 info->fix.visual = FB_VISUAL_MONO10;
851 maxclockidx = 0;
852 break; 800 break;
853 801
854 case 8: 802 case 8:
855 regs->line_length = var->xres_virtual; 803 info->fix.line_length = var->xres_virtual;
856 regs->visual = FB_VISUAL_PSEUDOCOLOR; 804 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
857 maxclockidx = 1;
858 break; 805 break;
859 806
860 case 16: 807 case 16:
861 regs->line_length = var->xres_virtual * 2;
862 regs->visual = FB_VISUAL_DIRECTCOLOR;
863 maxclockidx = 2;
864 break;
865
866 case 24: 808 case 24:
867 regs->line_length = var->xres_virtual * 3;
868 regs->visual = FB_VISUAL_DIRECTCOLOR;
869 maxclockidx = 3;
870 break;
871
872 case 32: 809 case 32:
873 regs->line_length = var->xres_virtual * 4; 810 info->fix.line_length = var->xres_virtual * maxclockidx;
874 regs->visual = FB_VISUAL_DIRECTCOLOR; 811 info->fix.visual = FB_VISUAL_DIRECTCOLOR;
875 maxclockidx = 4;
876 break; 812 break;
877 813
878 default: 814 default:
@@ -882,12 +818,12 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
882 break; 818 break;
883 } 819 }
884 820
885 regs->type = FB_TYPE_PACKED_PIXELS; 821 info->fix.type = FB_TYPE_PACKED_PIXELS;
886 822
887 /* convert from ps to kHz */ 823 /* convert from ps to kHz */
888 freq = 1000000000 / var->pixclock; 824 freq = PICOS2KHZ(var->pixclock);
889 825
890 DPRINTK ("desired pixclock: %ld kHz\n", freq); 826 DPRINTK("desired pixclock: %ld kHz\n", freq);
891 827
892 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx]; 828 maxclock = cirrusfb_board_info[cinfo->btype].maxclock[maxclockidx];
893 regs->multiplexing = 0; 829 regs->multiplexing = 0;
@@ -902,8 +838,9 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
902 break; 838 break;
903 839
904 default: 840 default:
905 printk (KERN_WARNING "cirrusfb: ERROR: Frequency greater than maxclock (%ld kHz)\n", maxclock); 841 printk(KERN_ERR "cirrusfb: Frequency greater "
906 DPRINTK ("EXIT - return -EINVAL\n"); 842 "than maxclock (%ld kHz)\n", maxclock);
843 DPRINTK("EXIT - return -EINVAL\n");
907 return -EINVAL; 844 return -EINVAL;
908 } 845 }
909 } 846 }
@@ -914,14 +851,16 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
914 case 16: 851 case 16:
915 case 32: 852 case 32:
916 if (regs->HorizRes <= 800) 853 if (regs->HorizRes <= 800)
917 freq /= 2; /* Xbh has this type of clock for 32-bit */ 854 /* Xbh has this type of clock for 32-bit */
855 freq /= 2;
918 break; 856 break;
919 } 857 }
920#endif 858#endif
921 859
922 bestclock (freq, &regs->freq, &regs->nom, &regs->den, &regs->div, 860 bestclock(freq, &regs->freq, &regs->nom, &regs->den, &regs->div,
923 maxclock); 861 maxclock);
924 regs->mclk = cirrusfb_get_mclk (freq, var->bits_per_pixel, &regs->divMCLK); 862 regs->mclk = cirrusfb_get_mclk(freq, var->bits_per_pixel,
863 &regs->divMCLK);
925 864
926 xres = var->xres; 865 xres = var->xres;
927 hfront = var->right_margin; 866 hfront = var->right_margin;
@@ -948,7 +887,8 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
948 regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5; 887 regs->HorizTotal = (xres + hfront + hsync + hback) / 8 - 5;
949 regs->HorizDispEnd = xres / 8 - 1; 888 regs->HorizDispEnd = xres / 8 - 1;
950 regs->HorizBlankStart = xres / 8; 889 regs->HorizBlankStart = xres / 8;
951 regs->HorizBlankEnd = regs->HorizTotal + 5; /* does not count with "-5" */ 890 /* does not count with "-5" */
891 regs->HorizBlankEnd = regs->HorizTotal + 5;
952 regs->HorizSyncStart = (xres + hfront) / 8 + 1; 892 regs->HorizSyncStart = (xres + hfront) / 8 + 1;
953 regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1; 893 regs->HorizSyncEnd = (xres + hfront + hsync) / 8 + 1;
954 894
@@ -976,23 +916,23 @@ static int cirrusfb_decode_var (const struct fb_var_screeninfo *var,
976 return 0; 916 return 0;
977} 917}
978 918
979 919static void cirrusfb_set_mclk(const struct cirrusfb_info *cinfo, int val,
980static void cirrusfb_set_mclk (const struct cirrusfb_info *cinfo, int val, int div) 920 int div)
981{ 921{
982 assert (cinfo != NULL); 922 assert(cinfo != NULL);
983 923
984 if (div == 2) { 924 if (div == 2) {
985 /* VCLK = MCLK/2 */ 925 /* VCLK = MCLK/2 */
986 unsigned char old = vga_rseq (cinfo->regbase, CL_SEQR1E); 926 unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
987 vga_wseq (cinfo->regbase, CL_SEQR1E, old | 0x1); 927 vga_wseq(cinfo->regbase, CL_SEQR1E, old | 0x1);
988 vga_wseq (cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f)); 928 vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
989 } else if (div == 1) { 929 } else if (div == 1) {
990 /* VCLK = MCLK */ 930 /* VCLK = MCLK */
991 unsigned char old = vga_rseq (cinfo->regbase, CL_SEQR1E); 931 unsigned char old = vga_rseq(cinfo->regbase, CL_SEQR1E);
992 vga_wseq (cinfo->regbase, CL_SEQR1E, old & ~0x1); 932 vga_wseq(cinfo->regbase, CL_SEQR1E, old & ~0x1);
993 vga_wseq (cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f)); 933 vga_wseq(cinfo->regbase, CL_SEQR1F, 0x40 | (val & 0x3f));
994 } else { 934 } else {
995 vga_wseq (cinfo->regbase, CL_SEQR1F, val & 0x3f); 935 vga_wseq(cinfo->regbase, CL_SEQR1F, val & 0x3f);
996 } 936 }
997} 937}
998 938
@@ -1001,7 +941,7 @@ static void cirrusfb_set_mclk (const struct cirrusfb_info *cinfo, int val, int d
1001 941
1002 actually writes the values for a new video mode into the hardware, 942 actually writes the values for a new video mode into the hardware,
1003**************************************************************************/ 943**************************************************************************/
1004static int cirrusfb_set_par_foo (struct fb_info *info) 944static int cirrusfb_set_par_foo(struct fb_info *info)
1005{ 945{
1006 struct cirrusfb_info *cinfo = info->par; 946 struct cirrusfb_info *cinfo = info->par;
1007 struct fb_var_screeninfo *var = &info->var; 947 struct fb_var_screeninfo *var = &info->var;
@@ -1011,15 +951,15 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1011 int offset = 0, err; 951 int offset = 0, err;
1012 const struct cirrusfb_board_info_rec *bi; 952 const struct cirrusfb_board_info_rec *bi;
1013 953
1014 DPRINTK ("ENTER\n"); 954 DPRINTK("ENTER\n");
1015 DPRINTK ("Requested mode: %dx%dx%d\n", 955 DPRINTK("Requested mode: %dx%dx%d\n",
1016 var->xres, var->yres, var->bits_per_pixel); 956 var->xres, var->yres, var->bits_per_pixel);
1017 DPRINTK ("pixclock: %d\n", var->pixclock); 957 DPRINTK("pixclock: %d\n", var->pixclock);
1018 958
1019 init_vgachip (cinfo); 959 init_vgachip(info);
1020 960
1021 err = cirrusfb_decode_var(var, &regs, info); 961 err = cirrusfb_decode_var(var, &regs, info);
1022 if(err) { 962 if (err) {
1023 /* should never happen */ 963 /* should never happen */
1024 DPRINTK("mode change aborted. invalid var.\n"); 964 DPRINTK("mode change aborted. invalid var.\n");
1025 return -EINVAL; 965 return -EINVAL;
@@ -1027,34 +967,35 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1027 967
1028 bi = &cirrusfb_board_info[cinfo->btype]; 968 bi = &cirrusfb_board_info[cinfo->btype];
1029 969
1030
1031 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */ 970 /* unlock register VGA_CRTC_H_TOTAL..CRT7 */
1032 vga_wcrt (regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */ 971 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20); /* previously: 0x00) */
1033 972
1034 /* if debugging is enabled, all parameters get output before writing */ 973 /* if debugging is enabled, all parameters get output before writing */
1035 DPRINTK ("CRT0: %ld\n", regs.HorizTotal); 974 DPRINTK("CRT0: %ld\n", regs.HorizTotal);
1036 vga_wcrt (regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal); 975 vga_wcrt(regbase, VGA_CRTC_H_TOTAL, regs.HorizTotal);
1037 976
1038 DPRINTK ("CRT1: %ld\n", regs.HorizDispEnd); 977 DPRINTK("CRT1: %ld\n", regs.HorizDispEnd);
1039 vga_wcrt (regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd); 978 vga_wcrt(regbase, VGA_CRTC_H_DISP, regs.HorizDispEnd);
1040 979
1041 DPRINTK ("CRT2: %ld\n", regs.HorizBlankStart); 980 DPRINTK("CRT2: %ld\n", regs.HorizBlankStart);
1042 vga_wcrt (regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart); 981 vga_wcrt(regbase, VGA_CRTC_H_BLANK_START, regs.HorizBlankStart);
1043 982
1044 DPRINTK ("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32); /* + 128: Compatible read */ 983 /* + 128: Compatible read */
1045 vga_wcrt (regbase, VGA_CRTC_H_BLANK_END, 128 + (regs.HorizBlankEnd % 32)); 984 DPRINTK("CRT3: 128+%ld\n", regs.HorizBlankEnd % 32);
985 vga_wcrt(regbase, VGA_CRTC_H_BLANK_END,
986 128 + (regs.HorizBlankEnd % 32));
1046 987
1047 DPRINTK ("CRT4: %ld\n", regs.HorizSyncStart); 988 DPRINTK("CRT4: %ld\n", regs.HorizSyncStart);
1048 vga_wcrt (regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart); 989 vga_wcrt(regbase, VGA_CRTC_H_SYNC_START, regs.HorizSyncStart);
1049 990
1050 tmp = regs.HorizSyncEnd % 32; 991 tmp = regs.HorizSyncEnd % 32;
1051 if (regs.HorizBlankEnd & 32) 992 if (regs.HorizBlankEnd & 32)
1052 tmp += 128; 993 tmp += 128;
1053 DPRINTK ("CRT5: %d\n", tmp); 994 DPRINTK("CRT5: %d\n", tmp);
1054 vga_wcrt (regbase, VGA_CRTC_H_SYNC_END, tmp); 995 vga_wcrt(regbase, VGA_CRTC_H_SYNC_END, tmp);
1055 996
1056 DPRINTK ("CRT6: %ld\n", regs.VertTotal & 0xff); 997 DPRINTK("CRT6: %ld\n", regs.VertTotal & 0xff);
1057 vga_wcrt (regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff)); 998 vga_wcrt(regbase, VGA_CRTC_V_TOTAL, (regs.VertTotal & 0xff));
1058 999
1059 tmp = 16; /* LineCompare bit #9 */ 1000 tmp = 16; /* LineCompare bit #9 */
1060 if (regs.VertTotal & 256) 1001 if (regs.VertTotal & 256)
@@ -1071,34 +1012,34 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1071 tmp |= 64; 1012 tmp |= 64;
1072 if (regs.VertSyncStart & 512) 1013 if (regs.VertSyncStart & 512)
1073 tmp |= 128; 1014 tmp |= 128;
1074 DPRINTK ("CRT7: %d\n", tmp); 1015 DPRINTK("CRT7: %d\n", tmp);
1075 vga_wcrt (regbase, VGA_CRTC_OVERFLOW, tmp); 1016 vga_wcrt(regbase, VGA_CRTC_OVERFLOW, tmp);
1076 1017
1077 tmp = 0x40; /* LineCompare bit #8 */ 1018 tmp = 0x40; /* LineCompare bit #8 */
1078 if (regs.VertBlankStart & 512) 1019 if (regs.VertBlankStart & 512)
1079 tmp |= 0x20; 1020 tmp |= 0x20;
1080 if (var->vmode & FB_VMODE_DOUBLE) 1021 if (var->vmode & FB_VMODE_DOUBLE)
1081 tmp |= 0x80; 1022 tmp |= 0x80;
1082 DPRINTK ("CRT9: %d\n", tmp); 1023 DPRINTK("CRT9: %d\n", tmp);
1083 vga_wcrt (regbase, VGA_CRTC_MAX_SCAN, tmp); 1024 vga_wcrt(regbase, VGA_CRTC_MAX_SCAN, tmp);
1084 1025
1085 DPRINTK ("CRT10: %ld\n", regs.VertSyncStart & 0xff); 1026 DPRINTK("CRT10: %ld\n", regs.VertSyncStart & 0xff);
1086 vga_wcrt (regbase, VGA_CRTC_V_SYNC_START, (regs.VertSyncStart & 0xff)); 1027 vga_wcrt(regbase, VGA_CRTC_V_SYNC_START, regs.VertSyncStart & 0xff);
1087 1028
1088 DPRINTK ("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16); 1029 DPRINTK("CRT11: 64+32+%ld\n", regs.VertSyncEnd % 16);
1089 vga_wcrt (regbase, VGA_CRTC_V_SYNC_END, (regs.VertSyncEnd % 16 + 64 + 32)); 1030 vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, regs.VertSyncEnd % 16 + 64 + 32);
1090 1031
1091 DPRINTK ("CRT12: %ld\n", regs.VertDispEnd & 0xff); 1032 DPRINTK("CRT12: %ld\n", regs.VertDispEnd & 0xff);
1092 vga_wcrt (regbase, VGA_CRTC_V_DISP_END, (regs.VertDispEnd & 0xff)); 1033 vga_wcrt(regbase, VGA_CRTC_V_DISP_END, regs.VertDispEnd & 0xff);
1093 1034
1094 DPRINTK ("CRT15: %ld\n", regs.VertBlankStart & 0xff); 1035 DPRINTK("CRT15: %ld\n", regs.VertBlankStart & 0xff);
1095 vga_wcrt (regbase, VGA_CRTC_V_BLANK_START, (regs.VertBlankStart & 0xff)); 1036 vga_wcrt(regbase, VGA_CRTC_V_BLANK_START, regs.VertBlankStart & 0xff);
1096 1037
1097 DPRINTK ("CRT16: %ld\n", regs.VertBlankEnd & 0xff); 1038 DPRINTK("CRT16: %ld\n", regs.VertBlankEnd & 0xff);
1098 vga_wcrt (regbase, VGA_CRTC_V_BLANK_END, (regs.VertBlankEnd & 0xff)); 1039 vga_wcrt(regbase, VGA_CRTC_V_BLANK_END, regs.VertBlankEnd & 0xff);
1099 1040
1100 DPRINTK ("CRT18: 0xff\n"); 1041 DPRINTK("CRT18: 0xff\n");
1101 vga_wcrt (regbase, VGA_CRTC_LINE_COMPARE, 0xff); 1042 vga_wcrt(regbase, VGA_CRTC_LINE_COMPARE, 0xff);
1102 1043
1103 tmp = 0; 1044 tmp = 0;
1104 if (var->vmode & FB_VMODE_INTERLACED) 1045 if (var->vmode & FB_VMODE_INTERLACED)
@@ -1112,57 +1053,63 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1112 if (regs.VertBlankEnd & 512) 1053 if (regs.VertBlankEnd & 512)
1113 tmp |= 128; 1054 tmp |= 128;
1114 1055
1115 DPRINTK ("CRT1a: %d\n", tmp); 1056 DPRINTK("CRT1a: %d\n", tmp);
1116 vga_wcrt (regbase, CL_CRT1A, tmp); 1057 vga_wcrt(regbase, CL_CRT1A, tmp);
1117 1058
1118 /* set VCLK0 */ 1059 /* set VCLK0 */
1119 /* hardware RefClock: 14.31818 MHz */ 1060 /* hardware RefClock: 14.31818 MHz */
1120 /* formula: VClk = (OSC * N) / (D * (1+P)) */ 1061 /* formula: VClk = (OSC * N) / (D * (1+P)) */
1121 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */ 1062 /* Example: VClk = (14.31818 * 91) / (23 * (1+1)) = 28.325 MHz */
1122 1063
1123 vga_wseq (regbase, CL_SEQRB, regs.nom); 1064 vga_wseq(regbase, CL_SEQRB, regs.nom);
1124 tmp = regs.den << 1; 1065 tmp = regs.den << 1;
1125 if (regs.div != 0) 1066 if (regs.div != 0)
1126 tmp |= 1; 1067 tmp |= 1;
1127 1068
1069 /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */
1128 if ((cinfo->btype == BT_SD64) || 1070 if ((cinfo->btype == BT_SD64) ||
1129 (cinfo->btype == BT_ALPINE) || 1071 (cinfo->btype == BT_ALPINE) ||
1130 (cinfo->btype == BT_GD5480)) 1072 (cinfo->btype == BT_GD5480))
1131 tmp |= 0x80; /* 6 bit denom; ONLY 5434!!! (bugged me 10 days) */ 1073 tmp |= 0x80;
1132 1074
1133 DPRINTK ("CL_SEQR1B: %ld\n", (long) tmp); 1075 DPRINTK("CL_SEQR1B: %ld\n", (long) tmp);
1134 vga_wseq (regbase, CL_SEQR1B, tmp); 1076 vga_wseq(regbase, CL_SEQR1B, tmp);
1135 1077
1136 if (regs.VertRes >= 1024) 1078 if (regs.VertRes >= 1024)
1137 /* 1280x1024 */ 1079 /* 1280x1024 */
1138 vga_wcrt (regbase, VGA_CRTC_MODE, 0xc7); 1080 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc7);
1139 else 1081 else
1140 /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit 1082 /* mode control: VGA_CRTC_START_HI enable, ROTATE(?), 16bit
1141 * address wrap, no compat. */ 1083 * address wrap, no compat. */
1142 vga_wcrt (regbase, VGA_CRTC_MODE, 0xc3); 1084 vga_wcrt(regbase, VGA_CRTC_MODE, 0xc3);
1143 1085
1144/* HAEH? vga_wcrt (regbase, VGA_CRTC_V_SYNC_END, 0x20); * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */ 1086/* HAEH? vga_wcrt(regbase, VGA_CRTC_V_SYNC_END, 0x20);
1087 * previously: 0x00 unlock VGA_CRTC_H_TOTAL..CRT7 */
1145 1088
1146 /* don't know if it would hurt to also program this if no interlaced */ 1089 /* don't know if it would hurt to also program this if no interlaced */
1147 /* mode is used, but I feel better this way.. :-) */ 1090 /* mode is used, but I feel better this way.. :-) */
1148 if (var->vmode & FB_VMODE_INTERLACED) 1091 if (var->vmode & FB_VMODE_INTERLACED)
1149 vga_wcrt (regbase, VGA_CRTC_REGS, regs.HorizTotal / 2); 1092 vga_wcrt(regbase, VGA_CRTC_REGS, regs.HorizTotal / 2);
1150 else 1093 else
1151 vga_wcrt (regbase, VGA_CRTC_REGS, 0x00); /* interlace control */ 1094 vga_wcrt(regbase, VGA_CRTC_REGS, 0x00); /* interlace control */
1152 1095
1153 vga_wseq (regbase, VGA_SEQ_CHARACTER_MAP, 0); 1096 vga_wseq(regbase, VGA_SEQ_CHARACTER_MAP, 0);
1154 1097
1155 /* adjust horizontal/vertical sync type (low/high) */ 1098 /* adjust horizontal/vertical sync type (low/high) */
1156 tmp = 0x03; /* enable display memory & CRTC I/O address for color mode */ 1099 /* enable display memory & CRTC I/O address for color mode */
1100 tmp = 0x03;
1157 if (var->sync & FB_SYNC_HOR_HIGH_ACT) 1101 if (var->sync & FB_SYNC_HOR_HIGH_ACT)
1158 tmp |= 0x40; 1102 tmp |= 0x40;
1159 if (var->sync & FB_SYNC_VERT_HIGH_ACT) 1103 if (var->sync & FB_SYNC_VERT_HIGH_ACT)
1160 tmp |= 0x80; 1104 tmp |= 0x80;
1161 WGen (cinfo, VGA_MIS_W, tmp); 1105 WGen(cinfo, VGA_MIS_W, tmp);
1162 1106
1163 vga_wcrt (regbase, VGA_CRTC_PRESET_ROW, 0); /* Screen A Preset Row-Scan register */ 1107 /* Screen A Preset Row-Scan register */
1164 vga_wcrt (regbase, VGA_CRTC_CURSOR_START, 0); /* text cursor on and start line */ 1108 vga_wcrt(regbase, VGA_CRTC_PRESET_ROW, 0);
1165 vga_wcrt (regbase, VGA_CRTC_CURSOR_END, 31); /* text cursor end line */ 1109 /* text cursor on and start line */
1110 vga_wcrt(regbase, VGA_CRTC_CURSOR_START, 0);
1111 /* text cursor end line */
1112 vga_wcrt(regbase, VGA_CRTC_CURSOR_END, 31);
1166 1113
1167 /****************************************************** 1114 /******************************************************
1168 * 1115 *
@@ -1172,8 +1119,8 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1172 1119
1173 /* programming for different color depths */ 1120 /* programming for different color depths */
1174 if (var->bits_per_pixel == 1) { 1121 if (var->bits_per_pixel == 1) {
1175 DPRINTK ("cirrusfb: preparing for 1 bit deep display\n"); 1122 DPRINTK("cirrusfb: preparing for 1 bit deep display\n");
1176 vga_wgfx (regbase, VGA_GFX_MODE, 0); /* mode register */ 1123 vga_wgfx(regbase, VGA_GFX_MODE, 0); /* mode register */
1177 1124
1178 /* SR07 */ 1125 /* SR07 */
1179 switch (cinfo->btype) { 1126 switch (cinfo->btype) {
@@ -1184,71 +1131,77 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1184 case BT_PICASSO4: 1131 case BT_PICASSO4:
1185 case BT_ALPINE: 1132 case BT_ALPINE:
1186 case BT_GD5480: 1133 case BT_GD5480:
1187 DPRINTK (" (for GD54xx)\n"); 1134 DPRINTK(" (for GD54xx)\n");
1188 vga_wseq (regbase, CL_SEQR7, 1135 vga_wseq(regbase, CL_SEQR7,
1189 regs.multiplexing ? 1136 regs.multiplexing ?
1190 bi->sr07_1bpp_mux : bi->sr07_1bpp); 1137 bi->sr07_1bpp_mux : bi->sr07_1bpp);
1191 break; 1138 break;
1192 1139
1193 case BT_LAGUNA: 1140 case BT_LAGUNA:
1194 DPRINTK (" (for GD546x)\n"); 1141 DPRINTK(" (for GD546x)\n");
1195 vga_wseq (regbase, CL_SEQR7, 1142 vga_wseq(regbase, CL_SEQR7,
1196 vga_rseq (regbase, CL_SEQR7) & ~0x01); 1143 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1197 break; 1144 break;
1198 1145
1199 default: 1146 default:
1200 printk (KERN_WARNING "cirrusfb: unknown Board\n"); 1147 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1201 break; 1148 break;
1202 } 1149 }
1203 1150
1204 /* Extended Sequencer Mode */ 1151 /* Extended Sequencer Mode */
1205 switch (cinfo->btype) { 1152 switch (cinfo->btype) {
1206 case BT_SD64: 1153 case BT_SD64:
1207 /* setting the SEQRF on SD64 is not necessary (only during init) */ 1154 /* setting the SEQRF on SD64 is not necessary
1208 DPRINTK ("(for SD64)\n"); 1155 * (only during init)
1209 vga_wseq (regbase, CL_SEQR1F, 0x1a); /* MCLK select */ 1156 */
1157 DPRINTK("(for SD64)\n");
1158 /* MCLK select */
1159 vga_wseq(regbase, CL_SEQR1F, 0x1a);
1210 break; 1160 break;
1211 1161
1212 case BT_PICCOLO: 1162 case BT_PICCOLO:
1213 DPRINTK ("(for Piccolo)\n"); 1163 case BT_SPECTRUM:
1214/* ### ueberall 0x22? */ 1164 DPRINTK("(for Piccolo/Spectrum)\n");
1215 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ##vorher 1c MCLK select */ 1165 /* ### ueberall 0x22? */
1216 vga_wseq (regbase, CL_SEQRF, 0xb0); /* evtl d0 bei 1 bit? avoid FIFO underruns..? */ 1166 /* ##vorher 1c MCLK select */
1167 vga_wseq(regbase, CL_SEQR1F, 0x22);
1168 /* evtl d0 bei 1 bit? avoid FIFO underruns..? */
1169 vga_wseq(regbase, CL_SEQRF, 0xb0);
1217 break; 1170 break;
1218 1171
1219 case BT_PICASSO: 1172 case BT_PICASSO:
1220 DPRINTK ("(for Picasso)\n"); 1173 DPRINTK("(for Picasso)\n");
1221 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ##vorher 22 MCLK select */ 1174 /* ##vorher 22 MCLK select */
1222 vga_wseq (regbase, CL_SEQRF, 0xd0); /* ## vorher d0 avoid FIFO underruns..? */ 1175 vga_wseq(regbase, CL_SEQR1F, 0x22);
1223 break; 1176 /* ## vorher d0 avoid FIFO underruns..? */
1224 1177 vga_wseq(regbase, CL_SEQRF, 0xd0);
1225 case BT_SPECTRUM:
1226 DPRINTK ("(for Spectrum)\n");
1227/* ### ueberall 0x22? */
1228 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ##vorher 1c MCLK select */
1229 vga_wseq (regbase, CL_SEQRF, 0xb0); /* evtl d0? avoid FIFO underruns..? */
1230 break; 1178 break;
1231 1179
1232 case BT_PICASSO4: 1180 case BT_PICASSO4:
1233 case BT_ALPINE: 1181 case BT_ALPINE:
1234 case BT_GD5480: 1182 case BT_GD5480:
1235 case BT_LAGUNA: 1183 case BT_LAGUNA:
1236 DPRINTK (" (for GD54xx)\n"); 1184 DPRINTK(" (for GD54xx)\n");
1237 /* do nothing */ 1185 /* do nothing */
1238 break; 1186 break;
1239 1187
1240 default: 1188 default:
1241 printk (KERN_WARNING "cirrusfb: unknown Board\n"); 1189 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1242 break; 1190 break;
1243 } 1191 }
1244 1192
1245 WGen (cinfo, VGA_PEL_MSK, 0x01); /* pixel mask: pass-through for first plane */ 1193 /* pixel mask: pass-through for first plane */
1194 WGen(cinfo, VGA_PEL_MSK, 0x01);
1246 if (regs.multiplexing) 1195 if (regs.multiplexing)
1247 WHDR (cinfo, 0x4a); /* hidden dac reg: 1280x1024 */ 1196 /* hidden dac reg: 1280x1024 */
1197 WHDR(cinfo, 0x4a);
1248 else 1198 else
1249 WHDR (cinfo, 0); /* hidden dac: nothing */ 1199 /* hidden dac: nothing */
1250 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x06); /* memory mode: odd/even, ext. memory */ 1200 WHDR(cinfo, 0);
1251 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0x01); /* plane mask: only write to first plane */ 1201 /* memory mode: odd/even, ext. memory */
1202 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x06);
1203 /* plane mask: only write to first plane */
1204 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0x01);
1252 offset = var->xres_virtual / 16; 1205 offset = var->xres_virtual / 16;
1253 } 1206 }
1254 1207
@@ -1259,7 +1212,7 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1259 */ 1212 */
1260 1213
1261 else if (var->bits_per_pixel == 8) { 1214 else if (var->bits_per_pixel == 8) {
1262 DPRINTK ("cirrusfb: preparing for 8 bit deep display\n"); 1215 DPRINTK("cirrusfb: preparing for 8 bit deep display\n");
1263 switch (cinfo->btype) { 1216 switch (cinfo->btype) {
1264 case BT_SD64: 1217 case BT_SD64:
1265 case BT_PICCOLO: 1218 case BT_PICCOLO:
@@ -1268,75 +1221,77 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1268 case BT_PICASSO4: 1221 case BT_PICASSO4:
1269 case BT_ALPINE: 1222 case BT_ALPINE:
1270 case BT_GD5480: 1223 case BT_GD5480:
1271 DPRINTK (" (for GD54xx)\n"); 1224 DPRINTK(" (for GD54xx)\n");
1272 vga_wseq (regbase, CL_SEQR7, 1225 vga_wseq(regbase, CL_SEQR7,
1273 regs.multiplexing ? 1226 regs.multiplexing ?
1274 bi->sr07_8bpp_mux : bi->sr07_8bpp); 1227 bi->sr07_8bpp_mux : bi->sr07_8bpp);
1275 break; 1228 break;
1276 1229
1277 case BT_LAGUNA: 1230 case BT_LAGUNA:
1278 DPRINTK (" (for GD546x)\n"); 1231 DPRINTK(" (for GD546x)\n");
1279 vga_wseq (regbase, CL_SEQR7, 1232 vga_wseq(regbase, CL_SEQR7,
1280 vga_rseq (regbase, CL_SEQR7) | 0x01); 1233 vga_rseq(regbase, CL_SEQR7) | 0x01);
1281 break; 1234 break;
1282 1235
1283 default: 1236 default:
1284 printk (KERN_WARNING "cirrusfb: unknown Board\n"); 1237 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1285 break; 1238 break;
1286 } 1239 }
1287 1240
1288 switch (cinfo->btype) { 1241 switch (cinfo->btype) {
1289 case BT_SD64: 1242 case BT_SD64:
1290 vga_wseq (regbase, CL_SEQR1F, 0x1d); /* MCLK select */ 1243 /* MCLK select */
1244 vga_wseq(regbase, CL_SEQR1F, 0x1d);
1291 break; 1245 break;
1292 1246
1293 case BT_PICCOLO: 1247 case BT_PICCOLO:
1294 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */
1295 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
1296 break;
1297
1298 case BT_PICASSO: 1248 case BT_PICASSO:
1299 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */
1300 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
1301 break;
1302
1303 case BT_SPECTRUM: 1249 case BT_SPECTRUM:
1304 vga_wseq (regbase, CL_SEQR1F, 0x22); /* ### vorher 1c MCLK select */ 1250 /* ### vorher 1c MCLK select */
1305 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */ 1251 vga_wseq(regbase, CL_SEQR1F, 0x22);
1252 /* Fast Page-Mode writes */
1253 vga_wseq(regbase, CL_SEQRF, 0xb0);
1306 break; 1254 break;
1307 1255
1308 case BT_PICASSO4: 1256 case BT_PICASSO4:
1309#ifdef CONFIG_ZORRO 1257#ifdef CONFIG_ZORRO
1310 vga_wseq (regbase, CL_SEQRF, 0xb8); /* ### INCOMPLETE!! */ 1258 /* ### INCOMPLETE!! */
1259 vga_wseq(regbase, CL_SEQRF, 0xb8);
1311#endif 1260#endif
1312/* vga_wseq (regbase, CL_SEQR1F, 0x1c); */ 1261/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1313 break; 1262 break;
1314 1263
1315 case BT_ALPINE: 1264 case BT_ALPINE:
1316 DPRINTK (" (for GD543x)\n"); 1265 DPRINTK(" (for GD543x)\n");
1317 cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK); 1266 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1318 /* We already set SRF and SR1F */ 1267 /* We already set SRF and SR1F */
1319 break; 1268 break;
1320 1269
1321 case BT_GD5480: 1270 case BT_GD5480:
1322 case BT_LAGUNA: 1271 case BT_LAGUNA:
1323 DPRINTK (" (for GD54xx)\n"); 1272 DPRINTK(" (for GD54xx)\n");
1324 /* do nothing */ 1273 /* do nothing */
1325 break; 1274 break;
1326 1275
1327 default: 1276 default:
1328 printk (KERN_WARNING "cirrusfb: unknown Board\n"); 1277 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1329 break; 1278 break;
1330 } 1279 }
1331 1280
1332 vga_wgfx (regbase, VGA_GFX_MODE, 64); /* mode register: 256 color mode */ 1281 /* mode register: 256 color mode */
1333 WGen (cinfo, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */ 1282 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1283 /* pixel mask: pass-through all planes */
1284 WGen(cinfo, VGA_PEL_MSK, 0xff);
1334 if (regs.multiplexing) 1285 if (regs.multiplexing)
1335 WHDR (cinfo, 0x4a); /* hidden dac reg: 1280x1024 */ 1286 /* hidden dac reg: 1280x1024 */
1287 WHDR(cinfo, 0x4a);
1336 else 1288 else
1337 WHDR (cinfo, 0); /* hidden dac: nothing */ 1289 /* hidden dac: nothing */
1338 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */ 1290 WHDR(cinfo, 0);
1339 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */ 1291 /* memory mode: chain4, ext. memory */
1292 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1293 /* plane mask: enable writing to all 4 planes */
1294 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1340 offset = var->xres_virtual / 8; 1295 offset = var->xres_virtual / 8;
1341 } 1296 }
1342 1297
@@ -1347,72 +1302,77 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1347 */ 1302 */
1348 1303
1349 else if (var->bits_per_pixel == 16) { 1304 else if (var->bits_per_pixel == 16) {
1350 DPRINTK ("cirrusfb: preparing for 16 bit deep display\n"); 1305 DPRINTK("cirrusfb: preparing for 16 bit deep display\n");
1351 switch (cinfo->btype) { 1306 switch (cinfo->btype) {
1352 case BT_SD64: 1307 case BT_SD64:
1353 vga_wseq (regbase, CL_SEQR7, 0xf7); /* Extended Sequencer Mode: 256c col. mode */ 1308 /* Extended Sequencer Mode: 256c col. mode */
1354 vga_wseq (regbase, CL_SEQR1F, 0x1e); /* MCLK select */ 1309 vga_wseq(regbase, CL_SEQR7, 0xf7);
1310 /* MCLK select */
1311 vga_wseq(regbase, CL_SEQR1F, 0x1e);
1355 break; 1312 break;
1356 1313
1357 case BT_PICCOLO: 1314 case BT_PICCOLO:
1358 vga_wseq (regbase, CL_SEQR7, 0x87); 1315 case BT_SPECTRUM:
1359 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */ 1316 vga_wseq(regbase, CL_SEQR7, 0x87);
1360 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */ 1317 /* Fast Page-Mode writes */
1318 vga_wseq(regbase, CL_SEQRF, 0xb0);
1319 /* MCLK select */
1320 vga_wseq(regbase, CL_SEQR1F, 0x22);
1361 break; 1321 break;
1362 1322
1363 case BT_PICASSO: 1323 case BT_PICASSO:
1364 vga_wseq (regbase, CL_SEQR7, 0x27); 1324 vga_wseq(regbase, CL_SEQR7, 0x27);
1365 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */ 1325 /* Fast Page-Mode writes */
1366 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */ 1326 vga_wseq(regbase, CL_SEQRF, 0xb0);
1367 break; 1327 /* MCLK select */
1368 1328 vga_wseq(regbase, CL_SEQR1F, 0x22);
1369 case BT_SPECTRUM:
1370 vga_wseq (regbase, CL_SEQR7, 0x87);
1371 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
1372 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */
1373 break; 1329 break;
1374 1330
1375 case BT_PICASSO4: 1331 case BT_PICASSO4:
1376 vga_wseq (regbase, CL_SEQR7, 0x27); 1332 vga_wseq(regbase, CL_SEQR7, 0x27);
1377/* vga_wseq (regbase, CL_SEQR1F, 0x1c); */ 1333/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1378 break; 1334 break;
1379 1335
1380 case BT_ALPINE: 1336 case BT_ALPINE:
1381 DPRINTK (" (for GD543x)\n"); 1337 DPRINTK(" (for GD543x)\n");
1382 if (regs.HorizRes >= 1024) 1338 if (regs.HorizRes >= 1024)
1383 vga_wseq (regbase, CL_SEQR7, 0xa7); 1339 vga_wseq(regbase, CL_SEQR7, 0xa7);
1384 else 1340 else
1385 vga_wseq (regbase, CL_SEQR7, 0xa3); 1341 vga_wseq(regbase, CL_SEQR7, 0xa3);
1386 cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK); 1342 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1387 break; 1343 break;
1388 1344
1389 case BT_GD5480: 1345 case BT_GD5480:
1390 DPRINTK (" (for GD5480)\n"); 1346 DPRINTK(" (for GD5480)\n");
1391 vga_wseq (regbase, CL_SEQR7, 0x17); 1347 vga_wseq(regbase, CL_SEQR7, 0x17);
1392 /* We already set SRF and SR1F */ 1348 /* We already set SRF and SR1F */
1393 break; 1349 break;
1394 1350
1395 case BT_LAGUNA: 1351 case BT_LAGUNA:
1396 DPRINTK (" (for GD546x)\n"); 1352 DPRINTK(" (for GD546x)\n");
1397 vga_wseq (regbase, CL_SEQR7, 1353 vga_wseq(regbase, CL_SEQR7,
1398 vga_rseq (regbase, CL_SEQR7) & ~0x01); 1354 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1399 break; 1355 break;
1400 1356
1401 default: 1357 default:
1402 printk (KERN_WARNING "CIRRUSFB: unknown Board\n"); 1358 printk(KERN_WARNING "CIRRUSFB: unknown Board\n");
1403 break; 1359 break;
1404 } 1360 }
1405 1361
1406 vga_wgfx (regbase, VGA_GFX_MODE, 64); /* mode register: 256 color mode */ 1362 /* mode register: 256 color mode */
1407 WGen (cinfo, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */ 1363 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1364 /* pixel mask: pass-through all planes */
1365 WGen(cinfo, VGA_PEL_MSK, 0xff);
1408#ifdef CONFIG_PCI 1366#ifdef CONFIG_PCI
1409 WHDR (cinfo, 0xc0); /* Copy Xbh */ 1367 WHDR(cinfo, 0xc0); /* Copy Xbh */
1410#elif defined(CONFIG_ZORRO) 1368#elif defined(CONFIG_ZORRO)
1411 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */ 1369 /* FIXME: CONFIG_PCI and CONFIG_ZORRO may be defined both */
1412 WHDR (cinfo, 0xa0); /* hidden dac reg: nothing special */ 1370 WHDR(cinfo, 0xa0); /* hidden dac reg: nothing special */
1413#endif 1371#endif
1414 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */ 1372 /* memory mode: chain4, ext. memory */
1415 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */ 1373 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1374 /* plane mask: enable writing to all 4 planes */
1375 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1416 offset = var->xres_virtual / 4; 1376 offset = var->xres_virtual / 4;
1417 } 1377 }
1418 1378
@@ -1423,64 +1383,70 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1423 */ 1383 */
1424 1384
1425 else if (var->bits_per_pixel == 32) { 1385 else if (var->bits_per_pixel == 32) {
1426 DPRINTK ("cirrusfb: preparing for 24/32 bit deep display\n"); 1386 DPRINTK("cirrusfb: preparing for 24/32 bit deep display\n");
1427 switch (cinfo->btype) { 1387 switch (cinfo->btype) {
1428 case BT_SD64: 1388 case BT_SD64:
1429 vga_wseq (regbase, CL_SEQR7, 0xf9); /* Extended Sequencer Mode: 256c col. mode */ 1389 /* Extended Sequencer Mode: 256c col. mode */
1430 vga_wseq (regbase, CL_SEQR1F, 0x1e); /* MCLK select */ 1390 vga_wseq(regbase, CL_SEQR7, 0xf9);
1391 /* MCLK select */
1392 vga_wseq(regbase, CL_SEQR1F, 0x1e);
1431 break; 1393 break;
1432 1394
1433 case BT_PICCOLO: 1395 case BT_PICCOLO:
1434 vga_wseq (regbase, CL_SEQR7, 0x85); 1396 case BT_SPECTRUM:
1435 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */ 1397 vga_wseq(regbase, CL_SEQR7, 0x85);
1436 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */ 1398 /* Fast Page-Mode writes */
1399 vga_wseq(regbase, CL_SEQRF, 0xb0);
1400 /* MCLK select */
1401 vga_wseq(regbase, CL_SEQR1F, 0x22);
1437 break; 1402 break;
1438 1403
1439 case BT_PICASSO: 1404 case BT_PICASSO:
1440 vga_wseq (regbase, CL_SEQR7, 0x25); 1405 vga_wseq(regbase, CL_SEQR7, 0x25);
1441 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */ 1406 /* Fast Page-Mode writes */
1442 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */ 1407 vga_wseq(regbase, CL_SEQRF, 0xb0);
1443 break; 1408 /* MCLK select */
1444 1409 vga_wseq(regbase, CL_SEQR1F, 0x22);
1445 case BT_SPECTRUM:
1446 vga_wseq (regbase, CL_SEQR7, 0x85);
1447 vga_wseq (regbase, CL_SEQRF, 0xb0); /* Fast Page-Mode writes */
1448 vga_wseq (regbase, CL_SEQR1F, 0x22); /* MCLK select */
1449 break; 1410 break;
1450 1411
1451 case BT_PICASSO4: 1412 case BT_PICASSO4:
1452 vga_wseq (regbase, CL_SEQR7, 0x25); 1413 vga_wseq(regbase, CL_SEQR7, 0x25);
1453/* vga_wseq (regbase, CL_SEQR1F, 0x1c); */ 1414/* vga_wseq(regbase, CL_SEQR1F, 0x1c); */
1454 break; 1415 break;
1455 1416
1456 case BT_ALPINE: 1417 case BT_ALPINE:
1457 DPRINTK (" (for GD543x)\n"); 1418 DPRINTK(" (for GD543x)\n");
1458 vga_wseq (regbase, CL_SEQR7, 0xa9); 1419 vga_wseq(regbase, CL_SEQR7, 0xa9);
1459 cirrusfb_set_mclk (cinfo, regs.mclk, regs.divMCLK); 1420 cirrusfb_set_mclk(cinfo, regs.mclk, regs.divMCLK);
1460 break; 1421 break;
1461 1422
1462 case BT_GD5480: 1423 case BT_GD5480:
1463 DPRINTK (" (for GD5480)\n"); 1424 DPRINTK(" (for GD5480)\n");
1464 vga_wseq (regbase, CL_SEQR7, 0x19); 1425 vga_wseq(regbase, CL_SEQR7, 0x19);
1465 /* We already set SRF and SR1F */ 1426 /* We already set SRF and SR1F */
1466 break; 1427 break;
1467 1428
1468 case BT_LAGUNA: 1429 case BT_LAGUNA:
1469 DPRINTK (" (for GD546x)\n"); 1430 DPRINTK(" (for GD546x)\n");
1470 vga_wseq (regbase, CL_SEQR7, 1431 vga_wseq(regbase, CL_SEQR7,
1471 vga_rseq (regbase, CL_SEQR7) & ~0x01); 1432 vga_rseq(regbase, CL_SEQR7) & ~0x01);
1472 break; 1433 break;
1473 1434
1474 default: 1435 default:
1475 printk (KERN_WARNING "cirrusfb: unknown Board\n"); 1436 printk(KERN_WARNING "cirrusfb: unknown Board\n");
1476 break; 1437 break;
1477 } 1438 }
1478 1439
1479 vga_wgfx (regbase, VGA_GFX_MODE, 64); /* mode register: 256 color mode */ 1440 /* mode register: 256 color mode */
1480 WGen (cinfo, VGA_PEL_MSK, 0xff); /* pixel mask: pass-through all planes */ 1441 vga_wgfx(regbase, VGA_GFX_MODE, 64);
1481 WHDR (cinfo, 0xc5); /* hidden dac reg: 8-8-8 mode (24 or 32) */ 1442 /* pixel mask: pass-through all planes */
1482 vga_wseq (regbase, VGA_SEQ_MEMORY_MODE, 0x0a); /* memory mode: chain4, ext. memory */ 1443 WGen(cinfo, VGA_PEL_MSK, 0xff);
1483 vga_wseq (regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: enable writing to all 4 planes */ 1444 /* hidden dac reg: 8-8-8 mode (24 or 32) */
1445 WHDR(cinfo, 0xc5);
1446 /* memory mode: chain4, ext. memory */
1447 vga_wseq(regbase, VGA_SEQ_MEMORY_MODE, 0x0a);
1448 /* plane mask: enable writing to all 4 planes */
1449 vga_wseq(regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1484 offset = var->xres_virtual / 4; 1450 offset = var->xres_virtual / 4;
1485 } 1451 }
1486 1452
@@ -1490,48 +1456,67 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1490 * 1456 *
1491 */ 1457 */
1492 1458
1493 else { 1459 else
1494 printk (KERN_ERR "cirrusfb: What's this?? requested color depth == %d.\n", 1460 printk(KERN_ERR "cirrusfb: What's this?? "
1461 " requested color depth == %d.\n",
1495 var->bits_per_pixel); 1462 var->bits_per_pixel);
1496 }
1497 1463
1498 vga_wcrt (regbase, VGA_CRTC_OFFSET, offset & 0xff); 1464 vga_wcrt(regbase, VGA_CRTC_OFFSET, offset & 0xff);
1499 tmp = 0x22; 1465 tmp = 0x22;
1500 if (offset & 0x100) 1466 if (offset & 0x100)
1501 tmp |= 0x10; /* offset overflow bit */ 1467 tmp |= 0x10; /* offset overflow bit */
1502 1468
1503 vga_wcrt (regbase, CL_CRT1B, tmp); /* screen start addr #16-18, fastpagemode cycles */ 1469 /* screen start addr #16-18, fastpagemode cycles */
1470 vga_wcrt(regbase, CL_CRT1B, tmp);
1504 1471
1505 if (cinfo->btype == BT_SD64 || 1472 if (cinfo->btype == BT_SD64 ||
1506 cinfo->btype == BT_PICASSO4 || 1473 cinfo->btype == BT_PICASSO4 ||
1507 cinfo->btype == BT_ALPINE || 1474 cinfo->btype == BT_ALPINE ||
1508 cinfo->btype == BT_GD5480) 1475 cinfo->btype == BT_GD5480)
1509 vga_wcrt (regbase, CL_CRT1D, 0x00); /* screen start address bit 19 */ 1476 /* screen start address bit 19 */
1510 1477 vga_wcrt(regbase, CL_CRT1D, 0x00);
1511 vga_wcrt (regbase, VGA_CRTC_CURSOR_HI, 0); /* text cursor location high */ 1478
1512 vga_wcrt (regbase, VGA_CRTC_CURSOR_LO, 0); /* text cursor location low */ 1479 /* text cursor location high */
1513 vga_wcrt (regbase, VGA_CRTC_UNDERLINE, 0); /* underline row scanline = at very bottom */ 1480 vga_wcrt(regbase, VGA_CRTC_CURSOR_HI, 0);
1514 1481 /* text cursor location low */
1515 vga_wattr (regbase, VGA_ATC_MODE, 1); /* controller mode */ 1482 vga_wcrt(regbase, VGA_CRTC_CURSOR_LO, 0);
1516 vga_wattr (regbase, VGA_ATC_OVERSCAN, 0); /* overscan (border) color */ 1483 /* underline row scanline = at very bottom */
1517 vga_wattr (regbase, VGA_ATC_PLANE_ENABLE, 15); /* color plane enable */ 1484 vga_wcrt(regbase, VGA_CRTC_UNDERLINE, 0);
1518 vga_wattr (regbase, CL_AR33, 0); /* pixel panning */ 1485
1519 vga_wattr (regbase, VGA_ATC_COLOR_PAGE, 0); /* color select */ 1486 /* controller mode */
1487 vga_wattr(regbase, VGA_ATC_MODE, 1);
1488 /* overscan (border) color */
1489 vga_wattr(regbase, VGA_ATC_OVERSCAN, 0);
1490 /* color plane enable */
1491 vga_wattr(regbase, VGA_ATC_PLANE_ENABLE, 15);
1492 /* pixel panning */
1493 vga_wattr(regbase, CL_AR33, 0);
1494 /* color select */
1495 vga_wattr(regbase, VGA_ATC_COLOR_PAGE, 0);
1520 1496
1521 /* [ EGS: SetOffset(); ] */ 1497 /* [ EGS: SetOffset(); ] */
1522 /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */ 1498 /* From SetOffset(): Turn on VideoEnable bit in Attribute controller */
1523 AttrOn (cinfo); 1499 AttrOn(cinfo);
1524 1500
1525 vga_wgfx (regbase, VGA_GFX_SR_VALUE, 0); /* set/reset register */ 1501 /* set/reset register */
1526 vga_wgfx (regbase, VGA_GFX_SR_ENABLE, 0); /* set/reset enable */ 1502 vga_wgfx(regbase, VGA_GFX_SR_VALUE, 0);
1527 vga_wgfx (regbase, VGA_GFX_COMPARE_VALUE, 0); /* color compare */ 1503 /* set/reset enable */
1528 vga_wgfx (regbase, VGA_GFX_DATA_ROTATE, 0); /* data rotate */ 1504 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, 0);
1529 vga_wgfx (regbase, VGA_GFX_PLANE_READ, 0); /* read map select */ 1505 /* color compare */
1530 vga_wgfx (regbase, VGA_GFX_MISC, 1); /* miscellaneous register */ 1506 vga_wgfx(regbase, VGA_GFX_COMPARE_VALUE, 0);
1531 vga_wgfx (regbase, VGA_GFX_COMPARE_MASK, 15); /* color don't care */ 1507 /* data rotate */
1532 vga_wgfx (regbase, VGA_GFX_BIT_MASK, 255); /* bit mask */ 1508 vga_wgfx(regbase, VGA_GFX_DATA_ROTATE, 0);
1533 1509 /* read map select */
1534 vga_wseq (regbase, CL_SEQR12, 0x0); /* graphics cursor attributes: nothing special */ 1510 vga_wgfx(regbase, VGA_GFX_PLANE_READ, 0);
1511 /* miscellaneous register */
1512 vga_wgfx(regbase, VGA_GFX_MISC, 1);
1513 /* color don't care */
1514 vga_wgfx(regbase, VGA_GFX_COMPARE_MASK, 15);
1515 /* bit mask */
1516 vga_wgfx(regbase, VGA_GFX_BIT_MASK, 255);
1517
1518 /* graphics cursor attributes: nothing special */
1519 vga_wseq(regbase, CL_SEQR12, 0x0);
1535 1520
1536 /* finally, turn on everything - turn off "FullBandwidth" bit */ 1521 /* finally, turn on everything - turn off "FullBandwidth" bit */
1537 /* also, set "DotClock%2" bit where requested */ 1522 /* also, set "DotClock%2" bit where requested */
@@ -1542,36 +1527,33 @@ static int cirrusfb_set_par_foo (struct fb_info *info)
1542 tmp |= 0x08; 1527 tmp |= 0x08;
1543*/ 1528*/
1544 1529
1545 vga_wseq (regbase, VGA_SEQ_CLOCK_MODE, tmp); 1530 vga_wseq(regbase, VGA_SEQ_CLOCK_MODE, tmp);
1546 DPRINTK ("CL_SEQR1: %d\n", tmp); 1531 DPRINTK("CL_SEQR1: %d\n", tmp);
1547 1532
1548 cinfo->currentmode = regs; 1533 cinfo->currentmode = regs;
1549 info->fix.type = regs.type;
1550 info->fix.visual = regs.visual;
1551 info->fix.line_length = regs.line_length;
1552 1534
1553 /* pan to requested offset */ 1535 /* pan to requested offset */
1554 cirrusfb_pan_display (var, info); 1536 cirrusfb_pan_display(var, info);
1555 1537
1556#ifdef CIRRUSFB_DEBUG 1538#ifdef CIRRUSFB_DEBUG
1557 cirrusfb_dump (); 1539 cirrusfb_dump();
1558#endif 1540#endif
1559 1541
1560 DPRINTK ("EXIT\n"); 1542 DPRINTK("EXIT\n");
1561 return 0; 1543 return 0;
1562} 1544}
1563 1545
1564/* for some reason incomprehensible to me, cirrusfb requires that you write 1546/* for some reason incomprehensible to me, cirrusfb requires that you write
1565 * the registers twice for the settings to take..grr. -dte */ 1547 * the registers twice for the settings to take..grr. -dte */
1566static int cirrusfb_set_par (struct fb_info *info) 1548static int cirrusfb_set_par(struct fb_info *info)
1567{ 1549{
1568 cirrusfb_set_par_foo (info); 1550 cirrusfb_set_par_foo(info);
1569 return cirrusfb_set_par_foo (info); 1551 return cirrusfb_set_par_foo(info);
1570} 1552}
1571 1553
1572static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green, 1554static int cirrusfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1573 unsigned blue, unsigned transp, 1555 unsigned blue, unsigned transp,
1574 struct fb_info *info) 1556 struct fb_info *info)
1575{ 1557{
1576 struct cirrusfb_info *cinfo = info->par; 1558 struct cirrusfb_info *cinfo = info->par;
1577 1559
@@ -1584,34 +1566,18 @@ static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
1584 green >>= (16 - info->var.green.length); 1566 green >>= (16 - info->var.green.length);
1585 blue >>= (16 - info->var.blue.length); 1567 blue >>= (16 - info->var.blue.length);
1586 1568
1587 if (regno>=16) 1569 if (regno >= 16)
1588 return 1; 1570 return 1;
1589 v = (red << info->var.red.offset) | 1571 v = (red << info->var.red.offset) |
1590 (green << info->var.green.offset) | 1572 (green << info->var.green.offset) |
1591 (blue << info->var.blue.offset); 1573 (blue << info->var.blue.offset);
1592 1574
1593 switch (info->var.bits_per_pixel) { 1575 cinfo->pseudo_palette[regno] = v;
1594 case 8:
1595 cinfo->pseudo_palette[regno] = v;
1596 break;
1597 case 16:
1598 cinfo->pseudo_palette[regno] = v;
1599 break;
1600 case 24:
1601 case 32:
1602 cinfo->pseudo_palette[regno] = v;
1603 break;
1604 }
1605 return 0; 1576 return 0;
1606 } 1577 }
1607 1578
1608 cinfo->palette[regno].red = red; 1579 if (info->var.bits_per_pixel == 8)
1609 cinfo->palette[regno].green = green; 1580 WClut(cinfo, regno, red >> 10, green >> 10, blue >> 10);
1610 cinfo->palette[regno].blue = blue;
1611
1612 if (info->var.bits_per_pixel == 8) {
1613 WClut (cinfo, regno, red >> 10, green >> 10, blue >> 10);
1614 }
1615 1581
1616 return 0; 1582 return 0;
1617 1583
@@ -1622,8 +1588,8 @@ static int cirrusfb_setcolreg (unsigned regno, unsigned red, unsigned green,
1622 1588
1623 performs display panning - provided hardware permits this 1589 performs display panning - provided hardware permits this
1624**************************************************************************/ 1590**************************************************************************/
1625static int cirrusfb_pan_display (struct fb_var_screeninfo *var, 1591static int cirrusfb_pan_display(struct fb_var_screeninfo *var,
1626 struct fb_info *info) 1592 struct fb_info *info)
1627{ 1593{
1628 int xoffset = 0; 1594 int xoffset = 0;
1629 int yoffset = 0; 1595 int yoffset = 0;
@@ -1631,8 +1597,8 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
1631 unsigned char tmp = 0, tmp2 = 0, xpix; 1597 unsigned char tmp = 0, tmp2 = 0, xpix;
1632 struct cirrusfb_info *cinfo = info->par; 1598 struct cirrusfb_info *cinfo = info->par;
1633 1599
1634 DPRINTK ("ENTER\n"); 1600 DPRINTK("ENTER\n");
1635 DPRINTK ("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset); 1601 DPRINTK("virtual offset: (%d,%d)\n", var->xoffset, var->yoffset);
1636 1602
1637 /* no range checks for xoffset and yoffset, */ 1603 /* no range checks for xoffset and yoffset, */
1638 /* as fb_pan_display has already done this */ 1604 /* as fb_pan_display has already done this */
@@ -1645,7 +1611,7 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
1645 xoffset = var->xoffset * info->var.bits_per_pixel / 8; 1611 xoffset = var->xoffset * info->var.bits_per_pixel / 8;
1646 yoffset = var->yoffset; 1612 yoffset = var->yoffset;
1647 1613
1648 base = yoffset * cinfo->currentmode.line_length + xoffset; 1614 base = yoffset * info->fix.line_length + xoffset;
1649 1615
1650 if (info->var.bits_per_pixel == 1) { 1616 if (info->var.bits_per_pixel == 1) {
1651 /* base is already correct */ 1617 /* base is already correct */
@@ -1655,11 +1621,13 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
1655 xpix = (unsigned char) ((xoffset % 4) * 2); 1621 xpix = (unsigned char) ((xoffset % 4) * 2);
1656 } 1622 }
1657 1623
1658 cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */ 1624 cirrusfb_WaitBLT(cinfo->regbase); /* make sure all the BLT's are done */
1659 1625
1660 /* lower 8 + 8 bits of screen start address */ 1626 /* lower 8 + 8 bits of screen start address */
1661 vga_wcrt (cinfo->regbase, VGA_CRTC_START_LO, (unsigned char) (base & 0xff)); 1627 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO,
1662 vga_wcrt (cinfo->regbase, VGA_CRTC_START_HI, (unsigned char) (base >> 8)); 1628 (unsigned char) (base & 0xff));
1629 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI,
1630 (unsigned char) (base >> 8));
1663 1631
1664 /* construct bits 16, 17 and 18 of screen start address */ 1632 /* construct bits 16, 17 and 18 of screen start address */
1665 if (base & 0x10000) 1633 if (base & 0x10000)
@@ -1669,50 +1637,49 @@ static int cirrusfb_pan_display (struct fb_var_screeninfo *var,
1669 if (base & 0x40000) 1637 if (base & 0x40000)
1670 tmp |= 0x08; 1638 tmp |= 0x08;
1671 1639
1672 tmp2 = (vga_rcrt (cinfo->regbase, CL_CRT1B) & 0xf2) | tmp; /* 0xf2 is %11110010, exclude tmp bits */ 1640 /* 0xf2 is %11110010, exclude tmp bits */
1673 vga_wcrt (cinfo->regbase, CL_CRT1B, tmp2); 1641 tmp2 = (vga_rcrt(cinfo->regbase, CL_CRT1B) & 0xf2) | tmp;
1642 vga_wcrt(cinfo->regbase, CL_CRT1B, tmp2);
1674 1643
1675 /* construct bit 19 of screen start address */ 1644 /* construct bit 19 of screen start address */
1676 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19) { 1645 if (cirrusfb_board_info[cinfo->btype].scrn_start_bit19)
1677 tmp2 = 0; 1646 vga_wcrt(cinfo->regbase, CL_CRT1D, (base >> 12) & 0x80);
1678 if (base & 0x80000)
1679 tmp2 = 0x80;
1680 vga_wcrt (cinfo->regbase, CL_CRT1D, tmp2);
1681 }
1682 1647
1683 /* write pixel panning value to AR33; this does not quite work in 8bpp */ 1648 /* write pixel panning value to AR33; this does not quite work in 8bpp
1684 /* ### Piccolo..? Will this work? */ 1649 *
1650 * ### Piccolo..? Will this work?
1651 */
1685 if (info->var.bits_per_pixel == 1) 1652 if (info->var.bits_per_pixel == 1)
1686 vga_wattr (cinfo->regbase, CL_AR33, xpix); 1653 vga_wattr(cinfo->regbase, CL_AR33, xpix);
1687 1654
1688 cirrusfb_WaitBLT (cinfo->regbase); 1655 cirrusfb_WaitBLT(cinfo->regbase);
1689 1656
1690 DPRINTK ("EXIT\n"); 1657 DPRINTK("EXIT\n");
1691 return (0); 1658 return 0;
1692} 1659}
1693 1660
1694 1661static int cirrusfb_blank(int blank_mode, struct fb_info *info)
1695static int cirrusfb_blank (int blank_mode, struct fb_info *info)
1696{ 1662{
1697 /* 1663 /*
1698 * Blank the screen if blank_mode != 0, else unblank. If blank == NULL 1664 * Blank the screen if blank_mode != 0, else unblank. If blank == NULL
1699 * then the caller blanks by setting the CLUT (Color Look Up Table) to all 1665 * then the caller blanks by setting the CLUT (Color Look Up Table)
1700 * black. Return 0 if blanking succeeded, != 0 if un-/blanking failed due 1666 * to all black. Return 0 if blanking succeeded, != 0 if un-/blanking
1701 * to e.g. a video mode which doesn't support it. Implements VESA suspend 1667 * failed due to e.g. a video mode which doesn't support it.
1702 * and powerdown modes on hardware that supports disabling hsync/vsync: 1668 * Implements VESA suspend and powerdown modes on hardware that
1703 * blank_mode == 2: suspend vsync 1669 * supports disabling hsync/vsync:
1704 * blank_mode == 3: suspend hsync 1670 * blank_mode == 2: suspend vsync
1705 * blank_mode == 4: powerdown 1671 * blank_mode == 3: suspend hsync
1672 * blank_mode == 4: powerdown
1706 */ 1673 */
1707 unsigned char val; 1674 unsigned char val;
1708 struct cirrusfb_info *cinfo = info->par; 1675 struct cirrusfb_info *cinfo = info->par;
1709 int current_mode = cinfo->blank_mode; 1676 int current_mode = cinfo->blank_mode;
1710 1677
1711 DPRINTK ("ENTER, blank mode = %d\n", blank_mode); 1678 DPRINTK("ENTER, blank mode = %d\n", blank_mode);
1712 1679
1713 if (info->state != FBINFO_STATE_RUNNING || 1680 if (info->state != FBINFO_STATE_RUNNING ||
1714 current_mode == blank_mode) { 1681 current_mode == blank_mode) {
1715 DPRINTK ("EXIT, returning 0\n"); 1682 DPRINTK("EXIT, returning 0\n");
1716 return 0; 1683 return 0;
1717 } 1684 }
1718 1685
@@ -1720,17 +1687,19 @@ static int cirrusfb_blank (int blank_mode, struct fb_info *info)
1720 if (current_mode == FB_BLANK_NORMAL || 1687 if (current_mode == FB_BLANK_NORMAL ||
1721 current_mode == FB_BLANK_UNBLANK) { 1688 current_mode == FB_BLANK_UNBLANK) {
1722 /* unblank the screen */ 1689 /* unblank the screen */
1723 val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE); 1690 val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
1724 vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf); /* clear "FullBandwidth" bit */ 1691 /* clear "FullBandwidth" bit */
1692 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val & 0xdf);
1725 /* and undo VESA suspend trickery */ 1693 /* and undo VESA suspend trickery */
1726 vga_wgfx (cinfo->regbase, CL_GRE, 0x00); 1694 vga_wgfx(cinfo->regbase, CL_GRE, 0x00);
1727 } 1695 }
1728 1696
1729 /* set new */ 1697 /* set new */
1730 if(blank_mode > FB_BLANK_NORMAL) { 1698 if (blank_mode > FB_BLANK_NORMAL) {
1731 /* blank the screen */ 1699 /* blank the screen */
1732 val = vga_rseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE); 1700 val = vga_rseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE);
1733 vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20); /* set "FullBandwidth" bit */ 1701 /* set "FullBandwidth" bit */
1702 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, val | 0x20);
1734 } 1703 }
1735 1704
1736 switch (blank_mode) { 1705 switch (blank_mode) {
@@ -1738,21 +1707,21 @@ static int cirrusfb_blank (int blank_mode, struct fb_info *info)
1738 case FB_BLANK_NORMAL: 1707 case FB_BLANK_NORMAL:
1739 break; 1708 break;
1740 case FB_BLANK_VSYNC_SUSPEND: 1709 case FB_BLANK_VSYNC_SUSPEND:
1741 vga_wgfx (cinfo->regbase, CL_GRE, 0x04); 1710 vga_wgfx(cinfo->regbase, CL_GRE, 0x04);
1742 break; 1711 break;
1743 case FB_BLANK_HSYNC_SUSPEND: 1712 case FB_BLANK_HSYNC_SUSPEND:
1744 vga_wgfx (cinfo->regbase, CL_GRE, 0x02); 1713 vga_wgfx(cinfo->regbase, CL_GRE, 0x02);
1745 break; 1714 break;
1746 case FB_BLANK_POWERDOWN: 1715 case FB_BLANK_POWERDOWN:
1747 vga_wgfx (cinfo->regbase, CL_GRE, 0x06); 1716 vga_wgfx(cinfo->regbase, CL_GRE, 0x06);
1748 break; 1717 break;
1749 default: 1718 default:
1750 DPRINTK ("EXIT, returning 1\n"); 1719 DPRINTK("EXIT, returning 1\n");
1751 return 1; 1720 return 1;
1752 } 1721 }
1753 1722
1754 cinfo->blank_mode = blank_mode; 1723 cinfo->blank_mode = blank_mode;
1755 DPRINTK ("EXIT, returning 0\n"); 1724 DPRINTK("EXIT, returning 0\n");
1756 1725
1757 /* Let fbcon do a soft blank for us */ 1726 /* Let fbcon do a soft blank for us */
1758 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0; 1727 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
@@ -1761,45 +1730,51 @@ static int cirrusfb_blank (int blank_mode, struct fb_info *info)
1761/****************************************************************************/ 1730/****************************************************************************/
1762/**** BEGIN Internal Routines ***********************************************/ 1731/**** BEGIN Internal Routines ***********************************************/
1763 1732
1764static void init_vgachip (struct cirrusfb_info *cinfo) 1733static void init_vgachip(struct fb_info *info)
1765{ 1734{
1735 struct cirrusfb_info *cinfo = info->par;
1766 const struct cirrusfb_board_info_rec *bi; 1736 const struct cirrusfb_board_info_rec *bi;
1767 1737
1768 DPRINTK ("ENTER\n"); 1738 DPRINTK("ENTER\n");
1769 1739
1770 assert (cinfo != NULL); 1740 assert(cinfo != NULL);
1771 1741
1772 bi = &cirrusfb_board_info[cinfo->btype]; 1742 bi = &cirrusfb_board_info[cinfo->btype];
1773 1743
1774 /* reset board globally */ 1744 /* reset board globally */
1775 switch (cinfo->btype) { 1745 switch (cinfo->btype) {
1776 case BT_PICCOLO: 1746 case BT_PICCOLO:
1777 WSFR (cinfo, 0x01); 1747 WSFR(cinfo, 0x01);
1778 udelay (500); 1748 udelay(500);
1779 WSFR (cinfo, 0x51); 1749 WSFR(cinfo, 0x51);
1780 udelay (500); 1750 udelay(500);
1781 break; 1751 break;
1782 case BT_PICASSO: 1752 case BT_PICASSO:
1783 WSFR2 (cinfo, 0xff); 1753 WSFR2(cinfo, 0xff);
1784 udelay (500); 1754 udelay(500);
1785 break; 1755 break;
1786 case BT_SD64: 1756 case BT_SD64:
1787 case BT_SPECTRUM: 1757 case BT_SPECTRUM:
1788 WSFR (cinfo, 0x1f); 1758 WSFR(cinfo, 0x1f);
1789 udelay (500); 1759 udelay(500);
1790 WSFR (cinfo, 0x4f); 1760 WSFR(cinfo, 0x4f);
1791 udelay (500); 1761 udelay(500);
1792 break; 1762 break;
1793 case BT_PICASSO4: 1763 case BT_PICASSO4:
1794 vga_wcrt (cinfo->regbase, CL_CRT51, 0x00); /* disable flickerfixer */ 1764 /* disable flickerfixer */
1795 mdelay (100); 1765 vga_wcrt(cinfo->regbase, CL_CRT51, 0x00);
1796 vga_wgfx (cinfo->regbase, CL_GR2F, 0x00); /* from Klaus' NetBSD driver: */ 1766 mdelay(100);
1797 vga_wgfx (cinfo->regbase, CL_GR33, 0x00); /* put blitter into 542x compat */ 1767 /* from Klaus' NetBSD driver: */
1798 vga_wgfx (cinfo->regbase, CL_GR31, 0x00); /* mode */ 1768 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1769 /* put blitter into 542x compat */
1770 vga_wgfx(cinfo->regbase, CL_GR33, 0x00);
1771 /* mode */
1772 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1799 break; 1773 break;
1800 1774
1801 case BT_GD5480: 1775 case BT_GD5480:
1802 vga_wgfx (cinfo->regbase, CL_GR2F, 0x00); /* from Klaus' NetBSD driver: */ 1776 /* from Klaus' NetBSD driver: */
1777 vga_wgfx(cinfo->regbase, CL_GR2F, 0x00);
1803 break; 1778 break;
1804 1779
1805 case BT_ALPINE: 1780 case BT_ALPINE:
@@ -1807,153 +1782,208 @@ static void init_vgachip (struct cirrusfb_info *cinfo)
1807 break; 1782 break;
1808 1783
1809 default: 1784 default:
1810 printk (KERN_ERR "cirrusfb: Warning: Unknown board type\n"); 1785 printk(KERN_ERR "cirrusfb: Warning: Unknown board type\n");
1811 break; 1786 break;
1812 } 1787 }
1813 1788
1814 assert (cinfo->size > 0); /* make sure RAM size set by this point */ 1789 /* make sure RAM size set by this point */
1790 assert(info->screen_size > 0);
1815 1791
1816 /* the P4 is not fully initialized here; I rely on it having been */ 1792 /* the P4 is not fully initialized here; I rely on it having been */
1817 /* inited under AmigaOS already, which seems to work just fine */ 1793 /* inited under AmigaOS already, which seems to work just fine */
1818 /* (Klaus advised to do it this way) */ 1794 /* (Klaus advised to do it this way) */
1819 1795
1820 if (cinfo->btype != BT_PICASSO4) { 1796 if (cinfo->btype != BT_PICASSO4) {
1821 WGen (cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */ 1797 WGen(cinfo, CL_VSSM, 0x10); /* EGS: 0x16 */
1822 WGen (cinfo, CL_POS102, 0x01); 1798 WGen(cinfo, CL_POS102, 0x01);
1823 WGen (cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */ 1799 WGen(cinfo, CL_VSSM, 0x08); /* EGS: 0x0e */
1824 1800
1825 if (cinfo->btype != BT_SD64) 1801 if (cinfo->btype != BT_SD64)
1826 WGen (cinfo, CL_VSSM2, 0x01); 1802 WGen(cinfo, CL_VSSM2, 0x01);
1827 1803
1828 vga_wseq (cinfo->regbase, CL_SEQR0, 0x03); /* reset sequencer logic */ 1804 /* reset sequencer logic */
1805 vga_wseq(cinfo->regbase, CL_SEQR0, 0x03);
1829 1806
1830 vga_wseq (cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21); /* FullBandwidth (video off) and 8/9 dot clock */ 1807 /* FullBandwidth (video off) and 8/9 dot clock */
1831 WGen (cinfo, VGA_MIS_W, 0xc1); /* polarity (-/-), disable access to display memory, VGA_CRTC_START_HI base address: color */ 1808 vga_wseq(cinfo->regbase, VGA_SEQ_CLOCK_MODE, 0x21);
1809 /* polarity (-/-), disable access to display memory,
1810 * VGA_CRTC_START_HI base address: color
1811 */
1812 WGen(cinfo, VGA_MIS_W, 0xc1);
1832 1813
1833/* vga_wgfx (cinfo->regbase, CL_GRA, 0xce); "magic cookie" - doesn't make any sense to me.. */ 1814 /* "magic cookie" - doesn't make any sense to me.. */
1834 vga_wseq (cinfo->regbase, CL_SEQR6, 0x12); /* unlock all extension registers */ 1815/* vga_wgfx(cinfo->regbase, CL_GRA, 0xce); */
1816 /* unlock all extension registers */
1817 vga_wseq(cinfo->regbase, CL_SEQR6, 0x12);
1835 1818
1836 vga_wgfx (cinfo->regbase, CL_GR31, 0x04); /* reset blitter */ 1819 /* reset blitter */
1820 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1837 1821
1838 switch (cinfo->btype) { 1822 switch (cinfo->btype) {
1839 case BT_GD5480: 1823 case BT_GD5480:
1840 vga_wseq (cinfo->regbase, CL_SEQRF, 0x98); 1824 vga_wseq(cinfo->regbase, CL_SEQRF, 0x98);
1841 break; 1825 break;
1842 case BT_ALPINE: 1826 case BT_ALPINE:
1843 break; 1827 break;
1844 case BT_SD64: 1828 case BT_SD64:
1845 vga_wseq (cinfo->regbase, CL_SEQRF, 0xb8); 1829 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb8);
1846 break; 1830 break;
1847 default: 1831 default:
1848 vga_wseq (cinfo->regbase, CL_SEQR16, 0x0f); 1832 vga_wseq(cinfo->regbase, CL_SEQR16, 0x0f);
1849 vga_wseq (cinfo->regbase, CL_SEQRF, 0xb0); 1833 vga_wseq(cinfo->regbase, CL_SEQRF, 0xb0);
1850 break; 1834 break;
1851 } 1835 }
1852 } 1836 }
1853 vga_wseq (cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff); /* plane mask: nothing */ 1837 /* plane mask: nothing */
1854 vga_wseq (cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00); /* character map select: doesn't even matter in gx mode */ 1838 vga_wseq(cinfo->regbase, VGA_SEQ_PLANE_WRITE, 0xff);
1855 vga_wseq (cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e); /* memory mode: chain-4, no odd/even, ext. memory */ 1839 /* character map select: doesn't even matter in gx mode */
1840 vga_wseq(cinfo->regbase, VGA_SEQ_CHARACTER_MAP, 0x00);
1841 /* memory mode: chain-4, no odd/even, ext. memory */
1842 vga_wseq(cinfo->regbase, VGA_SEQ_MEMORY_MODE, 0x0e);
1856 1843
1857 /* controller-internal base address of video memory */ 1844 /* controller-internal base address of video memory */
1858 if (bi->init_sr07) 1845 if (bi->init_sr07)
1859 vga_wseq (cinfo->regbase, CL_SEQR7, bi->sr07); 1846 vga_wseq(cinfo->regbase, CL_SEQR7, bi->sr07);
1860 1847
1861 /* vga_wseq (cinfo->regbase, CL_SEQR8, 0x00); *//* EEPROM control: shouldn't be necessary to write to this at all.. */ 1848 /* vga_wseq(cinfo->regbase, CL_SEQR8, 0x00); */
1849 /* EEPROM control: shouldn't be necessary to write to this at all.. */
1862 1850
1863 vga_wseq (cinfo->regbase, CL_SEQR10, 0x00); /* graphics cursor X position (incomplete; position gives rem. 3 bits */ 1851 /* graphics cursor X position (incomplete; position gives rem. 3 bits */
1864 vga_wseq (cinfo->regbase, CL_SEQR11, 0x00); /* graphics cursor Y position (..."... ) */ 1852 vga_wseq(cinfo->regbase, CL_SEQR10, 0x00);
1865 vga_wseq (cinfo->regbase, CL_SEQR12, 0x00); /* graphics cursor attributes */ 1853 /* graphics cursor Y position (..."... ) */
1866 vga_wseq (cinfo->regbase, CL_SEQR13, 0x00); /* graphics cursor pattern address */ 1854 vga_wseq(cinfo->regbase, CL_SEQR11, 0x00);
1855 /* graphics cursor attributes */
1856 vga_wseq(cinfo->regbase, CL_SEQR12, 0x00);
1857 /* graphics cursor pattern address */
1858 vga_wseq(cinfo->regbase, CL_SEQR13, 0x00);
1867 1859
1868 /* writing these on a P4 might give problems.. */ 1860 /* writing these on a P4 might give problems.. */
1869 if (cinfo->btype != BT_PICASSO4) { 1861 if (cinfo->btype != BT_PICASSO4) {
1870 vga_wseq (cinfo->regbase, CL_SEQR17, 0x00); /* configuration readback and ext. color */ 1862 /* configuration readback and ext. color */
1871 vga_wseq (cinfo->regbase, CL_SEQR18, 0x02); /* signature generator */ 1863 vga_wseq(cinfo->regbase, CL_SEQR17, 0x00);
1864 /* signature generator */
1865 vga_wseq(cinfo->regbase, CL_SEQR18, 0x02);
1872 } 1866 }
1873 1867
1874 /* MCLK select etc. */ 1868 /* MCLK select etc. */
1875 if (bi->init_sr1f) 1869 if (bi->init_sr1f)
1876 vga_wseq (cinfo->regbase, CL_SEQR1F, bi->sr1f); 1870 vga_wseq(cinfo->regbase, CL_SEQR1F, bi->sr1f);
1877 1871
1878 vga_wcrt (cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00); /* Screen A preset row scan: none */ 1872 /* Screen A preset row scan: none */
1879 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20); /* Text cursor start: disable text cursor */ 1873 vga_wcrt(cinfo->regbase, VGA_CRTC_PRESET_ROW, 0x00);
1880 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00); /* Text cursor end: - */ 1874 /* Text cursor start: disable text cursor */
1881 vga_wcrt (cinfo->regbase, VGA_CRTC_START_HI, 0x00); /* Screen start address high: 0 */ 1875 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_START, 0x20);
1882 vga_wcrt (cinfo->regbase, VGA_CRTC_START_LO, 0x00); /* Screen start address low: 0 */ 1876 /* Text cursor end: - */
1883 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00); /* text cursor location high: 0 */ 1877 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_END, 0x00);
1884 vga_wcrt (cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00); /* text cursor location low: 0 */ 1878 /* Screen start address high: 0 */
1885 1879 vga_wcrt(cinfo->regbase, VGA_CRTC_START_HI, 0x00);
1886 vga_wcrt (cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00); /* Underline Row scanline: - */ 1880 /* Screen start address low: 0 */
1887 vga_wcrt (cinfo->regbase, VGA_CRTC_MODE, 0xc3); /* mode control: timing enable, byte mode, no compat modes */ 1881 vga_wcrt(cinfo->regbase, VGA_CRTC_START_LO, 0x00);
1888 vga_wcrt (cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00); /* Line Compare: not needed */ 1882 /* text cursor location high: 0 */
1883 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_HI, 0x00);
1884 /* text cursor location low: 0 */
1885 vga_wcrt(cinfo->regbase, VGA_CRTC_CURSOR_LO, 0x00);
1886
1887 /* Underline Row scanline: - */
1888 vga_wcrt(cinfo->regbase, VGA_CRTC_UNDERLINE, 0x00);
1889 /* mode control: timing enable, byte mode, no compat modes */
1890 vga_wcrt(cinfo->regbase, VGA_CRTC_MODE, 0xc3);
1891 /* Line Compare: not needed */
1892 vga_wcrt(cinfo->regbase, VGA_CRTC_LINE_COMPARE, 0x00);
1889 /* ### add 0x40 for text modes with > 30 MHz pixclock */ 1893 /* ### add 0x40 for text modes with > 30 MHz pixclock */
1890 vga_wcrt (cinfo->regbase, CL_CRT1B, 0x02); /* ext. display controls: ext.adr. wrap */ 1894 /* ext. display controls: ext.adr. wrap */
1891 1895 vga_wcrt(cinfo->regbase, CL_CRT1B, 0x02);
1892 vga_wgfx (cinfo->regbase, VGA_GFX_SR_VALUE, 0x00); /* Set/Reset registes: - */ 1896
1893 vga_wgfx (cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00); /* Set/Reset enable: - */ 1897 /* Set/Reset registes: - */
1894 vga_wgfx (cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00); /* Color Compare: - */ 1898 vga_wgfx(cinfo->regbase, VGA_GFX_SR_VALUE, 0x00);
1895 vga_wgfx (cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00); /* Data Rotate: - */ 1899 /* Set/Reset enable: - */
1896 vga_wgfx (cinfo->regbase, VGA_GFX_PLANE_READ, 0x00); /* Read Map Select: - */ 1900 vga_wgfx(cinfo->regbase, VGA_GFX_SR_ENABLE, 0x00);
1897 vga_wgfx (cinfo->regbase, VGA_GFX_MODE, 0x00); /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */ 1901 /* Color Compare: - */
1898 vga_wgfx (cinfo->regbase, VGA_GFX_MISC, 0x01); /* Miscellaneous: memory map base address, graphics mode */ 1902 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_VALUE, 0x00);
1899 vga_wgfx (cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f); /* Color Don't care: involve all planes */ 1903 /* Data Rotate: - */
1900 vga_wgfx (cinfo->regbase, VGA_GFX_BIT_MASK, 0xff); /* Bit Mask: no mask at all */ 1904 vga_wgfx(cinfo->regbase, VGA_GFX_DATA_ROTATE, 0x00);
1905 /* Read Map Select: - */
1906 vga_wgfx(cinfo->regbase, VGA_GFX_PLANE_READ, 0x00);
1907 /* Mode: conf. for 16/4/2 color mode, no odd/even, read/write mode 0 */
1908 vga_wgfx(cinfo->regbase, VGA_GFX_MODE, 0x00);
1909 /* Miscellaneous: memory map base address, graphics mode */
1910 vga_wgfx(cinfo->regbase, VGA_GFX_MISC, 0x01);
1911 /* Color Don't care: involve all planes */
1912 vga_wgfx(cinfo->regbase, VGA_GFX_COMPARE_MASK, 0x0f);
1913 /* Bit Mask: no mask at all */
1914 vga_wgfx(cinfo->regbase, VGA_GFX_BIT_MASK, 0xff);
1901 if (cinfo->btype == BT_ALPINE) 1915 if (cinfo->btype == BT_ALPINE)
1902 vga_wgfx (cinfo->regbase, CL_GRB, 0x20); /* (5434 can't have bit 3 set for bitblt) */ 1916 /* (5434 can't have bit 3 set for bitblt) */
1917 vga_wgfx(cinfo->regbase, CL_GRB, 0x20);
1903 else 1918 else
1904 vga_wgfx (cinfo->regbase, CL_GRB, 0x28); /* Graphics controller mode extensions: finer granularity, 8byte data latches */ 1919 /* Graphics controller mode extensions: finer granularity,
1905 1920 * 8byte data latches
1906 vga_wgfx (cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */ 1921 */
1907 vga_wgfx (cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */ 1922 vga_wgfx(cinfo->regbase, CL_GRB, 0x28);
1908 vga_wgfx (cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */ 1923
1909 /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); *//* Background color byte 1: - */ 1924 vga_wgfx(cinfo->regbase, CL_GRC, 0xff); /* Color Key compare: - */
1910/* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */ 1925 vga_wgfx(cinfo->regbase, CL_GRD, 0x00); /* Color Key compare mask: - */
1911 1926 vga_wgfx(cinfo->regbase, CL_GRE, 0x00); /* Miscellaneous control: - */
1912 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE0, 0x00); /* Attribute Controller palette registers: "identity mapping" */ 1927 /* Background color byte 1: - */
1913 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE1, 0x01); 1928 /* vga_wgfx (cinfo->regbase, CL_GR10, 0x00); */
1914 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE2, 0x02); 1929 /* vga_wgfx (cinfo->regbase, CL_GR11, 0x00); */
1915 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE3, 0x03); 1930
1916 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE4, 0x04); 1931 /* Attribute Controller palette registers: "identity mapping" */
1917 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE5, 0x05); 1932 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE0, 0x00);
1918 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE6, 0x06); 1933 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE1, 0x01);
1919 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE7, 0x07); 1934 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE2, 0x02);
1920 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE8, 0x08); 1935 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE3, 0x03);
1921 vga_wattr (cinfo->regbase, VGA_ATC_PALETTE9, 0x09); 1936 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE4, 0x04);
1922 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEA, 0x0a); 1937 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE5, 0x05);
1923 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEB, 0x0b); 1938 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE6, 0x06);
1924 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEC, 0x0c); 1939 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE7, 0x07);
1925 vga_wattr (cinfo->regbase, VGA_ATC_PALETTED, 0x0d); 1940 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE8, 0x08);
1926 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEE, 0x0e); 1941 vga_wattr(cinfo->regbase, VGA_ATC_PALETTE9, 0x09);
1927 vga_wattr (cinfo->regbase, VGA_ATC_PALETTEF, 0x0f); 1942 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEA, 0x0a);
1928 1943 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEB, 0x0b);
1929 vga_wattr (cinfo->regbase, VGA_ATC_MODE, 0x01); /* Attribute Controller mode: graphics mode */ 1944 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEC, 0x0c);
1930 vga_wattr (cinfo->regbase, VGA_ATC_OVERSCAN, 0x00); /* Overscan color reg.: reg. 0 */ 1945 vga_wattr(cinfo->regbase, VGA_ATC_PALETTED, 0x0d);
1931 vga_wattr (cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f); /* Color Plane enable: Enable all 4 planes */ 1946 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEE, 0x0e);
1932/* ### vga_wattr (cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */ 1947 vga_wattr(cinfo->regbase, VGA_ATC_PALETTEF, 0x0f);
1933 vga_wattr (cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00); /* Color Select: - */ 1948
1934 1949 /* Attribute Controller mode: graphics mode */
1935 WGen (cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */ 1950 vga_wattr(cinfo->regbase, VGA_ATC_MODE, 0x01);
1951 /* Overscan color reg.: reg. 0 */
1952 vga_wattr(cinfo->regbase, VGA_ATC_OVERSCAN, 0x00);
1953 /* Color Plane enable: Enable all 4 planes */
1954 vga_wattr(cinfo->regbase, VGA_ATC_PLANE_ENABLE, 0x0f);
1955/* ### vga_wattr(cinfo->regbase, CL_AR33, 0x00); * Pixel Panning: - */
1956 /* Color Select: - */
1957 vga_wattr(cinfo->regbase, VGA_ATC_COLOR_PAGE, 0x00);
1958
1959 WGen(cinfo, VGA_PEL_MSK, 0xff); /* Pixel mask: no mask */
1936 1960
1937 if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480) 1961 if (cinfo->btype != BT_ALPINE && cinfo->btype != BT_GD5480)
1938 WGen (cinfo, VGA_MIS_W, 0xc3); /* polarity (-/-), enable display mem, VGA_CRTC_START_HI i/o base = color */ 1962 /* polarity (-/-), enable display mem,
1963 * VGA_CRTC_START_HI i/o base = color
1964 */
1965 WGen(cinfo, VGA_MIS_W, 0xc3);
1939 1966
1940 vga_wgfx (cinfo->regbase, CL_GR31, 0x04); /* BLT Start/status: Blitter reset */ 1967 /* BLT Start/status: Blitter reset */
1941 vga_wgfx (cinfo->regbase, CL_GR31, 0x00); /* - " - : "end-of-reset" */ 1968 vga_wgfx(cinfo->regbase, CL_GR31, 0x04);
1969 /* - " - : "end-of-reset" */
1970 vga_wgfx(cinfo->regbase, CL_GR31, 0x00);
1942 1971
1943 /* misc... */ 1972 /* misc... */
1944 WHDR (cinfo, 0); /* Hidden DAC register: - */ 1973 WHDR(cinfo, 0); /* Hidden DAC register: - */
1945 1974
1946 printk (KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n", cinfo->size); 1975 printk(KERN_DEBUG "cirrusfb: This board has %ld bytes of DRAM memory\n",
1947 DPRINTK ("EXIT\n"); 1976 info->screen_size);
1977 DPRINTK("EXIT\n");
1948 return; 1978 return;
1949} 1979}
1950 1980
1951static void switch_monitor (struct cirrusfb_info *cinfo, int on) 1981static void switch_monitor(struct cirrusfb_info *cinfo, int on)
1952{ 1982{
1953#ifdef CONFIG_ZORRO /* only works on Zorro boards */ 1983#ifdef CONFIG_ZORRO /* only works on Zorro boards */
1954 static int IsOn = 0; /* XXX not ok for multiple boards */ 1984 static int IsOn = 0; /* XXX not ok for multiple boards */
1955 1985
1956 DPRINTK ("ENTER\n"); 1986 DPRINTK("ENTER\n");
1957 1987
1958 if (cinfo->btype == BT_PICASSO4) 1988 if (cinfo->btype == BT_PICASSO4)
1959 return; /* nothing to switch */ 1989 return; /* nothing to switch */
@@ -1963,77 +1993,56 @@ static void switch_monitor (struct cirrusfb_info *cinfo, int on)
1963 return; /* nothing to switch */ 1993 return; /* nothing to switch */
1964 if (cinfo->btype == BT_PICASSO) { 1994 if (cinfo->btype == BT_PICASSO) {
1965 if ((on && !IsOn) || (!on && IsOn)) 1995 if ((on && !IsOn) || (!on && IsOn))
1966 WSFR (cinfo, 0xff); 1996 WSFR(cinfo, 0xff);
1967 1997
1968 DPRINTK ("EXIT\n"); 1998 DPRINTK("EXIT\n");
1969 return; 1999 return;
1970 } 2000 }
1971 if (on) { 2001 if (on) {
1972 switch (cinfo->btype) { 2002 switch (cinfo->btype) {
1973 case BT_SD64: 2003 case BT_SD64:
1974 WSFR (cinfo, cinfo->SFR | 0x21); 2004 WSFR(cinfo, cinfo->SFR | 0x21);
1975 break; 2005 break;
1976 case BT_PICCOLO: 2006 case BT_PICCOLO:
1977 WSFR (cinfo, cinfo->SFR | 0x28); 2007 WSFR(cinfo, cinfo->SFR | 0x28);
1978 break; 2008 break;
1979 case BT_SPECTRUM: 2009 case BT_SPECTRUM:
1980 WSFR (cinfo, 0x6f); 2010 WSFR(cinfo, 0x6f);
1981 break; 2011 break;
1982 default: /* do nothing */ break; 2012 default: /* do nothing */ break;
1983 } 2013 }
1984 } else { 2014 } else {
1985 switch (cinfo->btype) { 2015 switch (cinfo->btype) {
1986 case BT_SD64: 2016 case BT_SD64:
1987 WSFR (cinfo, cinfo->SFR & 0xde); 2017 WSFR(cinfo, cinfo->SFR & 0xde);
1988 break; 2018 break;
1989 case BT_PICCOLO: 2019 case BT_PICCOLO:
1990 WSFR (cinfo, cinfo->SFR & 0xd7); 2020 WSFR(cinfo, cinfo->SFR & 0xd7);
1991 break; 2021 break;
1992 case BT_SPECTRUM: 2022 case BT_SPECTRUM:
1993 WSFR (cinfo, 0x4f); 2023 WSFR(cinfo, 0x4f);
1994 break; 2024 break;
1995 default: /* do nothing */ break; 2025 default: /* do nothing */ break;
1996 } 2026 }
1997 } 2027 }
1998 2028
1999 DPRINTK ("EXIT\n"); 2029 DPRINTK("EXIT\n");
2000#endif /* CONFIG_ZORRO */ 2030#endif /* CONFIG_ZORRO */
2001} 2031}
2002 2032
2003
2004/******************************************/ 2033/******************************************/
2005/* Linux 2.6-style accelerated functions */ 2034/* Linux 2.6-style accelerated functions */
2006/******************************************/ 2035/******************************************/
2007 2036
2008static void cirrusfb_prim_fillrect(struct cirrusfb_info *cinfo, 2037static void cirrusfb_fillrect(struct fb_info *info,
2009 const struct fb_fillrect *region) 2038 const struct fb_fillrect *region)
2010{
2011 int m; /* bytes per pixel */
2012 u32 color = (cinfo->info->fix.visual == FB_VISUAL_TRUECOLOR) ?
2013 cinfo->pseudo_palette[region->color] : region->color;
2014
2015 if(cinfo->info->var.bits_per_pixel == 1) {
2016 cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2017 region->dx / 8, region->dy,
2018 region->width / 8, region->height,
2019 color,
2020 cinfo->currentmode.line_length);
2021 } else {
2022 m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8;
2023 cirrusfb_RectFill(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2024 region->dx * m, region->dy,
2025 region->width * m, region->height,
2026 color,
2027 cinfo->currentmode.line_length);
2028 }
2029 return;
2030}
2031
2032static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *region)
2033{ 2039{
2034 struct cirrusfb_info *cinfo = info->par;
2035 struct fb_fillrect modded; 2040 struct fb_fillrect modded;
2036 int vxres, vyres; 2041 int vxres, vyres;
2042 struct cirrusfb_info *cinfo = info->par;
2043 int m = info->var.bits_per_pixel;
2044 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
2045 cinfo->pseudo_palette[region->color] : region->color;
2037 2046
2038 if (info->state != FBINFO_STATE_RUNNING) 2047 if (info->state != FBINFO_STATE_RUNNING)
2039 return; 2048 return;
@@ -2047,49 +2056,30 @@ static void cirrusfb_fillrect (struct fb_info *info, const struct fb_fillrect *r
2047 2056
2048 memcpy(&modded, region, sizeof(struct fb_fillrect)); 2057 memcpy(&modded, region, sizeof(struct fb_fillrect));
2049 2058
2050 if(!modded.width || !modded.height || 2059 if (!modded.width || !modded.height ||
2051 modded.dx >= vxres || modded.dy >= vyres) 2060 modded.dx >= vxres || modded.dy >= vyres)
2052 return; 2061 return;
2053 2062
2054 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; 2063 if (modded.dx + modded.width > vxres)
2055 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; 2064 modded.width = vxres - modded.dx;
2056 2065 if (modded.dy + modded.height > vyres)
2057 cirrusfb_prim_fillrect(cinfo, &modded); 2066 modded.height = vyres - modded.dy;
2058} 2067
2059 2068 cirrusfb_RectFill(cinfo->regbase,
2060static void cirrusfb_prim_copyarea(struct cirrusfb_info *cinfo, 2069 info->var.bits_per_pixel,
2061 const struct fb_copyarea *area) 2070 (region->dx * m) / 8, region->dy,
2062{ 2071 (region->width * m) / 8, region->height,
2063 int m; /* bytes per pixel */ 2072 color,
2064 if(cinfo->info->var.bits_per_pixel == 1) { 2073 info->fix.line_length);
2065 cirrusfb_BitBLT(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2066 area->sx / 8, area->sy,
2067 area->dx / 8, area->dy,
2068 area->width / 8, area->height,
2069 cinfo->currentmode.line_length);
2070 } else {
2071 m = ( cinfo->info->var.bits_per_pixel + 7 ) / 8;
2072 cirrusfb_BitBLT(cinfo->regbase, cinfo->info->var.bits_per_pixel,
2073 area->sx * m, area->sy,
2074 area->dx * m, area->dy,
2075 area->width * m, area->height,
2076 cinfo->currentmode.line_length);
2077 }
2078 return;
2079} 2074}
2080 2075
2081 2076static void cirrusfb_copyarea(struct fb_info *info,
2082static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 2077 const struct fb_copyarea *area)
2083{ 2078{
2084 struct cirrusfb_info *cinfo = info->par;
2085 struct fb_copyarea modded; 2079 struct fb_copyarea modded;
2086 u32 vxres, vyres; 2080 u32 vxres, vyres;
2087 modded.sx = area->sx; 2081 struct cirrusfb_info *cinfo = info->par;
2088 modded.sy = area->sy; 2082 int m = info->var.bits_per_pixel;
2089 modded.dx = area->dx;
2090 modded.dy = area->dy;
2091 modded.width = area->width;
2092 modded.height = area->height;
2093 2083
2094 if (info->state != FBINFO_STATE_RUNNING) 2084 if (info->state != FBINFO_STATE_RUNNING)
2095 return; 2085 return;
@@ -2100,90 +2090,106 @@ static void cirrusfb_copyarea(struct fb_info *info, const struct fb_copyarea *ar
2100 2090
2101 vxres = info->var.xres_virtual; 2091 vxres = info->var.xres_virtual;
2102 vyres = info->var.yres_virtual; 2092 vyres = info->var.yres_virtual;
2093 memcpy(&modded, area, sizeof(struct fb_copyarea));
2103 2094
2104 if(!modded.width || !modded.height || 2095 if (!modded.width || !modded.height ||
2105 modded.sx >= vxres || modded.sy >= vyres || 2096 modded.sx >= vxres || modded.sy >= vyres ||
2106 modded.dx >= vxres || modded.dy >= vyres) 2097 modded.dx >= vxres || modded.dy >= vyres)
2107 return; 2098 return;
2108 2099
2109 if(modded.sx + modded.width > vxres) modded.width = vxres - modded.sx; 2100 if (modded.sx + modded.width > vxres)
2110 if(modded.dx + modded.width > vxres) modded.width = vxres - modded.dx; 2101 modded.width = vxres - modded.sx;
2111 if(modded.sy + modded.height > vyres) modded.height = vyres - modded.sy; 2102 if (modded.dx + modded.width > vxres)
2112 if(modded.dy + modded.height > vyres) modded.height = vyres - modded.dy; 2103 modded.width = vxres - modded.dx;
2104 if (modded.sy + modded.height > vyres)
2105 modded.height = vyres - modded.sy;
2106 if (modded.dy + modded.height > vyres)
2107 modded.height = vyres - modded.dy;
2108
2109 cirrusfb_BitBLT(cinfo->regbase, info->var.bits_per_pixel,
2110 (area->sx * m) / 8, area->sy,
2111 (area->dx * m) / 8, area->dy,
2112 (area->width * m) / 8, area->height,
2113 info->fix.line_length);
2113 2114
2114 cirrusfb_prim_copyarea(cinfo, &modded);
2115} 2115}
2116 2116
2117static void cirrusfb_imageblit(struct fb_info *info, const struct fb_image *image) 2117static void cirrusfb_imageblit(struct fb_info *info,
2118 const struct fb_image *image)
2118{ 2119{
2119 struct cirrusfb_info *cinfo = info->par; 2120 struct cirrusfb_info *cinfo = info->par;
2120 2121
2121 cirrusfb_WaitBLT(cinfo->regbase); 2122 cirrusfb_WaitBLT(cinfo->regbase);
2122 cfb_imageblit(info, image); 2123 cfb_imageblit(info, image);
2123} 2124}
2124 2125
2125
2126#ifdef CONFIG_PPC_PREP 2126#ifdef CONFIG_PPC_PREP
2127#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000) 2127#define PREP_VIDEO_BASE ((volatile unsigned long) 0xC0000000)
2128#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000) 2128#define PREP_IO_BASE ((volatile unsigned char *) 0x80000000)
2129static void get_prep_addrs (unsigned long *display, unsigned long *registers) 2129static void get_prep_addrs(unsigned long *display, unsigned long *registers)
2130{ 2130{
2131 DPRINTK ("ENTER\n"); 2131 DPRINTK("ENTER\n");
2132 2132
2133 *display = PREP_VIDEO_BASE; 2133 *display = PREP_VIDEO_BASE;
2134 *registers = (unsigned long) PREP_IO_BASE; 2134 *registers = (unsigned long) PREP_IO_BASE;
2135 2135
2136 DPRINTK ("EXIT\n"); 2136 DPRINTK("EXIT\n");
2137} 2137}
2138 2138
2139#endif /* CONFIG_PPC_PREP */ 2139#endif /* CONFIG_PPC_PREP */
2140 2140
2141
2142#ifdef CONFIG_PCI 2141#ifdef CONFIG_PCI
2143static int release_io_ports = 0; 2142static int release_io_ports;
2144 2143
2145/* Pulled the logic from XFree86 Cirrus driver to get the memory size, 2144/* Pulled the logic from XFree86 Cirrus driver to get the memory size,
2146 * based on the DRAM bandwidth bit and DRAM bank switching bit. This 2145 * based on the DRAM bandwidth bit and DRAM bank switching bit. This
2147 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards 2146 * works with 1MB, 2MB and 4MB configurations (which the Motorola boards
2148 * seem to have. */ 2147 * seem to have. */
2149static unsigned int cirrusfb_get_memsize (u8 __iomem *regbase) 2148static unsigned int cirrusfb_get_memsize(u8 __iomem *regbase)
2150{ 2149{
2151 unsigned long mem; 2150 unsigned long mem;
2152 unsigned char SRF; 2151 unsigned char SRF;
2153 2152
2154 DPRINTK ("ENTER\n"); 2153 DPRINTK("ENTER\n");
2155 2154
2156 SRF = vga_rseq (regbase, CL_SEQRF); 2155 SRF = vga_rseq(regbase, CL_SEQRF);
2157 switch ((SRF & 0x18)) { 2156 switch ((SRF & 0x18)) {
2158 case 0x08: mem = 512 * 1024; break; 2157 case 0x08:
2159 case 0x10: mem = 1024 * 1024; break; 2158 mem = 512 * 1024;
2160 /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory 2159 break;
2161 * on the 5430. */ 2160 case 0x10:
2162 case 0x18: mem = 2048 * 1024; break; 2161 mem = 1024 * 1024;
2163 default: printk ("CLgenfb: Unknown memory size!\n"); 2162 break;
2163 /* 64-bit DRAM data bus width; assume 2MB. Also indicates 2MB memory
2164 * on the 5430.
2165 */
2166 case 0x18:
2167 mem = 2048 * 1024;
2168 break;
2169 default:
2170 printk(KERN_WARNING "CLgenfb: Unknown memory size!\n");
2164 mem = 1024 * 1024; 2171 mem = 1024 * 1024;
2165 } 2172 }
2166 if (SRF & 0x80) { 2173 if (SRF & 0x80)
2167 /* If DRAM bank switching is enabled, there must be twice as much 2174 /* If DRAM bank switching is enabled, there must be twice as much
2168 * memory installed. (4MB on the 5434) */ 2175 * memory installed. (4MB on the 5434)
2176 */
2169 mem *= 2; 2177 mem *= 2;
2170 } 2178
2171 /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */ 2179 /* TODO: Handling of GD5446/5480 (see XF86 sources ...) */
2172 2180
2173 DPRINTK ("EXIT\n"); 2181 DPRINTK("EXIT\n");
2174 return mem; 2182 return mem;
2175} 2183}
2176 2184
2177 2185static void get_pci_addrs(const struct pci_dev *pdev,
2178 2186 unsigned long *display, unsigned long *registers)
2179static void get_pci_addrs (const struct pci_dev *pdev,
2180 unsigned long *display, unsigned long *registers)
2181{ 2187{
2182 assert (pdev != NULL); 2188 assert(pdev != NULL);
2183 assert (display != NULL); 2189 assert(display != NULL);
2184 assert (registers != NULL); 2190 assert(registers != NULL);
2185 2191
2186 DPRINTK ("ENTER\n"); 2192 DPRINTK("ENTER\n");
2187 2193
2188 *display = 0; 2194 *display = 0;
2189 *registers = 0; 2195 *registers = 0;
@@ -2198,51 +2204,47 @@ static void get_pci_addrs (const struct pci_dev *pdev,
2198 *registers = pci_resource_start(pdev, 1); 2204 *registers = pci_resource_start(pdev, 1);
2199 } 2205 }
2200 2206
2201 assert (*display != 0); 2207 assert(*display != 0);
2202 2208
2203 DPRINTK ("EXIT\n"); 2209 DPRINTK("EXIT\n");
2204} 2210}
2205 2211
2206 2212static void cirrusfb_pci_unmap(struct fb_info *info)
2207static void cirrusfb_pci_unmap (struct cirrusfb_info *cinfo)
2208{ 2213{
2214 struct cirrusfb_info *cinfo = info->par;
2209 struct pci_dev *pdev = cinfo->pdev; 2215 struct pci_dev *pdev = cinfo->pdev;
2210 2216
2211 iounmap(cinfo->fbmem); 2217 iounmap(info->screen_base);
2212#if 0 /* if system didn't claim this region, we would... */ 2218#if 0 /* if system didn't claim this region, we would... */
2213 release_mem_region(0xA0000, 65535); 2219 release_mem_region(0xA0000, 65535);
2214#endif 2220#endif
2215 if (release_io_ports) 2221 if (release_io_ports)
2216 release_region(0x3C0, 32); 2222 release_region(0x3C0, 32);
2217 pci_release_regions(pdev); 2223 pci_release_regions(pdev);
2218 framebuffer_release(cinfo->info);
2219} 2224}
2220#endif /* CONFIG_PCI */ 2225#endif /* CONFIG_PCI */
2221 2226
2222
2223#ifdef CONFIG_ZORRO 2227#ifdef CONFIG_ZORRO
2224static void __devexit cirrusfb_zorro_unmap (struct cirrusfb_info *cinfo) 2228static void __devexit cirrusfb_zorro_unmap(struct cirrusfb_info *cinfo)
2225{ 2229{
2226 zorro_release_device(cinfo->zdev); 2230 zorro_release_device(cinfo->zdev);
2227 2231
2228 if (cinfo->btype == BT_PICASSO4) { 2232 if (cinfo->btype == BT_PICASSO4) {
2229 cinfo->regbase -= 0x600000; 2233 cinfo->regbase -= 0x600000;
2230 iounmap ((void *)cinfo->regbase); 2234 iounmap((void *)cinfo->regbase);
2231 iounmap ((void *)cinfo->fbmem); 2235 iounmap(info->screen_base);
2232 } else { 2236 } else {
2233 if (zorro_resource_start(cinfo->zdev) > 0x01000000) 2237 if (zorro_resource_start(cinfo->zdev) > 0x01000000)
2234 iounmap ((void *)cinfo->fbmem); 2238 iounmap(info->screen_base);
2235 } 2239 }
2236 framebuffer_release(cinfo->info);
2237} 2240}
2238#endif /* CONFIG_ZORRO */ 2241#endif /* CONFIG_ZORRO */
2239 2242
2240static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo) 2243static int cirrusfb_set_fbinfo(struct fb_info *info)
2241{ 2244{
2242 struct fb_info *info = cinfo->info; 2245 struct cirrusfb_info *cinfo = info->par;
2243 struct fb_var_screeninfo *var = &info->var; 2246 struct fb_var_screeninfo *var = &info->var;
2244 2247
2245 info->par = cinfo;
2246 info->pseudo_palette = cinfo->pseudo_palette; 2248 info->pseudo_palette = cinfo->pseudo_palette;
2247 info->flags = FBINFO_DEFAULT 2249 info->flags = FBINFO_DEFAULT
2248 | FBINFO_HWACCEL_XPAN 2250 | FBINFO_HWACCEL_XPAN
@@ -2252,7 +2254,6 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
2252 if (noaccel) 2254 if (noaccel)
2253 info->flags |= FBINFO_HWACCEL_DISABLED; 2255 info->flags |= FBINFO_HWACCEL_DISABLED;
2254 info->fbops = &cirrusfb_ops; 2256 info->fbops = &cirrusfb_ops;
2255 info->screen_base = cinfo->fbmem;
2256 if (cinfo->btype == BT_GD5480) { 2257 if (cinfo->btype == BT_GD5480) {
2257 if (var->bits_per_pixel == 16) 2258 if (var->bits_per_pixel == 16)
2258 info->screen_base += 1 * MB_; 2259 info->screen_base += 1 * MB_;
@@ -2266,18 +2267,15 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
2266 2267
2267 /* monochrome: only 1 memory plane */ 2268 /* monochrome: only 1 memory plane */
2268 /* 8 bit and above: Use whole memory area */ 2269 /* 8 bit and above: Use whole memory area */
2269 info->fix.smem_start = cinfo->fbmem_phys; 2270 info->fix.smem_len = info->screen_size;
2270 info->fix.smem_len = (var->bits_per_pixel == 1) ? cinfo->size / 4 : cinfo->size; 2271 if (var->bits_per_pixel == 1)
2271 info->fix.type = cinfo->currentmode.type; 2272 info->fix.smem_len /= 4;
2272 info->fix.type_aux = 0; 2273 info->fix.type_aux = 0;
2273 info->fix.visual = cinfo->currentmode.visual;
2274 info->fix.xpanstep = 1; 2274 info->fix.xpanstep = 1;
2275 info->fix.ypanstep = 1; 2275 info->fix.ypanstep = 1;
2276 info->fix.ywrapstep = 0; 2276 info->fix.ywrapstep = 0;
2277 info->fix.line_length = cinfo->currentmode.line_length;
2278 2277
2279 /* FIXME: map region at 0xB8000 if available, fill in here */ 2278 /* FIXME: map region at 0xB8000 if available, fill in here */
2280 info->fix.mmio_start = cinfo->fbregs_phys;
2281 info->fix.mmio_len = 0; 2279 info->fix.mmio_len = 0;
2282 info->fix.accel = FB_ACCEL_NONE; 2280 info->fix.accel = FB_ACCEL_NONE;
2283 2281
@@ -2286,23 +2284,23 @@ static int cirrusfb_set_fbinfo(struct cirrusfb_info *cinfo)
2286 return 0; 2284 return 0;
2287} 2285}
2288 2286
2289static int cirrusfb_register(struct cirrusfb_info *cinfo) 2287static int cirrusfb_register(struct fb_info *info)
2290{ 2288{
2291 struct fb_info *info; 2289 struct cirrusfb_info *cinfo = info->par;
2292 int err; 2290 int err;
2293 cirrusfb_board_t btype; 2291 enum cirrus_board btype;
2294 2292
2295 DPRINTK ("ENTER\n"); 2293 DPRINTK("ENTER\n");
2296 2294
2297 printk (KERN_INFO "cirrusfb: Driver for Cirrus Logic based graphic boards, v" CIRRUSFB_VERSION "\n"); 2295 printk(KERN_INFO "cirrusfb: Driver for Cirrus Logic based "
2296 "graphic boards, v" CIRRUSFB_VERSION "\n");
2298 2297
2299 info = cinfo->info;
2300 btype = cinfo->btype; 2298 btype = cinfo->btype;
2301 2299
2302 /* sanity checks */ 2300 /* sanity checks */
2303 assert (btype != BT_NONE); 2301 assert(btype != BT_NONE);
2304 2302
2305 DPRINTK ("cirrusfb: (RAM start set to: 0x%p)\n", cinfo->fbmem); 2303 DPRINTK("cirrusfb: (RAM start set to: 0x%p)\n", info->screen_base);
2306 2304
2307 /* Make pretend we've set the var so our structures are in a "good" */ 2305 /* Make pretend we've set the var so our structures are in a "good" */
2308 /* state, even though we haven't written the mode to the hw yet... */ 2306 /* state, even though we haven't written the mode to the hw yet... */
@@ -2317,47 +2315,49 @@ static int cirrusfb_register(struct cirrusfb_info *cinfo)
2317 } 2315 }
2318 2316
2319 /* set all the vital stuff */ 2317 /* set all the vital stuff */
2320 cirrusfb_set_fbinfo(cinfo); 2318 cirrusfb_set_fbinfo(info);
2321 2319
2322 err = register_framebuffer(info); 2320 err = register_framebuffer(info);
2323 if (err < 0) { 2321 if (err < 0) {
2324 printk (KERN_ERR "cirrusfb: could not register fb device; err = %d!\n", err); 2322 printk(KERN_ERR "cirrusfb: could not register "
2323 "fb device; err = %d!\n", err);
2325 goto err_dealloc_cmap; 2324 goto err_dealloc_cmap;
2326 } 2325 }
2327 2326
2328 DPRINTK ("EXIT, returning 0\n"); 2327 DPRINTK("EXIT, returning 0\n");
2329 return 0; 2328 return 0;
2330 2329
2331err_dealloc_cmap: 2330err_dealloc_cmap:
2332 fb_dealloc_cmap(&info->cmap); 2331 fb_dealloc_cmap(&info->cmap);
2333err_unmap_cirrusfb: 2332err_unmap_cirrusfb:
2334 cinfo->unmap(cinfo); 2333 cinfo->unmap(info);
2334 framebuffer_release(info);
2335 return err; 2335 return err;
2336} 2336}
2337 2337
2338static void __devexit cirrusfb_cleanup (struct fb_info *info) 2338static void __devexit cirrusfb_cleanup(struct fb_info *info)
2339{ 2339{
2340 struct cirrusfb_info *cinfo = info->par; 2340 struct cirrusfb_info *cinfo = info->par;
2341 DPRINTK ("ENTER\n"); 2341 DPRINTK("ENTER\n");
2342 2342
2343 switch_monitor (cinfo, 0); 2343 switch_monitor(cinfo, 0);
2344 2344
2345 unregister_framebuffer (info); 2345 unregister_framebuffer(info);
2346 fb_dealloc_cmap (&info->cmap); 2346 fb_dealloc_cmap(&info->cmap);
2347 printk ("Framebuffer unregistered\n"); 2347 printk("Framebuffer unregistered\n");
2348 cinfo->unmap(cinfo); 2348 cinfo->unmap(info);
2349 framebuffer_release(info);
2349 2350
2350 DPRINTK ("EXIT\n"); 2351 DPRINTK("EXIT\n");
2351} 2352}
2352 2353
2353
2354#ifdef CONFIG_PCI 2354#ifdef CONFIG_PCI
2355static int cirrusfb_pci_register (struct pci_dev *pdev, 2355static int cirrusfb_pci_register(struct pci_dev *pdev,
2356 const struct pci_device_id *ent) 2356 const struct pci_device_id *ent)
2357{ 2357{
2358 struct cirrusfb_info *cinfo; 2358 struct cirrusfb_info *cinfo;
2359 struct fb_info *info; 2359 struct fb_info *info;
2360 cirrusfb_board_t btype; 2360 enum cirrus_board btype;
2361 unsigned long board_addr, board_size; 2361 unsigned long board_addr, board_size;
2362 int ret; 2362 int ret;
2363 2363
@@ -2375,35 +2375,37 @@ static int cirrusfb_pci_register (struct pci_dev *pdev,
2375 } 2375 }
2376 2376
2377 cinfo = info->par; 2377 cinfo = info->par;
2378 cinfo->info = info;
2379 cinfo->pdev = pdev; 2378 cinfo->pdev = pdev;
2380 cinfo->btype = btype = (cirrusfb_board_t) ent->driver_data; 2379 cinfo->btype = btype = (enum cirrus_board) ent->driver_data;
2381 2380
2382 DPRINTK (" Found PCI device, base address 0 is 0x%lx, btype set to %d\n", 2381 DPRINTK(" Found PCI device, base address 0 is 0x%x, btype set to %d\n",
2383 pdev->resource[0].start, btype); 2382 pdev->resource[0].start, btype);
2384 DPRINTK (" base address 1 is 0x%lx\n", pdev->resource[1].start); 2383 DPRINTK(" base address 1 is 0x%x\n", pdev->resource[1].start);
2385 2384
2386 if(isPReP) { 2385 if (isPReP) {
2387 pci_write_config_dword (pdev, PCI_BASE_ADDRESS_0, 0x00000000); 2386 pci_write_config_dword(pdev, PCI_BASE_ADDRESS_0, 0x00000000);
2388#ifdef CONFIG_PPC_PREP 2387#ifdef CONFIG_PPC_PREP
2389 get_prep_addrs (&board_addr, &cinfo->fbregs_phys); 2388 get_prep_addrs(&board_addr, &info->fix.mmio_start);
2390#endif 2389#endif
2391 /* PReP dies if we ioremap the IO registers, but it works w/out... */ 2390 /* PReP dies if we ioremap the IO registers, but it works w/out... */
2392 cinfo->regbase = (char __iomem *) cinfo->fbregs_phys; 2391 cinfo->regbase = (char __iomem *) info->fix.mmio_start;
2393 } else { 2392 } else {
2394 DPRINTK ("Attempt to get PCI info for Cirrus Graphics Card\n"); 2393 DPRINTK("Attempt to get PCI info for Cirrus Graphics Card\n");
2395 get_pci_addrs (pdev, &board_addr, &cinfo->fbregs_phys); 2394 get_pci_addrs(pdev, &board_addr, &info->fix.mmio_start);
2396 cinfo->regbase = NULL; /* FIXME: this forces VGA. alternatives? */ 2395 /* FIXME: this forces VGA. alternatives? */
2396 cinfo->regbase = NULL;
2397 } 2397 }
2398 2398
2399 DPRINTK ("Board address: 0x%lx, register address: 0x%lx\n", board_addr, cinfo->fbregs_phys); 2399 DPRINTK("Board address: 0x%lx, register address: 0x%lx\n",
2400 board_addr, info->fix.mmio_start);
2400 2401
2401 board_size = (btype == BT_GD5480) ? 2402 board_size = (btype == BT_GD5480) ?
2402 32 * MB_ : cirrusfb_get_memsize (cinfo->regbase); 2403 32 * MB_ : cirrusfb_get_memsize(cinfo->regbase);
2403 2404
2404 ret = pci_request_regions(pdev, "cirrusfb"); 2405 ret = pci_request_regions(pdev, "cirrusfb");
2405 if (ret <0) { 2406 if (ret < 0) {
2406 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n", 2407 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
2408 "abort\n",
2407 board_addr); 2409 board_addr);
2408 goto err_release_fb; 2410 goto err_release_fb;
2409 } 2411 }
@@ -2419,23 +2421,24 @@ static int cirrusfb_pci_register (struct pci_dev *pdev,
2419 if (request_region(0x3C0, 32, "cirrusfb")) 2421 if (request_region(0x3C0, 32, "cirrusfb"))
2420 release_io_ports = 1; 2422 release_io_ports = 1;
2421 2423
2422 cinfo->fbmem = ioremap(board_addr, board_size); 2424 info->screen_base = ioremap(board_addr, board_size);
2423 if (!cinfo->fbmem) { 2425 if (!info->screen_base) {
2424 ret = -EIO; 2426 ret = -EIO;
2425 goto err_release_legacy; 2427 goto err_release_legacy;
2426 } 2428 }
2427 2429
2428 cinfo->fbmem_phys = board_addr; 2430 info->fix.smem_start = board_addr;
2429 cinfo->size = board_size; 2431 info->screen_size = board_size;
2430 cinfo->unmap = cirrusfb_pci_unmap; 2432 cinfo->unmap = cirrusfb_pci_unmap;
2431 2433
2432 printk (" RAM (%lu kB) at 0xx%lx, ", cinfo->size / KB_, board_addr); 2434 printk(KERN_INFO " RAM (%lu kB) at 0xx%lx, ",
2433 printk ("Cirrus Logic chipset on PCI bus\n"); 2435 info->screen_size >> 10, board_addr);
2436 printk(KERN_INFO "Cirrus Logic chipset on PCI bus\n");
2434 pci_set_drvdata(pdev, info); 2437 pci_set_drvdata(pdev, info);
2435 2438
2436 ret = cirrusfb_register(cinfo); 2439 ret = cirrusfb_register(info);
2437 if (ret) 2440 if (ret)
2438 iounmap(cinfo->fbmem); 2441 iounmap(info->screen_base);
2439 return ret; 2442 return ret;
2440 2443
2441err_release_legacy: 2444err_release_legacy:
@@ -2453,14 +2456,14 @@ err_out:
2453 return ret; 2456 return ret;
2454} 2457}
2455 2458
2456static void __devexit cirrusfb_pci_unregister (struct pci_dev *pdev) 2459static void __devexit cirrusfb_pci_unregister(struct pci_dev *pdev)
2457{ 2460{
2458 struct fb_info *info = pci_get_drvdata(pdev); 2461 struct fb_info *info = pci_get_drvdata(pdev);
2459 DPRINTK ("ENTER\n"); 2462 DPRINTK("ENTER\n");
2460 2463
2461 cirrusfb_cleanup (info); 2464 cirrusfb_cleanup(info);
2462 2465
2463 DPRINTK ("EXIT\n"); 2466 DPRINTK("EXIT\n");
2464} 2467}
2465 2468
2466static struct pci_driver cirrusfb_pci_driver = { 2469static struct pci_driver cirrusfb_pci_driver = {
@@ -2477,14 +2480,13 @@ static struct pci_driver cirrusfb_pci_driver = {
2477}; 2480};
2478#endif /* CONFIG_PCI */ 2481#endif /* CONFIG_PCI */
2479 2482
2480
2481#ifdef CONFIG_ZORRO 2483#ifdef CONFIG_ZORRO
2482static int cirrusfb_zorro_register(struct zorro_dev *z, 2484static int cirrusfb_zorro_register(struct zorro_dev *z,
2483 const struct zorro_device_id *ent) 2485 const struct zorro_device_id *ent)
2484{ 2486{
2485 struct cirrusfb_info *cinfo; 2487 struct cirrusfb_info *cinfo;
2486 struct fb_info *info; 2488 struct fb_info *info;
2487 cirrusfb_board_t btype; 2489 enum cirrus_board btype;
2488 struct zorro_dev *z2 = NULL; 2490 struct zorro_dev *z2 = NULL;
2489 unsigned long board_addr, board_size, size; 2491 unsigned long board_addr, board_size, size;
2490 int ret; 2492 int ret;
@@ -2498,83 +2500,86 @@ static int cirrusfb_zorro_register(struct zorro_dev *z,
2498 2500
2499 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev); 2501 info = framebuffer_alloc(sizeof(struct cirrusfb_info), &z->dev);
2500 if (!info) { 2502 if (!info) {
2501 printk (KERN_ERR "cirrusfb: could not allocate memory\n"); 2503 printk(KERN_ERR "cirrusfb: could not allocate memory\n");
2502 ret = -ENOMEM; 2504 ret = -ENOMEM;
2503 goto err_out; 2505 goto err_out;
2504 } 2506 }
2505 2507
2506 cinfo = info->par; 2508 cinfo = info->par;
2507 cinfo->info = info;
2508 cinfo->btype = btype; 2509 cinfo->btype = btype;
2509 2510
2510 assert (z > 0); 2511 assert(z > 0);
2511 assert (z2 >= 0); 2512 assert(z2 >= 0);
2512 assert (btype != BT_NONE); 2513 assert(btype != BT_NONE);
2513 2514
2514 cinfo->zdev = z; 2515 cinfo->zdev = z;
2515 board_addr = zorro_resource_start(z); 2516 board_addr = zorro_resource_start(z);
2516 board_size = zorro_resource_len(z); 2517 board_size = zorro_resource_len(z);
2517 cinfo->size = size; 2518 info->screen_size = size;
2518 2519
2519 if (!zorro_request_device(z, "cirrusfb")) { 2520 if (!zorro_request_device(z, "cirrusfb")) {
2520 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, abort\n", 2521 printk(KERN_ERR "cirrusfb: cannot reserve region 0x%lx, "
2522 "abort\n",
2521 board_addr); 2523 board_addr);
2522 ret = -EBUSY; 2524 ret = -EBUSY;
2523 goto err_release_fb; 2525 goto err_release_fb;
2524 } 2526 }
2525 2527
2526 printk (" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr); 2528 printk(" RAM (%lu MB) at $%lx, ", board_size / MB_, board_addr);
2527 2529
2528 ret = -EIO; 2530 ret = -EIO;
2529 2531
2530 if (btype == BT_PICASSO4) { 2532 if (btype == BT_PICASSO4) {
2531 printk (" REG at $%lx\n", board_addr + 0x600000); 2533 printk(KERN_INFO " REG at $%lx\n", board_addr + 0x600000);
2532 2534
2533 /* To be precise, for the P4 this is not the */ 2535 /* To be precise, for the P4 this is not the */
2534 /* begin of the board, but the begin of RAM. */ 2536 /* begin of the board, but the begin of RAM. */
2535 /* for P4, map in its address space in 2 chunks (### TEST! ) */ 2537 /* for P4, map in its address space in 2 chunks (### TEST! ) */
2536 /* (note the ugly hardcoded 16M number) */ 2538 /* (note the ugly hardcoded 16M number) */
2537 cinfo->regbase = ioremap (board_addr, 16777216); 2539 cinfo->regbase = ioremap(board_addr, 16777216);
2538 if (!cinfo->regbase) 2540 if (!cinfo->regbase)
2539 goto err_release_region; 2541 goto err_release_region;
2540 2542
2541 DPRINTK ("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase); 2543 DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
2544 cinfo->regbase);
2542 cinfo->regbase += 0x600000; 2545 cinfo->regbase += 0x600000;
2543 cinfo->fbregs_phys = board_addr + 0x600000; 2546 info->fix.mmio_start = board_addr + 0x600000;
2544 2547
2545 cinfo->fbmem_phys = board_addr + 16777216; 2548 info->fix.smem_start = board_addr + 16777216;
2546 cinfo->fbmem = ioremap (cinfo->fbmem_phys, 16777216); 2549 info->screen_base = ioremap(info->fix.smem_start, 16777216);
2547 if (!cinfo->fbmem) 2550 if (!info->screen_base)
2548 goto err_unmap_regbase; 2551 goto err_unmap_regbase;
2549 } else { 2552 } else {
2550 printk (" REG at $%lx\n", (unsigned long) z2->resource.start); 2553 printk(KERN_INFO " REG at $%lx\n",
2554 (unsigned long) z2->resource.start);
2551 2555
2552 cinfo->fbmem_phys = board_addr; 2556 info->fix.smem_start = board_addr;
2553 if (board_addr > 0x01000000) 2557 if (board_addr > 0x01000000)
2554 cinfo->fbmem = ioremap (board_addr, board_size); 2558 info->screen_base = ioremap(board_addr, board_size);
2555 else 2559 else
2556 cinfo->fbmem = (caddr_t) ZTWO_VADDR (board_addr); 2560 info->screen_base = (caddr_t) ZTWO_VADDR(board_addr);
2557 if (!cinfo->fbmem) 2561 if (!info->screen_base)
2558 goto err_release_region; 2562 goto err_release_region;
2559 2563
2560 /* set address for REG area of board */ 2564 /* set address for REG area of board */
2561 cinfo->regbase = (caddr_t) ZTWO_VADDR (z2->resource.start); 2565 cinfo->regbase = (caddr_t) ZTWO_VADDR(z2->resource.start);
2562 cinfo->fbregs_phys = z2->resource.start; 2566 info->fix.mmio_start = z2->resource.start;
2563 2567
2564 DPRINTK ("cirrusfb: Virtual address for board set to: $%p\n", cinfo->regbase); 2568 DPRINTK("cirrusfb: Virtual address for board set to: $%p\n",
2569 cinfo->regbase);
2565 } 2570 }
2566 cinfo->unmap = cirrusfb_zorro_unmap; 2571 cinfo->unmap = cirrusfb_zorro_unmap;
2567 2572
2568 printk (KERN_INFO "Cirrus Logic chipset on Zorro bus\n"); 2573 printk(KERN_INFO "Cirrus Logic chipset on Zorro bus\n");
2569 zorro_set_drvdata(z, info); 2574 zorro_set_drvdata(z, info);
2570 2575
2571 ret = cirrusfb_register(cinfo); 2576 ret = cirrusfb_register(cinfo);
2572 if (ret) { 2577 if (ret) {
2573 if (btype == BT_PICASSO4) { 2578 if (btype == BT_PICASSO4) {
2574 iounmap(cinfo->fbmem); 2579 iounmap(info->screen_base);
2575 iounmap(cinfo->regbase - 0x600000); 2580 iounmap(cinfo->regbase - 0x600000);
2576 } else if (board_addr > 0x01000000) 2581 } else if (board_addr > 0x01000000)
2577 iounmap(cinfo->fbmem); 2582 iounmap(info->screen_base);
2578 } 2583 }
2579 return ret; 2584 return ret;
2580 2585
@@ -2592,11 +2597,11 @@ err_out:
2592void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z) 2597void __devexit cirrusfb_zorro_unregister(struct zorro_dev *z)
2593{ 2598{
2594 struct fb_info *info = zorro_get_drvdata(z); 2599 struct fb_info *info = zorro_get_drvdata(z);
2595 DPRINTK ("ENTER\n"); 2600 DPRINTK("ENTER\n");
2596 2601
2597 cirrusfb_cleanup (info); 2602 cirrusfb_cleanup(info);
2598 2603
2599 DPRINTK ("EXIT\n"); 2604 DPRINTK("EXIT\n");
2600} 2605}
2601 2606
2602static struct zorro_driver cirrusfb_zorro_driver = { 2607static struct zorro_driver cirrusfb_zorro_driver = {
@@ -2628,26 +2633,24 @@ static int __init cirrusfb_init(void)
2628 return error; 2633 return error;
2629} 2634}
2630 2635
2631
2632
2633#ifndef MODULE 2636#ifndef MODULE
2634static int __init cirrusfb_setup(char *options) { 2637static int __init cirrusfb_setup(char *options) {
2635 char *this_opt, s[32]; 2638 char *this_opt, s[32];
2636 int i; 2639 int i;
2637 2640
2638 DPRINTK ("ENTER\n"); 2641 DPRINTK("ENTER\n");
2639 2642
2640 if (!options || !*options) 2643 if (!options || !*options)
2641 return 0; 2644 return 0;
2642 2645
2643 while ((this_opt = strsep (&options, ",")) != NULL) { 2646 while ((this_opt = strsep(&options, ",")) != NULL) {
2644 if (!*this_opt) continue; 2647 if (!*this_opt) continue;
2645 2648
2646 DPRINTK("cirrusfb_setup: option '%s'\n", this_opt); 2649 DPRINTK("cirrusfb_setup: option '%s'\n", this_opt);
2647 2650
2648 for (i = 0; i < NUM_TOTAL_MODES; i++) { 2651 for (i = 0; i < NUM_TOTAL_MODES; i++) {
2649 sprintf (s, "mode:%s", cirrusfb_predefined[i].name); 2652 sprintf(s, "mode:%s", cirrusfb_predefined[i].name);
2650 if (strcmp (this_opt, s) == 0) 2653 if (strcmp(this_opt, s) == 0)
2651 cirrusfb_def_mode = i; 2654 cirrusfb_def_mode = i;
2652 } 2655 }
2653 if (!strcmp(this_opt, "noaccel")) 2656 if (!strcmp(this_opt, "noaccel"))
@@ -2657,7 +2660,6 @@ static int __init cirrusfb_setup(char *options) {
2657} 2660}
2658#endif 2661#endif
2659 2662
2660
2661 /* 2663 /*
2662 * Modularization 2664 * Modularization
2663 */ 2665 */
@@ -2666,7 +2668,7 @@ MODULE_AUTHOR("Copyright 1999,2000 Jeff Garzik <jgarzik@pobox.com>");
2666MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips"); 2668MODULE_DESCRIPTION("Accelerated FBDev driver for Cirrus Logic chips");
2667MODULE_LICENSE("GPL"); 2669MODULE_LICENSE("GPL");
2668 2670
2669static void __exit cirrusfb_exit (void) 2671static void __exit cirrusfb_exit(void)
2670{ 2672{
2671#ifdef CONFIG_PCI 2673#ifdef CONFIG_PCI
2672 pci_unregister_driver(&cirrusfb_pci_driver); 2674 pci_unregister_driver(&cirrusfb_pci_driver);
@@ -2682,66 +2684,67 @@ module_init(cirrusfb_init);
2682module_exit(cirrusfb_exit); 2684module_exit(cirrusfb_exit);
2683#endif 2685#endif
2684 2686
2685
2686/**********************************************************************/ 2687/**********************************************************************/
2687/* about the following functions - I have used the same names for the */ 2688/* about the following functions - I have used the same names for the */
2688/* functions as Markus Wild did in his Retina driver for NetBSD as */ 2689/* functions as Markus Wild did in his Retina driver for NetBSD as */
2689/* they just made sense for this purpose. Apart from that, I wrote */ 2690/* they just made sense for this purpose. Apart from that, I wrote */
2690/* these functions myself. */ 2691/* these functions myself. */
2691/**********************************************************************/ 2692/**********************************************************************/
2692 2693
2693/*** WGen() - write into one of the external/general registers ***/ 2694/*** WGen() - write into one of the external/general registers ***/
2694static void WGen (const struct cirrusfb_info *cinfo, 2695static void WGen(const struct cirrusfb_info *cinfo,
2695 int regnum, unsigned char val) 2696 int regnum, unsigned char val)
2696{ 2697{
2697 unsigned long regofs = 0; 2698 unsigned long regofs = 0;
2698 2699
2699 if (cinfo->btype == BT_PICASSO) { 2700 if (cinfo->btype == BT_PICASSO) {
2700 /* Picasso II specific hack */ 2701 /* Picasso II specific hack */
2701/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */ 2702/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2703 regnum == CL_VSSM2) */
2702 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D) 2704 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2703 regofs = 0xfff; 2705 regofs = 0xfff;
2704 } 2706 }
2705 2707
2706 vga_w (cinfo->regbase, regofs + regnum, val); 2708 vga_w(cinfo->regbase, regofs + regnum, val);
2707} 2709}
2708 2710
2709/*** RGen() - read out one of the external/general registers ***/ 2711/*** RGen() - read out one of the external/general registers ***/
2710static unsigned char RGen (const struct cirrusfb_info *cinfo, int regnum) 2712static unsigned char RGen(const struct cirrusfb_info *cinfo, int regnum)
2711{ 2713{
2712 unsigned long regofs = 0; 2714 unsigned long regofs = 0;
2713 2715
2714 if (cinfo->btype == BT_PICASSO) { 2716 if (cinfo->btype == BT_PICASSO) {
2715 /* Picasso II specific hack */ 2717 /* Picasso II specific hack */
2716/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D || regnum == CL_VSSM2) */ 2718/* if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D ||
2719 regnum == CL_VSSM2) */
2717 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D) 2720 if (regnum == VGA_PEL_IR || regnum == VGA_PEL_D)
2718 regofs = 0xfff; 2721 regofs = 0xfff;
2719 } 2722 }
2720 2723
2721 return vga_r (cinfo->regbase, regofs + regnum); 2724 return vga_r(cinfo->regbase, regofs + regnum);
2722} 2725}
2723 2726
2724/*** AttrOn() - turn on VideoEnable for Attribute controller ***/ 2727/*** AttrOn() - turn on VideoEnable for Attribute controller ***/
2725static void AttrOn (const struct cirrusfb_info *cinfo) 2728static void AttrOn(const struct cirrusfb_info *cinfo)
2726{ 2729{
2727 assert (cinfo != NULL); 2730 assert(cinfo != NULL);
2728 2731
2729 DPRINTK ("ENTER\n"); 2732 DPRINTK("ENTER\n");
2730 2733
2731 if (vga_rcrt (cinfo->regbase, CL_CRT24) & 0x80) { 2734 if (vga_rcrt(cinfo->regbase, CL_CRT24) & 0x80) {
2732 /* if we're just in "write value" mode, write back the */ 2735 /* if we're just in "write value" mode, write back the */
2733 /* same value as before to not modify anything */ 2736 /* same value as before to not modify anything */
2734 vga_w (cinfo->regbase, VGA_ATT_IW, 2737 vga_w(cinfo->regbase, VGA_ATT_IW,
2735 vga_r (cinfo->regbase, VGA_ATT_R)); 2738 vga_r(cinfo->regbase, VGA_ATT_R));
2736 } 2739 }
2737 /* turn on video bit */ 2740 /* turn on video bit */
2738/* vga_w (cinfo->regbase, VGA_ATT_IW, 0x20); */ 2741/* vga_w(cinfo->regbase, VGA_ATT_IW, 0x20); */
2739 vga_w (cinfo->regbase, VGA_ATT_IW, 0x33); 2742 vga_w(cinfo->regbase, VGA_ATT_IW, 0x33);
2740 2743
2741 /* dummy write on Reg0 to be on "write index" mode next time */ 2744 /* dummy write on Reg0 to be on "write index" mode next time */
2742 vga_w (cinfo->regbase, VGA_ATT_IW, 0x00); 2745 vga_w(cinfo->regbase, VGA_ATT_IW, 0x00);
2743 2746
2744 DPRINTK ("EXIT\n"); 2747 DPRINTK("EXIT\n");
2745} 2748}
2746 2749
2747/*** WHDR() - write into the Hidden DAC register ***/ 2750/*** WHDR() - write into the Hidden DAC register ***/
@@ -2750,119 +2753,115 @@ static void AttrOn (const struct cirrusfb_info *cinfo)
2750 * registers of their functional group) here is a specialized routine for 2753 * registers of their functional group) here is a specialized routine for
2751 * accessing the HDR 2754 * accessing the HDR
2752 */ 2755 */
2753static void WHDR (const struct cirrusfb_info *cinfo, unsigned char val) 2756static void WHDR(const struct cirrusfb_info *cinfo, unsigned char val)
2754{ 2757{
2755 unsigned char dummy; 2758 unsigned char dummy;
2756 2759
2757 if (cinfo->btype == BT_PICASSO) { 2760 if (cinfo->btype == BT_PICASSO) {
2758 /* Klaus' hint for correct access to HDR on some boards */ 2761 /* Klaus' hint for correct access to HDR on some boards */
2759 /* first write 0 to pixel mask (3c6) */ 2762 /* first write 0 to pixel mask (3c6) */
2760 WGen (cinfo, VGA_PEL_MSK, 0x00); 2763 WGen(cinfo, VGA_PEL_MSK, 0x00);
2761 udelay (200); 2764 udelay(200);
2762 /* next read dummy from pixel address (3c8) */ 2765 /* next read dummy from pixel address (3c8) */
2763 dummy = RGen (cinfo, VGA_PEL_IW); 2766 dummy = RGen(cinfo, VGA_PEL_IW);
2764 udelay (200); 2767 udelay(200);
2765 } 2768 }
2766 /* now do the usual stuff to access the HDR */ 2769 /* now do the usual stuff to access the HDR */
2767 2770
2768 dummy = RGen (cinfo, VGA_PEL_MSK); 2771 dummy = RGen(cinfo, VGA_PEL_MSK);
2769 udelay (200); 2772 udelay(200);
2770 dummy = RGen (cinfo, VGA_PEL_MSK); 2773 dummy = RGen(cinfo, VGA_PEL_MSK);
2771 udelay (200); 2774 udelay(200);
2772 dummy = RGen (cinfo, VGA_PEL_MSK); 2775 dummy = RGen(cinfo, VGA_PEL_MSK);
2773 udelay (200); 2776 udelay(200);
2774 dummy = RGen (cinfo, VGA_PEL_MSK); 2777 dummy = RGen(cinfo, VGA_PEL_MSK);
2775 udelay (200); 2778 udelay(200);
2776 2779
2777 WGen (cinfo, VGA_PEL_MSK, val); 2780 WGen(cinfo, VGA_PEL_MSK, val);
2778 udelay (200); 2781 udelay(200);
2779 2782
2780 if (cinfo->btype == BT_PICASSO) { 2783 if (cinfo->btype == BT_PICASSO) {
2781 /* now first reset HDR access counter */ 2784 /* now first reset HDR access counter */
2782 dummy = RGen (cinfo, VGA_PEL_IW); 2785 dummy = RGen(cinfo, VGA_PEL_IW);
2783 udelay (200); 2786 udelay(200);
2784 2787
2785 /* and at the end, restore the mask value */ 2788 /* and at the end, restore the mask value */
2786 /* ## is this mask always 0xff? */ 2789 /* ## is this mask always 0xff? */
2787 WGen (cinfo, VGA_PEL_MSK, 0xff); 2790 WGen(cinfo, VGA_PEL_MSK, 0xff);
2788 udelay (200); 2791 udelay(200);
2789 } 2792 }
2790} 2793}
2791 2794
2792
2793/*** WSFR() - write to the "special function register" (SFR) ***/ 2795/*** WSFR() - write to the "special function register" (SFR) ***/
2794static void WSFR (struct cirrusfb_info *cinfo, unsigned char val) 2796static void WSFR(struct cirrusfb_info *cinfo, unsigned char val)
2795{ 2797{
2796#ifdef CONFIG_ZORRO 2798#ifdef CONFIG_ZORRO
2797 assert (cinfo->regbase != NULL); 2799 assert(cinfo->regbase != NULL);
2798 cinfo->SFR = val; 2800 cinfo->SFR = val;
2799 z_writeb (val, cinfo->regbase + 0x8000); 2801 z_writeb(val, cinfo->regbase + 0x8000);
2800#endif 2802#endif
2801} 2803}
2802 2804
2803/* The Picasso has a second register for switching the monitor bit */ 2805/* The Picasso has a second register for switching the monitor bit */
2804static void WSFR2 (struct cirrusfb_info *cinfo, unsigned char val) 2806static void WSFR2(struct cirrusfb_info *cinfo, unsigned char val)
2805{ 2807{
2806#ifdef CONFIG_ZORRO 2808#ifdef CONFIG_ZORRO
2807 /* writing an arbitrary value to this one causes the monitor switcher */ 2809 /* writing an arbitrary value to this one causes the monitor switcher */
2808 /* to flip to Amiga display */ 2810 /* to flip to Amiga display */
2809 assert (cinfo->regbase != NULL); 2811 assert(cinfo->regbase != NULL);
2810 cinfo->SFR = val; 2812 cinfo->SFR = val;
2811 z_writeb (val, cinfo->regbase + 0x9000); 2813 z_writeb(val, cinfo->regbase + 0x9000);
2812#endif 2814#endif
2813} 2815}
2814 2816
2815
2816/*** WClut - set CLUT entry (range: 0..63) ***/ 2817/*** WClut - set CLUT entry (range: 0..63) ***/
2817static void WClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red, 2818static void WClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char red,
2818 unsigned char green, unsigned char blue) 2819 unsigned char green, unsigned char blue)
2819{ 2820{
2820 unsigned int data = VGA_PEL_D; 2821 unsigned int data = VGA_PEL_D;
2821 2822
2822 /* address write mode register is not translated.. */ 2823 /* address write mode register is not translated.. */
2823 vga_w (cinfo->regbase, VGA_PEL_IW, regnum); 2824 vga_w(cinfo->regbase, VGA_PEL_IW, regnum);
2824 2825
2825 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || 2826 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2826 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) { 2827 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2827 /* but DAC data register IS, at least for Picasso II */ 2828 /* but DAC data register IS, at least for Picasso II */
2828 if (cinfo->btype == BT_PICASSO) 2829 if (cinfo->btype == BT_PICASSO)
2829 data += 0xfff; 2830 data += 0xfff;
2830 vga_w (cinfo->regbase, data, red); 2831 vga_w(cinfo->regbase, data, red);
2831 vga_w (cinfo->regbase, data, green); 2832 vga_w(cinfo->regbase, data, green);
2832 vga_w (cinfo->regbase, data, blue); 2833 vga_w(cinfo->regbase, data, blue);
2833 } else { 2834 } else {
2834 vga_w (cinfo->regbase, data, blue); 2835 vga_w(cinfo->regbase, data, blue);
2835 vga_w (cinfo->regbase, data, green); 2836 vga_w(cinfo->regbase, data, green);
2836 vga_w (cinfo->regbase, data, red); 2837 vga_w(cinfo->regbase, data, red);
2837 } 2838 }
2838} 2839}
2839 2840
2840
2841#if 0 2841#if 0
2842/*** RClut - read CLUT entry (range 0..63) ***/ 2842/*** RClut - read CLUT entry (range 0..63) ***/
2843static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red, 2843static void RClut(struct cirrusfb_info *cinfo, unsigned char regnum, unsigned char *red,
2844 unsigned char *green, unsigned char *blue) 2844 unsigned char *green, unsigned char *blue)
2845{ 2845{
2846 unsigned int data = VGA_PEL_D; 2846 unsigned int data = VGA_PEL_D;
2847 2847
2848 vga_w (cinfo->regbase, VGA_PEL_IR, regnum); 2848 vga_w(cinfo->regbase, VGA_PEL_IR, regnum);
2849 2849
2850 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 || 2850 if (cinfo->btype == BT_PICASSO || cinfo->btype == BT_PICASSO4 ||
2851 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) { 2851 cinfo->btype == BT_ALPINE || cinfo->btype == BT_GD5480) {
2852 if (cinfo->btype == BT_PICASSO) 2852 if (cinfo->btype == BT_PICASSO)
2853 data += 0xfff; 2853 data += 0xfff;
2854 *red = vga_r (cinfo->regbase, data); 2854 *red = vga_r(cinfo->regbase, data);
2855 *green = vga_r (cinfo->regbase, data); 2855 *green = vga_r(cinfo->regbase, data);
2856 *blue = vga_r (cinfo->regbase, data); 2856 *blue = vga_r(cinfo->regbase, data);
2857 } else { 2857 } else {
2858 *blue = vga_r (cinfo->regbase, data); 2858 *blue = vga_r(cinfo->regbase, data);
2859 *green = vga_r (cinfo->regbase, data); 2859 *green = vga_r(cinfo->regbase, data);
2860 *red = vga_r (cinfo->regbase, data); 2860 *red = vga_r(cinfo->regbase, data);
2861 } 2861 }
2862} 2862}
2863#endif 2863#endif
2864 2864
2865
2866/******************************************************************* 2865/*******************************************************************
2867 cirrusfb_WaitBLT() 2866 cirrusfb_WaitBLT()
2868 2867
@@ -2870,10 +2869,10 @@ static void RClut (struct cirrusfb_info *cinfo, unsigned char regnum, unsigned c
2870*********************************************************************/ 2869*********************************************************************/
2871 2870
2872/* FIXME: use interrupts instead */ 2871/* FIXME: use interrupts instead */
2873static void cirrusfb_WaitBLT (u8 __iomem *regbase) 2872static void cirrusfb_WaitBLT(u8 __iomem *regbase)
2874{ 2873{
2875 /* now busy-wait until we're done */ 2874 /* now busy-wait until we're done */
2876 while (vga_rgfx (regbase, CL_GR31) & 0x08) 2875 while (vga_rgfx(regbase, CL_GR31) & 0x08)
2877 /* do nothing */ ; 2876 /* do nothing */ ;
2878} 2877}
2879 2878
@@ -2883,15 +2882,17 @@ static void cirrusfb_WaitBLT (u8 __iomem *regbase)
2883 perform accelerated "scrolling" 2882 perform accelerated "scrolling"
2884********************************************************************/ 2883********************************************************************/
2885 2884
2886static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel, 2885static void cirrusfb_BitBLT(u8 __iomem *regbase, int bits_per_pixel,
2887 u_short curx, u_short cury, u_short destx, u_short desty, 2886 u_short curx, u_short cury,
2888 u_short width, u_short height, u_short line_length) 2887 u_short destx, u_short desty,
2888 u_short width, u_short height,
2889 u_short line_length)
2889{ 2890{
2890 u_short nwidth, nheight; 2891 u_short nwidth, nheight;
2891 u_long nsrc, ndest; 2892 u_long nsrc, ndest;
2892 u_char bltmode; 2893 u_char bltmode;
2893 2894
2894 DPRINTK ("ENTER\n"); 2895 DPRINTK("ENTER\n");
2895 2896
2896 nwidth = width - 1; 2897 nwidth = width - 1;
2897 nheight = height - 1; 2898 nheight = height - 1;
@@ -2911,9 +2912,13 @@ static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
2911 nsrc = (cury * line_length) + curx; 2912 nsrc = (cury * line_length) + curx;
2912 ndest = (desty * line_length) + destx; 2913 ndest = (desty * line_length) + destx;
2913 } else { 2914 } else {
2914 /* this means start addresses are at the end, counting backwards */ 2915 /* this means start addresses are at the end,
2915 nsrc = cury * line_length + curx + nheight * line_length + nwidth; 2916 * counting backwards
2916 ndest = desty * line_length + destx + nheight * line_length + nwidth; 2917 */
2918 nsrc = cury * line_length + curx +
2919 nheight * line_length + nwidth;
2920 ndest = desty * line_length + destx +
2921 nheight * line_length + nwidth;
2917 } 2922 }
2918 2923
2919 /* 2924 /*
@@ -2929,52 +2934,65 @@ static void cirrusfb_BitBLT (u8 __iomem *regbase, int bits_per_pixel,
2929 start/stop 2934 start/stop
2930 */ 2935 */
2931 2936
2932 cirrusfb_WaitBLT(regbase); 2937 cirrusfb_WaitBLT(regbase);
2933 2938
2934 /* pitch: set to line_length */ 2939 /* pitch: set to line_length */
2935 vga_wgfx (regbase, CL_GR24, line_length & 0xff); /* dest pitch low */ 2940 /* dest pitch low */
2936 vga_wgfx (regbase, CL_GR25, (line_length >> 8)); /* dest pitch hi */ 2941 vga_wgfx(regbase, CL_GR24, line_length & 0xff);
2937 vga_wgfx (regbase, CL_GR26, line_length & 0xff); /* source pitch low */ 2942 /* dest pitch hi */
2938 vga_wgfx (regbase, CL_GR27, (line_length >> 8)); /* source pitch hi */ 2943 vga_wgfx(regbase, CL_GR25, line_length >> 8);
2944 /* source pitch low */
2945 vga_wgfx(regbase, CL_GR26, line_length & 0xff);
2946 /* source pitch hi */
2947 vga_wgfx(regbase, CL_GR27, line_length >> 8);
2939 2948
2940 /* BLT width: actual number of pixels - 1 */ 2949 /* BLT width: actual number of pixels - 1 */
2941 vga_wgfx (regbase, CL_GR20, nwidth & 0xff); /* BLT width low */ 2950 /* BLT width low */
2942 vga_wgfx (regbase, CL_GR21, (nwidth >> 8)); /* BLT width hi */ 2951 vga_wgfx(regbase, CL_GR20, nwidth & 0xff);
2952 /* BLT width hi */
2953 vga_wgfx(regbase, CL_GR21, nwidth >> 8);
2943 2954
2944 /* BLT height: actual number of lines -1 */ 2955 /* BLT height: actual number of lines -1 */
2945 vga_wgfx (regbase, CL_GR22, nheight & 0xff); /* BLT height low */ 2956 /* BLT height low */
2946 vga_wgfx (regbase, CL_GR23, (nheight >> 8)); /* BLT width hi */ 2957 vga_wgfx(regbase, CL_GR22, nheight & 0xff);
2958 /* BLT width hi */
2959 vga_wgfx(regbase, CL_GR23, nheight >> 8);
2947 2960
2948 /* BLT destination */ 2961 /* BLT destination */
2949 vga_wgfx (regbase, CL_GR28, (u_char) (ndest & 0xff)); /* BLT dest low */ 2962 /* BLT dest low */
2950 vga_wgfx (regbase, CL_GR29, (u_char) (ndest >> 8)); /* BLT dest mid */ 2963 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
2951 vga_wgfx (regbase, CL_GR2A, (u_char) (ndest >> 16)); /* BLT dest hi */ 2964 /* BLT dest mid */
2965 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
2966 /* BLT dest hi */
2967 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
2952 2968
2953 /* BLT source */ 2969 /* BLT source */
2954 vga_wgfx (regbase, CL_GR2C, (u_char) (nsrc & 0xff)); /* BLT src low */ 2970 /* BLT src low */
2955 vga_wgfx (regbase, CL_GR2D, (u_char) (nsrc >> 8)); /* BLT src mid */ 2971 vga_wgfx(regbase, CL_GR2C, (u_char) (nsrc & 0xff));
2956 vga_wgfx (regbase, CL_GR2E, (u_char) (nsrc >> 16)); /* BLT src hi */ 2972 /* BLT src mid */
2973 vga_wgfx(regbase, CL_GR2D, (u_char) (nsrc >> 8));
2974 /* BLT src hi */
2975 vga_wgfx(regbase, CL_GR2E, (u_char) (nsrc >> 16));
2957 2976
2958 /* BLT mode */ 2977 /* BLT mode */
2959 vga_wgfx (regbase, CL_GR30, bltmode); /* BLT mode */ 2978 vga_wgfx(regbase, CL_GR30, bltmode); /* BLT mode */
2960 2979
2961 /* BLT ROP: SrcCopy */ 2980 /* BLT ROP: SrcCopy */
2962 vga_wgfx (regbase, CL_GR32, 0x0d); /* BLT ROP */ 2981 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
2963 2982
2964 /* and finally: GO! */ 2983 /* and finally: GO! */
2965 vga_wgfx (regbase, CL_GR31, 0x02); /* BLT Start/status */ 2984 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
2966 2985
2967 DPRINTK ("EXIT\n"); 2986 DPRINTK("EXIT\n");
2968} 2987}
2969 2988
2970
2971/******************************************************************* 2989/*******************************************************************
2972 cirrusfb_RectFill() 2990 cirrusfb_RectFill()
2973 2991
2974 perform accelerated rectangle fill 2992 perform accelerated rectangle fill
2975********************************************************************/ 2993********************************************************************/
2976 2994
2977static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel, 2995static void cirrusfb_RectFill(u8 __iomem *regbase, int bits_per_pixel,
2978 u_short x, u_short y, u_short width, u_short height, 2996 u_short x, u_short y, u_short width, u_short height,
2979 u_char color, u_short line_length) 2997 u_char color, u_short line_length)
2980{ 2998{
@@ -2982,93 +3000,95 @@ static void cirrusfb_RectFill (u8 __iomem *regbase, int bits_per_pixel,
2982 u_long ndest; 3000 u_long ndest;
2983 u_char op; 3001 u_char op;
2984 3002
2985 DPRINTK ("ENTER\n"); 3003 DPRINTK("ENTER\n");
2986 3004
2987 nwidth = width - 1; 3005 nwidth = width - 1;
2988 nheight = height - 1; 3006 nheight = height - 1;
2989 3007
2990 ndest = (y * line_length) + x; 3008 ndest = (y * line_length) + x;
2991 3009
2992 cirrusfb_WaitBLT(regbase); 3010 cirrusfb_WaitBLT(regbase);
2993 3011
2994 /* pitch: set to line_length */ 3012 /* pitch: set to line_length */
2995 vga_wgfx (regbase, CL_GR24, line_length & 0xff); /* dest pitch low */ 3013 vga_wgfx(regbase, CL_GR24, line_length & 0xff); /* dest pitch low */
2996 vga_wgfx (regbase, CL_GR25, (line_length >> 8)); /* dest pitch hi */ 3014 vga_wgfx(regbase, CL_GR25, line_length >> 8); /* dest pitch hi */
2997 vga_wgfx (regbase, CL_GR26, line_length & 0xff); /* source pitch low */ 3015 vga_wgfx(regbase, CL_GR26, line_length & 0xff); /* source pitch low */
2998 vga_wgfx (regbase, CL_GR27, (line_length >> 8)); /* source pitch hi */ 3016 vga_wgfx(regbase, CL_GR27, line_length >> 8); /* source pitch hi */
2999 3017
3000 /* BLT width: actual number of pixels - 1 */ 3018 /* BLT width: actual number of pixels - 1 */
3001 vga_wgfx (regbase, CL_GR20, nwidth & 0xff); /* BLT width low */ 3019 vga_wgfx(regbase, CL_GR20, nwidth & 0xff); /* BLT width low */
3002 vga_wgfx (regbase, CL_GR21, (nwidth >> 8)); /* BLT width hi */ 3020 vga_wgfx(regbase, CL_GR21, nwidth >> 8); /* BLT width hi */
3003 3021
3004 /* BLT height: actual number of lines -1 */ 3022 /* BLT height: actual number of lines -1 */
3005 vga_wgfx (regbase, CL_GR22, nheight & 0xff); /* BLT height low */ 3023 vga_wgfx(regbase, CL_GR22, nheight & 0xff); /* BLT height low */
3006 vga_wgfx (regbase, CL_GR23, (nheight >> 8)); /* BLT width hi */ 3024 vga_wgfx(regbase, CL_GR23, nheight >> 8); /* BLT width hi */
3007 3025
3008 /* BLT destination */ 3026 /* BLT destination */
3009 vga_wgfx (regbase, CL_GR28, (u_char) (ndest & 0xff)); /* BLT dest low */ 3027 /* BLT dest low */
3010 vga_wgfx (regbase, CL_GR29, (u_char) (ndest >> 8)); /* BLT dest mid */ 3028 vga_wgfx(regbase, CL_GR28, (u_char) (ndest & 0xff));
3011 vga_wgfx (regbase, CL_GR2A, (u_char) (ndest >> 16)); /* BLT dest hi */ 3029 /* BLT dest mid */
3030 vga_wgfx(regbase, CL_GR29, (u_char) (ndest >> 8));
3031 /* BLT dest hi */
3032 vga_wgfx(regbase, CL_GR2A, (u_char) (ndest >> 16));
3012 3033
3013 /* BLT source: set to 0 (is a dummy here anyway) */ 3034 /* BLT source: set to 0 (is a dummy here anyway) */
3014 vga_wgfx (regbase, CL_GR2C, 0x00); /* BLT src low */ 3035 vga_wgfx(regbase, CL_GR2C, 0x00); /* BLT src low */
3015 vga_wgfx (regbase, CL_GR2D, 0x00); /* BLT src mid */ 3036 vga_wgfx(regbase, CL_GR2D, 0x00); /* BLT src mid */
3016 vga_wgfx (regbase, CL_GR2E, 0x00); /* BLT src hi */ 3037 vga_wgfx(regbase, CL_GR2E, 0x00); /* BLT src hi */
3017 3038
3018 /* This is a ColorExpand Blt, using the */ 3039 /* This is a ColorExpand Blt, using the */
3019 /* same color for foreground and background */ 3040 /* same color for foreground and background */
3020 vga_wgfx (regbase, VGA_GFX_SR_VALUE, color); /* foreground color */ 3041 vga_wgfx(regbase, VGA_GFX_SR_VALUE, color); /* foreground color */
3021 vga_wgfx (regbase, VGA_GFX_SR_ENABLE, color); /* background color */ 3042 vga_wgfx(regbase, VGA_GFX_SR_ENABLE, color); /* background color */
3022 3043
3023 op = 0xc0; 3044 op = 0xc0;
3024 if (bits_per_pixel == 16) { 3045 if (bits_per_pixel == 16) {
3025 vga_wgfx (regbase, CL_GR10, color); /* foreground color */ 3046 vga_wgfx(regbase, CL_GR10, color); /* foreground color */
3026 vga_wgfx (regbase, CL_GR11, color); /* background color */ 3047 vga_wgfx(regbase, CL_GR11, color); /* background color */
3027 op = 0x50; 3048 op = 0x50;
3028 op = 0xd0; 3049 op = 0xd0;
3029 } else if (bits_per_pixel == 32) { 3050 } else if (bits_per_pixel == 32) {
3030 vga_wgfx (regbase, CL_GR10, color); /* foreground color */ 3051 vga_wgfx(regbase, CL_GR10, color); /* foreground color */
3031 vga_wgfx (regbase, CL_GR11, color); /* background color */ 3052 vga_wgfx(regbase, CL_GR11, color); /* background color */
3032 vga_wgfx (regbase, CL_GR12, color); /* foreground color */ 3053 vga_wgfx(regbase, CL_GR12, color); /* foreground color */
3033 vga_wgfx (regbase, CL_GR13, color); /* background color */ 3054 vga_wgfx(regbase, CL_GR13, color); /* background color */
3034 vga_wgfx (regbase, CL_GR14, 0); /* foreground color */ 3055 vga_wgfx(regbase, CL_GR14, 0); /* foreground color */
3035 vga_wgfx (regbase, CL_GR15, 0); /* background color */ 3056 vga_wgfx(regbase, CL_GR15, 0); /* background color */
3036 op = 0x50; 3057 op = 0x50;
3037 op = 0xf0; 3058 op = 0xf0;
3038 } 3059 }
3039 /* BLT mode: color expand, Enable 8x8 copy (faster?) */ 3060 /* BLT mode: color expand, Enable 8x8 copy (faster?) */
3040 vga_wgfx (regbase, CL_GR30, op); /* BLT mode */ 3061 vga_wgfx(regbase, CL_GR30, op); /* BLT mode */
3041 3062
3042 /* BLT ROP: SrcCopy */ 3063 /* BLT ROP: SrcCopy */
3043 vga_wgfx (regbase, CL_GR32, 0x0d); /* BLT ROP */ 3064 vga_wgfx(regbase, CL_GR32, 0x0d); /* BLT ROP */
3044 3065
3045 /* and finally: GO! */ 3066 /* and finally: GO! */
3046 vga_wgfx (regbase, CL_GR31, 0x02); /* BLT Start/status */ 3067 vga_wgfx(regbase, CL_GR31, 0x02); /* BLT Start/status */
3047 3068
3048 DPRINTK ("EXIT\n"); 3069 DPRINTK("EXIT\n");
3049} 3070}
3050 3071
3051
3052/************************************************************************** 3072/**************************************************************************
3053 * bestclock() - determine closest possible clock lower(?) than the 3073 * bestclock() - determine closest possible clock lower(?) than the
3054 * desired pixel clock 3074 * desired pixel clock
3055 **************************************************************************/ 3075 **************************************************************************/
3056static void bestclock (long freq, long *best, long *nom, 3076static void bestclock(long freq, long *best, long *nom,
3057 long *den, long *div, long maxfreq) 3077 long *den, long *div, long maxfreq)
3058{ 3078{
3059 long n, h, d, f; 3079 long n, h, d, f;
3060 3080
3061 assert (best != NULL); 3081 assert(best != NULL);
3062 assert (nom != NULL); 3082 assert(nom != NULL);
3063 assert (den != NULL); 3083 assert(den != NULL);
3064 assert (div != NULL); 3084 assert(div != NULL);
3065 assert (maxfreq > 0); 3085 assert(maxfreq > 0);
3066 3086
3067 *nom = 0; 3087 *nom = 0;
3068 *den = 0; 3088 *den = 0;
3069 *div = 0; 3089 *div = 0;
3070 3090
3071 DPRINTK ("ENTER\n"); 3091 DPRINTK("ENTER\n");
3072 3092
3073 if (freq < 8000) 3093 if (freq < 8000)
3074 freq = 8000; 3094 freq = 8000;
@@ -3085,7 +3105,7 @@ static void bestclock (long freq, long *best, long *nom,
3085 if (d > 31) 3105 if (d > 31)
3086 d = (d / 2) * 2; 3106 d = (d / 2) * 2;
3087 h = (14318 * n) / d; 3107 h = (14318 * n) / d;
3088 if (abs (h - freq) < abs (*best - freq)) { 3108 if (abs(h - freq) < abs(*best - freq)) {
3089 *best = h; 3109 *best = h;
3090 *nom = n; 3110 *nom = n;
3091 if (d < 32) { 3111 if (d < 32) {
@@ -3102,7 +3122,7 @@ static void bestclock (long freq, long *best, long *nom,
3102 if (d > 31) 3122 if (d > 31)
3103 d = (d / 2) * 2; 3123 d = (d / 2) * 2;
3104 h = (14318 * n) / d; 3124 h = (14318 * n) / d;
3105 if (abs (h - freq) < abs (*best - freq)) { 3125 if (abs(h - freq) < abs(*best - freq)) {
3106 *best = h; 3126 *best = h;
3107 *nom = n; 3127 *nom = n;
3108 if (d < 32) { 3128 if (d < 32) {
@@ -3116,14 +3136,13 @@ static void bestclock (long freq, long *best, long *nom,
3116 } 3136 }
3117 } 3137 }
3118 3138
3119 DPRINTK ("Best possible values for given frequency:\n"); 3139 DPRINTK("Best possible values for given frequency:\n");
3120 DPRINTK (" best: %ld kHz nom: %ld den: %ld div: %ld\n", 3140 DPRINTK(" best: %ld kHz nom: %ld den: %ld div: %ld\n",
3121 freq, *nom, *den, *div); 3141 freq, *nom, *den, *div);
3122 3142
3123 DPRINTK ("EXIT\n"); 3143 DPRINTK("EXIT\n");
3124} 3144}
3125 3145
3126
3127/* ------------------------------------------------------------------------- 3146/* -------------------------------------------------------------------------
3128 * 3147 *
3129 * debugging functions 3148 * debugging functions
@@ -3145,21 +3164,20 @@ static void bestclock (long freq, long *best, long *nom,
3145 */ 3164 */
3146 3165
3147static 3166static
3148void cirrusfb_dbg_print_byte (const char *name, unsigned char val) 3167void cirrusfb_dbg_print_byte(const char *name, unsigned char val)
3149{ 3168{
3150 DPRINTK ("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n", 3169 DPRINTK("%8s = 0x%02X (bits 7-0: %c%c%c%c%c%c%c%c)\n",
3151 name, val, 3170 name, val,
3152 val & 0x80 ? '1' : '0', 3171 val & 0x80 ? '1' : '0',
3153 val & 0x40 ? '1' : '0', 3172 val & 0x40 ? '1' : '0',
3154 val & 0x20 ? '1' : '0', 3173 val & 0x20 ? '1' : '0',
3155 val & 0x10 ? '1' : '0', 3174 val & 0x10 ? '1' : '0',
3156 val & 0x08 ? '1' : '0', 3175 val & 0x08 ? '1' : '0',
3157 val & 0x04 ? '1' : '0', 3176 val & 0x04 ? '1' : '0',
3158 val & 0x02 ? '1' : '0', 3177 val & 0x02 ? '1' : '0',
3159 val & 0x01 ? '1' : '0'); 3178 val & 0x01 ? '1' : '0');
3160} 3179}
3161 3180
3162
3163/** 3181/**
3164 * cirrusfb_dbg_print_regs 3182 * cirrusfb_dbg_print_regs
3165 * @base: If using newmmio, the newmmio base address, otherwise %NULL 3183 * @base: If using newmmio, the newmmio base address, otherwise %NULL
@@ -3172,25 +3190,26 @@ void cirrusfb_dbg_print_byte (const char *name, unsigned char val)
3172 */ 3190 */
3173 3191
3174static 3192static
3175void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_class,...) 3193void cirrusfb_dbg_print_regs(caddr_t regbase,
3194 enum cirrusfb_dbg_reg_class reg_class, ...)
3176{ 3195{
3177 va_list list; 3196 va_list list;
3178 unsigned char val = 0; 3197 unsigned char val = 0;
3179 unsigned reg; 3198 unsigned reg;
3180 char *name; 3199 char *name;
3181 3200
3182 va_start (list, reg_class); 3201 va_start(list, reg_class);
3183 3202
3184 name = va_arg (list, char *); 3203 name = va_arg(list, char *);
3185 while (name != NULL) { 3204 while (name != NULL) {
3186 reg = va_arg (list, int); 3205 reg = va_arg(list, int);
3187 3206
3188 switch (reg_class) { 3207 switch (reg_class) {
3189 case CRT: 3208 case CRT:
3190 val = vga_rcrt (regbase, (unsigned char) reg); 3209 val = vga_rcrt(regbase, (unsigned char) reg);
3191 break; 3210 break;
3192 case SEQ: 3211 case SEQ:
3193 val = vga_rseq (regbase, (unsigned char) reg); 3212 val = vga_rseq(regbase, (unsigned char) reg);
3194 break; 3213 break;
3195 default: 3214 default:
3196 /* should never occur */ 3215 /* should never occur */
@@ -3198,15 +3217,14 @@ void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_clas
3198 break; 3217 break;
3199 } 3218 }
3200 3219
3201 cirrusfb_dbg_print_byte (name, val); 3220 cirrusfb_dbg_print_byte(name, val);
3202 3221
3203 name = va_arg (list, char *); 3222 name = va_arg(list, char *);
3204 } 3223 }
3205 3224
3206 va_end (list); 3225 va_end(list);
3207} 3226}
3208 3227
3209
3210/** 3228/**
3211 * cirrusfb_dump 3229 * cirrusfb_dump
3212 * @cirrusfbinfo: 3230 * @cirrusfbinfo:
@@ -3214,13 +3232,11 @@ void cirrusfb_dbg_print_regs (caddr_t regbase, cirrusfb_dbg_reg_class_t reg_clas
3214 * DESCRIPTION: 3232 * DESCRIPTION:
3215 */ 3233 */
3216 3234
3217static 3235static void cirrusfb_dump(void)
3218void cirrusfb_dump (void)
3219{ 3236{
3220 cirrusfb_dbg_reg_dump (NULL); 3237 cirrusfb_dbg_reg_dump(NULL);
3221} 3238}
3222 3239
3223
3224/** 3240/**
3225 * cirrusfb_dbg_reg_dump 3241 * cirrusfb_dbg_reg_dump
3226 * @base: If using newmmio, the newmmio base address, otherwise %NULL 3242 * @base: If using newmmio, the newmmio base address, otherwise %NULL
@@ -3232,11 +3248,11 @@ void cirrusfb_dump (void)
3232 */ 3248 */
3233 3249
3234static 3250static
3235void cirrusfb_dbg_reg_dump (caddr_t regbase) 3251void cirrusfb_dbg_reg_dump(caddr_t regbase)
3236{ 3252{
3237 DPRINTK ("CIRRUSFB VGA CRTC register dump:\n"); 3253 DPRINTK("CIRRUSFB VGA CRTC register dump:\n");
3238 3254
3239 cirrusfb_dbg_print_regs (regbase, CRT, 3255 cirrusfb_dbg_print_regs(regbase, CRT,
3240 "CR00", 0x00, 3256 "CR00", 0x00,
3241 "CR01", 0x01, 3257 "CR01", 0x01,
3242 "CR02", 0x02, 3258 "CR02", 0x02,
@@ -3286,11 +3302,11 @@ void cirrusfb_dbg_reg_dump (caddr_t regbase)
3286 "CR3F", 0x3F, 3302 "CR3F", 0x3F,
3287 NULL); 3303 NULL);
3288 3304
3289 DPRINTK ("\n"); 3305 DPRINTK("\n");
3290 3306
3291 DPRINTK ("CIRRUSFB VGA SEQ register dump:\n"); 3307 DPRINTK("CIRRUSFB VGA SEQ register dump:\n");
3292 3308
3293 cirrusfb_dbg_print_regs (regbase, SEQ, 3309 cirrusfb_dbg_print_regs(regbase, SEQ,
3294 "SR00", 0x00, 3310 "SR00", 0x00,
3295 "SR01", 0x01, 3311 "SR01", 0x01,
3296 "SR02", 0x02, 3312 "SR02", 0x02,
@@ -3319,7 +3335,7 @@ void cirrusfb_dbg_reg_dump (caddr_t regbase)
3319 "SR1F", 0x1F, 3335 "SR1F", 0x1F,
3320 NULL); 3336 NULL);
3321 3337
3322 DPRINTK ("\n"); 3338 DPRINTK("\n");
3323} 3339}
3324 3340
3325#endif /* CIRRUSFB_DEBUG */ 3341#endif /* CIRRUSFB_DEBUG */
diff --git a/drivers/video/clps711xfb.c b/drivers/video/clps711xfb.c
index dea6579941b7..17b5267f44d7 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/clps711xfb.c
@@ -29,7 +29,7 @@
29 29
30#include <asm/hardware.h> 30#include <asm/hardware.h>
31#include <asm/mach-types.h> 31#include <asm/mach-types.h>
32#include <asm/uaccess.h> 32#include <linux/uaccess.h>
33 33
34#include <asm/hardware/clps7111.h> 34#include <asm/hardware/clps7111.h>
35#include <asm/arch/syspld.h> 35#include <asm/arch/syspld.h>
diff --git a/drivers/video/console/fbcon.c b/drivers/video/console/fbcon.c
index e58c87b3e3a0..0f32f4a00b2d 100644
--- a/drivers/video/console/fbcon.c
+++ b/drivers/video/console/fbcon.c
@@ -78,7 +78,6 @@
78#include <asm/fb.h> 78#include <asm/fb.h>
79#include <asm/irq.h> 79#include <asm/irq.h>
80#include <asm/system.h> 80#include <asm/system.h>
81#include <asm/uaccess.h>
82#ifdef CONFIG_ATARI 81#ifdef CONFIG_ATARI
83#include <asm/atariints.h> 82#include <asm/atariints.h>
84#endif 83#endif
@@ -2169,7 +2168,7 @@ static __inline__ void updatescrollmode(struct display *p,
2169} 2168}
2170 2169
2171static int fbcon_resize(struct vc_data *vc, unsigned int width, 2170static int fbcon_resize(struct vc_data *vc, unsigned int width,
2172 unsigned int height) 2171 unsigned int height, unsigned int user)
2173{ 2172{
2174 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]]; 2173 struct fb_info *info = registered_fb[con2fb_map[vc->vc_num]];
2175 struct fbcon_ops *ops = info->fbcon_par; 2174 struct fbcon_ops *ops = info->fbcon_par;
@@ -2406,7 +2405,7 @@ static int fbcon_blank(struct vc_data *vc, int blank, int mode_switch)
2406 update_screen(vc); 2405 update_screen(vc);
2407 } 2406 }
2408 2407
2409 if (fbcon_is_inactive(vc, info) || 2408 if (mode_switch || fbcon_is_inactive(vc, info) ||
2410 ops->blank_state != FB_BLANK_UNBLANK) 2409 ops->blank_state != FB_BLANK_UNBLANK)
2411 fbcon_del_cursor_timer(info); 2410 fbcon_del_cursor_timer(info);
2412 else 2411 else
diff --git a/drivers/video/console/font_10x18.c b/drivers/video/console/font_10x18.c
index e6aa0eab5bb6..6be72bb218ee 100644
--- a/drivers/video/console/font_10x18.c
+++ b/drivers/video/console/font_10x18.c
@@ -5133,14 +5133,14 @@ static const unsigned char fontdata_10x18[FONTDATAMAX] = {
5133 5133
5134 5134
5135const struct font_desc font_10x18 = { 5135const struct font_desc font_10x18 = {
5136 FONT10x18_IDX, 5136 .idx = FONT10x18_IDX,
5137 "10x18", 5137 .name = "10x18",
5138 10, 5138 .width = 10,
5139 18, 5139 .height = 18,
5140 fontdata_10x18, 5140 .data = fontdata_10x18,
5141#ifdef __sparc__ 5141#ifdef __sparc__
5142 5 5142 .pref = 5,
5143#else 5143#else
5144 -1 5144 .pref = -1,
5145#endif 5145#endif
5146}; 5146};
diff --git a/drivers/video/console/font_6x11.c b/drivers/video/console/font_6x11.c
index 89976cd97494..46e86e67aa6a 100644
--- a/drivers/video/console/font_6x11.c
+++ b/drivers/video/console/font_6x11.c
@@ -3342,10 +3342,11 @@ static const unsigned char fontdata_6x11[FONTDATAMAX] = {
3342 3342
3343 3343
3344const struct font_desc font_vga_6x11 = { 3344const struct font_desc font_vga_6x11 = {
3345 VGA6x11_IDX, 3345 .idx = VGA6x11_IDX,
3346 "ProFont6x11", 3346 .name = "ProFont6x11",
3347 6, 3347 .width = 6,
3348 11, 3348 .height = 11,
3349 fontdata_6x11, 3349 .data = fontdata_6x11,
3350 -2000 /* Try avoiding this font if possible unless on MAC */ 3350 /* Try avoiding this font if possible unless on MAC */
3351 .pref = -2000,
3351}; 3352};
diff --git a/drivers/video/console/font_7x14.c b/drivers/video/console/font_7x14.c
index bbf116647397..3b7dbf9c060b 100644
--- a/drivers/video/console/font_7x14.c
+++ b/drivers/video/console/font_7x14.c
@@ -4109,10 +4109,10 @@ static const unsigned char fontdata_7x14[FONTDATAMAX] = {
4109 4109
4110 4110
4111const struct font_desc font_7x14 = { 4111const struct font_desc font_7x14 = {
4112 FONT7x14_IDX, 4112 .idx = FONT7x14_IDX,
4113 "7x14", 4113 .name = "7x14",
4114 7, 4114 .width = 7,
4115 14, 4115 .height = 14,
4116 fontdata_7x14, 4116 .data = fontdata_7x14,
4117 0 4117 .pref = 0,
4118}; 4118};
diff --git a/drivers/video/console/font_8x16.c b/drivers/video/console/font_8x16.c
index 74fe86f28ff4..00a0c67a5c7d 100644
--- a/drivers/video/console/font_8x16.c
+++ b/drivers/video/console/font_8x16.c
@@ -5,6 +5,7 @@
5/**********************************************/ 5/**********************************************/
6 6
7#include <linux/font.h> 7#include <linux/font.h>
8#include <linux/module.h>
8 9
9#define FONTDATAMAX 4096 10#define FONTDATAMAX 4096
10 11
@@ -4622,10 +4623,11 @@ static const unsigned char fontdata_8x16[FONTDATAMAX] = {
4622 4623
4623 4624
4624const struct font_desc font_vga_8x16 = { 4625const struct font_desc font_vga_8x16 = {
4625 VGA8x16_IDX, 4626 .idx = VGA8x16_IDX,
4626 "VGA8x16", 4627 .name = "VGA8x16",
4627 8, 4628 .width = 8,
4628 16, 4629 .height = 16,
4629 fontdata_8x16, 4630 .data = fontdata_8x16,
4630 0 4631 .pref = 0,
4631}; 4632};
4633EXPORT_SYMBOL(font_vga_8x16);
diff --git a/drivers/video/console/font_8x8.c b/drivers/video/console/font_8x8.c
index 26199f8ee908..9f56efe2cee7 100644
--- a/drivers/video/console/font_8x8.c
+++ b/drivers/video/console/font_8x8.c
@@ -2574,10 +2574,10 @@ static const unsigned char fontdata_8x8[FONTDATAMAX] = {
2574 2574
2575 2575
2576const struct font_desc font_vga_8x8 = { 2576const struct font_desc font_vga_8x8 = {
2577 VGA8x8_IDX, 2577 .idx = VGA8x8_IDX,
2578 "VGA8x8", 2578 .name = "VGA8x8",
2579 8, 2579 .width = 8,
2580 8, 2580 .height = 8,
2581 fontdata_8x8, 2581 .data = fontdata_8x8,
2582 0 2582 .pref = 0,
2583}; 2583};
diff --git a/drivers/video/console/font_acorn_8x8.c b/drivers/video/console/font_acorn_8x8.c
index 40f3d4eeb198..639e31ae1100 100644
--- a/drivers/video/console/font_acorn_8x8.c
+++ b/drivers/video/console/font_acorn_8x8.c
@@ -262,14 +262,14 @@ static const unsigned char acorndata_8x8[] = {
262}; 262};
263 263
264const struct font_desc font_acorn_8x8 = { 264const struct font_desc font_acorn_8x8 = {
265 ACORN8x8_IDX, 265 .idx = ACORN8x8_IDX,
266 "Acorn8x8", 266 .name = "Acorn8x8",
267 8, 267 .width = 8,
268 8, 268 .height = 8,
269 acorndata_8x8, 269 .data = acorndata_8x8,
270#ifdef CONFIG_ARCH_ACORN 270#ifdef CONFIG_ARCH_ACORN
271 20 271 .pref = 20,
272#else 272#else
273 0 273 .pref = 0,
274#endif 274#endif
275}; 275};
diff --git a/drivers/video/console/font_mini_4x6.c b/drivers/video/console/font_mini_4x6.c
index d818234fdf11..a19a7f33133e 100644
--- a/drivers/video/console/font_mini_4x6.c
+++ b/drivers/video/console/font_mini_4x6.c
@@ -2148,11 +2148,11 @@ static const unsigned char fontdata_mini_4x6[FONTDATAMAX] = {
2148}; 2148};
2149 2149
2150const struct font_desc font_mini_4x6 = { 2150const struct font_desc font_mini_4x6 = {
2151 MINI4x6_IDX, 2151 .idx = MINI4x6_IDX,
2152 "MINI4x6", 2152 .name = "MINI4x6",
2153 4, 2153 .width = 4,
2154 6, 2154 .height = 6,
2155 fontdata_mini_4x6, 2155 .data = fontdata_mini_4x6,
2156 3 2156 .pref = 3,
2157}; 2157};
2158 2158
diff --git a/drivers/video/console/font_pearl_8x8.c b/drivers/video/console/font_pearl_8x8.c
index e646c88f55c7..dc6ad539ca4e 100644
--- a/drivers/video/console/font_pearl_8x8.c
+++ b/drivers/video/console/font_pearl_8x8.c
@@ -2578,10 +2578,10 @@ static const unsigned char fontdata_pearl8x8[FONTDATAMAX] = {
2578}; 2578};
2579 2579
2580const struct font_desc font_pearl_8x8 = { 2580const struct font_desc font_pearl_8x8 = {
2581 PEARL8x8_IDX, 2581 .idx = PEARL8x8_IDX,
2582 "PEARL8x8", 2582 .name = "PEARL8x8",
2583 8, 2583 .width = 8,
2584 8, 2584 .height = 8,
2585 fontdata_pearl8x8, 2585 .data = fontdata_pearl8x8,
2586 2 2586 .pref = 2,
2587}; 2587};
diff --git a/drivers/video/console/font_sun12x22.c b/drivers/video/console/font_sun12x22.c
index ab5eb93407b4..d3643853c33a 100644
--- a/drivers/video/console/font_sun12x22.c
+++ b/drivers/video/console/font_sun12x22.c
@@ -6152,14 +6152,14 @@ static const unsigned char fontdata_sun12x22[FONTDATAMAX] = {
6152 6152
6153 6153
6154const struct font_desc font_sun_12x22 = { 6154const struct font_desc font_sun_12x22 = {
6155 SUN12x22_IDX, 6155 .idx = SUN12x22_IDX,
6156 "SUN12x22", 6156 .name = "SUN12x22",
6157 12, 6157 .width = 12,
6158 22, 6158 .height = 22,
6159 fontdata_sun12x22, 6159 .data = fontdata_sun12x22,
6160#ifdef __sparc__ 6160#ifdef __sparc__
6161 5 6161 .pref = 5,
6162#else 6162#else
6163 -1 6163 .pref = -1,
6164#endif 6164#endif
6165}; 6165};
diff --git a/drivers/video/console/font_sun8x16.c b/drivers/video/console/font_sun8x16.c
index 41f910f5529c..5abf290c6eb7 100644
--- a/drivers/video/console/font_sun8x16.c
+++ b/drivers/video/console/font_sun8x16.c
@@ -262,14 +262,14 @@ static const unsigned char fontdata_sun8x16[FONTDATAMAX] = {
262}; 262};
263 263
264const struct font_desc font_sun_8x16 = { 264const struct font_desc font_sun_8x16 = {
265 SUN8x16_IDX, 265 .idx = SUN8x16_IDX,
266 "SUN8x16", 266 .name = "SUN8x16",
267 8, 267 .width = 8,
268 16, 268 .height = 16,
269 fontdata_sun8x16, 269 .data = fontdata_sun8x16,
270#ifdef __sparc__ 270#ifdef __sparc__
271 10 271 .pref = 10,
272#else 272#else
273 -1 273 .pref = -1,
274#endif 274#endif
275}; 275};
diff --git a/drivers/video/console/newport_con.c b/drivers/video/console/newport_con.c
index dda0586ab3f3..f57d7b2758b7 100644
--- a/drivers/video/console/newport_con.c
+++ b/drivers/video/console/newport_con.c
@@ -98,14 +98,19 @@ static inline void newport_init_cmap(void)
98 } 98 }
99} 99}
100 100
101static void newport_show_logo(void) 101static struct linux_logo *newport_show_logo(void)
102{ 102{
103#ifdef CONFIG_LOGO_SGI_CLUT224 103#ifdef CONFIG_LOGO_SGI_CLUT224
104 const struct linux_logo *logo = fb_find_logo(8); 104 const struct linux_logo *logo = fb_find_logo(8);
105 const unsigned char *clut = logo->clut; 105 const unsigned char *clut;
106 const unsigned char *data = logo->data; 106 const unsigned char *data;
107 unsigned long i; 107 unsigned long i;
108 108
109 if (!logo)
110 return NULL;
111 *clut = logo->clut;
112 *data = logo->data;
113
109 for (i = 0; i < logo->clutsize; i++) { 114 for (i = 0; i < logo->clutsize; i++) {
110 newport_bfwait(npregs); 115 newport_bfwait(npregs);
111 newport_cmap_setaddr(npregs, i + 0x20); 116 newport_cmap_setaddr(npregs, i + 0x20);
@@ -123,6 +128,8 @@ static void newport_show_logo(void)
123 128
124 for (i = 0; i < logo->width*logo->height; i++) 129 for (i = 0; i < logo->width*logo->height; i++)
125 npregs->go.hostrw0 = *data++ << 24; 130 npregs->go.hostrw0 = *data++ << 24;
131
132 return logo;
126#endif /* CONFIG_LOGO_SGI_CLUT224 */ 133#endif /* CONFIG_LOGO_SGI_CLUT224 */
127} 134}
128 135
@@ -465,9 +472,10 @@ static int newport_switch(struct vc_data *vc)
465 npregs->cset.topscan = 0x3ff; 472 npregs->cset.topscan = 0x3ff;
466 473
467 if (!logo_drawn) { 474 if (!logo_drawn) {
468 newport_show_logo(); 475 if (newport_show_logo()) {
469 logo_drawn = 1; 476 logo_drawn = 1;
470 logo_active = 1; 477 logo_active = 1;
478 }
471 } 479 }
472 480
473 return 1; 481 return 1;
diff --git a/drivers/video/console/softcursor.c b/drivers/video/console/softcursor.c
index 03cfb7ac5733..25f835bf3d72 100644
--- a/drivers/video/console/softcursor.c
+++ b/drivers/video/console/softcursor.c
@@ -15,7 +15,6 @@
15#include <linux/fb.h> 15#include <linux/fb.h>
16#include <linux/slab.h> 16#include <linux/slab.h>
17 17
18#include <asm/uaccess.h>
19#include <asm/io.h> 18#include <asm/io.h>
20 19
21#include "fbcon.h" 20#include "fbcon.h"
diff --git a/drivers/video/console/vgacon.c b/drivers/video/console/vgacon.c
index d18b73aafa0d..e9afb7ebd566 100644
--- a/drivers/video/console/vgacon.c
+++ b/drivers/video/console/vgacon.c
@@ -1278,13 +1278,14 @@ static int vgacon_font_get(struct vc_data *c, struct console_font *font)
1278#endif 1278#endif
1279 1279
1280static int vgacon_resize(struct vc_data *c, unsigned int width, 1280static int vgacon_resize(struct vc_data *c, unsigned int width,
1281 unsigned int height) 1281 unsigned int height, unsigned int user)
1282{ 1282{
1283 if (width % 2 || width > ORIG_VIDEO_COLS || 1283 if (width % 2 || width > ORIG_VIDEO_COLS ||
1284 height > (ORIG_VIDEO_LINES * vga_default_font_height)/ 1284 height > (ORIG_VIDEO_LINES * vga_default_font_height)/
1285 c->vc_font.height) 1285 c->vc_font.height)
1286 /* let svgatextmode tinker with video timings */ 1286 /* let svgatextmode tinker with video timings and
1287 return 0; 1287 return success */
1288 return (user) ? 0 : -EINVAL;
1288 1289
1289 if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */ 1290 if (CON_IS_VISIBLE(c) && !vga_is_gfx) /* who knows */
1290 vgacon_doresize(c, width, height); 1291 vgacon_doresize(c, width, height);
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/cyber2000fb.c
index 30ede6e8830f..9bb2cbfe4a3d 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/cyber2000fb.c
@@ -50,7 +50,6 @@
50#include <asm/io.h> 50#include <asm/io.h>
51#include <asm/pgtable.h> 51#include <asm/pgtable.h>
52#include <asm/system.h> 52#include <asm/system.h>
53#include <asm/uaccess.h>
54 53
55#ifdef __arm__ 54#ifdef __arm__
56#include <asm/mach-types.h> 55#include <asm/mach-types.h>
diff --git a/drivers/video/epson1355fb.c b/drivers/video/epson1355fb.c
index 33be46ccb54f..cc2810ef5de5 100644
--- a/drivers/video/epson1355fb.c
+++ b/drivers/video/epson1355fb.c
@@ -57,7 +57,7 @@
57 57
58#include <asm/types.h> 58#include <asm/types.h>
59#include <asm/io.h> 59#include <asm/io.h>
60#include <asm/uaccess.h> 60#include <linux/uaccess.h>
61 61
62#include <video/epson1355.h> 62#include <video/epson1355.h>
63 63
diff --git a/drivers/video/fb_defio.c b/drivers/video/fb_defio.c
index 1a8643f053d8..a0c5d9d90d74 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fb_defio.c
@@ -19,7 +19,6 @@
19#include <linux/interrupt.h> 19#include <linux/interrupt.h>
20#include <linux/fb.h> 20#include <linux/fb.h>
21#include <linux/list.h> 21#include <linux/list.h>
22#include <asm/uaccess.h>
23 22
24/* to support deferred IO */ 23/* to support deferred IO */
25#include <linux/rmap.h> 24#include <linux/rmap.h>
diff --git a/drivers/video/fb_draw.h b/drivers/video/fb_draw.h
index c5c45203833b..cdafbe14ef1f 100644
--- a/drivers/video/fb_draw.h
+++ b/drivers/video/fb_draw.h
@@ -2,6 +2,7 @@
2#define _FB_DRAW_H 2#define _FB_DRAW_H
3 3
4#include <asm/types.h> 4#include <asm/types.h>
5#include <linux/fb.h>
5 6
6 /* 7 /*
7 * Compose two values, using a bitmask as decision value 8 * Compose two values, using a bitmask as decision value
@@ -69,4 +70,97 @@ pixel_to_pat( u32 bpp, u32 pixel)
69 } 70 }
70} 71}
71#endif 72#endif
73
74#ifdef CONFIG_FB_CFB_REV_PIXELS_IN_BYTE
75#if BITS_PER_LONG == 64
76#define REV_PIXELS_MASK1 0x5555555555555555ul
77#define REV_PIXELS_MASK2 0x3333333333333333ul
78#define REV_PIXELS_MASK4 0x0f0f0f0f0f0f0f0ful
79#else
80#define REV_PIXELS_MASK1 0x55555555ul
81#define REV_PIXELS_MASK2 0x33333333ul
82#define REV_PIXELS_MASK4 0x0f0f0f0ful
83#endif
84
85static inline unsigned long fb_rev_pixels_in_long(unsigned long val,
86 u32 bswapmask)
87{
88 if (bswapmask & 1)
89 val = comp(val >> 1, val << 1, REV_PIXELS_MASK1);
90 if (bswapmask & 2)
91 val = comp(val >> 2, val << 2, REV_PIXELS_MASK2);
92 if (bswapmask & 3)
93 val = comp(val >> 4, val << 4, REV_PIXELS_MASK4);
94}
95
96static inline u32 fb_shifted_pixels_mask_u32(u32 index, u32 bswapmask)
97{
98 u32 mask;
99
100 if (!bswapmask) {
101 mask = FB_SHIFT_HIGH(~(u32)0, index);
102 } else {
103 mask = 0xff << FB_LEFT_POS(8);
104 mask = FB_SHIFT_LOW(mask, index & (bswapmask)) & mask;
105 mask = FB_SHIFT_HIGH(mask, index & ~(bswapmask));
106#if defined(__i386__) || defined(__x86_64__)
107 /* Shift argument is limited to 0 - 31 on x86 based CPU's */
108 if(index + bswapmask < 32)
109#endif
110 mask |= FB_SHIFT_HIGH(~(u32)0,
111 (index + bswapmask) & ~(bswapmask));
112 }
113 return mask;
114}
115
116static inline unsigned long fb_shifted_pixels_mask_long(u32 index, u32 bswapmask)
117{
118 unsigned long mask;
119
120 if (!bswapmask) {
121 mask = FB_SHIFT_HIGH(~0UL, index);
122 } else {
123 mask = 0xff << FB_LEFT_POS(8);
124 mask = FB_SHIFT_LOW(mask, index & (bswapmask)) & mask;
125 mask = FB_SHIFT_HIGH(mask, index & ~(bswapmask));
126#if defined(__i386__) || defined(__x86_64__)
127 /* Shift argument is limited to 0 - 31 on x86 based CPU's */
128 if(index + bswapmask < BITS_PER_LONG)
129#endif
130 mask |= FB_SHIFT_HIGH(~0UL,
131 (index + bswapmask) & ~(bswapmask));
132 }
133 return mask;
134}
135
136
137static inline u32 fb_compute_bswapmask(struct fb_info *info)
138{
139 u32 bswapmask = 0;
140 unsigned bpp = info->var.bits_per_pixel;
141
142 if ((bpp < 8) && (info->var.nonstd & FB_NONSTD_REV_PIX_IN_B)) {
143 /*
144 * Reversed order of pixel layout in bytes
145 * works only for 1, 2 and 4 bpp
146 */
147 bswapmask = 7 - bpp + 1;
148 }
149 return bswapmask;
150}
151
152#else /* CONFIG_FB_CFB_REV_PIXELS_IN_BYTE */
153
154static inline unsigned long fb_rev_pixels_in_long(unsigned long val,
155 u32 bswapmask)
156{
157 return val;
158}
159
160#define fb_shifted_pixels_mask_u32(i, b) FB_SHIFT_HIGH(~(u32)0, (i))
161#define fb_shifted_pixels_mask_long(i, b) FB_SHIFT_HIGH(~0UL, (i))
162#define fb_compute_bswapmask(...) 0
163
164#endif /* CONFIG_FB_CFB_REV_PIXELS_IN_BYTE */
165
72#endif /* FB_DRAW_H */ 166#endif /* FB_DRAW_H */
diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fb_sys_fops.c
index cf2538d669cd..ff275d7f3eaf 100644
--- a/drivers/video/fb_sys_fops.c
+++ b/drivers/video/fb_sys_fops.c
@@ -11,7 +11,7 @@
11 */ 11 */
12#include <linux/fb.h> 12#include <linux/fb.h>
13#include <linux/module.h> 13#include <linux/module.h>
14#include <asm/uaccess.h> 14#include <linux/uaccess.h>
15 15
16ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count, 16ssize_t fb_sys_read(struct fb_info *info, char __user *buf, size_t count,
17 loff_t *ppos) 17 loff_t *ppos)
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbcmap.c
index 148108afdd51..91b78e691505 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbcmap.c
@@ -15,8 +15,7 @@
15#include <linux/module.h> 15#include <linux/module.h>
16#include <linux/fb.h> 16#include <linux/fb.h>
17#include <linux/slab.h> 17#include <linux/slab.h>
18 18#include <linux/uaccess.h>
19#include <asm/uaccess.h>
20 19
21static u16 red2[] __read_mostly = { 20static u16 red2[] __read_mostly = {
22 0x0000, 0xaaaa 21 0x0000, 0xaaaa
diff --git a/drivers/video/fbmem.c b/drivers/video/fbmem.c
index 074027204702..1194f5e060ea 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbmem.c
@@ -1567,8 +1567,6 @@ int fb_new_modelist(struct fb_info *info)
1567static char *video_options[FB_MAX] __read_mostly; 1567static char *video_options[FB_MAX] __read_mostly;
1568static int ofonly __read_mostly; 1568static int ofonly __read_mostly;
1569 1569
1570extern const char *global_mode_option;
1571
1572/** 1570/**
1573 * fb_get_options - get kernel boot parameters 1571 * fb_get_options - get kernel boot parameters
1574 * @name: framebuffer name as it would appear in 1572 * @name: framebuffer name as it would appear in
@@ -1636,7 +1634,7 @@ static int __init video_setup(char *options)
1636 } 1634 }
1637 1635
1638 if (!global && !strstr(options, "fb:")) { 1636 if (!global && !strstr(options, "fb:")) {
1639 global_mode_option = options; 1637 fb_mode_option = options;
1640 global = 1; 1638 global = 1;
1641 } 1639 }
1642 1640
@@ -1663,7 +1661,6 @@ EXPORT_SYMBOL(register_framebuffer);
1663EXPORT_SYMBOL(unregister_framebuffer); 1661EXPORT_SYMBOL(unregister_framebuffer);
1664EXPORT_SYMBOL(num_registered_fb); 1662EXPORT_SYMBOL(num_registered_fb);
1665EXPORT_SYMBOL(registered_fb); 1663EXPORT_SYMBOL(registered_fb);
1666EXPORT_SYMBOL(fb_prepare_logo);
1667EXPORT_SYMBOL(fb_show_logo); 1664EXPORT_SYMBOL(fb_show_logo);
1668EXPORT_SYMBOL(fb_set_var); 1665EXPORT_SYMBOL(fb_set_var);
1669EXPORT_SYMBOL(fb_blank); 1666EXPORT_SYMBOL(fb_blank);
diff --git a/drivers/video/fbmon.c b/drivers/video/fbmon.c
index 438b9411905c..4ba9c0894416 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbmon.c
@@ -591,7 +591,7 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
591{ 591{
592 struct fb_videomode *mode, *m; 592 struct fb_videomode *mode, *m;
593 unsigned char *block; 593 unsigned char *block;
594 int num = 0, i; 594 int num = 0, i, first = 1;
595 595
596 mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL); 596 mode = kzalloc(50 * sizeof(struct fb_videomode), GFP_KERNEL);
597 if (mode == NULL) 597 if (mode == NULL)
@@ -608,8 +608,6 @@ static struct fb_videomode *fb_create_modedb(unsigned char *edid, int *dbsize)
608 DPRINTK(" Detailed Timings\n"); 608 DPRINTK(" Detailed Timings\n");
609 block = edid + DETAILED_TIMING_DESCRIPTIONS_START; 609 block = edid + DETAILED_TIMING_DESCRIPTIONS_START;
610 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) { 610 for (i = 0; i < 4; i++, block+= DETAILED_TIMING_DESCRIPTION_SIZE) {
611 int first = 1;
612
613 if (!(block[0] == 0x00 && block[1] == 0x00)) { 611 if (!(block[0] == 0x00 && block[1] == 0x00)) {
614 get_detailed_timing(block, &mode[num]); 612 get_detailed_timing(block, &mode[num]);
615 if (first) { 613 if (first) {
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/geode/lxfb_core.c
index 5e30b40c8c0f..583185fd7c94 100644
--- a/drivers/video/geode/lxfb_core.c
+++ b/drivers/video/geode/lxfb_core.c
@@ -566,12 +566,7 @@ static int __init lxfb_setup(char *options)
566 if (!options || !*options) 566 if (!options || !*options)
567 return 0; 567 return 0;
568 568
569 while (1) { 569 while ((opt = strsep(&options, ",")) != NULL) {
570 char *opt = strsep(&options, ",");
571
572 if (opt == NULL)
573 break;
574
575 if (!*opt) 570 if (!*opt)
576 continue; 571 continue;
577 572
diff --git a/drivers/video/hecubafb.c b/drivers/video/hecubafb.c
index abfcb50364c8..94e0df8a6f60 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/hecubafb.c
@@ -45,7 +45,7 @@
45#include <linux/init.h> 45#include <linux/init.h>
46#include <linux/platform_device.h> 46#include <linux/platform_device.h>
47#include <linux/list.h> 47#include <linux/list.h>
48#include <asm/uaccess.h> 48#include <linux/uaccess.h>
49 49
50/* Apollo controller specific defines */ 50/* Apollo controller specific defines */
51#define APOLLO_START_NEW_IMG 0xA0 51#define APOLLO_START_NEW_IMG 0xA0
diff --git a/drivers/video/imsttfb.c b/drivers/video/imsttfb.c
index 94f4511023d8..3ab91bf21576 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/imsttfb.c
@@ -29,7 +29,7 @@
29#include <linux/init.h> 29#include <linux/init.h>
30#include <linux/pci.h> 30#include <linux/pci.h>
31#include <asm/io.h> 31#include <asm/io.h>
32#include <asm/uaccess.h> 32#include <linux/uaccess.h>
33 33
34#if defined(CONFIG_PPC) 34#if defined(CONFIG_PPC)
35#include <linux/nvram.h> 35#include <linux/nvram.h>
diff --git a/drivers/video/imxfb.c b/drivers/video/imxfb.c
index a12589898597..11609552a387 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/imxfb.c
@@ -34,7 +34,6 @@
34 34
35#include <asm/hardware.h> 35#include <asm/hardware.h>
36#include <asm/io.h> 36#include <asm/io.h>
37#include <asm/uaccess.h>
38#include <asm/arch/imxfb.h> 37#include <asm/arch/imxfb.h>
39 38
40/* 39/*
@@ -467,7 +466,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
467 info->var.vmode = FB_VMODE_NONINTERLACED; 466 info->var.vmode = FB_VMODE_NONINTERLACED;
468 467
469 info->fbops = &imxfb_ops; 468 info->fbops = &imxfb_ops;
470 info->flags = FBINFO_FLAG_DEFAULT; 469 info->flags = FBINFO_FLAG_DEFAULT | FBINFO_READS_FAST;
471 470
472 fbi->rgb[RGB_16] = &def_rgb_16; 471 fbi->rgb[RGB_16] = &def_rgb_16;
473 fbi->rgb[RGB_8] = &def_rgb_8; 472 fbi->rgb[RGB_8] = &def_rgb_8;
@@ -480,6 +479,7 @@ static int __init imxfb_init_fbinfo(struct device *dev)
480 info->var.yres_virtual = inf->yres; 479 info->var.yres_virtual = inf->yres;
481 fbi->max_bpp = inf->bpp; 480 fbi->max_bpp = inf->bpp;
482 info->var.bits_per_pixel = inf->bpp; 481 info->var.bits_per_pixel = inf->bpp;
482 info->var.nonstd = inf->nonstd;
483 info->var.pixclock = inf->pixclock; 483 info->var.pixclock = inf->pixclock;
484 info->var.hsync_len = inf->hsync_len; 484 info->var.hsync_len = inf->hsync_len;
485 info->var.left_margin = inf->left_margin; 485 info->var.left_margin = inf->left_margin;
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/intelfb/intelfb.h
index 6148300fadd6..2fe3f7def530 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/intelfb/intelfb.h
@@ -231,8 +231,8 @@ struct intelfb_hwstate {
231struct intelfb_heap_data { 231struct intelfb_heap_data {
232 u32 physical; 232 u32 physical;
233 u8 __iomem *virtual; 233 u8 __iomem *virtual;
234 u32 offset; // in GATT pages 234 u32 offset; /* in GATT pages */
235 u32 size; // in bytes 235 u32 size; /* in bytes */
236}; 236};
237 237
238#ifdef CONFIG_FB_INTEL_I2C 238#ifdef CONFIG_FB_INTEL_I2C
@@ -270,9 +270,9 @@ struct intelfb_info {
270 struct intelfb_hwstate save_state; 270 struct intelfb_hwstate save_state;
271 271
272 /* agpgart structs */ 272 /* agpgart structs */
273 struct agp_memory *gtt_fb_mem; // use all stolen memory or vram 273 struct agp_memory *gtt_fb_mem; /* use all stolen memory or vram */
274 struct agp_memory *gtt_ring_mem; // ring buffer 274 struct agp_memory *gtt_ring_mem; /* ring buffer */
275 struct agp_memory *gtt_cursor_mem; // hw cursor 275 struct agp_memory *gtt_cursor_mem; /* hw cursor */
276 276
277 /* use a gart reserved fb mem */ 277 /* use a gart reserved fb mem */
278 u8 fbmem_gart; 278 u8 fbmem_gart;
@@ -346,7 +346,7 @@ struct intelfb_info {
346 346
347 /* driver registered */ 347 /* driver registered */
348 int registered; 348 int registered;
349 349
350 /* index into plls */ 350 /* index into plls */
351 int pll_index; 351 int pll_index;
352 352
@@ -355,7 +355,10 @@ struct intelfb_info {
355 struct intelfb_output_rec output[MAX_OUTPUTS]; 355 struct intelfb_output_rec output[MAX_OUTPUTS];
356}; 356};
357 357
358#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G)||(dinfo->chipset == INTEL_915GM)||((dinfo)->chipset == INTEL_945G)||(dinfo->chipset==INTEL_945GM)) 358#define IS_I9XX(dinfo) (((dinfo)->chipset == INTEL_915G) || \
359 ((dinfo)->chipset == INTEL_915GM) || \
360 ((dinfo)->chipset == INTEL_945G) || \
361 ((dinfo)->chipset==INTEL_945GM))
359 362
360#ifndef FBIO_WAITFORVSYNC 363#ifndef FBIO_WAITFORVSYNC
361#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32) 364#define FBIO_WAITFORVSYNC _IOW('F', 0x20, __u32)
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/intelfb/intelfb_i2c.c
index 61e4c8759b23..94c08bb5acf1 100644
--- a/drivers/video/intelfb/intelfb_i2c.c
+++ b/drivers/video/intelfb/intelfb_i2c.c
@@ -58,7 +58,8 @@ static void intelfb_gpio_setscl(void *data, int state)
58 struct intelfb_info *dinfo = chan->dinfo; 58 struct intelfb_info *dinfo = chan->dinfo;
59 u32 val; 59 u32 val;
60 60
61 OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) | SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK); 61 OUTREG(chan->reg, (state ? SCL_VAL_OUT : 0) |
62 SCL_DIR | SCL_DIR_MASK | SCL_VAL_MASK);
62 val = INREG(chan->reg); 63 val = INREG(chan->reg);
63} 64}
64 65
@@ -68,7 +69,8 @@ static void intelfb_gpio_setsda(void *data, int state)
68 struct intelfb_info *dinfo = chan->dinfo; 69 struct intelfb_info *dinfo = chan->dinfo;
69 u32 val; 70 u32 val;
70 71
71 OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) | SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK); 72 OUTREG(chan->reg, (state ? SDA_VAL_OUT : 0) |
73 SDA_DIR | SDA_DIR_MASK | SDA_VAL_MASK);
72 val = INREG(chan->reg); 74 val = INREG(chan->reg);
73} 75}
74 76
@@ -97,26 +99,26 @@ static int intelfb_gpio_getsda(void *data)
97} 99}
98 100
99static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo, 101static int intelfb_setup_i2c_bus(struct intelfb_info *dinfo,
100 struct intelfb_i2c_chan *chan, 102 struct intelfb_i2c_chan *chan,
101 const u32 reg, const char *name) 103 const u32 reg, const char *name)
102{ 104{
103 int rc; 105 int rc;
104 106
105 chan->dinfo = dinfo; 107 chan->dinfo = dinfo;
106 chan->reg = reg; 108 chan->reg = reg;
107 snprintf(chan->adapter.name, sizeof(chan->adapter.name), 109 snprintf(chan->adapter.name, sizeof(chan->adapter.name),
108 "intelfb %s", name); 110 "intelfb %s", name);
109 chan->adapter.owner = THIS_MODULE; 111 chan->adapter.owner = THIS_MODULE;
110 chan->adapter.id = I2C_HW_B_INTELFB; 112 chan->adapter.id = I2C_HW_B_INTELFB;
111 chan->adapter.algo_data = &chan->algo; 113 chan->adapter.algo_data = &chan->algo;
112 chan->adapter.dev.parent = &chan->dinfo->pdev->dev; 114 chan->adapter.dev.parent = &chan->dinfo->pdev->dev;
113 chan->algo.setsda = intelfb_gpio_setsda; 115 chan->algo.setsda = intelfb_gpio_setsda;
114 chan->algo.setscl = intelfb_gpio_setscl; 116 chan->algo.setscl = intelfb_gpio_setscl;
115 chan->algo.getsda = intelfb_gpio_getsda; 117 chan->algo.getsda = intelfb_gpio_getsda;
116 chan->algo.getscl = intelfb_gpio_getscl; 118 chan->algo.getscl = intelfb_gpio_getscl;
117 chan->algo.udelay = 40; 119 chan->algo.udelay = 40;
118 chan->algo.timeout = 20; 120 chan->algo.timeout = 20;
119 chan->algo.data = chan; 121 chan->algo.data = chan;
120 122
121 i2c_set_adapdata(&chan->adapter, chan); 123 i2c_set_adapdata(&chan->adapter, chan);
122 124
@@ -142,40 +144,44 @@ void intelfb_create_i2c_busses(struct intelfb_info *dinfo)
142 dinfo->output[i].type = INTELFB_OUTPUT_ANALOG; 144 dinfo->output[i].type = INTELFB_OUTPUT_ANALOG;
143 145
144 /* setup the DDC bus for analog output */ 146 /* setup the DDC bus for analog output */
145 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA, "CRTDDC_A"); 147 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOA,
148 "CRTDDC_A");
146 i++; 149 i++;
147 150
148 /* need to add the output busses for each device 151 /* need to add the output busses for each device
149 - this function is very incomplete 152 - this function is very incomplete
150 - i915GM has LVDS and TVOUT for example 153 - i915GM has LVDS and TVOUT for example
151 */ 154 */
152 switch(dinfo->chipset) { 155 switch(dinfo->chipset) {
153 case INTEL_830M: 156 case INTEL_830M:
154 case INTEL_845G: 157 case INTEL_845G:
155 case INTEL_855GM: 158 case INTEL_855GM:
156 case INTEL_865G: 159 case INTEL_865G:
157 dinfo->output[i].type = INTELFB_OUTPUT_DVO; 160 dinfo->output[i].type = INTELFB_OUTPUT_DVO;
158 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus, GPIOD, "DVODDC_D"); 161 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].ddc_bus,
159 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "DVOI2C_E"); 162 GPIOD, "DVODDC_D");
163 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus,
164 GPIOE, "DVOI2C_E");
160 i++; 165 i++;
161 break; 166 break;
162 case INTEL_915G: 167 case INTEL_915G:
163 case INTEL_915GM: 168 case INTEL_915GM:
164 /* has some LVDS + tv-out */ 169 /* has some LVDS + tv-out */
165 case INTEL_945G: 170 case INTEL_945G:
166 case INTEL_945GM: 171 case INTEL_945GM:
167 /* SDVO ports have a single control bus - 2 devices */ 172 /* SDVO ports have a single control bus - 2 devices */
168 dinfo->output[i].type = INTELFB_OUTPUT_SDVO; 173 dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
169 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus, GPIOE, "SDVOCTRL_E"); 174 intelfb_setup_i2c_bus(dinfo, &dinfo->output[i].i2c_bus,
175 GPIOE, "SDVOCTRL_E");
170 /* TODO: initialize the SDVO */ 176 /* TODO: initialize the SDVO */
171// I830SDVOInit(pScrn, i, DVOB); 177 /* I830SDVOInit(pScrn, i, DVOB); */
172 i++; 178 i++;
173 179
174 /* set up SDVOC */ 180 /* set up SDVOC */
175 dinfo->output[i].type = INTELFB_OUTPUT_SDVO; 181 dinfo->output[i].type = INTELFB_OUTPUT_SDVO;
176 dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus; 182 dinfo->output[i].i2c_bus = dinfo->output[i - 1].i2c_bus;
177 /* TODO: initialize the SDVO */ 183 /* TODO: initialize the SDVO */
178// I830SDVOInit(pScrn, i, DVOC); 184 /* I830SDVOInit(pScrn, i, DVOC); */
179 i++; 185 i++;
180 break; 186 break;
181 } 187 }
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/intelfb/intelfbdrv.c
index b75eda84858f..0428f211f192 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/intelfb/intelfbdrv.c
@@ -99,13 +99,6 @@
99 * Add vram option to reserve more memory than stolen by BIOS 99 * Add vram option to reserve more memory than stolen by BIOS
100 * Fix intelfbhw_pan_display typo 100 * Fix intelfbhw_pan_display typo
101 * Add __initdata annotations 101 * Add __initdata annotations
102 *
103 * TODO:
104 *
105 *
106 * Wish List:
107 *
108 *
109 */ 102 */
110 103
111#include <linux/module.h> 104#include <linux/module.h>
@@ -222,8 +215,8 @@ static struct pci_driver intelfb_driver = {
222/* Module description/parameters */ 215/* Module description/parameters */
223MODULE_AUTHOR("David Dawes <dawes@tungstengraphics.com>, " 216MODULE_AUTHOR("David Dawes <dawes@tungstengraphics.com>, "
224 "Sylvain Meyer <sylvain.meyer@worldonline.fr>"); 217 "Sylvain Meyer <sylvain.meyer@worldonline.fr>");
225MODULE_DESCRIPTION( 218MODULE_DESCRIPTION("Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS
226 "Framebuffer driver for Intel(R) " SUPPORTED_CHIPSETS " chipsets"); 219 " chipsets");
227MODULE_LICENSE("Dual BSD/GPL"); 220MODULE_LICENSE("Dual BSD/GPL");
228MODULE_DEVICE_TABLE(pci, intelfb_pci_table); 221MODULE_DEVICE_TABLE(pci, intelfb_pci_table);
229 222
@@ -271,8 +264,7 @@ MODULE_PARM_DESC(mode,
271#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name) + 1, NULL, 0) 264#define OPT_INTVAL(opt, name) simple_strtoul(opt + strlen(name) + 1, NULL, 0)
272#define OPT_STRVAL(opt, name) (opt + strlen(name)) 265#define OPT_STRVAL(opt, name) (opt + strlen(name))
273 266
274static __inline__ char * 267static __inline__ char * get_opt_string(const char *this_opt, const char *name)
275get_opt_string(const char *this_opt, const char *name)
276{ 268{
277 const char *p; 269 const char *p;
278 int i; 270 int i;
@@ -290,8 +282,8 @@ get_opt_string(const char *this_opt, const char *name)
290 return ret; 282 return ret;
291} 283}
292 284
293static __inline__ int 285static __inline__ int get_opt_int(const char *this_opt, const char *name,
294get_opt_int(const char *this_opt, const char *name, int *ret) 286 int *ret)
295{ 287{
296 if (!ret) 288 if (!ret)
297 return 0; 289 return 0;
@@ -303,8 +295,8 @@ get_opt_int(const char *this_opt, const char *name, int *ret)
303 return 1; 295 return 1;
304} 296}
305 297
306static __inline__ int 298static __inline__ int get_opt_bool(const char *this_opt, const char *name,
307get_opt_bool(const char *this_opt, const char *name, int *ret) 299 int *ret)
308{ 300{
309 if (!ret) 301 if (!ret)
310 return 0; 302 return 0;
@@ -324,8 +316,7 @@ get_opt_bool(const char *this_opt, const char *name, int *ret)
324 return 1; 316 return 1;
325} 317}
326 318
327static int __init 319static int __init intelfb_setup(char *options)
328intelfb_setup(char *options)
329{ 320{
330 char *this_opt; 321 char *this_opt;
331 322
@@ -355,7 +346,7 @@ intelfb_setup(char *options)
355 continue; 346 continue;
356 if (get_opt_bool(this_opt, "accel", &accel)) 347 if (get_opt_bool(this_opt, "accel", &accel))
357 ; 348 ;
358 else if (get_opt_int(this_opt, "vram", &vram)) 349 else if (get_opt_int(this_opt, "vram", &vram))
359 ; 350 ;
360 else if (get_opt_bool(this_opt, "hwcursor", &hwcursor)) 351 else if (get_opt_bool(this_opt, "hwcursor", &hwcursor))
361 ; 352 ;
@@ -376,8 +367,7 @@ intelfb_setup(char *options)
376 367
377#endif 368#endif
378 369
379static int __init 370static int __init intelfb_init(void)
380intelfb_init(void)
381{ 371{
382#ifndef MODULE 372#ifndef MODULE
383 char *option = NULL; 373 char *option = NULL;
@@ -401,8 +391,7 @@ intelfb_init(void)
401 return pci_register_driver(&intelfb_driver); 391 return pci_register_driver(&intelfb_driver);
402} 392}
403 393
404static void __exit 394static void __exit intelfb_exit(void)
405intelfb_exit(void)
406{ 395{
407 DBG_MSG("intelfb_exit\n"); 396 DBG_MSG("intelfb_exit\n");
408 pci_unregister_driver(&intelfb_driver); 397 pci_unregister_driver(&intelfb_driver);
@@ -428,8 +417,8 @@ static inline void __devinit set_mtrr(struct intelfb_info *dinfo)
428} 417}
429static inline void unset_mtrr(struct intelfb_info *dinfo) 418static inline void unset_mtrr(struct intelfb_info *dinfo)
430{ 419{
431 if (dinfo->has_mtrr) 420 if (dinfo->has_mtrr)
432 mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical, 421 mtrr_del(dinfo->mtrr_reg, dinfo->aperture.physical,
433 dinfo->aperture.size); 422 dinfo->aperture.size);
434} 423}
435#else 424#else
@@ -442,8 +431,7 @@ static inline void unset_mtrr(struct intelfb_info *dinfo)
442 * driver init / cleanup * 431 * driver init / cleanup *
443 ***************************************************************/ 432 ***************************************************************/
444 433
445static void 434static void cleanup(struct intelfb_info *dinfo)
446cleanup(struct intelfb_info *dinfo)
447{ 435{
448 DBG_MSG("cleanup\n"); 436 DBG_MSG("cleanup\n");
449 437
@@ -499,8 +487,8 @@ cleanup(struct intelfb_info *dinfo)
499} while (0) 487} while (0)
500 488
501 489
502static int __devinit 490static int __devinit intelfb_pci_register(struct pci_dev *pdev,
503intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent) 491 const struct pci_device_id *ent)
504{ 492{
505 struct fb_info *info; 493 struct fb_info *info;
506 struct intelfb_info *dinfo; 494 struct intelfb_info *dinfo;
@@ -510,8 +498,8 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
510 int agp_memtype; 498 int agp_memtype;
511 const char *s; 499 const char *s;
512 struct agp_bridge_data *bridge; 500 struct agp_bridge_data *bridge;
513 int aperture_bar = 0; 501 int aperture_bar = 0;
514 int mmio_bar = 1; 502 int mmio_bar = 1;
515 int offset; 503 int offset;
516 504
517 DBG_MSG("intelfb_pci_register\n"); 505 DBG_MSG("intelfb_pci_register\n");
@@ -637,9 +625,8 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
637 dinfo->ring.size = RINGBUFFER_SIZE; 625 dinfo->ring.size = RINGBUFFER_SIZE;
638 dinfo->ring_tail_mask = dinfo->ring.size - 1; 626 dinfo->ring_tail_mask = dinfo->ring.size - 1;
639 } 627 }
640 if (dinfo->hwcursor) { 628 if (dinfo->hwcursor)
641 dinfo->cursor.size = HW_CURSOR_SIZE; 629 dinfo->cursor.size = HW_CURSOR_SIZE;
642 }
643 630
644 /* Use agpgart to manage the GATT */ 631 /* Use agpgart to manage the GATT */
645 if (!(bridge = agp_backend_acquire(pdev))) { 632 if (!(bridge = agp_backend_acquire(pdev))) {
@@ -662,18 +649,15 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
662 offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE; 649 offset = ROUND_UP_TO_PAGE(MB(voffset))/GTT_PAGE_SIZE;
663 650
664 /* set the mem offsets - set them after the already used pages */ 651 /* set the mem offsets - set them after the already used pages */
665 if (dinfo->accel) { 652 if (dinfo->accel)
666 dinfo->ring.offset = offset + gtt_info.current_memory; 653 dinfo->ring.offset = offset + gtt_info.current_memory;
667 } 654 if (dinfo->hwcursor)
668 if (dinfo->hwcursor) {
669 dinfo->cursor.offset = offset + 655 dinfo->cursor.offset = offset +
670 + gtt_info.current_memory + (dinfo->ring.size >> 12); 656 + gtt_info.current_memory + (dinfo->ring.size >> 12);
671 } 657 if (dinfo->fbmem_gart)
672 if (dinfo->fbmem_gart) {
673 dinfo->fb.offset = offset + 658 dinfo->fb.offset = offset +
674 + gtt_info.current_memory + (dinfo->ring.size >> 12) 659 + gtt_info.current_memory + (dinfo->ring.size >> 12)
675 + (dinfo->cursor.size >> 12); 660 + (dinfo->cursor.size >> 12);
676 }
677 661
678 /* Allocate memories (which aren't stolen) */ 662 /* Allocate memories (which aren't stolen) */
679 /* Map the fb and MMIO regions */ 663 /* Map the fb and MMIO regions */
@@ -689,7 +673,7 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
689 673
690 dinfo->mmio_base = 674 dinfo->mmio_base =
691 (u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys, 675 (u8 __iomem *)ioremap_nocache(dinfo->mmio_base_phys,
692 INTEL_REG_SIZE); 676 INTEL_REG_SIZE);
693 if (!dinfo->mmio_base) { 677 if (!dinfo->mmio_base) {
694 ERR_MSG("Cannot remap MMIO region.\n"); 678 ERR_MSG("Cannot remap MMIO region.\n");
695 cleanup(dinfo); 679 cleanup(dinfo);
@@ -837,10 +821,8 @@ intelfb_pci_register(struct pci_dev *pdev, const struct pci_device_id *ent)
837 if (bailearly == 3) 821 if (bailearly == 3)
838 bailout(dinfo); 822 bailout(dinfo);
839 823
840 if (FIXED_MODE(dinfo)) { 824 if (FIXED_MODE(dinfo)) /* remap fb address */
841 /* remap fb address */
842 update_dinfo(dinfo, &dinfo->initial_var); 825 update_dinfo(dinfo, &dinfo->initial_var);
843 }
844 826
845 if (bailearly == 4) 827 if (bailearly == 4)
846 bailout(dinfo); 828 bailout(dinfo);
@@ -939,8 +921,7 @@ intelfb_pci_unregister(struct pci_dev *pdev)
939 * helper functions * 921 * helper functions *
940 ***************************************************************/ 922 ***************************************************************/
941 923
942int __inline__ 924int __inline__ intelfb_var_to_depth(const struct fb_var_screeninfo *var)
943intelfb_var_to_depth(const struct fb_var_screeninfo *var)
944{ 925{
945 DBG_MSG("intelfb_var_to_depth: bpp: %d, green.length is %d\n", 926 DBG_MSG("intelfb_var_to_depth: bpp: %d, green.length is %d\n",
946 var->bits_per_pixel, var->green.length); 927 var->bits_per_pixel, var->green.length);
@@ -956,8 +937,7 @@ intelfb_var_to_depth(const struct fb_var_screeninfo *var)
956} 937}
957 938
958 939
959static __inline__ int 940static __inline__ int var_to_refresh(const struct fb_var_screeninfo *var)
960var_to_refresh(const struct fb_var_screeninfo *var)
961{ 941{
962 int xtot = var->xres + var->left_margin + var->right_margin + 942 int xtot = var->xres + var->left_margin + var->right_margin +
963 var->hsync_len; 943 var->hsync_len;
@@ -971,8 +951,7 @@ var_to_refresh(const struct fb_var_screeninfo *var)
971 * Various intialisation functions * 951 * Various intialisation functions *
972 ***************************************************************/ 952 ***************************************************************/
973 953
974static void __devinit 954static void __devinit get_initial_mode(struct intelfb_info *dinfo)
975get_initial_mode(struct intelfb_info *dinfo)
976{ 955{
977 struct fb_var_screeninfo *var; 956 struct fb_var_screeninfo *var;
978 int xtot, ytot; 957 int xtot, ytot;
@@ -1039,8 +1018,7 @@ get_initial_mode(struct intelfb_info *dinfo)
1039 } 1018 }
1040} 1019}
1041 1020
1042static int __devinit 1021static int __devinit intelfb_init_var(struct intelfb_info *dinfo)
1043intelfb_init_var(struct intelfb_info *dinfo)
1044{ 1022{
1045 struct fb_var_screeninfo *var; 1023 struct fb_var_screeninfo *var;
1046 int msrc = 0; 1024 int msrc = 0;
@@ -1087,10 +1065,9 @@ intelfb_init_var(struct intelfb_info *dinfo)
1087 1065
1088 } 1066 }
1089 1067
1090 if (!msrc) { 1068 if (!msrc)
1091 msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE, 1069 msrc = fb_find_mode(var, dinfo->info, PREFERRED_MODE,
1092 NULL, 0, NULL, 0); 1070 NULL, 0, NULL, 0);
1093 }
1094 } 1071 }
1095 1072
1096 if (!msrc) { 1073 if (!msrc) {
@@ -1122,8 +1099,7 @@ intelfb_init_var(struct intelfb_info *dinfo)
1122 return 0; 1099 return 0;
1123} 1100}
1124 1101
1125static int __devinit 1102static int __devinit intelfb_set_fbinfo(struct intelfb_info *dinfo)
1126intelfb_set_fbinfo(struct intelfb_info *dinfo)
1127{ 1103{
1128 struct fb_info *info = dinfo->info; 1104 struct fb_info *info = dinfo->info;
1129 1105
@@ -1159,8 +1135,8 @@ intelfb_set_fbinfo(struct intelfb_info *dinfo)
1159} 1135}
1160 1136
1161/* Update dinfo to match the active video mode. */ 1137/* Update dinfo to match the active video mode. */
1162static void 1138static void update_dinfo(struct intelfb_info *dinfo,
1163update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var) 1139 struct fb_var_screeninfo *var)
1164{ 1140{
1165 DBG_MSG("update_dinfo\n"); 1141 DBG_MSG("update_dinfo\n");
1166 1142
@@ -1208,36 +1184,32 @@ update_dinfo(struct intelfb_info *dinfo, struct fb_var_screeninfo *var)
1208 * fbdev interface * 1184 * fbdev interface *
1209 ***************************************************************/ 1185 ***************************************************************/
1210 1186
1211static int 1187static int intelfb_open(struct fb_info *info, int user)
1212intelfb_open(struct fb_info *info, int user)
1213{ 1188{
1214 struct intelfb_info *dinfo = GET_DINFO(info); 1189 struct intelfb_info *dinfo = GET_DINFO(info);
1215 1190
1216 if (user) { 1191 if (user)
1217 dinfo->open++; 1192 dinfo->open++;
1218 }
1219 1193
1220 return 0; 1194 return 0;
1221} 1195}
1222 1196
1223static int 1197static int intelfb_release(struct fb_info *info, int user)
1224intelfb_release(struct fb_info *info, int user)
1225{ 1198{
1226 struct intelfb_info *dinfo = GET_DINFO(info); 1199 struct intelfb_info *dinfo = GET_DINFO(info);
1227 1200
1228 if (user) { 1201 if (user) {
1229 dinfo->open--; 1202 dinfo->open--;
1230 msleep(1); 1203 msleep(1);
1231 if (!dinfo->open) { 1204 if (!dinfo->open)
1232 intelfbhw_disable_irq(dinfo); 1205 intelfbhw_disable_irq(dinfo);
1233 }
1234 } 1206 }
1235 1207
1236 return 0; 1208 return 0;
1237} 1209}
1238 1210
1239static int 1211static int intelfb_check_var(struct fb_var_screeninfo *var,
1240intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 1212 struct fb_info *info)
1241{ 1213{
1242 int change_var = 0; 1214 int change_var = 0;
1243 struct fb_var_screeninfo v; 1215 struct fb_var_screeninfo v;
@@ -1271,15 +1243,15 @@ intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1271 } 1243 }
1272 1244
1273 /* Check for a supported bpp. */ 1245 /* Check for a supported bpp. */
1274 if (v.bits_per_pixel <= 8) { 1246 if (v.bits_per_pixel <= 8)
1275 v.bits_per_pixel = 8; 1247 v.bits_per_pixel = 8;
1276 } else if (v.bits_per_pixel <= 16) { 1248 else if (v.bits_per_pixel <= 16) {
1277 if (v.bits_per_pixel == 16) 1249 if (v.bits_per_pixel == 16)
1278 v.green.length = 6; 1250 v.green.length = 6;
1279 v.bits_per_pixel = 16; 1251 v.bits_per_pixel = 16;
1280 } else if (v.bits_per_pixel <= 32) { 1252 } else if (v.bits_per_pixel <= 32)
1281 v.bits_per_pixel = 32; 1253 v.bits_per_pixel = 32;
1282 } else 1254 else
1283 return -EINVAL; 1255 return -EINVAL;
1284 1256
1285 change_var = ((info->var.xres != var->xres) || 1257 change_var = ((info->var.xres != var->xres) ||
@@ -1361,10 +1333,9 @@ intelfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
1361 return 0; 1333 return 0;
1362} 1334}
1363 1335
1364static int 1336static int intelfb_set_par(struct fb_info *info)
1365intelfb_set_par(struct fb_info *info)
1366{ 1337{
1367 struct intelfb_hwstate *hw; 1338 struct intelfb_hwstate *hw;
1368 struct intelfb_info *dinfo = GET_DINFO(info); 1339 struct intelfb_info *dinfo = GET_DINFO(info);
1369 1340
1370 if (FIXED_MODE(dinfo)) { 1341 if (FIXED_MODE(dinfo)) {
@@ -1372,9 +1343,9 @@ intelfb_set_par(struct fb_info *info)
1372 return -EINVAL; 1343 return -EINVAL;
1373 } 1344 }
1374 1345
1375 hw = kmalloc(sizeof(*hw), GFP_ATOMIC); 1346 hw = kmalloc(sizeof(*hw), GFP_ATOMIC);
1376 if (!hw) 1347 if (!hw)
1377 return -ENOMEM; 1348 return -ENOMEM;
1378 1349
1379 DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres, 1350 DBG_MSG("intelfb_set_par (%dx%d-%d)\n", info->var.xres,
1380 info->var.yres, info->var.bits_per_pixel); 1351 info->var.yres, info->var.bits_per_pixel);
@@ -1384,15 +1355,15 @@ intelfb_set_par(struct fb_info *info)
1384 if (ACCEL(dinfo, info)) 1355 if (ACCEL(dinfo, info))
1385 intelfbhw_2d_stop(dinfo); 1356 intelfbhw_2d_stop(dinfo);
1386 1357
1387 memcpy(hw, &dinfo->save_state, sizeof(*hw)); 1358 memcpy(hw, &dinfo->save_state, sizeof(*hw));
1388 if (intelfbhw_mode_to_hw(dinfo, hw, &info->var)) 1359 if (intelfbhw_mode_to_hw(dinfo, hw, &info->var))
1389 goto invalid_mode; 1360 goto invalid_mode;
1390 if (intelfbhw_program_mode(dinfo, hw, 0)) 1361 if (intelfbhw_program_mode(dinfo, hw, 0))
1391 goto invalid_mode; 1362 goto invalid_mode;
1392 1363
1393#if REGDUMP > 0 1364#if REGDUMP > 0
1394 intelfbhw_read_hw_state(dinfo, hw, 0); 1365 intelfbhw_read_hw_state(dinfo, hw, 0);
1395 intelfbhw_print_hw_state(dinfo, hw); 1366 intelfbhw_print_hw_state(dinfo, hw);
1396#endif 1367#endif
1397 1368
1398 update_dinfo(dinfo, &info->var); 1369 update_dinfo(dinfo, &info->var);
@@ -1408,9 +1379,9 @@ intelfb_set_par(struct fb_info *info)
1408 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN | 1379 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN |
1409 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT | 1380 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_FILLRECT |
1410 FBINFO_HWACCEL_IMAGEBLIT; 1381 FBINFO_HWACCEL_IMAGEBLIT;
1411 } else { 1382 } else
1412 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1383 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1413 } 1384
1414 kfree(hw); 1385 kfree(hw);
1415 return 0; 1386 return 0;
1416invalid_mode: 1387invalid_mode:
@@ -1418,9 +1389,9 @@ invalid_mode:
1418 return -EINVAL; 1389 return -EINVAL;
1419} 1390}
1420 1391
1421static int 1392static int intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1422intelfb_setcolreg(unsigned regno, unsigned red, unsigned green, 1393 unsigned blue, unsigned transp,
1423 unsigned blue, unsigned transp, struct fb_info *info) 1394 struct fb_info *info)
1424{ 1395{
1425 struct intelfb_info *dinfo = GET_DINFO(info); 1396 struct intelfb_info *dinfo = GET_DINFO(info);
1426 1397
@@ -1463,23 +1434,22 @@ intelfb_setcolreg(unsigned regno, unsigned red, unsigned green,
1463 return 0; 1434 return 0;
1464} 1435}
1465 1436
1466static int 1437static int intelfb_blank(int blank, struct fb_info *info)
1467intelfb_blank(int blank, struct fb_info *info)
1468{ 1438{
1469 intelfbhw_do_blank(blank, info); 1439 intelfbhw_do_blank(blank, info);
1470 return 0; 1440 return 0;
1471} 1441}
1472 1442
1473static int 1443static int intelfb_pan_display(struct fb_var_screeninfo *var,
1474intelfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info) 1444 struct fb_info *info)
1475{ 1445{
1476 intelfbhw_pan_display(var, info); 1446 intelfbhw_pan_display(var, info);
1477 return 0; 1447 return 0;
1478} 1448}
1479 1449
1480/* When/if we have our own ioctls. */ 1450/* When/if we have our own ioctls. */
1481static int 1451static int intelfb_ioctl(struct fb_info *info, unsigned int cmd,
1482intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg) 1452 unsigned long arg)
1483{ 1453{
1484 int retval = 0; 1454 int retval = 0;
1485 struct intelfb_info *dinfo = GET_DINFO(info); 1455 struct intelfb_info *dinfo = GET_DINFO(info);
@@ -1499,8 +1469,8 @@ intelfb_ioctl(struct fb_info *info, unsigned int cmd, unsigned long arg)
1499 return retval; 1469 return retval;
1500} 1470}
1501 1471
1502static void 1472static void intelfb_fillrect (struct fb_info *info,
1503intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect) 1473 const struct fb_fillrect *rect)
1504{ 1474{
1505 struct intelfb_info *dinfo = GET_DINFO(info); 1475 struct intelfb_info *dinfo = GET_DINFO(info);
1506 u32 rop, color; 1476 u32 rop, color;
@@ -1514,7 +1484,7 @@ intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect)
1514 1484
1515 if (rect->rop == ROP_COPY) 1485 if (rect->rop == ROP_COPY)
1516 rop = PAT_ROP_GXCOPY; 1486 rop = PAT_ROP_GXCOPY;
1517 else // ROP_XOR 1487 else /* ROP_XOR */
1518 rop = PAT_ROP_GXXOR; 1488 rop = PAT_ROP_GXXOR;
1519 1489
1520 if (dinfo->depth != 8) 1490 if (dinfo->depth != 8)
@@ -1528,8 +1498,8 @@ intelfb_fillrect (struct fb_info *info, const struct fb_fillrect *rect)
1528 rop); 1498 rop);
1529} 1499}
1530 1500
1531static void 1501static void intelfb_copyarea(struct fb_info *info,
1532intelfb_copyarea(struct fb_info *info, const struct fb_copyarea *region) 1502 const struct fb_copyarea *region)
1533{ 1503{
1534 struct intelfb_info *dinfo = GET_DINFO(info); 1504 struct intelfb_info *dinfo = GET_DINFO(info);
1535 1505
@@ -1545,8 +1515,8 @@ intelfb_copyarea(struct fb_info *info, const struct fb_copyarea *region)
1545 dinfo->pitch, info->var.bits_per_pixel); 1515 dinfo->pitch, info->var.bits_per_pixel);
1546} 1516}
1547 1517
1548static void 1518static void intelfb_imageblit(struct fb_info *info,
1549intelfb_imageblit(struct fb_info *info, const struct fb_image *image) 1519 const struct fb_image *image)
1550{ 1520{
1551 struct intelfb_info *dinfo = GET_DINFO(info); 1521 struct intelfb_info *dinfo = GET_DINFO(info);
1552 u32 fgcolor, bgcolor; 1522 u32 fgcolor, bgcolor;
@@ -1574,8 +1544,7 @@ intelfb_imageblit(struct fb_info *info, const struct fb_image *image)
1574 return cfb_imageblit(info, image); 1544 return cfb_imageblit(info, image);
1575} 1545}
1576 1546
1577static int 1547static int intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1578intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1579{ 1548{
1580 struct intelfb_info *dinfo = GET_DINFO(info); 1549 struct intelfb_info *dinfo = GET_DINFO(info);
1581 u32 physical; 1550 u32 physical;
@@ -1689,8 +1658,7 @@ intelfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1689 return 0; 1658 return 0;
1690} 1659}
1691 1660
1692static int 1661static int intelfb_sync(struct fb_info *info)
1693intelfb_sync(struct fb_info *info)
1694{ 1662{
1695 struct intelfb_info *dinfo = GET_DINFO(info); 1663 struct intelfb_info *dinfo = GET_DINFO(info);
1696 1664
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/intelfb/intelfbhw.c
index 6a47682d8614..2a0e32074f7d 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/intelfb/intelfbhw.c
@@ -56,17 +56,16 @@ static struct pll_min_max plls[PLLS_MAX] = {
56 6, 16, 3, 16, 56 6, 16, 3, 16,
57 4, 128, 0, 31, 57 4, 128, 0, 31,
58 930000, 1400000, 165000, 48000, 58 930000, 1400000, 165000, 48000,
59 4, 2 }, //I8xx 59 4, 2 }, /* I8xx */
60 60
61 { 75, 120, 10, 20, 61 { 75, 120, 10, 20,
62 5, 9, 4, 7, 62 5, 9, 4, 7,
63 5, 80, 1, 8, 63 5, 80, 1, 8,
64 1400000, 2800000, 200000, 96000, 64 1400000, 2800000, 200000, 96000,
65 10, 5 } //I9xx 65 10, 5 } /* I9xx */
66}; 66};
67 67
68int 68int intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
69intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
70{ 69{
71 u32 tmp; 70 u32 tmp;
72 if (!pdev || !dinfo) 71 if (!pdev || !dinfo)
@@ -149,9 +148,8 @@ intelfbhw_get_chipset(struct pci_dev *pdev, struct intelfb_info *dinfo)
149 } 148 }
150} 149}
151 150
152int 151int intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
153intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size, 152 int *stolen_size)
154 int *stolen_size)
155{ 153{
156 struct pci_dev *bridge_dev; 154 struct pci_dev *bridge_dev;
157 u16 tmp; 155 u16 tmp;
@@ -254,8 +252,7 @@ intelfbhw_get_memory(struct pci_dev *pdev, int *aperture_size,
254 } 252 }
255} 253}
256 254
257int 255int intelfbhw_check_non_crt(struct intelfb_info *dinfo)
258intelfbhw_check_non_crt(struct intelfb_info *dinfo)
259{ 256{
260 int dvo = 0; 257 int dvo = 0;
261 258
@@ -271,8 +268,7 @@ intelfbhw_check_non_crt(struct intelfb_info *dinfo)
271 return dvo; 268 return dvo;
272} 269}
273 270
274const char * 271const char * intelfbhw_dvo_to_string(int dvo)
275intelfbhw_dvo_to_string(int dvo)
276{ 272{
277 if (dvo & DVOA_PORT) 273 if (dvo & DVOA_PORT)
278 return "DVO port A"; 274 return "DVO port A";
@@ -287,9 +283,8 @@ intelfbhw_dvo_to_string(int dvo)
287} 283}
288 284
289 285
290int 286int intelfbhw_validate_mode(struct intelfb_info *dinfo,
291intelfbhw_validate_mode(struct intelfb_info *dinfo, 287 struct fb_var_screeninfo *var)
292 struct fb_var_screeninfo *var)
293{ 288{
294 int bytes_per_pixel; 289 int bytes_per_pixel;
295 int tmp; 290 int tmp;
@@ -322,17 +317,26 @@ intelfbhw_validate_mode(struct intelfb_info *dinfo,
322 var->yres, VACTIVE_MASK + 1); 317 var->yres, VACTIVE_MASK + 1);
323 return 1; 318 return 1;
324 } 319 }
325 320 if (var->xres < 4) {
326 /* Check for interlaced/doublescan modes. */ 321 WRN_MSG("X resolution too small (%d vs 4).\n", var->xres);
327 if (var->vmode & FB_VMODE_INTERLACED) { 322 return 1;
328 WRN_MSG("Mode is interlaced.\n"); 323 }
324 if (var->yres < 4) {
325 WRN_MSG("Y resolution too small (%d vs 4).\n", var->yres);
329 return 1; 326 return 1;
330 } 327 }
328
329 /* Check for doublescan modes. */
331 if (var->vmode & FB_VMODE_DOUBLE) { 330 if (var->vmode & FB_VMODE_DOUBLE) {
332 WRN_MSG("Mode is double-scan.\n"); 331 WRN_MSG("Mode is double-scan.\n");
333 return 1; 332 return 1;
334 } 333 }
335 334
335 if ((var->vmode & FB_VMODE_INTERLACED) && (var->yres & 1)) {
336 WRN_MSG("Odd number of lines in interlaced mode\n");
337 return 1;
338 }
339
336 /* Check if clock is OK. */ 340 /* Check if clock is OK. */
337 tmp = 1000000000 / var->pixclock; 341 tmp = 1000000000 / var->pixclock;
338 if (tmp < MIN_CLOCK) { 342 if (tmp < MIN_CLOCK) {
@@ -349,8 +353,7 @@ intelfbhw_validate_mode(struct intelfb_info *dinfo,
349 return 0; 353 return 0;
350} 354}
351 355
352int 356int intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
353intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
354{ 357{
355 struct intelfb_info *dinfo = GET_DINFO(info); 358 struct intelfb_info *dinfo = GET_DINFO(info);
356 u32 offset, xoffset, yoffset; 359 u32 offset, xoffset, yoffset;
@@ -372,9 +375,10 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
372 offset += dinfo->fb.offset << 12; 375 offset += dinfo->fb.offset << 12;
373 376
374 dinfo->vsync.pan_offset = offset; 377 dinfo->vsync.pan_offset = offset;
375 if ((var->activate & FB_ACTIVATE_VBL) && !intelfbhw_enable_irq(dinfo, 0)) { 378 if ((var->activate & FB_ACTIVATE_VBL) &&
379 !intelfbhw_enable_irq(dinfo))
376 dinfo->vsync.pan_display = 1; 380 dinfo->vsync.pan_display = 1;
377 } else { 381 else {
378 dinfo->vsync.pan_display = 0; 382 dinfo->vsync.pan_display = 0;
379 OUTREG(DSPABASE, offset); 383 OUTREG(DSPABASE, offset);
380 } 384 }
@@ -383,8 +387,7 @@ intelfbhw_pan_display(struct fb_var_screeninfo *var, struct fb_info *info)
383} 387}
384 388
385/* Blank the screen. */ 389/* Blank the screen. */
386void 390void intelfbhw_do_blank(int blank, struct fb_info *info)
387intelfbhw_do_blank(int blank, struct fb_info *info)
388{ 391{
389 struct intelfb_info *dinfo = GET_DINFO(info); 392 struct intelfb_info *dinfo = GET_DINFO(info);
390 u32 tmp; 393 u32 tmp;
@@ -409,11 +412,10 @@ intelfbhw_do_blank(int blank, struct fb_info *info)
409 DBG_MSG("cursor_on is %d\n", dinfo->cursor_on); 412 DBG_MSG("cursor_on is %d\n", dinfo->cursor_on);
410#endif 413#endif
411 if (dinfo->cursor_on) { 414 if (dinfo->cursor_on) {
412 if (blank) { 415 if (blank)
413 intelfbhw_cursor_hide(dinfo); 416 intelfbhw_cursor_hide(dinfo);
414 } else { 417 else
415 intelfbhw_cursor_show(dinfo); 418 intelfbhw_cursor_show(dinfo);
416 }
417 dinfo->cursor_on = 1; 419 dinfo->cursor_on = 1;
418 } 420 }
419 dinfo->cursor_blanked = blank; 421 dinfo->cursor_blanked = blank;
@@ -441,19 +443,18 @@ intelfbhw_do_blank(int blank, struct fb_info *info)
441} 443}
442 444
443 445
444void 446void intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno,
445intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno, 447 unsigned red, unsigned green, unsigned blue,
446 unsigned red, unsigned green, unsigned blue, 448 unsigned transp)
447 unsigned transp)
448{ 449{
450 u32 palette_reg = (dinfo->pipe == PIPE_A) ?
451 PALETTE_A : PALETTE_B;
452
449#if VERBOSE > 0 453#if VERBOSE > 0
450 DBG_MSG("intelfbhw_setcolreg: %d: (%d, %d, %d)\n", 454 DBG_MSG("intelfbhw_setcolreg: %d: (%d, %d, %d)\n",
451 regno, red, green, blue); 455 regno, red, green, blue);
452#endif 456#endif
453 457
454 u32 palette_reg = (dinfo->pipe == PIPE_A) ?
455 PALETTE_A : PALETTE_B;
456
457 OUTREG(palette_reg + (regno << 2), 458 OUTREG(palette_reg + (regno << 2),
458 (red << PALETTE_8_RED_SHIFT) | 459 (red << PALETTE_8_RED_SHIFT) |
459 (green << PALETTE_8_GREEN_SHIFT) | 460 (green << PALETTE_8_GREEN_SHIFT) |
@@ -461,9 +462,8 @@ intelfbhw_setcolreg(struct intelfb_info *dinfo, unsigned regno,
461} 462}
462 463
463 464
464int 465int intelfbhw_read_hw_state(struct intelfb_info *dinfo,
465intelfbhw_read_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, 466 struct intelfb_hwstate *hw, int flag)
466 int flag)
467{ 467{
468 int i; 468 int i;
469 469
@@ -610,7 +610,8 @@ static int calc_vclock3(int index, int m, int n, int p)
610 return plls[index].ref_clk * m / n / p; 610 return plls[index].ref_clk * m / n / p;
611} 611}
612 612
613static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvds) 613static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2,
614 int lvds)
614{ 615{
615 struct pll_min_max *pll = &plls[index]; 616 struct pll_min_max *pll = &plls[index];
616 u32 m, vco, p; 617 u32 m, vco, p;
@@ -619,17 +620,16 @@ static int calc_vclock(int index, int m1, int m2, int n, int p1, int p2, int lvd
619 n += 2; 620 n += 2;
620 vco = pll->ref_clk * m / n; 621 vco = pll->ref_clk * m / n;
621 622
622 if (index == PLLS_I8xx) { 623 if (index == PLLS_I8xx)
623 p = ((p1 + 2) * (1 << (p2 + 1))); 624 p = ((p1 + 2) * (1 << (p2 + 1)));
624 } else { 625 else
625 p = ((p1) * (p2 ? 5 : 10)); 626 p = ((p1) * (p2 ? 5 : 10));
626 }
627 return vco / p; 627 return vco / p;
628} 628}
629 629
630#if REGDUMP 630#if REGDUMP
631static void 631static void intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll,
632intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2) 632 int *o_p1, int *o_p2)
633{ 633{
634 int p1, p2; 634 int p1, p2;
635 635
@@ -638,7 +638,7 @@ intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
638 p1 = 1; 638 p1 = 1;
639 else 639 else
640 p1 = (dpll >> DPLL_P1_SHIFT) & 0xff; 640 p1 = (dpll >> DPLL_P1_SHIFT) & 0xff;
641 641
642 p1 = ffs(p1); 642 p1 = ffs(p1);
643 643
644 p2 = (dpll >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK; 644 p2 = (dpll >> DPLL_I9XX_P2_SHIFT) & DPLL_P2_MASK;
@@ -656,8 +656,8 @@ intelfbhw_get_p1p2(struct intelfb_info *dinfo, int dpll, int *o_p1, int *o_p2)
656#endif 656#endif
657 657
658 658
659void 659void intelfbhw_print_hw_state(struct intelfb_info *dinfo,
660intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw) 660 struct intelfb_hwstate *hw)
661{ 661{
662#if REGDUMP 662#if REGDUMP
663 int i, m1, m2, n, p1, p2; 663 int i, m1, m2, n, p1, p2;
@@ -670,7 +670,7 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
670 printk("hw state dump start\n"); 670 printk("hw state dump start\n");
671 printk(" VGA0_DIVISOR: 0x%08x\n", hw->vga0_divisor); 671 printk(" VGA0_DIVISOR: 0x%08x\n", hw->vga0_divisor);
672 printk(" VGA1_DIVISOR: 0x%08x\n", hw->vga1_divisor); 672 printk(" VGA1_DIVISOR: 0x%08x\n", hw->vga1_divisor);
673 printk(" VGAPD: 0x%08x\n", hw->vga_pd); 673 printk(" VGAPD: 0x%08x\n", hw->vga_pd);
674 n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 674 n = (hw->vga0_divisor >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
675 m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 675 m1 = (hw->vga0_divisor >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
676 m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 676 m2 = (hw->vga0_divisor >> FP_M2_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
@@ -689,7 +689,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
689 intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2); 689 intelfbhw_get_p1p2(dinfo, hw->vga_pd, &p1, &p2);
690 printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 690 printk(" VGA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
691 m1, m2, n, p1, p2); 691 m1, m2, n, p1, p2);
692 printk(" VGA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); 692 printk(" VGA1: clock is %d\n",
693 calc_vclock(index, m1, m2, n, p1, p2, 0));
693 694
694 printk(" DPLL_A: 0x%08x\n", hw->dpll_a); 695 printk(" DPLL_A: 0x%08x\n", hw->dpll_a);
695 printk(" DPLL_B: 0x%08x\n", hw->dpll_b); 696 printk(" DPLL_B: 0x%08x\n", hw->dpll_b);
@@ -706,7 +707,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
706 707
707 printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 708 printk(" PLLA0: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
708 m1, m2, n, p1, p2); 709 m1, m2, n, p1, p2);
709 printk(" PLLA0: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); 710 printk(" PLLA0: clock is %d\n",
711 calc_vclock(index, m1, m2, n, p1, p2, 0));
710 712
711 n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 713 n = (hw->fpa1 >> FP_N_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
712 m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK; 714 m1 = (hw->fpa1 >> FP_M1_DIVISOR_SHIFT) & FP_DIVISOR_MASK;
@@ -716,7 +718,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
716 718
717 printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n", 719 printk(" PLLA1: (m1, m2, n, p1, p2) = (%d, %d, %d, %d, %d)\n",
718 m1, m2, n, p1, p2); 720 m1, m2, n, p1, p2);
719 printk(" PLLA1: clock is %d\n", calc_vclock(index, m1, m2, n, p1, p2, 0)); 721 printk(" PLLA1: clock is %d\n",
722 calc_vclock(index, m1, m2, n, p1, p2, 0));
720 723
721#if 0 724#if 0
722 printk(" PALETTE_A:\n"); 725 printk(" PALETTE_A:\n");
@@ -821,8 +824,8 @@ intelfbhw_print_hw_state(struct intelfb_info *dinfo, struct intelfb_hwstate *hw)
821 824
822 825
823/* Split the M parameter into M1 and M2. */ 826/* Split the M parameter into M1 and M2. */
824static int 827static int splitm(int index, unsigned int m, unsigned int *retm1,
825splitm(int index, unsigned int m, unsigned int *retm1, unsigned int *retm2) 828 unsigned int *retm2)
826{ 829{
827 int m1, m2; 830 int m1, m2;
828 int testm; 831 int testm;
@@ -843,8 +846,8 @@ splitm(int index, unsigned int m, unsigned int *retm1, unsigned int *retm2)
843} 846}
844 847
845/* Split the P parameter into P1 and P2. */ 848/* Split the P parameter into P1 and P2. */
846static int 849static int splitp(int index, unsigned int p, unsigned int *retp1,
847splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2) 850 unsigned int *retp2)
848{ 851{
849 int p1, p2; 852 int p1, p2;
850 struct pll_min_max *pll = &plls[index]; 853 struct pll_min_max *pll = &plls[index];
@@ -878,9 +881,8 @@ splitp(int index, unsigned int p, unsigned int *retp1, unsigned int *retp2)
878 } 881 }
879} 882}
880 883
881static int 884static int calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2,
882calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *retp1, 885 u32 *retn, u32 *retp1, u32 *retp2, u32 *retclock)
883 u32 *retp2, u32 *retclock)
884{ 886{
885 u32 m1, m2, n, p1, p2, n1, testm; 887 u32 m1, m2, n, p1, p2, n1, testm;
886 u32 f_vco, p, p_best = 0, m, f_out = 0; 888 u32 f_vco, p, p_best = 0, m, f_out = 0;
@@ -975,8 +977,8 @@ calc_pll_params(int index, int clock, u32 *retm1, u32 *retm2, u32 *retn, u32 *re
975 return 0; 977 return 0;
976} 978}
977 979
978static __inline__ int 980static __inline__ int check_overflow(u32 value, u32 limit,
979check_overflow(u32 value, u32 limit, const char *description) 981 const char *description)
980{ 982{
981 if (value > limit) { 983 if (value > limit) {
982 WRN_MSG("%s value %d exceeds limit %d\n", 984 WRN_MSG("%s value %d exceeds limit %d\n",
@@ -987,9 +989,9 @@ check_overflow(u32 value, u32 limit, const char *description)
987} 989}
988 990
989/* It is assumed that hw is filled in with the initial state information. */ 991/* It is assumed that hw is filled in with the initial state information. */
990int 992int intelfbhw_mode_to_hw(struct intelfb_info *dinfo,
991intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw, 993 struct intelfb_hwstate *hw,
992 struct fb_var_screeninfo *var) 994 struct fb_var_screeninfo *var)
993{ 995{
994 int pipe = PIPE_A; 996 int pipe = PIPE_A;
995 u32 *dpll, *fp0, *fp1; 997 u32 *dpll, *fp0, *fp1;
@@ -1093,9 +1095,8 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
1093 if (IS_I9XX(dinfo)) { 1095 if (IS_I9XX(dinfo)) {
1094 *dpll |= (p2 << DPLL_I9XX_P2_SHIFT); 1096 *dpll |= (p2 << DPLL_I9XX_P2_SHIFT);
1095 *dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT; 1097 *dpll |= (1 << (p1 - 1)) << DPLL_P1_SHIFT;
1096 } else { 1098 } else
1097 *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT); 1099 *dpll |= (p2 << DPLL_P2_SHIFT) | (p1 << DPLL_P1_SHIFT);
1098 }
1099 1100
1100 *fp0 = (n << FP_N_DIVISOR_SHIFT) | 1101 *fp0 = (n << FP_N_DIVISOR_SHIFT) |
1101 (m1 << FP_M1_DIVISOR_SHIFT) | 1102 (m1 << FP_M1_DIVISOR_SHIFT) |
@@ -1139,6 +1140,8 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
1139 hblank_end); 1140 hblank_end);
1140 1141
1141 vactive = var->yres; 1142 vactive = var->yres;
1143 if (var->vmode & FB_VMODE_INTERLACED)
1144 vactive--; /* the chip adds 2 halflines automatically */
1142 vsync_start = vactive + var->lower_margin; 1145 vsync_start = vactive + var->lower_margin;
1143 vsync_end = vsync_start + var->vsync_len; 1146 vsync_end = vsync_start + var->vsync_len;
1144 vtotal = vsync_end + var->upper_margin; 1147 vtotal = vsync_end + var->upper_margin;
@@ -1220,19 +1223,24 @@ intelfbhw_mode_to_hw(struct intelfb_info *dinfo, struct intelfb_hwstate *hw,
1220 1223
1221 /* Set the palette to 8-bit mode. */ 1224 /* Set the palette to 8-bit mode. */
1222 *pipe_conf &= ~PIPECONF_GAMMA; 1225 *pipe_conf &= ~PIPECONF_GAMMA;
1226
1227 if (var->vmode & FB_VMODE_INTERLACED)
1228 *pipe_conf |= PIPECONF_INTERLACE_W_FIELD_INDICATION;
1229 else
1230 *pipe_conf &= ~PIPECONF_INTERLACE_MASK;
1231
1223 return 0; 1232 return 0;
1224} 1233}
1225 1234
1226/* Program a (non-VGA) video mode. */ 1235/* Program a (non-VGA) video mode. */
1227int 1236int intelfbhw_program_mode(struct intelfb_info *dinfo,
1228intelfbhw_program_mode(struct intelfb_info *dinfo, 1237 const struct intelfb_hwstate *hw, int blank)
1229 const struct intelfb_hwstate *hw, int blank)
1230{ 1238{
1231 int pipe = PIPE_A; 1239 int pipe = PIPE_A;
1232 u32 tmp; 1240 u32 tmp;
1233 const u32 *dpll, *fp0, *fp1, *pipe_conf; 1241 const u32 *dpll, *fp0, *fp1, *pipe_conf;
1234 const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss; 1242 const u32 *hs, *ht, *hb, *vs, *vt, *vb, *ss;
1235 u32 dpll_reg, fp0_reg, fp1_reg, pipe_conf_reg; 1243 u32 dpll_reg, fp0_reg, fp1_reg, pipe_conf_reg, pipe_stat_reg;
1236 u32 hsync_reg, htotal_reg, hblank_reg; 1244 u32 hsync_reg, htotal_reg, hblank_reg;
1237 u32 vsync_reg, vtotal_reg, vblank_reg; 1245 u32 vsync_reg, vtotal_reg, vblank_reg;
1238 u32 src_size_reg; 1246 u32 src_size_reg;
@@ -1273,6 +1281,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1273 fp0_reg = FPB0; 1281 fp0_reg = FPB0;
1274 fp1_reg = FPB1; 1282 fp1_reg = FPB1;
1275 pipe_conf_reg = PIPEBCONF; 1283 pipe_conf_reg = PIPEBCONF;
1284 pipe_stat_reg = PIPEBSTAT;
1276 hsync_reg = HSYNC_B; 1285 hsync_reg = HSYNC_B;
1277 htotal_reg = HTOTAL_B; 1286 htotal_reg = HTOTAL_B;
1278 hblank_reg = HBLANK_B; 1287 hblank_reg = HBLANK_B;
@@ -1296,6 +1305,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1296 fp0_reg = FPA0; 1305 fp0_reg = FPA0;
1297 fp1_reg = FPA1; 1306 fp1_reg = FPA1;
1298 pipe_conf_reg = PIPEACONF; 1307 pipe_conf_reg = PIPEACONF;
1308 pipe_stat_reg = PIPEASTAT;
1299 hsync_reg = HSYNC_A; 1309 hsync_reg = HSYNC_A;
1300 htotal_reg = HTOTAL_A; 1310 htotal_reg = HTOTAL_A;
1301 hblank_reg = HBLANK_A; 1311 hblank_reg = HBLANK_A;
@@ -1312,8 +1322,8 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1312 1322
1313 count = 0; 1323 count = 0;
1314 do { 1324 do {
1315 tmp_val[count%3] = INREG(0x70000); 1325 tmp_val[count % 3] = INREG(PIPEA_DSL);
1316 if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1]==tmp_val[2])) 1326 if ((tmp_val[0] == tmp_val[1]) && (tmp_val[1] == tmp_val[2]))
1317 break; 1327 break;
1318 count++; 1328 count++;
1319 udelay(1); 1329 udelay(1);
@@ -1322,7 +1332,7 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1322 tmp &= ~PIPECONF_ENABLE; 1332 tmp &= ~PIPECONF_ENABLE;
1323 OUTREG(pipe_conf_reg, tmp); 1333 OUTREG(pipe_conf_reg, tmp);
1324 } 1334 }
1325 } while(count < 2000); 1335 } while (count < 2000);
1326 1336
1327 OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE); 1337 OUTREG(ADPA, INREG(ADPA) & ~ADPA_DAC_ENABLE);
1328 1338
@@ -1382,6 +1392,17 @@ intelfbhw_program_mode(struct intelfb_info *dinfo,
1382 OUTREG(vtotal_reg, *vt); 1392 OUTREG(vtotal_reg, *vt);
1383 OUTREG(src_size_reg, *ss); 1393 OUTREG(src_size_reg, *ss);
1384 1394
1395 switch (dinfo->info->var.vmode & (FB_VMODE_INTERLACED |
1396 FB_VMODE_ODD_FLD_FIRST)) {
1397 case FB_VMODE_INTERLACED | FB_VMODE_ODD_FLD_FIRST:
1398 OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_ODD_EN);
1399 break;
1400 case FB_VMODE_INTERLACED: /* even lines first */
1401 OUTREG(pipe_stat_reg, 0xFFFF | PIPESTAT_FLD_EVT_EVEN_EN);
1402 break;
1403 default: /* non-interlaced */
1404 OUTREG(pipe_stat_reg, 0xFFFF); /* clear all status bits only */
1405 }
1385 /* Enable pipe */ 1406 /* Enable pipe */
1386 OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE); 1407 OUTREG(pipe_conf_reg, *pipe_conf | PIPECONF_ENABLE);
1387 1408
@@ -1446,8 +1467,7 @@ static u32 get_ring_space(struct intelfb_info *dinfo)
1446 return ring_space; 1467 return ring_space;
1447} 1468}
1448 1469
1449static int 1470static int wait_ring(struct intelfb_info *dinfo, int n)
1450wait_ring(struct intelfb_info *dinfo, int n)
1451{ 1471{
1452 int i = 0; 1472 int i = 0;
1453 unsigned long end; 1473 unsigned long end;
@@ -1489,16 +1509,15 @@ wait_ring(struct intelfb_info *dinfo, int n)
1489 return i; 1509 return i;
1490} 1510}
1491 1511
1492static void 1512static void do_flush(struct intelfb_info *dinfo)
1493do_flush(struct intelfb_info *dinfo) { 1513{
1494 START_RING(2); 1514 START_RING(2);
1495 OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE); 1515 OUT_RING(MI_FLUSH | MI_WRITE_DIRTY_STATE | MI_INVALIDATE_MAP_CACHE);
1496 OUT_RING(MI_NOOP); 1516 OUT_RING(MI_NOOP);
1497 ADVANCE_RING(); 1517 ADVANCE_RING();
1498} 1518}
1499 1519
1500void 1520void intelfbhw_do_sync(struct intelfb_info *dinfo)
1501intelfbhw_do_sync(struct intelfb_info *dinfo)
1502{ 1521{
1503#if VERBOSE > 0 1522#if VERBOSE > 0
1504 DBG_MSG("intelfbhw_do_sync\n"); 1523 DBG_MSG("intelfbhw_do_sync\n");
@@ -1517,8 +1536,7 @@ intelfbhw_do_sync(struct intelfb_info *dinfo)
1517 dinfo->ring_space = dinfo->ring.size - RING_MIN_FREE; 1536 dinfo->ring_space = dinfo->ring.size - RING_MIN_FREE;
1518} 1537}
1519 1538
1520static void 1539static void refresh_ring(struct intelfb_info *dinfo)
1521refresh_ring(struct intelfb_info *dinfo)
1522{ 1540{
1523#if VERBOSE > 0 1541#if VERBOSE > 0
1524 DBG_MSG("refresh_ring\n"); 1542 DBG_MSG("refresh_ring\n");
@@ -1529,8 +1547,7 @@ refresh_ring(struct intelfb_info *dinfo)
1529 dinfo->ring_space = get_ring_space(dinfo); 1547 dinfo->ring_space = get_ring_space(dinfo);
1530} 1548}
1531 1549
1532static void 1550static void reset_state(struct intelfb_info *dinfo)
1533reset_state(struct intelfb_info *dinfo)
1534{ 1551{
1535 int i; 1552 int i;
1536 u32 tmp; 1553 u32 tmp;
@@ -1560,12 +1577,11 @@ reset_state(struct intelfb_info *dinfo)
1560} 1577}
1561 1578
1562/* Stop the 2D engine, and turn off the ring buffer. */ 1579/* Stop the 2D engine, and turn off the ring buffer. */
1563void 1580void intelfbhw_2d_stop(struct intelfb_info *dinfo)
1564intelfbhw_2d_stop(struct intelfb_info *dinfo)
1565{ 1581{
1566#if VERBOSE > 0 1582#if VERBOSE > 0
1567 DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n", dinfo->accel, 1583 DBG_MSG("intelfbhw_2d_stop: accel: %d, ring_active: %d\n",
1568 dinfo->ring_active); 1584 dinfo->accel, dinfo->ring_active);
1569#endif 1585#endif
1570 1586
1571 if (!dinfo->accel) 1587 if (!dinfo->accel)
@@ -1580,8 +1596,7 @@ intelfbhw_2d_stop(struct intelfb_info *dinfo)
1580 * It is assumed that the graphics engine has been stopped by previously 1596 * It is assumed that the graphics engine has been stopped by previously
1581 * calling intelfb_2d_stop(). 1597 * calling intelfb_2d_stop().
1582 */ 1598 */
1583void 1599void intelfbhw_2d_start(struct intelfb_info *dinfo)
1584intelfbhw_2d_start(struct intelfb_info *dinfo)
1585{ 1600{
1586#if VERBOSE > 0 1601#if VERBOSE > 0
1587 DBG_MSG("intelfbhw_2d_start: accel: %d, ring_active: %d\n", 1602 DBG_MSG("intelfbhw_2d_start: accel: %d, ring_active: %d\n",
@@ -1605,9 +1620,8 @@ intelfbhw_2d_start(struct intelfb_info *dinfo)
1605} 1620}
1606 1621
1607/* 2D fillrect (solid fill or invert) */ 1622/* 2D fillrect (solid fill or invert) */
1608void 1623void intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w,
1609intelfbhw_do_fillrect(struct intelfb_info *dinfo, u32 x, u32 y, u32 w, u32 h, 1624 u32 h, u32 color, u32 pitch, u32 bpp, u32 rop)
1610 u32 color, u32 pitch, u32 bpp, u32 rop)
1611{ 1625{
1612 u32 br00, br09, br13, br14, br16; 1626 u32 br00, br09, br13, br14, br16;
1613 1627
@@ -1696,9 +1710,9 @@ intelfbhw_do_bitblt(struct intelfb_info *dinfo, u32 curx, u32 cury,
1696 ADVANCE_RING(); 1710 ADVANCE_RING();
1697} 1711}
1698 1712
1699int 1713int intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w,
1700intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w, 1714 u32 h, const u8* cdat, u32 x, u32 y, u32 pitch,
1701 u32 h, const u8* cdat, u32 x, u32 y, u32 pitch, u32 bpp) 1715 u32 bpp)
1702{ 1716{
1703 int nbytes, ndwords, pad, tmp; 1717 int nbytes, ndwords, pad, tmp;
1704 u32 br00, br09, br13, br18, br19, br22, br23; 1718 u32 br00, br09, br13, br18, br19, br22, br23;
@@ -1785,8 +1799,7 @@ intelfbhw_do_drawglyph(struct intelfb_info *dinfo, u32 fg, u32 bg, u32 w,
1785} 1799}
1786 1800
1787/* HW cursor functions. */ 1801/* HW cursor functions. */
1788void 1802void intelfbhw_cursor_init(struct intelfb_info *dinfo)
1789intelfbhw_cursor_init(struct intelfb_info *dinfo)
1790{ 1803{
1791 u32 tmp; 1804 u32 tmp;
1792 1805
@@ -1817,8 +1830,7 @@ intelfbhw_cursor_init(struct intelfb_info *dinfo)
1817 } 1830 }
1818} 1831}
1819 1832
1820void 1833void intelfbhw_cursor_hide(struct intelfb_info *dinfo)
1821intelfbhw_cursor_hide(struct intelfb_info *dinfo)
1822{ 1834{
1823 u32 tmp; 1835 u32 tmp;
1824 1836
@@ -1843,8 +1855,7 @@ intelfbhw_cursor_hide(struct intelfb_info *dinfo)
1843 } 1855 }
1844} 1856}
1845 1857
1846void 1858void intelfbhw_cursor_show(struct intelfb_info *dinfo)
1847intelfbhw_cursor_show(struct intelfb_info *dinfo)
1848{ 1859{
1849 u32 tmp; 1860 u32 tmp;
1850 1861
@@ -1873,8 +1884,7 @@ intelfbhw_cursor_show(struct intelfb_info *dinfo)
1873 } 1884 }
1874} 1885}
1875 1886
1876void 1887void intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
1877intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
1878{ 1888{
1879 u32 tmp; 1889 u32 tmp;
1880 1890
@@ -1892,13 +1902,11 @@ intelfbhw_cursor_setpos(struct intelfb_info *dinfo, int x, int y)
1892 ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT); 1902 ((y & CURSOR_POS_MASK) << CURSOR_Y_SHIFT);
1893 OUTREG(CURSOR_A_POSITION, tmp); 1903 OUTREG(CURSOR_A_POSITION, tmp);
1894 1904
1895 if (IS_I9XX(dinfo)) { 1905 if (IS_I9XX(dinfo))
1896 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical); 1906 OUTREG(CURSOR_A_BASEADDR, dinfo->cursor.physical);
1897 }
1898} 1907}
1899 1908
1900void 1909void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg)
1901intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg)
1902{ 1910{
1903#if VERBOSE > 0 1911#if VERBOSE > 0
1904 DBG_MSG("intelfbhw_cursor_setcolor\n"); 1912 DBG_MSG("intelfbhw_cursor_setcolor\n");
@@ -1910,9 +1918,8 @@ intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg, u32 fg)
1910 OUTREG(CURSOR_A_PALETTE3, bg & CURSOR_PALETTE_MASK); 1918 OUTREG(CURSOR_A_PALETTE3, bg & CURSOR_PALETTE_MASK);
1911} 1919}
1912 1920
1913void 1921void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height,
1914intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height, 1922 u8 *data)
1915 u8 *data)
1916{ 1923{
1917 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual; 1924 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual;
1918 int i, j, w = width / 8; 1925 int i, j, w = width / 8;
@@ -1940,8 +1947,8 @@ intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, int height,
1940 } 1947 }
1941} 1948}
1942 1949
1943void 1950void intelfbhw_cursor_reset(struct intelfb_info *dinfo)
1944intelfbhw_cursor_reset(struct intelfb_info *dinfo) { 1951{
1945 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual; 1952 u8 __iomem *addr = (u8 __iomem *)dinfo->cursor.virtual;
1946 int i, j; 1953 int i, j;
1947 1954
@@ -1961,72 +1968,72 @@ intelfbhw_cursor_reset(struct intelfb_info *dinfo) {
1961 } 1968 }
1962} 1969}
1963 1970
1964static irqreturn_t 1971static irqreturn_t intelfbhw_irq(int irq, void *dev_id)
1965intelfbhw_irq(int irq, void *dev_id) { 1972{
1966 int handled = 0;
1967 u16 tmp; 1973 u16 tmp;
1968 struct intelfb_info *dinfo = (struct intelfb_info *)dev_id; 1974 struct intelfb_info *dinfo = (struct intelfb_info *)dev_id;
1969 1975
1970 spin_lock(&dinfo->int_lock); 1976 spin_lock(&dinfo->int_lock);
1971 1977
1972 tmp = INREG16(IIR); 1978 tmp = INREG16(IIR);
1973 tmp &= VSYNC_PIPE_A_INTERRUPT; 1979 if (dinfo->info->var.vmode & FB_VMODE_INTERLACED)
1980 tmp &= PIPE_A_EVENT_INTERRUPT;
1981 else
1982 tmp &= VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */
1974 1983
1975 if (tmp == 0) { 1984 if (tmp == 0) {
1976 spin_unlock(&dinfo->int_lock); 1985 spin_unlock(&dinfo->int_lock);
1977 return IRQ_RETVAL(handled); 1986 return IRQ_RETVAL(0); /* not us */
1978 } 1987 }
1979 1988
1980 OUTREG16(IIR, tmp); 1989 /* clear status bits 0-15 ASAP and don't touch bits 16-31 */
1990 OUTREG(PIPEASTAT, INREG(PIPEASTAT));
1981 1991
1982 if (tmp & VSYNC_PIPE_A_INTERRUPT) { 1992 OUTREG16(IIR, tmp);
1983 dinfo->vsync.count++; 1993 if (dinfo->vsync.pan_display) {
1984 if (dinfo->vsync.pan_display) { 1994 dinfo->vsync.pan_display = 0;
1985 dinfo->vsync.pan_display = 0; 1995 OUTREG(DSPABASE, dinfo->vsync.pan_offset);
1986 OUTREG(DSPABASE, dinfo->vsync.pan_offset);
1987 }
1988 wake_up_interruptible(&dinfo->vsync.wait);
1989 handled = 1;
1990 } 1996 }
1991 1997
1998 dinfo->vsync.count++;
1999 wake_up_interruptible(&dinfo->vsync.wait);
2000
1992 spin_unlock(&dinfo->int_lock); 2001 spin_unlock(&dinfo->int_lock);
1993 2002
1994 return IRQ_RETVAL(handled); 2003 return IRQ_RETVAL(1);
1995} 2004}
1996 2005
1997int 2006int intelfbhw_enable_irq(struct intelfb_info *dinfo)
1998intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable) { 2007{
1999 2008 u16 tmp;
2000 if (!test_and_set_bit(0, &dinfo->irq_flags)) { 2009 if (!test_and_set_bit(0, &dinfo->irq_flags)) {
2001 if (request_irq(dinfo->pdev->irq, intelfbhw_irq, IRQF_SHARED, 2010 if (request_irq(dinfo->pdev->irq, intelfbhw_irq, IRQF_SHARED,
2002 "intelfb", dinfo)) { 2011 "intelfb", dinfo)) {
2003 clear_bit(0, &dinfo->irq_flags); 2012 clear_bit(0, &dinfo->irq_flags);
2004 return -EINVAL; 2013 return -EINVAL;
2005 } 2014 }
2006 2015
2007 spin_lock_irq(&dinfo->int_lock); 2016 spin_lock_irq(&dinfo->int_lock);
2008 OUTREG16(HWSTAM, 0xfffe); 2017 OUTREG16(HWSTAM, 0xfffe); /* i830 DRM uses ffff */
2009 OUTREG16(IMR, 0x0); 2018 OUTREG16(IMR, 0);
2010 OUTREG16(IER, VSYNC_PIPE_A_INTERRUPT); 2019 } else
2011 spin_unlock_irq(&dinfo->int_lock);
2012 } else if (reenable) {
2013 u16 ier;
2014
2015 spin_lock_irq(&dinfo->int_lock); 2020 spin_lock_irq(&dinfo->int_lock);
2016 ier = INREG16(IER); 2021
2017 if ((ier & VSYNC_PIPE_A_INTERRUPT)) { 2022 if (dinfo->info->var.vmode & FB_VMODE_INTERLACED)
2018 DBG_MSG("someone disabled the IRQ [%08X]\n", ier); 2023 tmp = PIPE_A_EVENT_INTERRUPT;
2019 OUTREG(IER, VSYNC_PIPE_A_INTERRUPT); 2024 else
2020 } 2025 tmp = VSYNC_PIPE_A_INTERRUPT; /* non-interlaced */
2021 spin_unlock_irq(&dinfo->int_lock); 2026 if (tmp != INREG16(IER)) {
2027 DBG_MSG("changing IER to 0x%X\n", tmp);
2028 OUTREG16(IER, tmp);
2022 } 2029 }
2030
2031 spin_unlock_irq(&dinfo->int_lock);
2023 return 0; 2032 return 0;
2024} 2033}
2025 2034
2026void 2035void intelfbhw_disable_irq(struct intelfb_info *dinfo)
2027intelfbhw_disable_irq(struct intelfb_info *dinfo) { 2036{
2028 u16 tmp;
2029
2030 if (test_and_clear_bit(0, &dinfo->irq_flags)) { 2037 if (test_and_clear_bit(0, &dinfo->irq_flags)) {
2031 if (dinfo->vsync.pan_display) { 2038 if (dinfo->vsync.pan_display) {
2032 dinfo->vsync.pan_display = 0; 2039 dinfo->vsync.pan_display = 0;
@@ -2037,16 +2044,15 @@ intelfbhw_disable_irq(struct intelfb_info *dinfo) {
2037 OUTREG16(IMR, 0xffff); 2044 OUTREG16(IMR, 0xffff);
2038 OUTREG16(IER, 0x0); 2045 OUTREG16(IER, 0x0);
2039 2046
2040 tmp = INREG16(IIR); 2047 OUTREG16(IIR, INREG16(IIR)); /* clear IRQ requests */
2041 OUTREG16(IIR, tmp);
2042 spin_unlock_irq(&dinfo->int_lock); 2048 spin_unlock_irq(&dinfo->int_lock);
2043 2049
2044 free_irq(dinfo->pdev->irq, dinfo); 2050 free_irq(dinfo->pdev->irq, dinfo);
2045 } 2051 }
2046} 2052}
2047 2053
2048int 2054int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe)
2049intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) { 2055{
2050 struct intelfb_vsync *vsync; 2056 struct intelfb_vsync *vsync;
2051 unsigned int count; 2057 unsigned int count;
2052 int ret; 2058 int ret;
@@ -2059,18 +2065,16 @@ intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe) {
2059 return -ENODEV; 2065 return -ENODEV;
2060 } 2066 }
2061 2067
2062 ret = intelfbhw_enable_irq(dinfo, 0); 2068 ret = intelfbhw_enable_irq(dinfo);
2063 if (ret) { 2069 if (ret)
2064 return ret; 2070 return ret;
2065 }
2066 2071
2067 count = vsync->count; 2072 count = vsync->count;
2068 ret = wait_event_interruptible_timeout(vsync->wait, count != vsync->count, HZ/10); 2073 ret = wait_event_interruptible_timeout(vsync->wait,
2069 if (ret < 0) { 2074 count != vsync->count, HZ / 10);
2075 if (ret < 0)
2070 return ret; 2076 return ret;
2071 }
2072 if (ret == 0) { 2077 if (ret == 0) {
2073 intelfbhw_enable_irq(dinfo, 1);
2074 DBG_MSG("wait_for_vsync timed out!\n"); 2078 DBG_MSG("wait_for_vsync timed out!\n");
2075 return -ETIMEDOUT; 2079 return -ETIMEDOUT;
2076 } 2080 }
diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/intelfb/intelfbhw.h
index 8c54ba8fbdda..0b076bac321b 100644
--- a/drivers/video/intelfb/intelfbhw.h
+++ b/drivers/video/intelfb/intelfbhw.h
@@ -83,7 +83,7 @@
83 */ 83 */
84#define RING_MIN_FREE 64 84#define RING_MIN_FREE 64
85 85
86#define IPEHR 0x2088 86#define IPEHR 0x2088
87 87
88#define INSTDONE 0x2090 88#define INSTDONE 0x2090
89#define PRI_RING_EMPTY 1 89#define PRI_RING_EMPTY 1
@@ -93,7 +93,7 @@
93#define IIR 0x20A4 93#define IIR 0x20A4
94#define IMR 0x20A8 94#define IMR 0x20A8
95#define VSYNC_PIPE_A_INTERRUPT (1 << 7) 95#define VSYNC_PIPE_A_INTERRUPT (1 << 7)
96#define PIPE_A_EVENT_INTERRUPT (1 << 4) 96#define PIPE_A_EVENT_INTERRUPT (1 << 6)
97#define VSYNC_PIPE_B_INTERRUPT (1 << 5) 97#define VSYNC_PIPE_B_INTERRUPT (1 << 5)
98#define PIPE_B_EVENT_INTERRUPT (1 << 4) 98#define PIPE_B_EVENT_INTERRUPT (1 << 4)
99#define HOST_PORT_EVENT_INTERRUPT (1 << 3) 99#define HOST_PORT_EVENT_INTERRUPT (1 << 3)
@@ -128,9 +128,9 @@
128 128
129#define GPIOA 0x5010 129#define GPIOA 0x5010
130#define GPIOB 0x5014 130#define GPIOB 0x5014
131#define GPIOC 0x5018 // this may be external DDC on i830 131#define GPIOC 0x5018 /* this may be external DDC on i830 */
132#define GPIOD 0x501C // this is DVO DDC 132#define GPIOD 0x501C /* this is DVO DDC */
133#define GPIOE 0x5020 // this is DVO i2C 133#define GPIOE 0x5020 /* this is DVO i2C */
134#define GPIOF 0x5024 134#define GPIOF 0x5024
135 135
136/* PLL registers */ 136/* PLL registers */
@@ -269,15 +269,20 @@
269#define PORT_ENABLE (1 << 31) 269#define PORT_ENABLE (1 << 31)
270#define PORT_PIPE_SELECT_SHIFT 30 270#define PORT_PIPE_SELECT_SHIFT 30
271#define PORT_TV_FLAGS_MASK 0xFF 271#define PORT_TV_FLAGS_MASK 0xFF
272#define PORT_TV_FLAGS 0xC4 // ripped from my BIOS 272#define PORT_TV_FLAGS 0xC4 /* ripped from my BIOS
273 // to understand and correct 273 to understand and correct */
274 274
275#define DVOA_SRCDIM 0x61124 275#define DVOA_SRCDIM 0x61124
276#define DVOB_SRCDIM 0x61144 276#define DVOB_SRCDIM 0x61144
277#define DVOC_SRCDIM 0x61164 277#define DVOC_SRCDIM 0x61164
278 278
279#define PIPEA_DSL 0x70000
280#define PIPEB_DSL 0x71000
279#define PIPEACONF 0x70008 281#define PIPEACONF 0x70008
280#define PIPEBCONF 0x71008 282#define PIPEBCONF 0x71008
283#define PIPEASTAT 0x70024 /* bits 0-15 are "write 1 to clear" */
284#define PIPEBSTAT 0x71024
285
281#define PIPECONF_ENABLE (1 << 31) 286#define PIPECONF_ENABLE (1 << 31)
282#define PIPECONF_DISABLE 0 287#define PIPECONF_DISABLE 0
283#define PIPECONF_DOUBLE_WIDE (1 << 30) 288#define PIPECONF_DOUBLE_WIDE (1 << 30)
@@ -286,6 +291,35 @@
286#define PIPECONF_UNLOCKED 0 291#define PIPECONF_UNLOCKED 0
287#define PIPECONF_GAMMA (1 << 24) 292#define PIPECONF_GAMMA (1 << 24)
288#define PIPECONF_PALETTE 0 293#define PIPECONF_PALETTE 0
294#define PIPECONF_PROGRESSIVE (0 << 21)
295#define PIPECONF_INTERLACE_W_FIELD_INDICATION (6 << 21)
296#define PIPECONF_INTERLACE_FIELD_0_ONLY (7 << 21)
297#define PIPECONF_INTERLACE_MASK (7 << 21)
298
299/* enable bits, write 1 to enable */
300#define PIPESTAT_FIFO_UNDERRUN (1 << 31)
301#define PIPESTAT_CRC_ERROR_EN (1 << 29)
302#define PIPESTAT_CRC_DONE_EN (1 << 28)
303#define PIPESTAT_HOTPLUG_EN (1 << 26)
304#define PIPESTAT_VERTICAL_SYNC_EN (1 << 25)
305#define PIPESTAT_DISPLINE_COMP_EN (1 << 24)
306#define PIPESTAT_FLD_EVT_ODD_EN (1 << 21)
307#define PIPESTAT_FLD_EVT_EVEN_EN (1 << 20)
308#define PIPESTAT_TV_HOTPLUG_EN (1 << 18)
309#define PIPESTAT_VBLANK_EN (1 << 17)
310#define PIPESTAT_OVL_UPDATE_EN (1 << 16)
311/* status bits, write 1 to clear */
312#define PIPESTAT_HOTPLUG_STATE (1 << 15)
313#define PIPESTAT_CRC_ERROR (1 << 13)
314#define PIPESTAT_CRC_DONE (1 << 12)
315#define PIPESTAT_HOTPLUG (1 << 10)
316#define PIPESTAT_VSYNC (1 << 9)
317#define PIPESTAT_DISPLINE_COMP (1 << 8)
318#define PIPESTAT_FLD_EVT_ODD (1 << 5)
319#define PIPESTAT_FLD_EVT_EVEN (1 << 4)
320#define PIPESTAT_TV_HOTPLUG (1 << 2)
321#define PIPESTAT_VBLANK (1 << 1)
322#define PIPESTAT_OVL_UPDATE (1 << 0)
289 323
290#define DISPARB 0x70030 324#define DISPARB 0x70030
291#define DISPARB_AEND_MASK 0x1ff 325#define DISPARB_AEND_MASK 0x1ff
@@ -365,7 +399,7 @@
365#define DISPPLANE_8BPP (0x2<<26) 399#define DISPPLANE_8BPP (0x2<<26)
366#define DISPPLANE_15_16BPP (0x4<<26) 400#define DISPPLANE_15_16BPP (0x4<<26)
367#define DISPPLANE_16BPP (0x5<<26) 401#define DISPPLANE_16BPP (0x5<<26)
368#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26) 402#define DISPPLANE_32BPP_NO_ALPHA (0x6<<26)
369#define DISPPLANE_32BPP (0x7<<26) 403#define DISPPLANE_32BPP (0x7<<26)
370#define DISPPLANE_STEREO_ENABLE (1<<25) 404#define DISPPLANE_STEREO_ENABLE (1<<25)
371#define DISPPLANE_STEREO_DISABLE 0 405#define DISPPLANE_STEREO_DISABLE 0
@@ -567,7 +601,7 @@ extern void intelfbhw_cursor_setcolor(struct intelfb_info *dinfo, u32 bg,
567extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width, 601extern void intelfbhw_cursor_load(struct intelfb_info *dinfo, int width,
568 int height, u8 *data); 602 int height, u8 *data);
569extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo); 603extern void intelfbhw_cursor_reset(struct intelfb_info *dinfo);
570extern int intelfbhw_enable_irq(struct intelfb_info *dinfo, int reenable); 604extern int intelfbhw_enable_irq(struct intelfb_info *dinfo);
571extern void intelfbhw_disable_irq(struct intelfb_info *dinfo); 605extern void intelfbhw_disable_irq(struct intelfb_info *dinfo);
572extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe); 606extern int intelfbhw_wait_for_vsync(struct intelfb_info *dinfo, u32 pipe);
573 607
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/kyro/fbdev.c
index 1c5579907397..acb9370fdb14 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/kyro/fbdev.c
@@ -21,7 +21,7 @@
21#include <linux/init.h> 21#include <linux/init.h>
22#include <linux/pci.h> 22#include <linux/pci.h>
23#include <asm/io.h> 23#include <asm/io.h>
24#include <asm/uaccess.h> 24#include <linux/uaccess.h>
25#ifdef CONFIG_MTRR 25#ifdef CONFIG_MTRR
26#include <asm/mtrr.h> 26#include <asm/mtrr.h>
27#endif 27#endif
diff --git a/drivers/video/logo/logo.c b/drivers/video/logo/logo.c
index 2b0f799aa8da..a9283bae7790 100644
--- a/drivers/video/logo/logo.c
+++ b/drivers/video/logo/logo.c
@@ -34,6 +34,10 @@ extern const struct linux_logo logo_superh_vga16;
34extern const struct linux_logo logo_superh_clut224; 34extern const struct linux_logo logo_superh_clut224;
35extern const struct linux_logo logo_m32r_clut224; 35extern const struct linux_logo logo_m32r_clut224;
36 36
37static int nologo;
38module_param(nologo, bool, 0);
39MODULE_PARM_DESC(nologo, "Disables startup logo");
40
37/* logo's are marked __initdata. Use __init_refok to tell 41/* logo's are marked __initdata. Use __init_refok to tell
38 * modpost that it is intended that this function uses data 42 * modpost that it is intended that this function uses data
39 * marked __initdata. 43 * marked __initdata.
@@ -42,6 +46,9 @@ const struct linux_logo * __init_refok fb_find_logo(int depth)
42{ 46{
43 const struct linux_logo *logo = NULL; 47 const struct linux_logo *logo = NULL;
44 48
49 if (nologo)
50 return NULL;
51
45 if (depth >= 1) { 52 if (depth >= 1) {
46#ifdef CONFIG_LOGO_LINUX_MONO 53#ifdef CONFIG_LOGO_LINUX_MONO
47 /* Generic Linux logo */ 54 /* Generic Linux logo */
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/matrox/matroxfb_base.c
index 86ca7b179000..b25972ac6eeb 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/matrox/matroxfb_base.c
@@ -113,7 +113,7 @@
113#include "matroxfb_g450.h" 113#include "matroxfb_g450.h"
114#include <linux/matroxfb.h> 114#include <linux/matroxfb.h>
115#include <linux/interrupt.h> 115#include <linux/interrupt.h>
116#include <asm/uaccess.h> 116#include <linux/uaccess.h>
117 117
118#ifdef CONFIG_PPC_PMAC 118#ifdef CONFIG_PPC_PMAC
119#include <asm/machdep.h> 119#include <asm/machdep.h>
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/matrox/matroxfb_crtc2.c
index 4b3344e03695..a6ab5b6a58d0 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/matrox/matroxfb_crtc2.c
@@ -15,7 +15,7 @@
15#include "matroxfb_misc.h" 15#include "matroxfb_misc.h"
16#include "matroxfb_DAC1064.h" 16#include "matroxfb_DAC1064.h"
17#include <linux/matroxfb.h> 17#include <linux/matroxfb.h>
18#include <asm/uaccess.h> 18#include <linux/uaccess.h>
19 19
20/* **************************************************** */ 20/* **************************************************** */
21 21
diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/matrox/matroxfb_g450.c
index 4d610b405d45..6209a761f674 100644
--- a/drivers/video/matrox/matroxfb_g450.c
+++ b/drivers/video/matrox/matroxfb_g450.c
@@ -17,7 +17,6 @@
17#include "matroxfb_DAC1064.h" 17#include "matroxfb_DAC1064.h"
18#include "g450_pll.h" 18#include "g450_pll.h"
19#include <linux/matroxfb.h> 19#include <linux/matroxfb.h>
20#include <asm/uaccess.h>
21#include <asm/div64.h> 20#include <asm/div64.h>
22 21
23#include "matroxfb_g450.h" 22#include "matroxfb_g450.h"
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/matrox/matroxfb_maven.c
index de0d755f9019..49cd53e46c0a 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/matrox/matroxfb_maven.c
@@ -18,7 +18,6 @@
18#include <linux/i2c.h> 18#include <linux/i2c.h>
19#include <linux/matroxfb.h> 19#include <linux/matroxfb.h>
20#include <asm/div64.h> 20#include <asm/div64.h>
21#include <asm/uaccess.h>
22 21
23#define MAVEN_I2CID (0x1B) 22#define MAVEN_I2CID (0x1B)
24 23
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/mbx/mbxfb.c
index 980d5f623902..80cd117ca65c 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/mbx/mbxfb.c
@@ -1,7 +1,7 @@
1/* 1/*
2 * linux/drivers/video/mbx/mbxfb.c 2 * linux/drivers/video/mbx/mbxfb.c
3 * 3 *
4 * Copyright (C) 2006 8D Technologies inc 4 * Copyright (C) 2006-2007 8D Technologies inc
5 * Raphael Assenat <raph@8d.com> 5 * Raphael Assenat <raph@8d.com>
6 * - Added video overlay support 6 * - Added video overlay support
7 * - Various improvements 7 * - Various improvements
@@ -334,8 +334,8 @@ static int mbxfb_blank(int blank, struct fb_info *info)
334 334
335static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set) 335static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
336{ 336{
337 u32 vsctrl, vbbase, vscadr, vsadr; 337 u32 vsctrl, vscadr, vsadr;
338 u32 sssize, spoctrl, svctrl, shctrl; 338 u32 sssize, spoctrl, shctrl;
339 u32 vubase, vvbase; 339 u32 vubase, vvbase;
340 u32 vovrclk; 340 u32 vovrclk;
341 341
@@ -349,13 +349,11 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
349 vscadr = readl(VSCADR); 349 vscadr = readl(VSCADR);
350 vubase = readl(VUBASE); 350 vubase = readl(VUBASE);
351 vvbase = readl(VVBASE); 351 vvbase = readl(VVBASE);
352 shctrl = readl(SHCTRL);
352 353
353 spoctrl = readl(SPOCTRL); 354 spoctrl = readl(SPOCTRL);
354 sssize = readl(SSSIZE); 355 sssize = readl(SSSIZE);
355 356
356
357 vbbase = Vbbase_Glalpha(set->alpha);
358
359 vsctrl &= ~( FMsk(VSCTRL_VSWIDTH) | 357 vsctrl &= ~( FMsk(VSCTRL_VSWIDTH) |
360 FMsk(VSCTRL_VSHEIGHT) | 358 FMsk(VSCTRL_VSHEIGHT) |
361 FMsk(VSCTRL_VPIXFMT) | 359 FMsk(VSCTRL_VPIXFMT) |
@@ -364,38 +362,41 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
364 vsctrl |= Vsctrl_Width(set->width) | Vsctrl_Height(set->height) | 362 vsctrl |= Vsctrl_Width(set->width) | Vsctrl_Height(set->height) |
365 VSCTRL_CSC_EN; 363 VSCTRL_CSC_EN;
366 364
367 vscadr &= ~(VSCADR_STR_EN | VSCADR_COLKEY_EN | VSCADR_COLKEYSRC | 365 vscadr &= ~(VSCADR_STR_EN | FMsk(VSCADR_VBASE_ADR) );
368 FMsk(VSCADR_BLEND_M) | FMsk(VSCADR_BLEND_POS) |
369 FMsk(VSCADR_VBASE_ADR) );
370 vubase &= ~(VUBASE_UVHALFSTR | FMsk(VUBASE_UBASE_ADR)); 366 vubase &= ~(VUBASE_UVHALFSTR | FMsk(VUBASE_UBASE_ADR));
371 vvbase &= ~(FMsk(VVBASE_VBASE_ADR)); 367 vvbase &= ~(FMsk(VVBASE_VBASE_ADR));
372 368
373 switch (set->fmt) 369 switch (set->fmt) {
374 { 370 case MBXFB_FMT_YUV16:
375 case MBXFB_FMT_YUV12: 371 vsctrl |= VSCTRL_VPIXFMT_YUV12;
376 vsctrl |= VSCTRL_VPIXFMT_YUV12;
377 372
378 set->Y_stride = ((set->width) + 0xf ) & ~0xf; 373 set->Y_stride = ((set->width) + 0xf ) & ~0xf;
374 break;
375 case MBXFB_FMT_YUV12:
376 vsctrl |= VSCTRL_VPIXFMT_YUV12;
379 377
378 set->Y_stride = ((set->width) + 0xf ) & ~0xf;
379 vubase |= VUBASE_UVHALFSTR;
380
381 break;
382 case MBXFB_FMT_UY0VY1:
383 vsctrl |= VSCTRL_VPIXFMT_UY0VY1;
384 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
385 break;
386 case MBXFB_FMT_VY0UY1:
387 vsctrl |= VSCTRL_VPIXFMT_VY0UY1;
388 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
389 break;
390 case MBXFB_FMT_Y0UY1V:
391 vsctrl |= VSCTRL_VPIXFMT_Y0UY1V;
392 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
393 break;
394 case MBXFB_FMT_Y0VY1U:
395 vsctrl |= VSCTRL_VPIXFMT_Y0VY1U;
396 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
380 break; 397 break;
381 case MBXFB_FMT_UY0VY1: 398 default:
382 vsctrl |= VSCTRL_VPIXFMT_UY0VY1; 399 return -EINVAL;
383 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
384 break;
385 case MBXFB_FMT_VY0UY1:
386 vsctrl |= VSCTRL_VPIXFMT_VY0UY1;
387 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
388 break;
389 case MBXFB_FMT_Y0UY1V:
390 vsctrl |= VSCTRL_VPIXFMT_Y0UY1V;
391 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
392 break;
393 case MBXFB_FMT_Y0VY1U:
394 vsctrl |= VSCTRL_VPIXFMT_Y0VY1U;
395 set->Y_stride = (set->width*2 + 0xf ) & ~0xf;
396 break;
397 default:
398 return -EINVAL;
399 } 400 }
400 401
401 /* VSCTRL has the bits which sets the Video Pixel Format. 402 /* VSCTRL has the bits which sets the Video Pixel Format.
@@ -417,8 +418,7 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
417 (0x60000 + set->mem_offset + set->V_offset)>>3); 418 (0x60000 + set->mem_offset + set->V_offset)>>3);
418 419
419 420
420 vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_GLOB | 421 vscadr |= Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4);
421 Vscadr_Vbase_Adr((0x60000 + set->mem_offset)>>4);
422 422
423 if (set->enable) 423 if (set->enable)
424 vscadr |= VSCADR_STR_EN; 424 vscadr |= VSCADR_STR_EN;
@@ -433,9 +433,8 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
433 433
434 spoctrl &= ~(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP | 434 spoctrl &= ~(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP |
435 SPOCTRL_HV_SC_OR | SPOCTRL_VS_UR_C | 435 SPOCTRL_HV_SC_OR | SPOCTRL_VS_UR_C |
436 FMsk(SPOCTRL_VORDER) | FMsk(SPOCTRL_VPITCH)); 436 FMsk(SPOCTRL_VPITCH));
437 spoctrl = Spoctrl_Vpitch((set->height<<11)/set->scaled_height) 437 spoctrl |= Spoctrl_Vpitch((set->height<<11)/set->scaled_height);
438 | SPOCTRL_VORDER_2TAP;
439 438
440 /* Bypass horiz/vert scaler when same size */ 439 /* Bypass horiz/vert scaler when same size */
441 if (set->scaled_width == set->width) 440 if (set->scaled_width == set->width)
@@ -443,14 +442,11 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
443 if (set->scaled_height == set->height) 442 if (set->scaled_height == set->height)
444 spoctrl |= SPOCTRL_V_SC_BP; 443 spoctrl |= SPOCTRL_V_SC_BP;
445 444
446 svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10); 445 shctrl &= ~(FMsk(SHCTRL_HPITCH) | SHCTRL_HDECIM);
447 446 shctrl |= Shctrl_Hpitch((set->width<<11)/set->scaled_width);
448 shctrl = Shctrl_Hinitial(4<<11)
449 | Shctrl_Hpitch((set->width<<11)/set->scaled_width);
450 447
451 /* Video plane registers */ 448 /* Video plane registers */
452 write_reg(vsctrl, VSCTRL); 449 write_reg(vsctrl, VSCTRL);
453 write_reg(vbbase, VBBASE);
454 write_reg(vscadr, VSCADR); 450 write_reg(vscadr, VSCADR);
455 write_reg(vubase, VUBASE); 451 write_reg(vubase, VUBASE);
456 write_reg(vvbase, VVBASE); 452 write_reg(vvbase, VVBASE);
@@ -459,28 +455,8 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
459 /* Video scaler registers */ 455 /* Video scaler registers */
460 write_reg(sssize, SSSIZE); 456 write_reg(sssize, SSSIZE);
461 write_reg(spoctrl, SPOCTRL); 457 write_reg(spoctrl, SPOCTRL);
462 write_reg(svctrl, SVCTRL);
463 write_reg(shctrl, SHCTRL); 458 write_reg(shctrl, SHCTRL);
464 459
465 /* RAPH: Using those coefficients, the scaled
466 * image is quite blurry. I dont know how
467 * to improve them ; The chip documentation
468 * was not helpful.. */
469 write_reg(0x21212121, VSCOEFF0);
470 write_reg(0x21212121, VSCOEFF1);
471 write_reg(0x21212121, VSCOEFF2);
472 write_reg(0x21212121, VSCOEFF3);
473 write_reg(0x21212121, VSCOEFF4);
474 write_reg(0x00000000, HSCOEFF0);
475 write_reg(0x00000000, HSCOEFF1);
476 write_reg(0x00000000, HSCOEFF2);
477 write_reg(0x03020201, HSCOEFF3);
478 write_reg(0x09070604, HSCOEFF4);
479 write_reg(0x0f0e0c0a, HSCOEFF5);
480 write_reg(0x15141211, HSCOEFF6);
481 write_reg(0x19181716, HSCOEFF7);
482 write_reg(0x00000019, HSCOEFF8);
483
484 /* Clock */ 460 /* Clock */
485 if (set->enable) 461 if (set->enable)
486 vovrclk |= 1; 462 vovrclk |= 1;
@@ -492,27 +468,206 @@ static int mbxfb_setupOverlay(struct mbxfb_overlaySetup *set)
492 return 0; 468 return 0;
493} 469}
494 470
471static int mbxfb_ioctl_planeorder(struct mbxfb_planeorder *porder)
472{
473 unsigned long gscadr, vscadr;
474
475 if (porder->bottom == porder->top)
476 return -EINVAL;
477
478 gscadr = readl(GSCADR);
479 vscadr = readl(VSCADR);
480
481 gscadr &= ~(FMsk(GSCADR_BLEND_POS));
482 vscadr &= ~(FMsk(VSCADR_BLEND_POS));
483
484 switch (porder->bottom) {
485 case MBXFB_PLANE_GRAPHICS:
486 gscadr |= GSCADR_BLEND_GFX;
487 break;
488 case MBXFB_PLANE_VIDEO:
489 vscadr |= VSCADR_BLEND_GFX;
490 break;
491 default:
492 return -EINVAL;
493 }
494
495 switch (porder->top) {
496 case MBXFB_PLANE_GRAPHICS:
497 gscadr |= GSCADR_BLEND_VID;
498 break;
499 case MBXFB_PLANE_VIDEO:
500 vscadr |= GSCADR_BLEND_VID;
501 break;
502 default:
503 return -EINVAL;
504 }
505
506 write_reg_dly(vscadr, VSCADR);
507 write_reg_dly(gscadr, GSCADR);
508
509 return 0;
510
511}
512
513static int mbxfb_ioctl_alphactl(struct mbxfb_alphaCtl *alpha)
514{
515 unsigned long vscadr, vbbase, vcmsk;
516 unsigned long gscadr, gbbase, gdrctrl;
517
518 vbbase = Vbbase_Glalpha(alpha->overlay_global_alpha) |
519 Vbbase_Colkey(alpha->overlay_colorkey);
520
521 gbbase = Gbbase_Glalpha(alpha->graphics_global_alpha) |
522 Gbbase_Colkey(alpha->graphics_colorkey);
523
524 vcmsk = readl(VCMSK);
525 vcmsk &= ~(FMsk(VCMSK_COLKEY_M));
526 vcmsk |= Vcmsk_colkey_m(alpha->overlay_colorkey_mask);
527
528 gdrctrl = readl(GDRCTRL);
529 gdrctrl &= ~(FMsk(GDRCTRL_COLKEYM));
530 gdrctrl |= Gdrctrl_Colkeym(alpha->graphics_colorkey_mask);
531
532 vscadr = readl(VSCADR);
533 vscadr &= ~(FMsk(VSCADR_BLEND_M) | VSCADR_COLKEYSRC | VSCADR_COLKEY_EN);
534
535 gscadr = readl(GSCADR);
536 gscadr &= ~(FMsk(GSCADR_BLEND_M) | GSCADR_COLKEY_EN | GSCADR_COLKEYSRC);
537
538 switch (alpha->overlay_colorkey_mode) {
539 case MBXFB_COLORKEY_DISABLED:
540 break;
541 case MBXFB_COLORKEY_PREVIOUS:
542 vscadr |= VSCADR_COLKEY_EN;
543 break;
544 case MBXFB_COLORKEY_CURRENT:
545 vscadr |= VSCADR_COLKEY_EN | VSCADR_COLKEYSRC;
546 break;
547 default:
548 return -EINVAL;
549 }
550
551 switch (alpha->overlay_blend_mode) {
552 case MBXFB_ALPHABLEND_NONE:
553 vscadr |= VSCADR_BLEND_NONE;
554 break;
555 case MBXFB_ALPHABLEND_GLOBAL:
556 vscadr |= VSCADR_BLEND_GLOB;
557 break;
558 case MBXFB_ALPHABLEND_PIXEL:
559 vscadr |= VSCADR_BLEND_PIX;
560 break;
561 default:
562 return -EINVAL;
563 }
564
565 switch (alpha->graphics_colorkey_mode) {
566 case MBXFB_COLORKEY_DISABLED:
567 break;
568 case MBXFB_COLORKEY_PREVIOUS:
569 gscadr |= GSCADR_COLKEY_EN;
570 break;
571 case MBXFB_COLORKEY_CURRENT:
572 gscadr |= GSCADR_COLKEY_EN | GSCADR_COLKEYSRC;
573 break;
574 default:
575 return -EINVAL;
576 }
577
578 switch (alpha->graphics_blend_mode) {
579 case MBXFB_ALPHABLEND_NONE:
580 gscadr |= GSCADR_BLEND_NONE;
581 break;
582 case MBXFB_ALPHABLEND_GLOBAL:
583 gscadr |= GSCADR_BLEND_GLOB;
584 break;
585 case MBXFB_ALPHABLEND_PIXEL:
586 gscadr |= GSCADR_BLEND_PIX;
587 break;
588 default:
589 return -EINVAL;
590 }
591
592 write_reg_dly(vbbase, VBBASE);
593 write_reg_dly(gbbase, GBBASE);
594 write_reg_dly(vcmsk, VCMSK);
595 write_reg_dly(gdrctrl, GDRCTRL);
596 write_reg_dly(gscadr, GSCADR);
597 write_reg_dly(vscadr, VSCADR);
598
599 return 0;
600}
601
495static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd, 602static int mbxfb_ioctl(struct fb_info *info, unsigned int cmd,
496 unsigned long arg) 603 unsigned long arg)
497{ 604{
498 struct mbxfb_overlaySetup setup; 605 struct mbxfb_overlaySetup setup;
606 struct mbxfb_planeorder porder;
607 struct mbxfb_alphaCtl alpha;
608 struct mbxfb_reg reg;
499 int res; 609 int res;
610 __u32 tmp;
500 611
501 if (cmd == MBXFB_IOCX_OVERLAY) 612 switch (cmd)
502 { 613 {
503 if (copy_from_user(&setup, (void __user*)arg, 614 case MBXFB_IOCX_OVERLAY:
504 sizeof(struct mbxfb_overlaySetup))) 615 if (copy_from_user(&setup, (void __user*)arg,
616 sizeof(struct mbxfb_overlaySetup)))
617 return -EFAULT;
618
619 res = mbxfb_setupOverlay(&setup);
620 if (res)
621 return res;
622
623 if (copy_to_user((void __user*)arg, &setup,
624 sizeof(struct mbxfb_overlaySetup)))
625 return -EFAULT;
626
627 return 0;
628
629 case MBXFB_IOCS_PLANEORDER:
630 if (copy_from_user(&porder, (void __user*)arg,
631 sizeof(struct mbxfb_planeorder)))
505 return -EFAULT; 632 return -EFAULT;
506 633
507 res = mbxfb_setupOverlay(&setup); 634 return mbxfb_ioctl_planeorder(&porder);
508 if (res)
509 return res;
510 635
511 if (copy_to_user((void __user*)arg, &setup, 636 case MBXFB_IOCS_ALPHA:
512 sizeof(struct mbxfb_overlaySetup))) 637 if (copy_from_user(&alpha, (void __user*)arg,
638 sizeof(struct mbxfb_alphaCtl)))
513 return -EFAULT; 639 return -EFAULT;
514 640
515 return 0; 641 return mbxfb_ioctl_alphactl(&alpha);
642
643 case MBXFB_IOCS_REG:
644 if (copy_from_user(&reg, (void __user*)arg,
645 sizeof(struct mbxfb_reg)))
646 return -EFAULT;
647
648 if (reg.addr >= 0x10000) /* regs are from 0x3fe0000 to 0x3feffff */
649 return -EINVAL;
650
651 tmp = readl(virt_base_2700 + reg.addr);
652 tmp &= ~reg.mask;
653 tmp |= reg.val & reg.mask;
654 writel(tmp, virt_base_2700 + reg.addr);
655
656 return 0;
657 case MBXFB_IOCX_REG:
658 if (copy_from_user(&reg, (void __user*)arg,
659 sizeof(struct mbxfb_reg)))
660 return -EFAULT;
661
662 if (reg.addr >= 0x10000) /* regs are from 0x3fe0000 to 0x3feffff */
663 return -EINVAL;
664 reg.val = readl(virt_base_2700 + reg.addr);
665
666 if (copy_to_user((void __user*)arg, &reg,
667 sizeof(struct mbxfb_reg)))
668 return -EFAULT;
669
670 return 0;
516 } 671 }
517 return -EINVAL; 672 return -EINVAL;
518} 673}
@@ -558,7 +713,6 @@ static void __devinit setup_memc(struct fb_info *fbi)
558 LMTYPE); 713 LMTYPE);
559 /* enable memory controller */ 714 /* enable memory controller */
560 write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR); 715 write_reg_dly(LMPWR_MC_PWR_ACT, LMPWR);
561
562 /* perform dummy reads */ 716 /* perform dummy reads */
563 for ( i = 0; i < 16; i++ ) { 717 for ( i = 0; i < 16; i++ ) {
564 tmp = readl(fbi->screen_base); 718 tmp = readl(fbi->screen_base);
@@ -588,8 +742,8 @@ static void enable_clocks(struct fb_info *fbi)
588 write_reg_dly(0x00000000, VOVRCLK); 742 write_reg_dly(0x00000000, VOVRCLK);
589 write_reg_dly(PIXCLK_EN, PIXCLK); 743 write_reg_dly(PIXCLK_EN, PIXCLK);
590 write_reg_dly(MEMCLK_EN, MEMCLK); 744 write_reg_dly(MEMCLK_EN, MEMCLK);
591 write_reg_dly(0x00000006, M24CLK); 745 write_reg_dly(0x00000001, M24CLK);
592 write_reg_dly(0x00000006, MBXCLK); 746 write_reg_dly(0x00000001, MBXCLK);
593 write_reg_dly(SDCLK_EN, SDCLK); 747 write_reg_dly(SDCLK_EN, SDCLK);
594 write_reg_dly(0x00000001, PIXCLKDIV); 748 write_reg_dly(0x00000001, PIXCLKDIV);
595} 749}
@@ -597,6 +751,7 @@ static void enable_clocks(struct fb_info *fbi)
597static void __devinit setup_graphics(struct fb_info *fbi) 751static void __devinit setup_graphics(struct fb_info *fbi)
598{ 752{
599 unsigned long gsctrl; 753 unsigned long gsctrl;
754 unsigned long vscadr;
600 755
601 gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) | 756 gsctrl = GSCTRL_GAMMA_EN | Gsctrl_Width(fbi->var.xres) |
602 Gsctrl_Height(fbi->var.yres); 757 Gsctrl_Height(fbi->var.yres);
@@ -620,6 +775,11 @@ static void __devinit setup_graphics(struct fb_info *fbi)
620 write_reg_dly(0x00ffffff, GDRCTRL); 775 write_reg_dly(0x00ffffff, GDRCTRL);
621 write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR); 776 write_reg_dly((GSCADR_STR_EN | Gscadr_Gbase_Adr(0x6000)), GSCADR);
622 write_reg_dly(0x00000000, GPLUT); 777 write_reg_dly(0x00000000, GPLUT);
778
779 vscadr = readl(VSCADR);
780 vscadr &= ~(FMsk(VSCADR_BLEND_POS) | FMsk(VSCADR_BLEND_M));
781 vscadr |= VSCADR_BLEND_VID | VSCADR_BLEND_NONE;
782 write_reg_dly(vscadr, VSCADR);
623} 783}
624 784
625static void __devinit setup_display(struct fb_info *fbi) 785static void __devinit setup_display(struct fb_info *fbi)
@@ -638,13 +798,47 @@ static void __devinit setup_display(struct fb_info *fbi)
638 798
639static void __devinit enable_controller(struct fb_info *fbi) 799static void __devinit enable_controller(struct fb_info *fbi)
640{ 800{
801 u32 svctrl, shctrl;
802
641 write_reg_dly(SYSRST_RST, SYSRST); 803 write_reg_dly(SYSRST_RST, SYSRST);
642 804
805 /* setup a timeout, raise drive strength */
806 write_reg_dly(0xffffff0c, SYSCFG);
643 807
644 enable_clocks(fbi); 808 enable_clocks(fbi);
645 setup_memc(fbi); 809 setup_memc(fbi);
646 setup_graphics(fbi); 810 setup_graphics(fbi);
647 setup_display(fbi); 811 setup_display(fbi);
812
813 shctrl = readl(SHCTRL);
814 shctrl &= ~(FMsk(SHCTRL_HINITIAL));
815 shctrl |= Shctrl_Hinitial(4<<11);
816 writel(shctrl, SHCTRL);
817
818 svctrl = Svctrl_Initial1(1<<10) | Svctrl_Initial2(1<<10);
819 writel(svctrl, SVCTRL);
820
821 writel(SPOCTRL_H_SC_BP | SPOCTRL_V_SC_BP | SPOCTRL_VORDER_4TAP
822 , SPOCTRL);
823
824 /* Those coefficients are good for scaling up. For scaling
825 * down, the application has to calculate them. */
826 write_reg(0xff000100, VSCOEFF0);
827 write_reg(0xfdfcfdfe, VSCOEFF1);
828 write_reg(0x170d0500, VSCOEFF2);
829 write_reg(0x3d372d22, VSCOEFF3);
830 write_reg(0x00000040, VSCOEFF4);
831
832 write_reg(0xff010100, HSCOEFF0);
833 write_reg(0x00000000, HSCOEFF1);
834 write_reg(0x02010000, HSCOEFF2);
835 write_reg(0x01020302, HSCOEFF3);
836 write_reg(0xf9fbfe00, HSCOEFF4);
837 write_reg(0xfbf7f6f7, HSCOEFF5);
838 write_reg(0x1c110700, HSCOEFF6);
839 write_reg(0x3e393127, HSCOEFF7);
840 write_reg(0x00000040, HSCOEFF8);
841
648} 842}
649 843
650#ifdef CONFIG_PM 844#ifdef CONFIG_PM
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/mbx/reg_bits.h
index 9a24fb0c7d48..5f14b4befd71 100644
--- a/drivers/video/mbx/reg_bits.h
+++ b/drivers/video/mbx/reg_bits.h
@@ -215,7 +215,7 @@
215/* GSCADR graphics stream control address register fields */ 215/* GSCADR graphics stream control address register fields */
216#define GSCADR_STR_EN (1 << 31) 216#define GSCADR_STR_EN (1 << 31)
217#define GSCADR_COLKEY_EN (1 << 30) 217#define GSCADR_COLKEY_EN (1 << 30)
218#define GSCADR_COLKEYSCR (1 << 29) 218#define GSCADR_COLKEYSRC (1 << 29)
219#define GSCADR_BLEND_M Fld(2,27) 219#define GSCADR_BLEND_M Fld(2,27)
220#define GSCADR_BLEND_NONE ((0x0) << FShft(GSCADR_BLEND_M)) 220#define GSCADR_BLEND_NONE ((0x0) << FShft(GSCADR_BLEND_M))
221#define GSCADR_BLEND_INV ((0x1) << FShft(GSCADR_BLEND_M)) 221#define GSCADR_BLEND_INV ((0x1) << FShft(GSCADR_BLEND_M))
@@ -303,6 +303,67 @@
303#define VSADR_YSTART Fld(11,0) 303#define VSADR_YSTART Fld(11,0)
304#define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART)) 304#define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART))
305 305
306/* VSCTRL - Video Surface Control Register */
307#define VSCTRL_VPIXFMT Fld(4,27)
308#define VSCTRL_VPIXFMT_YUV12 ((0x9) << FShft(VSCTRL_VPIXFMT))
309#define VSCTRL_VPIXFMT_UY0VY1 ((0xc) << FShft(VSCTRL_VPIXFMT))
310#define VSCTRL_VPIXFMT_VY0UY1 ((0xd) << FShft(VSCTRL_VPIXFMT))
311#define VSCTRL_VPIXFMT_Y0UY1V ((0xe) << FShft(VSCTRL_VPIXFMT))
312#define VSCTRL_VPIXFMT_Y0VY1U ((0xf) << FShft(VSCTRL_VPIXFMT))
313#define VSCTRL_GAMMA_EN (1 << 26)
314#define VSCTRL_CSC_EN (1 << 25)
315#define VSCTRL_COSITED (1 << 22)
316#define VSCTRL_VSWIDTH Fld(11,11)
317#define Vsctrl_Width(Pixels) /* Video Width [1-2048] */ \
318 (((Pixels) - 1) << FShft(VSCTRL_VSWIDTH))
319#define VSCTRL_VSHEIGHT Fld(11,0)
320#define Vsctrl_Height(Pixels) /* Video Height [1-2048] */ \
321 (((Pixels) - 1) << FShft(VSCTRL_VSHEIGHT))
322
323/* VBBASE - Video Blending Base Register */
324#define VBBASE_GLALPHA Fld(8,24)
325#define Vbbase_Glalpha(x) ((x) << FShft(VBBASE_GLALPHA))
326
327#define VBBASE_COLKEY Fld(24,0)
328#define Vbbase_Colkey(x) ((x) << FShft(VBBASE_COLKEY))
329
330/* VCMSK - Video Color Key Mask Register */
331#define VCMSK_COLKEY_M Fld(24,0)
332#define Vcmsk_colkey_m(x) ((x) << FShft(VCMSK_COLKEY_M))
333
334/* VSCADR - Video Stream Control Rddress Register */
335#define VSCADR_STR_EN (1 << 31)
336#define VSCADR_COLKEY_EN (1 << 30)
337#define VSCADR_COLKEYSRC (1 << 29)
338#define VSCADR_BLEND_M Fld(2,27)
339#define VSCADR_BLEND_NONE ((0x0) << FShft(VSCADR_BLEND_M))
340#define VSCADR_BLEND_INV ((0x1) << FShft(VSCADR_BLEND_M))
341#define VSCADR_BLEND_GLOB ((0x2) << FShft(VSCADR_BLEND_M))
342#define VSCADR_BLEND_PIX ((0x3) << FShft(VSCADR_BLEND_M))
343#define VSCADR_BLEND_POS Fld(2,24)
344#define VSCADR_BLEND_GFX ((0x0) << FShft(VSCADR_BLEND_POS))
345#define VSCADR_BLEND_VID ((0x1) << FShft(VSCADR_BLEND_POS))
346#define VSCADR_BLEND_CUR ((0x2) << FShft(VSCADR_BLEND_POS))
347#define VSCADR_VBASE_ADR Fld(23,0)
348#define Vscadr_Vbase_Adr(x) ((x) << FShft(VSCADR_VBASE_ADR))
349
350/* VUBASE - Video U Base Register */
351#define VUBASE_UVHALFSTR (1 << 31)
352#define VUBASE_UBASE_ADR Fld(24,0)
353#define Vubase_Ubase_Adr(x) ((x) << FShft(VUBASE_UBASE_ADR))
354
355/* VVBASE - Video V Base Register */
356#define VVBASE_VBASE_ADR Fld(24,0)
357#define Vvbase_Vbase_Adr(x) ((x) << FShft(VVBASE_VBASE_ADR))
358
359/* VSADR - Video Stride Address Register */
360#define VSADR_SRCSTRIDE Fld(10,22)
361#define Vsadr_Srcstride(x) ((x) << FShft(VSADR_SRCSTRIDE))
362#define VSADR_XSTART Fld(11,11)
363#define Vsadr_Xstart(x) ((x) << FShft(VSADR_XSTART))
364#define VSADR_YSTART Fld(11,0)
365#define Vsadr_Ystart(x) ((x) << FShft(VSADR_YSTART))
366
306/* HCCTRL - Hardware Cursor Register fields */ 367/* HCCTRL - Hardware Cursor Register fields */
307#define HCCTRL_CUR_EN (1 << 31) 368#define HCCTRL_CUR_EN (1 << 31)
308#define HCCTRL_COLKEY_EN (1 << 29) 369#define HCCTRL_COLKEY_EN (1 << 29)
@@ -479,6 +540,30 @@
479#define DINTRE_HBLNK1_EN (1 << 1) 540#define DINTRE_HBLNK1_EN (1 << 1)
480#define DINTRE_HBLNK0_EN (1 << 0) 541#define DINTRE_HBLNK0_EN (1 << 0)
481 542
543/* DINTRS - Display Interrupt Status Register */
544#define DINTRS_CUR_OR_S (1 << 18)
545#define DINTRS_STR2_OR_S (1 << 17)
546#define DINTRS_STR1_OR_S (1 << 16)
547#define DINTRS_CUR_UR_S (1 << 6)
548#define DINTRS_STR2_UR_S (1 << 5)
549#define DINTRS_STR1_UR_S (1 << 4)
550#define DINTRS_VEVENT1_S (1 << 3)
551#define DINTRS_VEVENT0_S (1 << 2)
552#define DINTRS_HBLNK1_S (1 << 1)
553#define DINTRS_HBLNK0_S (1 << 0)
554
555/* DINTRE - Display Interrupt Enable Register */
556#define DINTRE_CUR_OR_EN (1 << 18)
557#define DINTRE_STR2_OR_EN (1 << 17)
558#define DINTRE_STR1_OR_EN (1 << 16)
559#define DINTRE_CUR_UR_EN (1 << 6)
560#define DINTRE_STR2_UR_EN (1 << 5)
561#define DINTRE_STR1_UR_EN (1 << 4)
562#define DINTRE_VEVENT1_EN (1 << 3)
563#define DINTRE_VEVENT0_EN (1 << 2)
564#define DINTRE_HBLNK1_EN (1 << 1)
565#define DINTRE_HBLNK0_EN (1 << 0)
566
482 567
483/* DLSTS - display load status register */ 568/* DLSTS - display load status register */
484#define DLSTS_RLD_ADONE (1 << 23) 569#define DLSTS_RLD_ADONE (1 << 23)
diff --git a/drivers/video/mbx/regs.h b/drivers/video/mbx/regs.h
index a7c63d865aad..063099d48839 100644
--- a/drivers/video/mbx/regs.h
+++ b/drivers/video/mbx/regs.h
@@ -30,7 +30,7 @@
30#define VOVRCLK __REG_2700G(0x00000044) 30#define VOVRCLK __REG_2700G(0x00000044)
31#define PIXCLK __REG_2700G(0x00000048) 31#define PIXCLK __REG_2700G(0x00000048)
32#define MEMCLK __REG_2700G(0x0000004c) 32#define MEMCLK __REG_2700G(0x0000004c)
33#define M24CLK __REG_2700G(0x00000054) 33#define M24CLK __REG_2700G(0x00000050)
34#define MBXCLK __REG_2700G(0x00000054) 34#define MBXCLK __REG_2700G(0x00000054)
35#define SDCLK __REG_2700G(0x00000058) 35#define SDCLK __REG_2700G(0x00000058)
36#define PIXCLKDIV __REG_2700G(0x0000005c) 36#define PIXCLKDIV __REG_2700G(0x0000005c)
diff --git a/drivers/video/modedb.c b/drivers/video/modedb.c
index 3741ad729401..42f5d76a8777 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/modedb.c
@@ -27,7 +27,7 @@
27#define DPRINTK(fmt, args...) 27#define DPRINTK(fmt, args...)
28#endif 28#endif
29 29
30const char *global_mode_option; 30const char *fb_mode_option;
31 31
32 /* 32 /*
33 * Standard video mode definitions (taken from XFree86) 33 * Standard video mode definitions (taken from XFree86)
@@ -72,7 +72,7 @@ static const struct fb_videomode modedb[] = {
72 0, FB_VMODE_NONINTERLACED 72 0, FB_VMODE_NONINTERLACED
73 }, { 73 }, {
74 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */ 74 /* 1152x864 @ 89 Hz interlaced, 44 kHz hsync */
75 NULL, 69, 1152, 864, 15384, 96, 16, 110, 1, 216, 10, 75 NULL, 89, 1152, 864, 15384, 96, 16, 110, 1, 216, 10,
76 0, FB_VMODE_INTERLACED 76 0, FB_VMODE_INTERLACED
77 }, { 77 }, {
78 /* 800x600 @ 72 Hz, 48.0 kHz hsync */ 78 /* 800x600 @ 72 Hz, 48.0 kHz hsync */
@@ -120,11 +120,11 @@ static const struct fb_videomode modedb[] = {
120 0, FB_VMODE_NONINTERLACED 120 0, FB_VMODE_NONINTERLACED
121 }, { 121 }, {
122 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */ 122 /* 1400x1050 @ 60Hz, 63.9 kHz hsync */
123 NULL, 68, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3, 123 NULL, 60, 1400, 1050, 9259, 136, 40, 13, 1, 112, 3,
124 0, FB_VMODE_NONINTERLACED 124 0, FB_VMODE_NONINTERLACED
125 }, { 125 }, {
126 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/ 126 /* 1400x1050 @ 75,107 Hz, 82,392 kHz +hsync +vsync*/
127 NULL, 75, 1400, 1050, 9271, 120, 56, 13, 0, 112, 3, 127 NULL, 75, 1400, 1050, 7190, 120, 56, 23, 10, 112, 13,
128 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 128 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
129 }, { 129 }, {
130 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/ 130 /* 1400x1050 @ 60 Hz, ? kHz +hsync +vsync*/
@@ -253,7 +253,7 @@ static const struct fb_videomode modedb[] = {
253 FB_VMODE_NONINTERLACED 253 FB_VMODE_NONINTERLACED
254 }, { 254 }, {
255 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */ 255 /* 1152x768, 60 Hz, PowerBook G4 Titanium I and II */
256 NULL, 60, 1152, 768, 15386, 158, 26, 29, 3, 136, 6, 256 NULL, 60, 1152, 768, 14047, 158, 26, 29, 3, 136, 6,
257 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED 257 FB_SYNC_HOR_HIGH_ACT|FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED
258 }, { 258 }, {
259 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */ 259 /* 1366x768, 60 Hz, 47.403 kHz hsync, WXGA 16:9 aspect ratio */
@@ -306,7 +306,7 @@ const struct fb_videomode vesa_modes[] = {
306 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 306 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
307 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 307 FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
308 /* 12 1024x768i-43 VESA */ 308 /* 12 1024x768i-43 VESA */
309 { NULL, 53, 1024, 768, 22271, 56, 8, 41, 0, 176, 8, 309 { NULL, 43, 1024, 768, 22271, 56, 8, 41, 0, 176, 8,
310 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT, 310 FB_SYNC_HOR_HIGH_ACT | FB_SYNC_VERT_HIGH_ACT,
311 FB_VMODE_INTERLACED, FB_MODE_IS_VESA }, 311 FB_VMODE_INTERLACED, FB_MODE_IS_VESA },
312 /* 13 1024x768-60 VESA */ 312 /* 13 1024x768-60 VESA */
@@ -383,7 +383,7 @@ const struct fb_videomode vesa_modes[] = {
383 { NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 200, 3, 383 { NULL, 60, 1920, 1440, 4273, 344, 128, 56, 1, 200, 3,
384 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 384 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
385 /* 33 1920x1440-75 VESA */ 385 /* 33 1920x1440-75 VESA */
386 { NULL, 60, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3, 386 { NULL, 75, 1920, 1440, 3367, 352, 144, 56, 1, 224, 3,
387 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA }, 387 FB_SYNC_VERT_HIGH_ACT, FB_VMODE_NONINTERLACED, FB_MODE_IS_VESA },
388}; 388};
389EXPORT_SYMBOL(vesa_modes); 389EXPORT_SYMBOL(vesa_modes);
@@ -510,7 +510,7 @@ int fb_find_mode(struct fb_var_screeninfo *var,
510 default_bpp = 8; 510 default_bpp = 8;
511 511
512 /* Did the user specify a video mode? */ 512 /* Did the user specify a video mode? */
513 if (mode_option || (mode_option = global_mode_option)) { 513 if (mode_option || (mode_option = fb_mode_option)) {
514 const char *name = mode_option; 514 const char *name = mode_option;
515 unsigned int namelen = strlen(name); 515 unsigned int namelen = strlen(name);
516 int res_specified = 0, bpp_specified = 0, refresh_specified = 0; 516 int res_specified = 0, bpp_specified = 0, refresh_specified = 0;
@@ -606,26 +606,43 @@ done:
606 DPRINTK("Trying specified video mode%s %ix%i\n", 606 DPRINTK("Trying specified video mode%s %ix%i\n",
607 refresh_specified ? "" : " (ignoring refresh rate)", xres, yres); 607 refresh_specified ? "" : " (ignoring refresh rate)", xres, yres);
608 608
609 diff = refresh; 609 if (!refresh_specified) {
610 /*
611 * If the caller has provided a custom mode database and a
612 * valid monspecs structure, we look for the mode with the
613 * highest refresh rate. Otherwise we play it safe it and
614 * try to find a mode with a refresh rate closest to the
615 * standard 60 Hz.
616 */
617 if (db != modedb &&
618 info->monspecs.vfmin && info->monspecs.vfmax &&
619 info->monspecs.hfmin && info->monspecs.hfmax &&
620 info->monspecs.dclkmax) {
621 refresh = 1000;
622 } else {
623 refresh = 60;
624 }
625 }
626
627 diff = -1;
610 best = -1; 628 best = -1;
611 for (i = 0; i < dbsize; i++) { 629 for (i = 0; i < dbsize; i++) {
612 if (name_matches(db[i], name, namelen) || 630 if ((name_matches(db[i], name, namelen) ||
613 (res_specified && res_matches(db[i], xres, yres))) { 631 (res_specified && res_matches(db[i], xres, yres))) &&
614 if(!fb_try_mode(var, info, &db[i], bpp)) { 632 !fb_try_mode(var, info, &db[i], bpp)) {
615 if(!refresh_specified || db[i].refresh == refresh) 633 if (refresh_specified && db[i].refresh == refresh) {
616 return 1; 634 return 1;
617 else { 635 } else {
618 if(diff > abs(db[i].refresh - refresh)) { 636 if (abs(db[i].refresh - refresh) < diff) {
619 diff = abs(db[i].refresh - refresh); 637 diff = abs(db[i].refresh - refresh);
620 best = i; 638 best = i;
621 }
622 } 639 }
623 } 640 }
624 } 641 }
625 } 642 }
626 if (best != -1) { 643 if (best != -1) {
627 fb_try_mode(var, info, &db[best], bpp); 644 fb_try_mode(var, info, &db[best], bpp);
628 return 2; 645 return (refresh_specified) ? 2 : 1;
629 } 646 }
630 647
631 diff = xres + yres; 648 diff = xres + yres;
@@ -938,6 +955,7 @@ void fb_destroy_modelist(struct list_head *head)
938 kfree(pos); 955 kfree(pos);
939 } 956 }
940} 957}
958EXPORT_SYMBOL_GPL(fb_destroy_modelist);
941 959
942/** 960/**
943 * fb_videomode_to_modelist: convert mode array to mode list 961 * fb_videomode_to_modelist: convert mode array to mode list
diff --git a/drivers/video/neofb.c b/drivers/video/neofb.c
index 731d7a5c5aa2..4b6a99b5be0d 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/neofb.c
@@ -72,7 +72,6 @@
72#include <asm/irq.h> 72#include <asm/irq.h>
73#include <asm/pgtable.h> 73#include <asm/pgtable.h>
74#include <asm/system.h> 74#include <asm/system.h>
75#include <asm/uaccess.h>
76 75
77#ifdef CONFIG_MTRR 76#ifdef CONFIG_MTRR
78#include <asm/mtrr.h> 77#include <asm/mtrr.h>
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/nvidia/nv_i2c.c
index afe4567e1ff4..6fd7cb8f9b8e 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/nvidia/nv_i2c.c
@@ -125,11 +125,13 @@ void nvidia_create_i2c_busses(struct nvidia_par *par)
125 par->chan[1].par = par; 125 par->chan[1].par = par;
126 par->chan[2].par = par; 126 par->chan[2].par = par;
127 127
128 par->chan[0].ddc_base = 0x36; 128 par->chan[0].ddc_base = (par->reverse_i2c) ? 0x36 : 0x3e;
129 nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0", I2C_CLASS_HWMON); 129 nvidia_setup_i2c_bus(&par->chan[0], "nvidia #0",
130 (par->reverse_i2c) ? I2C_CLASS_HWMON : 0);
130 131
131 par->chan[1].ddc_base = 0x3e; 132 par->chan[1].ddc_base = (par->reverse_i2c) ? 0x3e : 0x36;
132 nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1", 0); 133 nvidia_setup_i2c_bus(&par->chan[1], "nvidia #1",
134 (par->reverse_i2c) ? 0 : I2C_CLASS_HWMON);
133 135
134 par->chan[2].ddc_base = 0x50; 136 par->chan[2].ddc_base = 0x50;
135 nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2", 0); 137 nvidia_setup_i2c_bus(&par->chan[2], "nvidia #2", 0);
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/nvidia/nv_type.h
index 2fdf77ec39fc..f132aab8c5de 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/nvidia/nv_type.h
@@ -135,6 +135,7 @@ struct nvidia_par {
135 int paneltweak; 135 int paneltweak;
136 int LVDS; 136 int LVDS;
137 int pm_state; 137 int pm_state;
138 int reverse_i2c;
138 u32 crtcSync_read; 139 u32 crtcSync_read;
139 u32 fpSyncs; 140 u32 fpSyncs;
140 u32 dmaPut; 141 u32 dmaPut;
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/nvidia/nvidia.c
index a7fe214f0f77..30e14eb1f51e 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/nvidia/nvidia.c
@@ -79,6 +79,7 @@ static int noscale __devinitdata = 0;
79static int paneltweak __devinitdata = 0; 79static int paneltweak __devinitdata = 0;
80static int vram __devinitdata = 0; 80static int vram __devinitdata = 0;
81static int bpp __devinitdata = 8; 81static int bpp __devinitdata = 8;
82static int reverse_i2c __devinitdata;
82#ifdef CONFIG_MTRR 83#ifdef CONFIG_MTRR
83static int nomtrr __devinitdata = 0; 84static int nomtrr __devinitdata = 0;
84#endif 85#endif
@@ -1305,6 +1306,7 @@ static int __devinit nvidiafb_probe(struct pci_dev *pd,
1305 par->CRTCnumber = forceCRTC; 1306 par->CRTCnumber = forceCRTC;
1306 par->FpScale = (!noscale); 1307 par->FpScale = (!noscale);
1307 par->paneltweak = paneltweak; 1308 par->paneltweak = paneltweak;
1309 par->reverse_i2c = reverse_i2c;
1308 1310
1309 /* enable IO and mem if not already done */ 1311 /* enable IO and mem if not already done */
1310 pci_read_config_word(pd, PCI_COMMAND, &cmd); 1312 pci_read_config_word(pd, PCI_COMMAND, &cmd);
@@ -1486,6 +1488,8 @@ static int __devinit nvidiafb_setup(char *options)
1486 noaccel = 1; 1488 noaccel = 1;
1487 } else if (!strncmp(this_opt, "noscale", 7)) { 1489 } else if (!strncmp(this_opt, "noscale", 7)) {
1488 noscale = 1; 1490 noscale = 1;
1491 } else if (!strncmp(this_opt, "reverse_i2c", 11)) {
1492 reverse_i2c = 1;
1489 } else if (!strncmp(this_opt, "paneltweak:", 11)) { 1493 } else if (!strncmp(this_opt, "paneltweak:", 11)) {
1490 paneltweak = simple_strtoul(this_opt+11, NULL, 0); 1494 paneltweak = simple_strtoul(this_opt+11, NULL, 0);
1491 } else if (!strncmp(this_opt, "vram:", 5)) { 1495 } else if (!strncmp(this_opt, "vram:", 5)) {
@@ -1582,6 +1586,8 @@ MODULE_PARM_DESC(mode_option, "Specify initial video mode");
1582module_param(bpp, int, 0); 1586module_param(bpp, int, 0);
1583MODULE_PARM_DESC(bpp, "pixel width in bits" 1587MODULE_PARM_DESC(bpp, "pixel width in bits"
1584 "(default=8)"); 1588 "(default=8)");
1589module_param(reverse_i2c, int, 0);
1590MODULE_PARM_DESC(reverse_i2c, "reverse port assignment of the i2c bus");
1585#ifdef CONFIG_MTRR 1591#ifdef CONFIG_MTRR
1586module_param(nomtrr, bool, 0); 1592module_param(nomtrr, bool, 0);
1587MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) " 1593MODULE_PARM_DESC(nomtrr, "Disables MTRR support (0 or 1=disabled) "
diff --git a/drivers/video/pm2fb.c b/drivers/video/pm2fb.c
index 10c0cc6e93fc..5591dfb22b18 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/pm2fb.c
@@ -11,7 +11,7 @@
11 * and additional input from James Simmon's port of Hannu Mallat's tdfx 11 * and additional input from James Simmon's port of Hannu Mallat's tdfx
12 * driver. 12 * driver.
13 * 13 *
14 * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86. I 14 * I have a Creative Graphics Blaster Exxtreme card - pm2fb on x86. I
15 * have no access to other pm2fb implementations. Sparc (and thus 15 * have no access to other pm2fb implementations. Sparc (and thus
16 * hopefully other big-endian) devices now work, thanks to a lot of 16 * hopefully other big-endian) devices now work, thanks to a lot of
17 * testing work by Ron Murray. I have no access to CVision hardware, 17 * testing work by Ron Murray. I have no access to CVision hardware,
@@ -38,6 +38,9 @@
38#include <linux/fb.h> 38#include <linux/fb.h>
39#include <linux/init.h> 39#include <linux/init.h>
40#include <linux/pci.h> 40#include <linux/pci.h>
41#ifdef CONFIG_MTRR
42#include <asm/mtrr.h>
43#endif
41 44
42#include <video/permedia2.h> 45#include <video/permedia2.h>
43#include <video/cvisionppc.h> 46#include <video/cvisionppc.h>
@@ -52,15 +55,19 @@
52 55
53#undef PM2FB_MASTER_DEBUG 56#undef PM2FB_MASTER_DEBUG
54#ifdef PM2FB_MASTER_DEBUG 57#ifdef PM2FB_MASTER_DEBUG
55#define DPRINTK(a,b...) printk(KERN_DEBUG "pm2fb: %s: " a, __FUNCTION__ , ## b) 58#define DPRINTK(a, b...) \
59 printk(KERN_DEBUG "pm2fb: %s: " a, __FUNCTION__ , ## b)
56#else 60#else
57#define DPRINTK(a,b...) 61#define DPRINTK(a, b...)
58#endif 62#endif
59 63
64#define PM2_PIXMAP_SIZE (1600 * 4)
65
60/* 66/*
61 * Driver data 67 * Driver data
62 */ 68 */
63static char *mode __devinitdata = NULL; 69static int hwcursor = 1;
70static char *mode __devinitdata;
64 71
65/* 72/*
66 * The XFree GLINT driver will (I think to implement hardware cursor 73 * The XFree GLINT driver will (I think to implement hardware cursor
@@ -73,6 +80,11 @@ static char *mode __devinitdata = NULL;
73 */ 80 */
74static int lowhsync; 81static int lowhsync;
75static int lowvsync; 82static int lowvsync;
83static int noaccel __devinitdata;
84/* mtrr option */
85#ifdef CONFIG_MTRR
86static int nomtrr __devinitdata;
87#endif
76 88
77/* 89/*
78 * The hardware state of the graphics card that isn't part of the 90 * The hardware state of the graphics card that isn't part of the
@@ -88,6 +100,7 @@ struct pm2fb_par
88 u32 mem_control; /* MemControl reg at probe */ 100 u32 mem_control; /* MemControl reg at probe */
89 u32 boot_address; /* BootAddress reg at probe */ 101 u32 boot_address; /* BootAddress reg at probe */
90 u32 palette[16]; 102 u32 palette[16];
103 int mtrr_handle;
91}; 104};
92 105
93/* 106/*
@@ -135,60 +148,39 @@ static struct fb_var_screeninfo pm2fb_var __devinitdata = {
135 * Utility functions 148 * Utility functions
136 */ 149 */
137 150
138static inline u32 RD32(unsigned char __iomem *base, s32 off) 151static inline u32 pm2_RD(struct pm2fb_par *p, s32 off)
139{
140 return fb_readl(base + off);
141}
142
143static inline void WR32(unsigned char __iomem *base, s32 off, u32 v)
144{ 152{
145 fb_writel(v, base + off); 153 return fb_readl(p->v_regs + off);
146} 154}
147 155
148static inline u32 pm2_RD(struct pm2fb_par* p, s32 off) 156static inline void pm2_WR(struct pm2fb_par *p, s32 off, u32 v)
149{ 157{
150 return RD32(p->v_regs, off); 158 fb_writel(v, p->v_regs + off);
151} 159}
152 160
153static inline void pm2_WR(struct pm2fb_par* p, s32 off, u32 v) 161static inline u32 pm2_RDAC_RD(struct pm2fb_par *p, s32 idx)
154{ 162{
155 WR32(p->v_regs, off, v); 163 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
164 mb();
165 return pm2_RD(p, PM2R_RD_INDEXED_DATA);
156} 166}
157 167
158static inline u32 pm2_RDAC_RD(struct pm2fb_par* p, s32 idx) 168static inline u32 pm2v_RDAC_RD(struct pm2fb_par *p, s32 idx)
159{ 169{
160 int index = PM2R_RD_INDEXED_DATA; 170 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
161 switch (p->type) {
162 case PM2_TYPE_PERMEDIA2:
163 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
164 break;
165 case PM2_TYPE_PERMEDIA2V:
166 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
167 index = PM2VR_RD_INDEXED_DATA;
168 break;
169 }
170 mb(); 171 mb();
171 return pm2_RD(p, index); 172 return pm2_RD(p, PM2VR_RD_INDEXED_DATA);
172} 173}
173 174
174static inline void pm2_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) 175static inline void pm2_RDAC_WR(struct pm2fb_par *p, s32 idx, u32 v)
175{ 176{
176 int index = PM2R_RD_INDEXED_DATA; 177 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
177 switch (p->type) {
178 case PM2_TYPE_PERMEDIA2:
179 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, idx);
180 break;
181 case PM2_TYPE_PERMEDIA2V:
182 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
183 index = PM2VR_RD_INDEXED_DATA;
184 break;
185 }
186 wmb(); 178 wmb();
187 pm2_WR(p, index, v); 179 pm2_WR(p, PM2R_RD_INDEXED_DATA, v);
188 wmb(); 180 wmb();
189} 181}
190 182
191static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v) 183static inline void pm2v_RDAC_WR(struct pm2fb_par *p, s32 idx, u32 v)
192{ 184{
193 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff); 185 pm2_WR(p, PM2VR_RD_INDEX_LOW, idx & 0xff);
194 wmb(); 186 wmb();
@@ -199,10 +191,10 @@ static inline void pm2v_RDAC_WR(struct pm2fb_par* p, s32 idx, u32 v)
199#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT 191#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
200#define WAIT_FIFO(p, a) 192#define WAIT_FIFO(p, a)
201#else 193#else
202static inline void WAIT_FIFO(struct pm2fb_par* p, u32 a) 194static inline void WAIT_FIFO(struct pm2fb_par *p, u32 a)
203{ 195{
204 while( pm2_RD(p, PM2R_IN_FIFO_SPACE) < a ); 196 while (pm2_RD(p, PM2R_IN_FIFO_SPACE) < a)
205 mb(); 197 cpu_relax();
206} 198}
207#endif 199#endif
208 200
@@ -238,7 +230,7 @@ static u32 partprod(u32 xres)
238 230
239 for (i = 0; pp_table[i].width && pp_table[i].width != xres; i++) 231 for (i = 0; pp_table[i].width && pp_table[i].width != xres; i++)
240 ; 232 ;
241 if ( pp_table[i].width == 0 ) 233 if (pp_table[i].width == 0)
242 DPRINTK("invalid width %u\n", xres); 234 DPRINTK("invalid width %u\n", xres);
243 return pp_table[i].pp; 235 return pp_table[i].pp;
244} 236}
@@ -246,25 +238,22 @@ static u32 partprod(u32 xres)
246static u32 to3264(u32 timing, int bpp, int is64) 238static u32 to3264(u32 timing, int bpp, int is64)
247{ 239{
248 switch (bpp) { 240 switch (bpp) {
241 case 24:
242 timing *= 3;
249 case 8: 243 case 8:
250 timing >>= 2 + is64; 244 timing >>= 1;
251 break;
252 case 16: 245 case 16:
253 timing >>= 1 + is64; 246 timing >>= 1;
254 break;
255 case 24:
256 timing = (timing * 3) >> (2 + is64);
257 break;
258 case 32: 247 case 32:
259 if (is64)
260 timing >>= 1;
261 break; 248 break;
262 } 249 }
250 if (is64)
251 timing >>= 1;
263 return timing; 252 return timing;
264} 253}
265 254
266static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn, 255static void pm2_mnp(u32 clk, unsigned char *mm, unsigned char *nn,
267 unsigned char* pp) 256 unsigned char *pp)
268{ 257{
269 unsigned char m; 258 unsigned char m;
270 unsigned char n; 259 unsigned char n;
@@ -278,13 +267,13 @@ static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
278 for (m = 2; m; m++) { 267 for (m = 2; m; m++) {
279 f = PM2_REFERENCE_CLOCK * m / n; 268 f = PM2_REFERENCE_CLOCK * m / n;
280 if (f >= 150000 && f <= 300000) { 269 if (f >= 150000 && f <= 300000) {
281 for ( p = 0; p < 5; p++, f >>= 1) { 270 for (p = 0; p < 5; p++, f >>= 1) {
282 curr = ( clk > f ) ? clk - f : f - clk; 271 curr = (clk > f) ? clk - f : f - clk;
283 if ( curr < delta ) { 272 if (curr < delta) {
284 delta=curr; 273 delta = curr;
285 *mm=m; 274 *mm = m;
286 *nn=n; 275 *nn = n;
287 *pp=p; 276 *pp = p;
288 } 277 }
289 } 278 }
290 } 279 }
@@ -292,8 +281,8 @@ static void pm2_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
292 } 281 }
293} 282}
294 283
295static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn, 284static void pm2v_mnp(u32 clk, unsigned char *mm, unsigned char *nn,
296 unsigned char* pp) 285 unsigned char *pp)
297{ 286{
298 unsigned char m; 287 unsigned char m;
299 unsigned char n; 288 unsigned char n;
@@ -302,23 +291,24 @@ static void pm2v_mnp(u32 clk, unsigned char* mm, unsigned char* nn,
302 s32 delta = 1000; 291 s32 delta = 1000;
303 292
304 *mm = *nn = *pp = 0; 293 *mm = *nn = *pp = 0;
305 for ( m = 1; m < 128; m++) { 294 for (m = 1; m < 128; m++) {
306 for (n = 2 * m + 1; n; n++) { 295 for (n = 2 * m + 1; n; n++) {
307 for ( p = 0; p < 2; p++) { 296 for (p = 0; p < 2; p++) {
308 f = ( PM2_REFERENCE_CLOCK >> ( p + 1 )) * n / m; 297 f = (PM2_REFERENCE_CLOCK >> (p + 1)) * n / m;
309 if ( clk > f - delta && clk < f + delta ) { 298 if (clk > f - delta && clk < f + delta) {
310 delta = ( clk > f ) ? clk - f : f - clk; 299 delta = (clk > f) ? clk - f : f - clk;
311 *mm=m; 300 *mm = m;
312 *nn=n; 301 *nn = n;
313 *pp=p; 302 *pp = p;
314 } 303 }
315 } 304 }
316 } 305 }
317 } 306 }
318} 307}
319 308
320static void clear_palette(struct pm2fb_par* p) { 309static void clear_palette(struct pm2fb_par *p)
321 int i=256; 310{
311 int i = 256;
322 312
323 WAIT_FIFO(p, 1); 313 WAIT_FIFO(p, 1);
324 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, 0); 314 pm2_WR(p, PM2R_RD_PALETTE_WRITE_ADDRESS, 0);
@@ -331,14 +321,14 @@ static void clear_palette(struct pm2fb_par* p) {
331 } 321 }
332} 322}
333 323
334static void reset_card(struct pm2fb_par* p) 324static void reset_card(struct pm2fb_par *p)
335{ 325{
336 if (p->type == PM2_TYPE_PERMEDIA2V) 326 if (p->type == PM2_TYPE_PERMEDIA2V)
337 pm2_WR(p, PM2VR_RD_INDEX_HIGH, 0); 327 pm2_WR(p, PM2VR_RD_INDEX_HIGH, 0);
338 pm2_WR(p, PM2R_RESET_STATUS, 0); 328 pm2_WR(p, PM2R_RESET_STATUS, 0);
339 mb(); 329 mb();
340 while (pm2_RD(p, PM2R_RESET_STATUS) & PM2F_BEING_RESET) 330 while (pm2_RD(p, PM2R_RESET_STATUS) & PM2F_BEING_RESET)
341 ; 331 cpu_relax();
342 mb(); 332 mb();
343#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT 333#ifdef CONFIG_FB_PM2_FIFO_DISCONNECT
344 DPRINTK("FIFO disconnect enabled\n"); 334 DPRINTK("FIFO disconnect enabled\n");
@@ -354,11 +344,11 @@ static void reset_card(struct pm2fb_par* p)
354 pm2_WR(p, PM2R_MEM_CONFIG, p->mem_config); 344 pm2_WR(p, PM2R_MEM_CONFIG, p->mem_config);
355} 345}
356 346
357static void reset_config(struct pm2fb_par* p) 347static void reset_config(struct pm2fb_par *p)
358{ 348{
359 WAIT_FIFO(p, 52); 349 WAIT_FIFO(p, 53);
360 pm2_WR(p, PM2R_CHIP_CONFIG, pm2_RD(p, PM2R_CHIP_CONFIG) & 350 pm2_WR(p, PM2R_CHIP_CONFIG, pm2_RD(p, PM2R_CHIP_CONFIG) &
361 ~(PM2F_VGA_ENABLE|PM2F_VGA_FIXED)); 351 ~(PM2F_VGA_ENABLE | PM2F_VGA_FIXED));
362 pm2_WR(p, PM2R_BYPASS_WRITE_MASK, ~(0L)); 352 pm2_WR(p, PM2R_BYPASS_WRITE_MASK, ~(0L));
363 pm2_WR(p, PM2R_FRAMEBUFFER_WRITE_MASK, ~(0L)); 353 pm2_WR(p, PM2R_FRAMEBUFFER_WRITE_MASK, ~(0L));
364 pm2_WR(p, PM2R_FIFO_CONTROL, 0); 354 pm2_WR(p, PM2R_FIFO_CONTROL, 0);
@@ -393,31 +383,32 @@ static void reset_config(struct pm2fb_par* p)
393 pm2_WR(p, PM2R_STATISTICS_MODE, 0); 383 pm2_WR(p, PM2R_STATISTICS_MODE, 0);
394 pm2_WR(p, PM2R_SCISSOR_MODE, 0); 384 pm2_WR(p, PM2R_SCISSOR_MODE, 0);
395 pm2_WR(p, PM2R_FILTER_MODE, PM2F_SYNCHRONIZATION); 385 pm2_WR(p, PM2R_FILTER_MODE, PM2F_SYNCHRONIZATION);
386 pm2_WR(p, PM2R_RD_PIXEL_MASK, 0xff);
396 switch (p->type) { 387 switch (p->type) {
397 case PM2_TYPE_PERMEDIA2: 388 case PM2_TYPE_PERMEDIA2:
398 pm2_RDAC_WR(p, PM2I_RD_MODE_CONTROL, 0); /* no overlay */ 389 pm2_RDAC_WR(p, PM2I_RD_MODE_CONTROL, 0); /* no overlay */
399 pm2_RDAC_WR(p, PM2I_RD_CURSOR_CONTROL, 0); 390 pm2_RDAC_WR(p, PM2I_RD_CURSOR_CONTROL, 0);
400 pm2_RDAC_WR(p, PM2I_RD_MISC_CONTROL, PM2F_RD_PALETTE_WIDTH_8); 391 pm2_RDAC_WR(p, PM2I_RD_MISC_CONTROL, PM2F_RD_PALETTE_WIDTH_8);
392 pm2_RDAC_WR(p, PM2I_RD_COLOR_KEY_CONTROL, 0);
393 pm2_RDAC_WR(p, PM2I_RD_OVERLAY_KEY, 0);
394 pm2_RDAC_WR(p, PM2I_RD_RED_KEY, 0);
395 pm2_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0);
396 pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0);
401 break; 397 break;
402 case PM2_TYPE_PERMEDIA2V: 398 case PM2_TYPE_PERMEDIA2V:
403 pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1); /* 8bit */ 399 pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1); /* 8bit */
404 break; 400 break;
405 } 401 }
406 pm2_RDAC_WR(p, PM2I_RD_COLOR_KEY_CONTROL, 0);
407 pm2_RDAC_WR(p, PM2I_RD_OVERLAY_KEY, 0);
408 pm2_RDAC_WR(p, PM2I_RD_RED_KEY, 0);
409 pm2_RDAC_WR(p, PM2I_RD_GREEN_KEY, 0);
410 pm2_RDAC_WR(p, PM2I_RD_BLUE_KEY, 0);
411} 402}
412 403
413static void set_aperture(struct pm2fb_par* p, u32 depth) 404static void set_aperture(struct pm2fb_par *p, u32 depth)
414{ 405{
415 /* 406 /*
416 * The hardware is little-endian. When used in big-endian 407 * The hardware is little-endian. When used in big-endian
417 * hosts, the on-chip aperture settings are used where 408 * hosts, the on-chip aperture settings are used where
418 * possible to translate from host to card byte order. 409 * possible to translate from host to card byte order.
419 */ 410 */
420 WAIT_FIFO(p, 4); 411 WAIT_FIFO(p, 2);
421#ifdef __LITTLE_ENDIAN 412#ifdef __LITTLE_ENDIAN
422 pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_STANDARD); 413 pm2_WR(p, PM2R_APERTURE_ONE, PM2F_APERTURE_STANDARD);
423#else 414#else
@@ -440,11 +431,11 @@ static void set_aperture(struct pm2fb_par* p, u32 depth)
440 } 431 }
441#endif 432#endif
442 433
443 // We don't use aperture two, so this may be superflous 434 /* We don't use aperture two, so this may be superflous */
444 pm2_WR(p, PM2R_APERTURE_TWO, PM2F_APERTURE_STANDARD); 435 pm2_WR(p, PM2R_APERTURE_TWO, PM2F_APERTURE_STANDARD);
445} 436}
446 437
447static void set_color(struct pm2fb_par* p, unsigned char regno, 438static void set_color(struct pm2fb_par *p, unsigned char regno,
448 unsigned char r, unsigned char g, unsigned char b) 439 unsigned char r, unsigned char g, unsigned char b)
449{ 440{
450 WAIT_FIFO(p, 4); 441 WAIT_FIFO(p, 4);
@@ -457,7 +448,7 @@ static void set_color(struct pm2fb_par* p, unsigned char regno,
457 pm2_WR(p, PM2R_RD_PALETTE_DATA, b); 448 pm2_WR(p, PM2R_RD_PALETTE_DATA, b);
458} 449}
459 450
460static void set_memclock(struct pm2fb_par* par, u32 clk) 451static void set_memclock(struct pm2fb_par *par, u32 clk)
461{ 452{
462 int i; 453 int i;
463 unsigned char m, n, p; 454 unsigned char m, n, p;
@@ -465,7 +456,7 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
465 switch (par->type) { 456 switch (par->type) {
466 case PM2_TYPE_PERMEDIA2V: 457 case PM2_TYPE_PERMEDIA2V:
467 pm2v_mnp(clk/2, &m, &n, &p); 458 pm2v_mnp(clk/2, &m, &n, &p);
468 WAIT_FIFO(par, 8); 459 WAIT_FIFO(par, 12);
469 pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8); 460 pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_MCLK_CONTROL >> 8);
470 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0); 461 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 0);
471 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m); 462 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_PRESCALE, m);
@@ -473,10 +464,9 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
473 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p); 464 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_POSTSCALE, p);
474 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1); 465 pm2v_RDAC_WR(par, PM2VI_RD_MCLK_CONTROL, 1);
475 rmb(); 466 rmb();
476 for (i = 256; 467 for (i = 256; i; i--)
477 i && !(pm2_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2); 468 if (pm2v_RDAC_RD(par, PM2VI_RD_MCLK_CONTROL) & 2)
478 i--) 469 break;
479 ;
480 pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0); 470 pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
481 break; 471 break;
482 case PM2_TYPE_PERMEDIA2: 472 case PM2_TYPE_PERMEDIA2:
@@ -488,15 +478,14 @@ static void set_memclock(struct pm2fb_par* par, u32 clk)
488 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p); 478 pm2_RDAC_WR(par, PM2I_RD_MEMORY_CLOCK_3, 8|p);
489 pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS); 479 pm2_RDAC_RD(par, PM2I_RD_MEMORY_CLOCK_STATUS);
490 rmb(); 480 rmb();
491 for (i = 256; 481 for (i = 256; i; i--)
492 i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED); 482 if (pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED)
493 i--) 483 break;
494 ;
495 break; 484 break;
496 } 485 }
497} 486}
498 487
499static void set_pixclock(struct pm2fb_par* par, u32 clk) 488static void set_pixclock(struct pm2fb_par *par, u32 clk)
500{ 489{
501 int i; 490 int i;
502 unsigned char m, n, p; 491 unsigned char m, n, p;
@@ -504,17 +493,16 @@ static void set_pixclock(struct pm2fb_par* par, u32 clk)
504 switch (par->type) { 493 switch (par->type) {
505 case PM2_TYPE_PERMEDIA2: 494 case PM2_TYPE_PERMEDIA2:
506 pm2_mnp(clk, &m, &n, &p); 495 pm2_mnp(clk, &m, &n, &p);
507 WAIT_FIFO(par, 8); 496 WAIT_FIFO(par, 10);
508 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0); 497 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 0);
509 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m); 498 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A1, m);
510 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n); 499 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A2, n);
511 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p); 500 pm2_RDAC_WR(par, PM2I_RD_PIXEL_CLOCK_A3, 8|p);
512 pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS); 501 pm2_RDAC_RD(par, PM2I_RD_PIXEL_CLOCK_STATUS);
513 rmb(); 502 rmb();
514 for (i = 256; 503 for (i = 256; i; i--)
515 i && !(pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED); 504 if (pm2_RD(par, PM2R_RD_INDEXED_DATA) & PM2F_PLL_LOCKED)
516 i--) 505 break;
517 ;
518 break; 506 break;
519 case PM2_TYPE_PERMEDIA2V: 507 case PM2_TYPE_PERMEDIA2V:
520 pm2v_mnp(clk/2, &m, &n, &p); 508 pm2v_mnp(clk/2, &m, &n, &p);
@@ -528,11 +516,10 @@ static void set_pixclock(struct pm2fb_par* par, u32 clk)
528 } 516 }
529} 517}
530 518
531static void set_video(struct pm2fb_par* p, u32 video) { 519static void set_video(struct pm2fb_par *p, u32 video)
520{
532 u32 tmp; 521 u32 tmp;
533 u32 vsync; 522 u32 vsync = video;
534
535 vsync = video;
536 523
537 DPRINTK("video = 0x%x\n", video); 524 DPRINTK("video = 0x%x\n", video);
538 525
@@ -542,10 +529,10 @@ static void set_video(struct pm2fb_par* p, u32 video) {
542 * driver may well. So always set +hsync/+vsync and then set 529 * driver may well. So always set +hsync/+vsync and then set
543 * the RAMDAC to invert the sync if necessary. 530 * the RAMDAC to invert the sync if necessary.
544 */ 531 */
545 vsync &= ~(PM2F_HSYNC_MASK|PM2F_VSYNC_MASK); 532 vsync &= ~(PM2F_HSYNC_MASK | PM2F_VSYNC_MASK);
546 vsync |= PM2F_HSYNC_ACT_HIGH|PM2F_VSYNC_ACT_HIGH; 533 vsync |= PM2F_HSYNC_ACT_HIGH | PM2F_VSYNC_ACT_HIGH;
547 534
548 WAIT_FIFO(p, 5); 535 WAIT_FIFO(p, 3);
549 pm2_WR(p, PM2R_VIDEO_CONTROL, vsync); 536 pm2_WR(p, PM2R_VIDEO_CONTROL, vsync);
550 537
551 switch (p->type) { 538 switch (p->type) {
@@ -564,16 +551,11 @@ static void set_video(struct pm2fb_par* p, u32 video) {
564 if ((video & PM2F_VSYNC_MASK) == PM2F_VSYNC_ACT_LOW) 551 if ((video & PM2F_VSYNC_MASK) == PM2F_VSYNC_ACT_LOW)
565 tmp |= 4; /* invert vsync */ 552 tmp |= 4; /* invert vsync */
566 pm2v_RDAC_WR(p, PM2VI_RD_SYNC_CONTROL, tmp); 553 pm2v_RDAC_WR(p, PM2VI_RD_SYNC_CONTROL, tmp);
567 pm2v_RDAC_WR(p, PM2VI_RD_MISC_CONTROL, 1);
568 break; 554 break;
569 } 555 }
570} 556}
571 557
572/* 558/*
573 *
574 */
575
576/**
577 * pm2fb_check_var - Optional function. Validates a var passed in. 559 * pm2fb_check_var - Optional function. Validates a var passed in.
578 * @var: frame buffer variable screen structure 560 * @var: frame buffer variable screen structure
579 * @info: frame buffer structure that represents a single frame buffer 561 * @info: frame buffer structure that represents a single frame buffer
@@ -594,15 +576,22 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
594 } 576 }
595 577
596 if (var->xres != var->xres_virtual) { 578 if (var->xres != var->xres_virtual) {
597 DPRINTK("virtual x resolution != physical x resolution not supported\n"); 579 DPRINTK("virtual x resolution != "
580 "physical x resolution not supported\n");
598 return -EINVAL; 581 return -EINVAL;
599 } 582 }
600 583
601 if (var->yres > var->yres_virtual) { 584 if (var->yres > var->yres_virtual) {
602 DPRINTK("virtual y resolution < physical y resolution not possible\n"); 585 DPRINTK("virtual y resolution < "
586 "physical y resolution not possible\n");
603 return -EINVAL; 587 return -EINVAL;
604 } 588 }
605 589
590 /* permedia cannot blit over 2048 */
591 if (var->yres_virtual > 2047) {
592 var->yres_virtual = 2047;
593 }
594
606 if (var->xoffset) { 595 if (var->xoffset) {
607 DPRINTK("xoffset not supported\n"); 596 DPRINTK("xoffset not supported\n");
608 return -EINVAL; 597 return -EINVAL;
@@ -614,7 +603,7 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
614 } 603 }
615 604
616 var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */ 605 var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */
617 lpitch = var->xres * ((var->bits_per_pixel + 7)>>3); 606 lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3);
618 607
619 if (var->xres < 320 || var->xres > 1600) { 608 if (var->xres < 320 || var->xres > 1600) {
620 DPRINTK("width not supported: %u\n", var->xres); 609 DPRINTK("width not supported: %u\n", var->xres);
@@ -633,15 +622,18 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
633 } 622 }
634 623
635 if (PICOS2KHZ(var->pixclock) > PM2_MAX_PIXCLOCK) { 624 if (PICOS2KHZ(var->pixclock) > PM2_MAX_PIXCLOCK) {
636 DPRINTK("pixclock too high (%ldKHz)\n", PICOS2KHZ(var->pixclock)); 625 DPRINTK("pixclock too high (%ldKHz)\n",
626 PICOS2KHZ(var->pixclock));
637 return -EINVAL; 627 return -EINVAL;
638 } 628 }
639 629
640 var->transp.offset = 0; 630 var->transp.offset = 0;
641 var->transp.length = 0; 631 var->transp.length = 0;
642 switch(var->bits_per_pixel) { 632 switch (var->bits_per_pixel) {
643 case 8: 633 case 8:
644 var->red.length = var->green.length = var->blue.length = 8; 634 var->red.length = 8;
635 var->green.length = 8;
636 var->blue.length = 8;
645 break; 637 break;
646 case 16: 638 case 16:
647 var->red.offset = 11; 639 var->red.offset = 11;
@@ -657,7 +649,9 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
657 var->red.offset = 16; 649 var->red.offset = 16;
658 var->green.offset = 8; 650 var->green.offset = 8;
659 var->blue.offset = 0; 651 var->blue.offset = 0;
660 var->red.length = var->green.length = var->blue.length = 8; 652 var->red.length = 8;
653 var->green.length = 8;
654 var->blue.length = 8;
661 break; 655 break;
662 case 24: 656 case 24:
663#ifdef __BIG_ENDIAN 657#ifdef __BIG_ENDIAN
@@ -668,10 +662,13 @@ static int pm2fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
668 var->blue.offset = 0; 662 var->blue.offset = 0;
669#endif 663#endif
670 var->green.offset = 8; 664 var->green.offset = 8;
671 var->red.length = var->green.length = var->blue.length = 8; 665 var->red.length = 8;
666 var->green.length = 8;
667 var->blue.length = 8;
672 break; 668 break;
673 } 669 }
674 var->height = var->width = -1; 670 var->height = -1;
671 var->width = -1;
675 672
676 var->accel_flags = 0; /* Can't mmap if this is on */ 673 var->accel_flags = 0; /* Can't mmap if this is on */
677 674
@@ -691,7 +688,9 @@ static int pm2fb_set_par(struct fb_info *info)
691{ 688{
692 struct pm2fb_par *par = info->par; 689 struct pm2fb_par *par = info->par;
693 u32 pixclock; 690 u32 pixclock;
694 u32 width, height, depth; 691 u32 width = (info->var.xres_virtual + 7) & ~7;
692 u32 height = info->var.yres_virtual;
693 u32 depth = (info->var.bits_per_pixel + 7) & ~7;
695 u32 hsstart, hsend, hbend, htotal; 694 u32 hsstart, hsend, hbend, htotal;
696 u32 vsstart, vsend, vbend, vtotal; 695 u32 vsstart, vsend, vbend, vtotal;
697 u32 stride; 696 u32 stride;
@@ -701,22 +700,19 @@ static int pm2fb_set_par(struct fb_info *info)
701 u32 txtmap = 0; 700 u32 txtmap = 0;
702 u32 pixsize = 0; 701 u32 pixsize = 0;
703 u32 clrformat = 0; 702 u32 clrformat = 0;
704 u32 xres; 703 u32 misc = 1; /* 8-bit DAC */
704 u32 xres = (info->var.xres + 31) & ~31;
705 int data64; 705 int data64;
706 706
707 reset_card(par); 707 reset_card(par);
708 reset_config(par); 708 reset_config(par);
709 clear_palette(par); 709 clear_palette(par);
710 if ( par->memclock ) 710 if (par->memclock)
711 set_memclock(par, par->memclock); 711 set_memclock(par, par->memclock);
712 712
713 width = (info->var.xres_virtual + 7) & ~7;
714 height = info->var.yres_virtual;
715 depth = (info->var.bits_per_pixel + 7) & ~7;
716 depth = (depth > 32) ? 32 : depth; 713 depth = (depth > 32) ? 32 : depth;
717 data64 = depth > 8 || par->type == PM2_TYPE_PERMEDIA2V; 714 data64 = depth > 8 || par->type == PM2_TYPE_PERMEDIA2V;
718 715
719 xres = (info->var.xres + 31) & ~31;
720 pixclock = PICOS2KHZ(info->var.pixclock); 716 pixclock = PICOS2KHZ(info->var.pixclock);
721 if (pixclock > PM2_MAX_PIXCLOCK) { 717 if (pixclock > PM2_MAX_PIXCLOCK) {
722 DPRINTK("pixclock too high (%uKHz)\n", pixclock); 718 DPRINTK("pixclock too high (%uKHz)\n", pixclock);
@@ -731,7 +727,8 @@ static int pm2fb_set_par(struct fb_info *info)
731 ? info->var.lower_margin - 1 727 ? info->var.lower_margin - 1
732 : 0; /* FIXME! */ 728 : 0; /* FIXME! */
733 vsend = info->var.lower_margin + info->var.vsync_len - 1; 729 vsend = info->var.lower_margin + info->var.vsync_len - 1;
734 vbend = info->var.lower_margin + info->var.vsync_len + info->var.upper_margin; 730 vbend = info->var.lower_margin + info->var.vsync_len +
731 info->var.upper_margin;
735 vtotal = info->var.yres + vbend - 1; 732 vtotal = info->var.yres + vbend - 1;
736 stride = to3264(width, depth, 1); 733 stride = to3264(width, depth, 1);
737 base = to3264(info->var.yoffset * xres + info->var.xoffset, depth, 1); 734 base = to3264(info->var.yoffset * xres + info->var.xoffset, depth, 1);
@@ -744,25 +741,25 @@ static int pm2fb_set_par(struct fb_info *info)
744 video |= PM2F_HSYNC_ACT_LOW; 741 video |= PM2F_HSYNC_ACT_LOW;
745 } else 742 } else
746 video |= PM2F_HSYNC_ACT_HIGH; 743 video |= PM2F_HSYNC_ACT_HIGH;
747 } 744 } else
748 else
749 video |= PM2F_HSYNC_ACT_LOW; 745 video |= PM2F_HSYNC_ACT_LOW;
746
750 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) { 747 if (info->var.sync & FB_SYNC_VERT_HIGH_ACT) {
751 if (lowvsync) { 748 if (lowvsync) {
752 DPRINTK("ignoring +vsync, using -vsync.\n"); 749 DPRINTK("ignoring +vsync, using -vsync.\n");
753 video |= PM2F_VSYNC_ACT_LOW; 750 video |= PM2F_VSYNC_ACT_LOW;
754 } else 751 } else
755 video |= PM2F_VSYNC_ACT_HIGH; 752 video |= PM2F_VSYNC_ACT_HIGH;
756 } 753 } else
757 else
758 video |= PM2F_VSYNC_ACT_LOW; 754 video |= PM2F_VSYNC_ACT_LOW;
759 if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_INTERLACED) { 755
756 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) {
760 DPRINTK("interlaced not supported\n"); 757 DPRINTK("interlaced not supported\n");
761 return -EINVAL; 758 return -EINVAL;
762 } 759 }
763 if ((info->var.vmode & FB_VMODE_MASK)==FB_VMODE_DOUBLE) 760 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
764 video |= PM2F_LINE_DOUBLE; 761 video |= PM2F_LINE_DOUBLE;
765 if ((info->var.activate & FB_ACTIVATE_MASK)==FB_ACTIVATE_NOW) 762 if ((info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
766 video |= PM2F_VIDEO_ENABLE; 763 video |= PM2F_VIDEO_ENABLE;
767 par->video = video; 764 par->video = video;
768 765
@@ -783,12 +780,10 @@ static int pm2fb_set_par(struct fb_info *info)
783 780
784 mb(); 781 mb();
785 WAIT_FIFO(par, 19); 782 WAIT_FIFO(par, 19);
786 pm2_RDAC_WR(par, PM2I_RD_COLOR_KEY_CONTROL,
787 ( depth == 8 ) ? 0 : PM2F_COLOR_KEY_TEST_OFF);
788 switch (depth) { 783 switch (depth) {
789 case 8: 784 case 8:
790 pm2_WR(par, PM2R_FB_READ_PIXEL, 0); 785 pm2_WR(par, PM2R_FB_READ_PIXEL, 0);
791 clrformat = 0x0e; 786 clrformat = 0x2e;
792 break; 787 break;
793 case 16: 788 case 16:
794 pm2_WR(par, PM2R_FB_READ_PIXEL, 1); 789 pm2_WR(par, PM2R_FB_READ_PIXEL, 1);
@@ -796,6 +791,7 @@ static int pm2fb_set_par(struct fb_info *info)
796 txtmap = PM2F_TEXTEL_SIZE_16; 791 txtmap = PM2F_TEXTEL_SIZE_16;
797 pixsize = 1; 792 pixsize = 1;
798 clrformat = 0x70; 793 clrformat = 0x70;
794 misc |= 8;
799 break; 795 break;
800 case 32: 796 case 32:
801 pm2_WR(par, PM2R_FB_READ_PIXEL, 2); 797 pm2_WR(par, PM2R_FB_READ_PIXEL, 2);
@@ -803,6 +799,7 @@ static int pm2fb_set_par(struct fb_info *info)
803 txtmap = PM2F_TEXTEL_SIZE_32; 799 txtmap = PM2F_TEXTEL_SIZE_32;
804 pixsize = 2; 800 pixsize = 2;
805 clrformat = 0x20; 801 clrformat = 0x20;
802 misc |= 8;
806 break; 803 break;
807 case 24: 804 case 24:
808 pm2_WR(par, PM2R_FB_READ_PIXEL, 4); 805 pm2_WR(par, PM2R_FB_READ_PIXEL, 4);
@@ -810,6 +807,7 @@ static int pm2fb_set_par(struct fb_info *info)
810 txtmap = PM2F_TEXTEL_SIZE_24; 807 txtmap = PM2F_TEXTEL_SIZE_24;
811 pixsize = 4; 808 pixsize = 4;
812 clrformat = 0x20; 809 clrformat = 0x20;
810 misc |= 8;
813 break; 811 break;
814 } 812 }
815 pm2_WR(par, PM2R_FB_WRITE_MODE, PM2F_FB_WRITE_ENABLE); 813 pm2_WR(par, PM2R_FB_WRITE_MODE, PM2F_FB_WRITE_ENABLE);
@@ -834,14 +832,19 @@ static int pm2fb_set_par(struct fb_info *info)
834 pm2_WR(par, PM2R_SCREEN_BASE, base); 832 pm2_WR(par, PM2R_SCREEN_BASE, base);
835 wmb(); 833 wmb();
836 set_video(par, video); 834 set_video(par, video);
837 WAIT_FIFO(par, 4); 835 WAIT_FIFO(par, 10);
838 switch (par->type) { 836 switch (par->type) {
839 case PM2_TYPE_PERMEDIA2: 837 case PM2_TYPE_PERMEDIA2:
840 pm2_RDAC_WR(par, PM2I_RD_COLOR_MODE, clrmode); 838 pm2_RDAC_WR(par, PM2I_RD_COLOR_MODE, clrmode);
839 pm2_RDAC_WR(par, PM2I_RD_COLOR_KEY_CONTROL,
840 (depth == 8) ? 0 : PM2F_COLOR_KEY_TEST_OFF);
841 break; 841 break;
842 case PM2_TYPE_PERMEDIA2V: 842 case PM2_TYPE_PERMEDIA2V:
843 pm2v_RDAC_WR(par, PM2VI_RD_DAC_CONTROL, 0);
843 pm2v_RDAC_WR(par, PM2VI_RD_PIXEL_SIZE, pixsize); 844 pm2v_RDAC_WR(par, PM2VI_RD_PIXEL_SIZE, pixsize);
844 pm2v_RDAC_WR(par, PM2VI_RD_COLOR_FORMAT, clrformat); 845 pm2v_RDAC_WR(par, PM2VI_RD_COLOR_FORMAT, clrformat);
846 pm2v_RDAC_WR(par, PM2VI_RD_MISC_CONTROL, misc);
847 pm2v_RDAC_WR(par, PM2VI_RD_OVERLAY_KEY, 0);
845 break; 848 break;
846 } 849 }
847 set_pixclock(par, pixclock); 850 set_pixclock(par, pixclock);
@@ -872,16 +875,15 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
872 struct pm2fb_par *par = info->par; 875 struct pm2fb_par *par = info->par;
873 876
874 if (regno >= info->cmap.len) /* no. of hw registers */ 877 if (regno >= info->cmap.len) /* no. of hw registers */
875 return 1; 878 return -EINVAL;
876 /* 879 /*
877 * Program hardware... do anything you want with transp 880 * Program hardware... do anything you want with transp
878 */ 881 */
879 882
880 /* grayscale works only partially under directcolor */ 883 /* grayscale works only partially under directcolor */
881 if (info->var.grayscale) { 884 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
882 /* grayscale = 0.30*R + 0.59*G + 0.11*B */ 885 if (info->var.grayscale)
883 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; 886 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
884 }
885 887
886 /* Directcolor: 888 /* Directcolor:
887 * var->{color}.offset contains start of bitfield 889 * var->{color}.offset contains start of bitfield
@@ -931,7 +933,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
931 u32 v; 933 u32 v;
932 934
933 if (regno >= 16) 935 if (regno >= 16)
934 return 1; 936 return -EINVAL;
935 937
936 v = (red << info->var.red.offset) | 938 v = (red << info->var.red.offset) |
937 (green << info->var.green.offset) | 939 (green << info->var.green.offset) |
@@ -948,8 +950,7 @@ static int pm2fb_setcolreg(unsigned regno, unsigned red, unsigned green,
948 break; 950 break;
949 } 951 }
950 return 0; 952 return 0;
951 } 953 } else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
952 else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
953 set_color(par, regno, red, green, blue); 954 set_color(par, regno, red, green, blue);
954 955
955 return 0; 956 return 0;
@@ -972,11 +973,9 @@ static int pm2fb_pan_display(struct fb_var_screeninfo *var,
972{ 973{
973 struct pm2fb_par *p = info->par; 974 struct pm2fb_par *p = info->par;
974 u32 base; 975 u32 base;
975 u32 depth; 976 u32 depth = (var->bits_per_pixel + 7) & ~7;
976 u32 xres; 977 u32 xres = (var->xres + 31) & ~31;
977 978
978 xres = (var->xres + 31) & ~31;
979 depth = (var->bits_per_pixel + 7) & ~7;
980 depth = (depth > 32) ? 32 : depth; 979 depth = (depth > 32) ? 32 : depth;
981 base = to3264(var->yoffset * xres + var->xoffset, depth, 1); 980 base = to3264(var->yoffset * xres + var->xoffset, depth, 1);
982 WAIT_FIFO(p, 1); 981 WAIT_FIFO(p, 1);
@@ -1018,15 +1017,15 @@ static int pm2fb_blank(int blank_mode, struct fb_info *info)
1018 break; 1017 break;
1019 case FB_BLANK_VSYNC_SUSPEND: 1018 case FB_BLANK_VSYNC_SUSPEND:
1020 /* VSync: Off */ 1019 /* VSync: Off */
1021 video &= ~(PM2F_VSYNC_MASK | PM2F_BLANK_LOW ); 1020 video &= ~(PM2F_VSYNC_MASK | PM2F_BLANK_LOW);
1022 break; 1021 break;
1023 case FB_BLANK_HSYNC_SUSPEND: 1022 case FB_BLANK_HSYNC_SUSPEND:
1024 /* HSync: Off */ 1023 /* HSync: Off */
1025 video &= ~(PM2F_HSYNC_MASK | PM2F_BLANK_LOW ); 1024 video &= ~(PM2F_HSYNC_MASK | PM2F_BLANK_LOW);
1026 break; 1025 break;
1027 case FB_BLANK_POWERDOWN: 1026 case FB_BLANK_POWERDOWN:
1028 /* HSync: Off, VSync: Off */ 1027 /* HSync: Off, VSync: Off */
1029 video &= ~(PM2F_VSYNC_MASK | PM2F_HSYNC_MASK| PM2F_BLANK_LOW); 1028 video &= ~(PM2F_VSYNC_MASK | PM2F_HSYNC_MASK | PM2F_BLANK_LOW);
1030 break; 1029 break;
1031 } 1030 }
1032 set_video(par, video); 1031 set_video(par, video);
@@ -1042,48 +1041,20 @@ static int pm2fb_sync(struct fb_info *info)
1042 mb(); 1041 mb();
1043 do { 1042 do {
1044 while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0) 1043 while (pm2_RD(par, PM2R_OUT_FIFO_WORDS) == 0)
1045 udelay(10); 1044 cpu_relax();
1046 rmb();
1047 } while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC)); 1045 } while (pm2_RD(par, PM2R_OUT_FIFO) != PM2TAG(PM2R_SYNC));
1048 1046
1049 return 0; 1047 return 0;
1050} 1048}
1051 1049
1052/* 1050static void pm2fb_fillrect(struct fb_info *info,
1053 * block operation. copy=0: rectangle fill, copy=1: rectangle copy.
1054 */
1055static void pm2fb_block_op(struct fb_info* info, int copy,
1056 s32 xsrc, s32 ysrc,
1057 s32 x, s32 y, s32 w, s32 h,
1058 u32 color) {
1059 struct pm2fb_par *par = info->par;
1060
1061 if (!w || !h)
1062 return;
1063 WAIT_FIFO(par, 5);
1064 pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
1065 PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
1066 if (copy)
1067 pm2_WR(par, PM2R_FB_SOURCE_DELTA,
1068 ((ysrc-y) & 0xfff) << 16 | ((xsrc-x) & 0xfff));
1069 else
1070 pm2_WR(par, PM2R_FB_BLOCK_COLOR, color);
1071 pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (y << 16) | x);
1072 pm2_WR(par, PM2R_RECTANGLE_SIZE, (h << 16) | w);
1073 wmb();
1074 pm2_WR(par, PM2R_RENDER, PM2F_RENDER_RECTANGLE |
1075 (x<xsrc ? PM2F_INCREASE_X : 0) |
1076 (y<ysrc ? PM2F_INCREASE_Y : 0) |
1077 (copy ? 0 : PM2F_RENDER_FASTFILL));
1078}
1079
1080static void pm2fb_fillrect (struct fb_info *info,
1081 const struct fb_fillrect *region) 1051 const struct fb_fillrect *region)
1082{ 1052{
1053 struct pm2fb_par *par = info->par;
1083 struct fb_fillrect modded; 1054 struct fb_fillrect modded;
1084 int vxres, vyres; 1055 int vxres, vyres;
1085 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ? 1056 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
1086 ((u32*)info->pseudo_palette)[region->color] : region->color; 1057 ((u32 *)info->pseudo_palette)[region->color] : region->color;
1087 1058
1088 if (info->state != FBINFO_STATE_RUNNING) 1059 if (info->state != FBINFO_STATE_RUNNING)
1089 return; 1060 return;
@@ -1098,31 +1069,46 @@ static void pm2fb_fillrect (struct fb_info *info,
1098 1069
1099 memcpy(&modded, region, sizeof(struct fb_fillrect)); 1070 memcpy(&modded, region, sizeof(struct fb_fillrect));
1100 1071
1101 if(!modded.width || !modded.height || 1072 if (!modded.width || !modded.height ||
1102 modded.dx >= vxres || modded.dy >= vyres) 1073 modded.dx >= vxres || modded.dy >= vyres)
1103 return; 1074 return;
1104 1075
1105 if(modded.dx + modded.width > vxres) 1076 if (modded.dx + modded.width > vxres)
1106 modded.width = vxres - modded.dx; 1077 modded.width = vxres - modded.dx;
1107 if(modded.dy + modded.height > vyres) 1078 if (modded.dy + modded.height > vyres)
1108 modded.height = vyres - modded.dy; 1079 modded.height = vyres - modded.dy;
1109 1080
1110 if(info->var.bits_per_pixel == 8) 1081 if (info->var.bits_per_pixel == 8)
1111 color |= color << 8; 1082 color |= color << 8;
1112 if(info->var.bits_per_pixel <= 16) 1083 if (info->var.bits_per_pixel <= 16)
1113 color |= color << 16; 1084 color |= color << 16;
1114 1085
1115 if(info->var.bits_per_pixel != 24) 1086 WAIT_FIFO(par, 3);
1116 pm2fb_block_op(info, 0, 0, 0, 1087 pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE);
1117 modded.dx, modded.dy, 1088 pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (modded.dy << 16) | modded.dx);
1118 modded.width, modded.height, color); 1089 pm2_WR(par, PM2R_RECTANGLE_SIZE, (modded.height << 16) | modded.width);
1119 else 1090 if (info->var.bits_per_pixel != 24) {
1120 cfb_fillrect(info, region); 1091 WAIT_FIFO(par, 2);
1092 pm2_WR(par, PM2R_FB_BLOCK_COLOR, color);
1093 wmb();
1094 pm2_WR(par, PM2R_RENDER,
1095 PM2F_RENDER_RECTANGLE | PM2F_RENDER_FASTFILL);
1096 } else {
1097 WAIT_FIFO(par, 4);
1098 pm2_WR(par, PM2R_COLOR_DDA_MODE, 1);
1099 pm2_WR(par, PM2R_CONSTANT_COLOR, color);
1100 wmb();
1101 pm2_WR(par, PM2R_RENDER,
1102 PM2F_RENDER_RECTANGLE |
1103 PM2F_INCREASE_X | PM2F_INCREASE_Y );
1104 pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
1105 }
1121} 1106}
1122 1107
1123static void pm2fb_copyarea(struct fb_info *info, 1108static void pm2fb_copyarea(struct fb_info *info,
1124 const struct fb_copyarea *area) 1109 const struct fb_copyarea *area)
1125{ 1110{
1111 struct pm2fb_par *par = info->par;
1126 struct fb_copyarea modded; 1112 struct fb_copyarea modded;
1127 u32 vxres, vyres; 1113 u32 vxres, vyres;
1128 1114
@@ -1138,23 +1124,359 @@ static void pm2fb_copyarea(struct fb_info *info,
1138 vxres = info->var.xres_virtual; 1124 vxres = info->var.xres_virtual;
1139 vyres = info->var.yres_virtual; 1125 vyres = info->var.yres_virtual;
1140 1126
1141 if(!modded.width || !modded.height || 1127 if (!modded.width || !modded.height ||
1142 modded.sx >= vxres || modded.sy >= vyres || 1128 modded.sx >= vxres || modded.sy >= vyres ||
1143 modded.dx >= vxres || modded.dy >= vyres) 1129 modded.dx >= vxres || modded.dy >= vyres)
1144 return; 1130 return;
1145 1131
1146 if(modded.sx + modded.width > vxres) 1132 if (modded.sx + modded.width > vxres)
1147 modded.width = vxres - modded.sx; 1133 modded.width = vxres - modded.sx;
1148 if(modded.dx + modded.width > vxres) 1134 if (modded.dx + modded.width > vxres)
1149 modded.width = vxres - modded.dx; 1135 modded.width = vxres - modded.dx;
1150 if(modded.sy + modded.height > vyres) 1136 if (modded.sy + modded.height > vyres)
1151 modded.height = vyres - modded.sy; 1137 modded.height = vyres - modded.sy;
1152 if(modded.dy + modded.height > vyres) 1138 if (modded.dy + modded.height > vyres)
1153 modded.height = vyres - modded.dy; 1139 modded.height = vyres - modded.dy;
1154 1140
1155 pm2fb_block_op(info, 1, modded.sx, modded.sy, 1141 WAIT_FIFO(par, 5);
1156 modded.dx, modded.dy, 1142 pm2_WR(par, PM2R_CONFIG, PM2F_CONFIG_FB_WRITE_ENABLE |
1157 modded.width, modded.height, 0); 1143 PM2F_CONFIG_FB_READ_SOURCE_ENABLE);
1144 pm2_WR(par, PM2R_FB_SOURCE_DELTA,
1145 ((modded.sy - modded.dy) & 0xfff) << 16 |
1146 ((modded.sx - modded.dx) & 0xfff));
1147 pm2_WR(par, PM2R_RECTANGLE_ORIGIN, (modded.dy << 16) | modded.dx);
1148 pm2_WR(par, PM2R_RECTANGLE_SIZE, (modded.height << 16) | modded.width);
1149 wmb();
1150 pm2_WR(par, PM2R_RENDER, PM2F_RENDER_RECTANGLE |
1151 (modded.dx < modded.sx ? PM2F_INCREASE_X : 0) |
1152 (modded.dy < modded.sy ? PM2F_INCREASE_Y : 0));
1153}
1154
1155static void pm2fb_imageblit(struct fb_info *info, const struct fb_image *image)
1156{
1157 struct pm2fb_par *par = info->par;
1158 u32 height = image->height;
1159 u32 fgx, bgx;
1160 const u32 *src = (const u32 *)image->data;
1161 u32 xres = (info->var.xres + 31) & ~31;
1162
1163 if (info->state != FBINFO_STATE_RUNNING)
1164 return;
1165 if (info->flags & FBINFO_HWACCEL_DISABLED || image->depth != 1) {
1166 cfb_imageblit(info, image);
1167 return;
1168 }
1169 switch (info->fix.visual) {
1170 case FB_VISUAL_PSEUDOCOLOR:
1171 fgx = image->fg_color;
1172 bgx = image->bg_color;
1173 break;
1174 case FB_VISUAL_TRUECOLOR:
1175 default:
1176 fgx = par->palette[image->fg_color];
1177 bgx = par->palette[image->bg_color];
1178 break;
1179 }
1180 if (info->var.bits_per_pixel == 8) {
1181 fgx |= fgx << 8;
1182 bgx |= bgx << 8;
1183 }
1184 if (info->var.bits_per_pixel <= 16) {
1185 fgx |= fgx << 16;
1186 bgx |= bgx << 16;
1187 }
1188
1189 WAIT_FIFO(par, 13);
1190 pm2_WR(par, PM2R_FB_READ_MODE, partprod(xres));
1191 pm2_WR(par, PM2R_SCISSOR_MIN_XY,
1192 ((image->dy & 0xfff) << 16) | (image->dx & 0x0fff));
1193 pm2_WR(par, PM2R_SCISSOR_MAX_XY,
1194 (((image->dy + image->height) & 0x0fff) << 16) |
1195 ((image->dx + image->width) & 0x0fff));
1196 pm2_WR(par, PM2R_SCISSOR_MODE, 1);
1197 /* GXcopy & UNIT_ENABLE */
1198 pm2_WR(par, PM2R_LOGICAL_OP_MODE, (0x3 << 1) | 1);
1199 pm2_WR(par, PM2R_RECTANGLE_ORIGIN,
1200 ((image->dy & 0xfff) << 16) | (image->dx & 0x0fff));
1201 pm2_WR(par, PM2R_RECTANGLE_SIZE,
1202 ((image->height & 0x0fff) << 16) |
1203 ((image->width) & 0x0fff));
1204 if (info->var.bits_per_pixel == 24) {
1205 pm2_WR(par, PM2R_COLOR_DDA_MODE, 1);
1206 /* clear area */
1207 pm2_WR(par, PM2R_CONSTANT_COLOR, bgx);
1208 pm2_WR(par, PM2R_RENDER,
1209 PM2F_RENDER_RECTANGLE |
1210 PM2F_INCREASE_X | PM2F_INCREASE_Y);
1211 /* BitMapPackEachScanline & invert bits and byte order*/
1212 /* force background */
1213 pm2_WR(par, PM2R_RASTERIZER_MODE, (1 << 9) | 1 | (3 << 7));
1214 pm2_WR(par, PM2R_CONSTANT_COLOR, fgx);
1215 pm2_WR(par, PM2R_RENDER,
1216 PM2F_RENDER_RECTANGLE |
1217 PM2F_INCREASE_X | PM2F_INCREASE_Y |
1218 PM2F_RENDER_SYNC_ON_BIT_MASK);
1219 } else {
1220 pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
1221 /* clear area */
1222 pm2_WR(par, PM2R_FB_BLOCK_COLOR, bgx);
1223 pm2_WR(par, PM2R_RENDER,
1224 PM2F_RENDER_RECTANGLE |
1225 PM2F_RENDER_FASTFILL |
1226 PM2F_INCREASE_X | PM2F_INCREASE_Y);
1227 /* invert bits and byte order*/
1228 pm2_WR(par, PM2R_RASTERIZER_MODE, 1 | (3 << 7));
1229 pm2_WR(par, PM2R_FB_BLOCK_COLOR, fgx);
1230 pm2_WR(par, PM2R_RENDER,
1231 PM2F_RENDER_RECTANGLE |
1232 PM2F_INCREASE_X | PM2F_INCREASE_Y |
1233 PM2F_RENDER_FASTFILL |
1234 PM2F_RENDER_SYNC_ON_BIT_MASK);
1235 }
1236
1237 while (height--) {
1238 int width = ((image->width + 7) >> 3)
1239 + info->pixmap.scan_align - 1;
1240 width >>= 2;
1241 WAIT_FIFO(par, width);
1242 while (width--) {
1243 pm2_WR(par, PM2R_BIT_MASK_PATTERN, *src);
1244 src++;
1245 }
1246 }
1247 WAIT_FIFO(par, 3);
1248 pm2_WR(par, PM2R_RASTERIZER_MODE, 0);
1249 pm2_WR(par, PM2R_COLOR_DDA_MODE, 0);
1250 pm2_WR(par, PM2R_SCISSOR_MODE, 0);
1251}
1252
1253/*
1254 * Hardware cursor support.
1255 */
1256static const u8 cursor_bits_lookup[16] = {
1257 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
1258 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
1259};
1260
1261static int pm2vfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1262{
1263 struct pm2fb_par *par = info->par;
1264 u8 mode = PM2F_CURSORMODE_TYPE_X;
1265 int x = cursor->image.dx - info->var.xoffset;
1266 int y = cursor->image.dy - info->var.yoffset;
1267
1268 if (cursor->enable)
1269 mode |= PM2F_CURSORMODE_CURSOR_ENABLE;
1270
1271 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_MODE, mode);
1272
1273 if (!cursor->enable)
1274 x = 2047; /* push it outside display */
1275 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_X_LOW, x & 0xff);
1276 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_X_HIGH, (x >> 8) & 0xf);
1277 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_Y_LOW, y & 0xff);
1278 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_Y_HIGH, (y >> 8) & 0xf);
1279
1280 /*
1281 * If the cursor is not be changed this means either we want the
1282 * current cursor state (if enable is set) or we want to query what
1283 * we can do with the cursor (if enable is not set)
1284 */
1285 if (!cursor->set)
1286 return 0;
1287
1288 if (cursor->set & FB_CUR_SETHOT) {
1289 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_X_HOT,
1290 cursor->hot.x & 0x3f);
1291 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_Y_HOT,
1292 cursor->hot.y & 0x3f);
1293 }
1294
1295 if (cursor->set & FB_CUR_SETCMAP) {
1296 u32 fg_idx = cursor->image.fg_color;
1297 u32 bg_idx = cursor->image.bg_color;
1298 struct fb_cmap cmap = info->cmap;
1299
1300 /* the X11 driver says one should use these color registers */
1301 pm2_WR(par, PM2VR_RD_INDEX_HIGH, PM2VI_RD_CURSOR_PALETTE >> 8);
1302 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 0,
1303 cmap.red[bg_idx] >> 8 );
1304 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 1,
1305 cmap.green[bg_idx] >> 8 );
1306 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 2,
1307 cmap.blue[bg_idx] >> 8 );
1308
1309 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 3,
1310 cmap.red[fg_idx] >> 8 );
1311 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 4,
1312 cmap.green[fg_idx] >> 8 );
1313 pm2v_RDAC_WR(par, PM2VI_RD_CURSOR_PALETTE + 5,
1314 cmap.blue[fg_idx] >> 8 );
1315 pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
1316 }
1317
1318 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
1319 u8 *bitmap = (u8 *)cursor->image.data;
1320 u8 *mask = (u8 *)cursor->mask;
1321 int i;
1322 int pos = PM2VI_RD_CURSOR_PATTERN;
1323
1324 for (i = 0; i < cursor->image.height; i++) {
1325 int j = (cursor->image.width + 7) >> 3;
1326 int k = 8 - j;
1327
1328 pm2_WR(par, PM2VR_RD_INDEX_HIGH, pos >> 8);
1329
1330 for (; j > 0; j--) {
1331 u8 data = *bitmap ^ *mask;
1332
1333 if (cursor->rop == ROP_COPY)
1334 data = *mask & *bitmap;
1335 /* Upper 4 bits of bitmap data */
1336 pm2v_RDAC_WR(par, pos++,
1337 cursor_bits_lookup[data >> 4] |
1338 (cursor_bits_lookup[*mask >> 4] << 1));
1339 /* Lower 4 bits of bitmap */
1340 pm2v_RDAC_WR(par, pos++,
1341 cursor_bits_lookup[data & 0xf] |
1342 (cursor_bits_lookup[*mask & 0xf] << 1));
1343 bitmap++;
1344 mask++;
1345 }
1346 for (; k > 0; k--) {
1347 pm2v_RDAC_WR(par, pos++, 0);
1348 pm2v_RDAC_WR(par, pos++, 0);
1349 }
1350 }
1351
1352 while (pos < (1024 + PM2VI_RD_CURSOR_PATTERN)) {
1353 pm2_WR(par, PM2VR_RD_INDEX_HIGH, pos >> 8);
1354 pm2v_RDAC_WR(par, pos++, 0);
1355 }
1356
1357 pm2_WR(par, PM2VR_RD_INDEX_HIGH, 0);
1358 }
1359 return 0;
1360}
1361
1362static int pm2fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1363{
1364 struct pm2fb_par *par = info->par;
1365 u8 mode;
1366
1367 if (!hwcursor)
1368 return -EINVAL; /* just to force soft_cursor() call */
1369
1370 /* Too large of a cursor or wrong bpp :-( */
1371 if (cursor->image.width > 64 ||
1372 cursor->image.height > 64 ||
1373 cursor->image.depth > 1)
1374 return -EINVAL;
1375
1376 if (par->type == PM2_TYPE_PERMEDIA2V)
1377 return pm2vfb_cursor(info, cursor);
1378
1379 mode = 0x40;
1380 if (cursor->enable)
1381 mode = 0x43;
1382
1383 pm2_RDAC_WR(par, PM2I_RD_CURSOR_CONTROL, mode);
1384
1385 /*
1386 * If the cursor is not be changed this means either we want the
1387 * current cursor state (if enable is set) or we want to query what
1388 * we can do with the cursor (if enable is not set)
1389 */
1390 if (!cursor->set)
1391 return 0;
1392
1393 if (cursor->set & FB_CUR_SETPOS) {
1394 int x = cursor->image.dx - info->var.xoffset + 63;
1395 int y = cursor->image.dy - info->var.yoffset + 63;
1396
1397 WAIT_FIFO(par, 4);
1398 pm2_WR(par, PM2R_RD_CURSOR_X_LSB, x & 0xff);
1399 pm2_WR(par, PM2R_RD_CURSOR_X_MSB, (x >> 8) & 0x7);
1400 pm2_WR(par, PM2R_RD_CURSOR_Y_LSB, y & 0xff);
1401 pm2_WR(par, PM2R_RD_CURSOR_Y_MSB, (y >> 8) & 0x7);
1402 }
1403
1404 if (cursor->set & FB_CUR_SETCMAP) {
1405 u32 fg_idx = cursor->image.fg_color;
1406 u32 bg_idx = cursor->image.bg_color;
1407
1408 WAIT_FIFO(par, 7);
1409 pm2_WR(par, PM2R_RD_CURSOR_COLOR_ADDRESS, 1);
1410 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1411 info->cmap.red[bg_idx] >> 8);
1412 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1413 info->cmap.green[bg_idx] >> 8);
1414 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1415 info->cmap.blue[bg_idx] >> 8);
1416
1417 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1418 info->cmap.red[fg_idx] >> 8);
1419 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1420 info->cmap.green[fg_idx] >> 8);
1421 pm2_WR(par, PM2R_RD_CURSOR_COLOR_DATA,
1422 info->cmap.blue[fg_idx] >> 8);
1423 }
1424
1425 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
1426 u8 *bitmap = (u8 *)cursor->image.data;
1427 u8 *mask = (u8 *)cursor->mask;
1428 int i;
1429
1430 WAIT_FIFO(par, 1);
1431 pm2_WR(par, PM2R_RD_PALETTE_WRITE_ADDRESS, 0);
1432
1433 for (i = 0; i < cursor->image.height; i++) {
1434 int j = (cursor->image.width + 7) >> 3;
1435 int k = 8 - j;
1436
1437 WAIT_FIFO(par, 8);
1438 for (; j > 0; j--) {
1439 u8 data = *bitmap ^ *mask;
1440
1441 if (cursor->rop == ROP_COPY)
1442 data = *mask & *bitmap;
1443 /* bitmap data */
1444 pm2_WR(par, PM2R_RD_CURSOR_DATA, data);
1445 bitmap++;
1446 mask++;
1447 }
1448 for (; k > 0; k--)
1449 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1450 }
1451 for (; i < 64; i++) {
1452 int j = 8;
1453 WAIT_FIFO(par, 8);
1454 while (j-- > 0)
1455 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1456 }
1457
1458 mask = (u8 *)cursor->mask;
1459 for (i = 0; i < cursor->image.height; i++) {
1460 int j = (cursor->image.width + 7) >> 3;
1461 int k = 8 - j;
1462
1463 WAIT_FIFO(par, 8);
1464 for (; j > 0; j--) {
1465 /* mask */
1466 pm2_WR(par, PM2R_RD_CURSOR_DATA, *mask);
1467 mask++;
1468 }
1469 for (; k > 0; k--)
1470 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1471 }
1472 for (; i < 64; i++) {
1473 int j = 8;
1474 WAIT_FIFO(par, 8);
1475 while (j-- > 0)
1476 pm2_WR(par, PM2R_RD_CURSOR_DATA, 0);
1477 }
1478 }
1479 return 0;
1158} 1480}
1159 1481
1160/* ------------ Hardware Independent Functions ------------ */ 1482/* ------------ Hardware Independent Functions ------------ */
@@ -1172,8 +1494,9 @@ static struct fb_ops pm2fb_ops = {
1172 .fb_pan_display = pm2fb_pan_display, 1494 .fb_pan_display = pm2fb_pan_display,
1173 .fb_fillrect = pm2fb_fillrect, 1495 .fb_fillrect = pm2fb_fillrect,
1174 .fb_copyarea = pm2fb_copyarea, 1496 .fb_copyarea = pm2fb_copyarea,
1175 .fb_imageblit = cfb_imageblit, 1497 .fb_imageblit = pm2fb_imageblit,
1176 .fb_sync = pm2fb_sync, 1498 .fb_sync = pm2fb_sync,
1499 .fb_cursor = pm2fb_cursor,
1177}; 1500};
1178 1501
1179/* 1502/*
@@ -1194,16 +1517,17 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1194{ 1517{
1195 struct pm2fb_par *default_par; 1518 struct pm2fb_par *default_par;
1196 struct fb_info *info; 1519 struct fb_info *info;
1197 int err, err_retval = -ENXIO; 1520 int err;
1521 int retval = -ENXIO;
1198 1522
1199 err = pci_enable_device(pdev); 1523 err = pci_enable_device(pdev);
1200 if ( err ) { 1524 if (err) {
1201 printk(KERN_WARNING "pm2fb: Can't enable pdev: %d\n", err); 1525 printk(KERN_WARNING "pm2fb: Can't enable pdev: %d\n", err);
1202 return err; 1526 return err;
1203 } 1527 }
1204 1528
1205 info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev); 1529 info = framebuffer_alloc(sizeof(struct pm2fb_par), &pdev->dev);
1206 if ( !info ) 1530 if (!info)
1207 return -ENOMEM; 1531 return -ENOMEM;
1208 default_par = info->par; 1532 default_par = info->par;
1209 1533
@@ -1236,14 +1560,14 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1236 DPRINTK("Register base at 0x%lx\n", pm2fb_fix.mmio_start); 1560 DPRINTK("Register base at 0x%lx\n", pm2fb_fix.mmio_start);
1237 1561
1238 /* Registers - request region and map it. */ 1562 /* Registers - request region and map it. */
1239 if ( !request_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len, 1563 if (!request_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len,
1240 "pm2fb regbase") ) { 1564 "pm2fb regbase")) {
1241 printk(KERN_WARNING "pm2fb: Can't reserve regbase.\n"); 1565 printk(KERN_WARNING "pm2fb: Can't reserve regbase.\n");
1242 goto err_exit_neither; 1566 goto err_exit_neither;
1243 } 1567 }
1244 default_par->v_regs = 1568 default_par->v_regs =
1245 ioremap_nocache(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len); 1569 ioremap_nocache(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
1246 if ( !default_par->v_regs ) { 1570 if (!default_par->v_regs) {
1247 printk(KERN_WARNING "pm2fb: Can't remap %s register area.\n", 1571 printk(KERN_WARNING "pm2fb: Can't remap %s register area.\n",
1248 pm2fb_fix.id); 1572 pm2fb_fix.id);
1249 release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len); 1573 release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
@@ -1258,72 +1582,101 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1258 default_par->mem_control, default_par->boot_address, 1582 default_par->mem_control, default_par->boot_address,
1259 default_par->mem_config); 1583 default_par->mem_config);
1260 1584
1261 if(default_par->mem_control == 0 && 1585 if (default_par->mem_control == 0 &&
1262 default_par->boot_address == 0x31 && 1586 default_par->boot_address == 0x31 &&
1263 default_par->mem_config == 0x259fffff) { 1587 default_par->mem_config == 0x259fffff) {
1264 default_par->memclock = CVPPC_MEMCLOCK; 1588 default_par->memclock = CVPPC_MEMCLOCK;
1265 default_par->mem_control=0; 1589 default_par->mem_control = 0;
1266 default_par->boot_address=0x20; 1590 default_par->boot_address = 0x20;
1267 default_par->mem_config=0xe6002021; 1591 default_par->mem_config = 0xe6002021;
1268 if (pdev->subsystem_vendor == 0x1048 && 1592 if (pdev->subsystem_vendor == 0x1048 &&
1269 pdev->subsystem_device == 0x0a31) { 1593 pdev->subsystem_device == 0x0a31) {
1270 DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n", 1594 DPRINTK("subsystem_vendor: %04x, "
1595 "subsystem_device: %04x\n",
1271 pdev->subsystem_vendor, pdev->subsystem_device); 1596 pdev->subsystem_vendor, pdev->subsystem_device);
1272 DPRINTK("We have not been initialized by VGA BIOS " 1597 DPRINTK("We have not been initialized by VGA BIOS and "
1273 "and are running on an Elsa Winner 2000 Office\n"); 1598 "are running on an Elsa Winner 2000 Office\n");
1274 DPRINTK("Initializing card timings manually...\n"); 1599 DPRINTK("Initializing card timings manually...\n");
1275 default_par->memclock=70000; 1600 default_par->memclock = 100000;
1276 } 1601 }
1277 if (pdev->subsystem_vendor == 0x3d3d && 1602 if (pdev->subsystem_vendor == 0x3d3d &&
1278 pdev->subsystem_device == 0x0100) { 1603 pdev->subsystem_device == 0x0100) {
1279 DPRINTK("subsystem_vendor: %04x, subsystem_device: %04x\n", 1604 DPRINTK("subsystem_vendor: %04x, "
1605 "subsystem_device: %04x\n",
1280 pdev->subsystem_vendor, pdev->subsystem_device); 1606 pdev->subsystem_vendor, pdev->subsystem_device);
1281 DPRINTK("We have not been initialized by VGA BIOS " 1607 DPRINTK("We have not been initialized by VGA BIOS and "
1282 "and are running on an 3dlabs reference board\n"); 1608 "are running on an 3dlabs reference board\n");
1283 DPRINTK("Initializing card timings manually...\n"); 1609 DPRINTK("Initializing card timings manually...\n");
1284 default_par->memclock=74894; 1610 default_par->memclock = 74894;
1285 } 1611 }
1286 } 1612 }
1287 1613
1288 /* Now work out how big lfb is going to be. */ 1614 /* Now work out how big lfb is going to be. */
1289 switch(default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) { 1615 switch (default_par->mem_config & PM2F_MEM_CONFIG_RAM_MASK) {
1290 case PM2F_MEM_BANKS_1: 1616 case PM2F_MEM_BANKS_1:
1291 pm2fb_fix.smem_len=0x200000; 1617 pm2fb_fix.smem_len = 0x200000;
1292 break; 1618 break;
1293 case PM2F_MEM_BANKS_2: 1619 case PM2F_MEM_BANKS_2:
1294 pm2fb_fix.smem_len=0x400000; 1620 pm2fb_fix.smem_len = 0x400000;
1295 break; 1621 break;
1296 case PM2F_MEM_BANKS_3: 1622 case PM2F_MEM_BANKS_3:
1297 pm2fb_fix.smem_len=0x600000; 1623 pm2fb_fix.smem_len = 0x600000;
1298 break; 1624 break;
1299 case PM2F_MEM_BANKS_4: 1625 case PM2F_MEM_BANKS_4:
1300 pm2fb_fix.smem_len=0x800000; 1626 pm2fb_fix.smem_len = 0x800000;
1301 break; 1627 break;
1302 } 1628 }
1303 pm2fb_fix.smem_start = pci_resource_start(pdev, 1); 1629 pm2fb_fix.smem_start = pci_resource_start(pdev, 1);
1304 1630
1305 /* Linear frame buffer - request region and map it. */ 1631 /* Linear frame buffer - request region and map it. */
1306 if ( !request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len, 1632 if (!request_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len,
1307 "pm2fb smem") ) { 1633 "pm2fb smem")) {
1308 printk(KERN_WARNING "pm2fb: Can't reserve smem.\n"); 1634 printk(KERN_WARNING "pm2fb: Can't reserve smem.\n");
1309 goto err_exit_mmio; 1635 goto err_exit_mmio;
1310 } 1636 }
1311 info->screen_base = 1637 info->screen_base =
1312 ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len); 1638 ioremap_nocache(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
1313 if ( !info->screen_base ) { 1639 if (!info->screen_base) {
1314 printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n"); 1640 printk(KERN_WARNING "pm2fb: Can't ioremap smem area.\n");
1315 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len); 1641 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
1316 goto err_exit_mmio; 1642 goto err_exit_mmio;
1317 } 1643 }
1318 1644
1645#ifdef CONFIG_MTRR
1646 default_par->mtrr_handle = -1;
1647 if (!nomtrr)
1648 default_par->mtrr_handle =
1649 mtrr_add(pm2fb_fix.smem_start,
1650 pm2fb_fix.smem_len,
1651 MTRR_TYPE_WRCOMB, 1);
1652#endif
1653
1319 info->fbops = &pm2fb_ops; 1654 info->fbops = &pm2fb_ops;
1320 info->fix = pm2fb_fix; 1655 info->fix = pm2fb_fix;
1321 info->pseudo_palette = default_par->palette; 1656 info->pseudo_palette = default_par->palette;
1322 info->flags = FBINFO_DEFAULT | 1657 info->flags = FBINFO_DEFAULT |
1323 FBINFO_HWACCEL_YPAN | 1658 FBINFO_HWACCEL_YPAN |
1324 FBINFO_HWACCEL_COPYAREA | 1659 FBINFO_HWACCEL_COPYAREA |
1660 FBINFO_HWACCEL_IMAGEBLIT |
1325 FBINFO_HWACCEL_FILLRECT; 1661 FBINFO_HWACCEL_FILLRECT;
1326 1662
1663 info->pixmap.addr = kmalloc(PM2_PIXMAP_SIZE, GFP_KERNEL);
1664 if (!info->pixmap.addr) {
1665 retval = -ENOMEM;
1666 goto err_exit_pixmap;
1667 }
1668 info->pixmap.size = PM2_PIXMAP_SIZE;
1669 info->pixmap.buf_align = 4;
1670 info->pixmap.scan_align = 4;
1671 info->pixmap.access_align = 32;
1672 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1673
1674 if (noaccel) {
1675 printk(KERN_DEBUG "disabling acceleration\n");
1676 info->flags |= FBINFO_HWACCEL_DISABLED;
1677 info->pixmap.scan_align = 1;
1678 }
1679
1327 if (!mode) 1680 if (!mode)
1328 mode = "640x480@60"; 1681 mode = "640x480@60";
1329 1682
@@ -1350,6 +1703,8 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1350 err_exit_all: 1703 err_exit_all:
1351 fb_dealloc_cmap(&info->cmap); 1704 fb_dealloc_cmap(&info->cmap);
1352 err_exit_both: 1705 err_exit_both:
1706 kfree(info->pixmap.addr);
1707 err_exit_pixmap:
1353 iounmap(info->screen_base); 1708 iounmap(info->screen_base);
1354 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len); 1709 release_mem_region(pm2fb_fix.smem_start, pm2fb_fix.smem_len);
1355 err_exit_mmio: 1710 err_exit_mmio:
@@ -1357,7 +1712,7 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1357 release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len); 1712 release_mem_region(pm2fb_fix.mmio_start, pm2fb_fix.mmio_len);
1358 err_exit_neither: 1713 err_exit_neither:
1359 framebuffer_release(info); 1714 framebuffer_release(info);
1360 return err_retval; 1715 return retval;
1361} 1716}
1362 1717
1363/** 1718/**
@@ -1369,34 +1724,34 @@ static int __devinit pm2fb_probe(struct pci_dev *pdev,
1369 */ 1724 */
1370static void __devexit pm2fb_remove(struct pci_dev *pdev) 1725static void __devexit pm2fb_remove(struct pci_dev *pdev)
1371{ 1726{
1372 struct fb_info* info = pci_get_drvdata(pdev); 1727 struct fb_info *info = pci_get_drvdata(pdev);
1373 struct fb_fix_screeninfo* fix = &info->fix; 1728 struct fb_fix_screeninfo *fix = &info->fix;
1374 struct pm2fb_par *par = info->par; 1729 struct pm2fb_par *par = info->par;
1375 1730
1376 unregister_framebuffer(info); 1731 unregister_framebuffer(info);
1377 1732
1733#ifdef CONFIG_MTRR
1734 if (par->mtrr_handle >= 0)
1735 mtrr_del(par->mtrr_handle, info->fix.smem_start,
1736 info->fix.smem_len);
1737#endif /* CONFIG_MTRR */
1378 iounmap(info->screen_base); 1738 iounmap(info->screen_base);
1379 release_mem_region(fix->smem_start, fix->smem_len); 1739 release_mem_region(fix->smem_start, fix->smem_len);
1380 iounmap(par->v_regs); 1740 iounmap(par->v_regs);
1381 release_mem_region(fix->mmio_start, fix->mmio_len); 1741 release_mem_region(fix->mmio_start, fix->mmio_len);
1382 1742
1383 pci_set_drvdata(pdev, NULL); 1743 pci_set_drvdata(pdev, NULL);
1744 kfree(info->pixmap.addr);
1384 kfree(info); 1745 kfree(info);
1385} 1746}
1386 1747
1387static struct pci_device_id pm2fb_id_table[] = { 1748static struct pci_device_id pm2fb_id_table[] = {
1388 { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TVP4020, 1749 { PCI_VENDOR_ID_TI, PCI_DEVICE_ID_TI_TVP4020,
1389 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, 1750 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
1390 0xff0000, 0 },
1391 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2, 1751 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2,
1392 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16, 1752 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
1393 0xff0000, 0 },
1394 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
1395 PCI_ANY_ID, PCI_ANY_ID, PCI_BASE_CLASS_DISPLAY << 16,
1396 0xff0000, 0 },
1397 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V, 1753 { PCI_VENDOR_ID_3DLABS, PCI_DEVICE_ID_3DLABS_PERMEDIA2V,
1398 PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_NOT_DEFINED_VGA << 8, 1754 PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
1399 0xff00, 0 },
1400 { 0, } 1755 { 0, }
1401}; 1756};
1402 1757
@@ -1418,7 +1773,7 @@ MODULE_DEVICE_TABLE(pci, pm2fb_id_table);
1418 */ 1773 */
1419static int __init pm2fb_setup(char *options) 1774static int __init pm2fb_setup(char *options)
1420{ 1775{
1421 char* this_opt; 1776 char *this_opt;
1422 1777
1423 if (!options || !*options) 1778 if (!options || !*options)
1424 return 0; 1779 return 0;
@@ -1426,13 +1781,20 @@ static int __init pm2fb_setup(char *options)
1426 while ((this_opt = strsep(&options, ",")) != NULL) { 1781 while ((this_opt = strsep(&options, ",")) != NULL) {
1427 if (!*this_opt) 1782 if (!*this_opt)
1428 continue; 1783 continue;
1429 if(!strcmp(this_opt, "lowhsync")) { 1784 if (!strcmp(this_opt, "lowhsync"))
1430 lowhsync = 1; 1785 lowhsync = 1;
1431 } else if(!strcmp(this_opt, "lowvsync")) { 1786 else if (!strcmp(this_opt, "lowvsync"))
1432 lowvsync = 1; 1787 lowvsync = 1;
1433 } else { 1788 else if (!strncmp(this_opt, "hwcursor=", 9))
1789 hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
1790#ifdef CONFIG_MTRR
1791 else if (!strncmp(this_opt, "nomtrr", 6))
1792 nomtrr = 1;
1793#endif
1794 else if (!strncmp(this_opt, "noaccel", 7))
1795 noaccel = 1;
1796 else
1434 mode = this_opt; 1797 mode = this_opt;
1435 }
1436 } 1798 }
1437 return 0; 1799 return 0;
1438} 1800}
@@ -1474,6 +1836,15 @@ module_param(lowhsync, bool, 0);
1474MODULE_PARM_DESC(lowhsync, "Force horizontal sync low regardless of mode"); 1836MODULE_PARM_DESC(lowhsync, "Force horizontal sync low regardless of mode");
1475module_param(lowvsync, bool, 0); 1837module_param(lowvsync, bool, 0);
1476MODULE_PARM_DESC(lowvsync, "Force vertical sync low regardless of mode"); 1838MODULE_PARM_DESC(lowvsync, "Force vertical sync low regardless of mode");
1839module_param(noaccel, bool, 0);
1840MODULE_PARM_DESC(noaccel, "Disable acceleration");
1841module_param(hwcursor, int, 0644);
1842MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
1843 "(1=enable, 0=disable, default=1)");
1844#ifdef CONFIG_MTRR
1845module_param(nomtrr, bool, 0);
1846MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
1847#endif
1477 1848
1478MODULE_AUTHOR("Jim Hague <jim.hague@acm.org>"); 1849MODULE_AUTHOR("Jim Hague <jim.hague@acm.org>");
1479MODULE_DESCRIPTION("Permedia2 framebuffer device driver"); 1850MODULE_DESCRIPTION("Permedia2 framebuffer device driver");
diff --git a/drivers/video/pm3fb.c b/drivers/video/pm3fb.c
index 5b3f54c0918e..070659992c18 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/pm3fb.c
@@ -32,6 +32,9 @@
32#include <linux/fb.h> 32#include <linux/fb.h>
33#include <linux/init.h> 33#include <linux/init.h>
34#include <linux/pci.h> 34#include <linux/pci.h>
35#ifdef CONFIG_MTRR
36#include <asm/mtrr.h>
37#endif
35 38
36#include <video/pm3fb.h> 39#include <video/pm3fb.h>
37 40
@@ -41,15 +44,25 @@
41 44
42#undef PM3FB_MASTER_DEBUG 45#undef PM3FB_MASTER_DEBUG
43#ifdef PM3FB_MASTER_DEBUG 46#ifdef PM3FB_MASTER_DEBUG
44#define DPRINTK(a,b...) printk(KERN_DEBUG "pm3fb: %s: " a, __FUNCTION__ , ## b) 47#define DPRINTK(a, b...) \
48 printk(KERN_DEBUG "pm3fb: %s: " a, __FUNCTION__ , ## b)
45#else 49#else
46#define DPRINTK(a,b...) 50#define DPRINTK(a, b...)
47#endif 51#endif
48 52
53#define PM3_PIXMAP_SIZE (2048 * 4)
54
49/* 55/*
50 * Driver data 56 * Driver data
51 */ 57 */
58static int hwcursor = 1;
52static char *mode_option __devinitdata; 59static char *mode_option __devinitdata;
60static int noaccel __devinitdata;
61
62/* mtrr option */
63#ifdef CONFIG_MTRR
64static int nomtrr __devinitdata;
65#endif
53 66
54/* 67/*
55 * This structure defines the hardware state of the graphics card. Normally 68 * This structure defines the hardware state of the graphics card. Normally
@@ -61,8 +74,9 @@ static char *mode_option __devinitdata;
61struct pm3_par { 74struct pm3_par {
62 unsigned char __iomem *v_regs;/* virtual address of p_regs */ 75 unsigned char __iomem *v_regs;/* virtual address of p_regs */
63 u32 video; /* video flags before blanking */ 76 u32 video; /* video flags before blanking */
64 u32 base; /* screen base (xoffset+yoffset) in 128 bits unit */ 77 u32 base; /* screen base in 128 bits unit */
65 u32 palette[16]; 78 u32 palette[16];
79 int mtrr_handle;
66}; 80};
67 81
68/* 82/*
@@ -96,7 +110,8 @@ static inline void PM3_WRITE_REG(struct pm3_par *par, s32 off, u32 v)
96 110
97static inline void PM3_WAIT(struct pm3_par *par, u32 n) 111static inline void PM3_WAIT(struct pm3_par *par, u32 n)
98{ 112{
99 while (PM3_READ_REG(par, PM3InFIFOSpace) < n); 113 while (PM3_READ_REG(par, PM3InFIFOSpace) < n)
114 cpu_relax();
100} 115}
101 116
102static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v) 117static inline void PM3_WRITE_DAC_REG(struct pm3_par *par, unsigned r, u8 v)
@@ -133,7 +148,7 @@ static void pm3fb_clear_colormap(struct pm3_par *par,
133 148
134} 149}
135 150
136/* Calculating various clock parameter */ 151/* Calculating various clock parameters */
137static void pm3fb_calculate_clock(unsigned long reqclock, 152static void pm3fb_calculate_clock(unsigned long reqclock,
138 unsigned char *prescale, 153 unsigned char *prescale,
139 unsigned char *feedback, 154 unsigned char *feedback,
@@ -164,7 +179,7 @@ static void pm3fb_calculate_clock(unsigned long reqclock,
164 179
165static inline int pm3fb_depth(const struct fb_var_screeninfo *var) 180static inline int pm3fb_depth(const struct fb_var_screeninfo *var)
166{ 181{
167 if ( var->bits_per_pixel == 16 ) 182 if (var->bits_per_pixel == 16)
168 return var->red.length + var->green.length 183 return var->red.length + var->green.length
169 + var->blue.length; 184 + var->blue.length;
170 185
@@ -195,8 +210,8 @@ static int pm3fb_sync(struct fb_info *info)
195 PM3_WRITE_REG(par, PM3Sync, 0); 210 PM3_WRITE_REG(par, PM3Sync, 0);
196 mb(); 211 mb();
197 do { 212 do {
198 while ((PM3_READ_REG(par, PM3OutFIFOWords)) == 0); 213 while ((PM3_READ_REG(par, PM3OutFIFOWords)) == 0)
199 rmb(); 214 cpu_relax();
200 } while ((PM3_READ_REG(par, PM3OutputFifo)) != PM3Sync_Tag); 215 } while ((PM3_READ_REG(par, PM3OutputFifo)) != PM3Sync_Tag);
201 216
202 return 0; 217 return 0;
@@ -276,15 +291,22 @@ static void pm3fb_init_engine(struct fb_info *info)
276 291
277 PM3_WAIT(par, 2); 292 PM3_WAIT(par, 2);
278 { 293 {
279 unsigned long rm = 1; 294 /* invert bits in bitmask */
295 unsigned long rm = 1 | (3 << 7);
280 switch (info->var.bits_per_pixel) { 296 switch (info->var.bits_per_pixel) {
281 case 8: 297 case 8:
282 PM3_WRITE_REG(par, PM3PixelSize, 298 PM3_WRITE_REG(par, PM3PixelSize,
283 PM3PixelSize_GLOBAL_8BIT); 299 PM3PixelSize_GLOBAL_8BIT);
300#ifdef __BIG_ENDIAN
301 rm |= 3 << 15;
302#endif
284 break; 303 break;
285 case 16: 304 case 16:
286 PM3_WRITE_REG(par, PM3PixelSize, 305 PM3_WRITE_REG(par, PM3PixelSize,
287 PM3PixelSize_GLOBAL_16BIT); 306 PM3PixelSize_GLOBAL_16BIT);
307#ifdef __BIG_ENDIAN
308 rm |= 2 << 15;
309#endif
288 break; 310 break;
289 case 32: 311 case 32:
290 PM3_WRITE_REG(par, PM3PixelSize, 312 PM3_WRITE_REG(par, PM3PixelSize,
@@ -342,7 +364,7 @@ static void pm3fb_init_engine(struct fb_info *info)
342 364
343 PM3_WRITE_REG(par, PM3dXDom, 0x0); 365 PM3_WRITE_REG(par, PM3dXDom, 0x0);
344 PM3_WRITE_REG(par, PM3dXSub, 0x0); 366 PM3_WRITE_REG(par, PM3dXSub, 0x0);
345 PM3_WRITE_REG(par, PM3dY, (1 << 16)); 367 PM3_WRITE_REG(par, PM3dY, 1 << 16);
346 PM3_WRITE_REG(par, PM3StartXDom, 0x0); 368 PM3_WRITE_REG(par, PM3StartXDom, 0x0);
347 PM3_WRITE_REG(par, PM3StartXSub, 0x0); 369 PM3_WRITE_REG(par, PM3StartXSub, 0x0);
348 PM3_WRITE_REG(par, PM3StartY, 0x0); 370 PM3_WRITE_REG(par, PM3StartY, 0x0);
@@ -357,71 +379,350 @@ static void pm3fb_init_engine(struct fb_info *info)
357 pm3fb_sync(info); 379 pm3fb_sync(info);
358} 380}
359 381
360static void pm3fb_fillrect (struct fb_info *info, 382static void pm3fb_fillrect(struct fb_info *info,
361 const struct fb_fillrect *region) 383 const struct fb_fillrect *region)
362{ 384{
363 struct pm3_par *par = info->par; 385 struct pm3_par *par = info->par;
364 struct fb_fillrect modded; 386 struct fb_fillrect modded;
365 int vxres, vyres; 387 int vxres, vyres;
388 int rop;
366 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ? 389 u32 color = (info->fix.visual == FB_VISUAL_TRUECOLOR) ?
367 ((u32*)info->pseudo_palette)[region->color] : region->color; 390 ((u32 *)info->pseudo_palette)[region->color] : region->color;
368 391
369 if (info->state != FBINFO_STATE_RUNNING) 392 if (info->state != FBINFO_STATE_RUNNING)
370 return; 393 return;
371 if ((info->flags & FBINFO_HWACCEL_DISABLED) || 394 if (info->flags & FBINFO_HWACCEL_DISABLED) {
372 region->rop != ROP_COPY ) {
373 cfb_fillrect(info, region); 395 cfb_fillrect(info, region);
374 return; 396 return;
375 } 397 }
398 if (region->rop == ROP_COPY )
399 rop = PM3Config2D_ForegroundROP(0x3); /* GXcopy */
400 else
401 rop = PM3Config2D_ForegroundROP(0x6) | /* GXxor */
402 PM3Config2D_FBDestReadEnable;
376 403
377 vxres = info->var.xres_virtual; 404 vxres = info->var.xres_virtual;
378 vyres = info->var.yres_virtual; 405 vyres = info->var.yres_virtual;
379 406
380 memcpy(&modded, region, sizeof(struct fb_fillrect)); 407 memcpy(&modded, region, sizeof(struct fb_fillrect));
381 408
382 if(!modded.width || !modded.height || 409 if (!modded.width || !modded.height ||
383 modded.dx >= vxres || modded.dy >= vyres) 410 modded.dx >= vxres || modded.dy >= vyres)
384 return; 411 return;
385 412
386 if(modded.dx + modded.width > vxres) 413 if (modded.dx + modded.width > vxres)
387 modded.width = vxres - modded.dx; 414 modded.width = vxres - modded.dx;
388 if(modded.dy + modded.height > vyres) 415 if (modded.dy + modded.height > vyres)
389 modded.height = vyres - modded.dy; 416 modded.height = vyres - modded.dy;
390 417
391 if(info->var.bits_per_pixel == 8) 418 if (info->var.bits_per_pixel == 8)
392 color |= color << 8; 419 color |= color << 8;
393 if(info->var.bits_per_pixel <= 16) 420 if (info->var.bits_per_pixel <= 16)
394 color |= color << 16; 421 color |= color << 16;
395 422
396 PM3_WAIT(par, 4); 423 PM3_WAIT(par, 4);
397 424 /* ROP Ox3 is GXcopy */
398 PM3_WRITE_REG(par, PM3Config2D, 425 PM3_WRITE_REG(par, PM3Config2D,
399 PM3Config2D_UseConstantSource | 426 PM3Config2D_UseConstantSource |
400 PM3Config2D_ForegroundROPEnable | 427 PM3Config2D_ForegroundROPEnable |
401 (PM3Config2D_ForegroundROP(0x3)) | /* Ox3 is GXcopy */ 428 rop |
402 PM3Config2D_FBWriteEnable); 429 PM3Config2D_FBWriteEnable);
403 430
404 PM3_WRITE_REG(par, PM3ForegroundColor, color); 431 PM3_WRITE_REG(par, PM3ForegroundColor, color);
405 432
406 PM3_WRITE_REG(par, PM3RectanglePosition, 433 PM3_WRITE_REG(par, PM3RectanglePosition,
407 (PM3RectanglePosition_XOffset(modded.dx)) | 434 PM3RectanglePosition_XOffset(modded.dx) |
408 (PM3RectanglePosition_YOffset(modded.dy))); 435 PM3RectanglePosition_YOffset(modded.dy));
409 436
410 PM3_WRITE_REG(par, PM3Render2D, 437 PM3_WRITE_REG(par, PM3Render2D,
411 PM3Render2D_XPositive | 438 PM3Render2D_XPositive |
412 PM3Render2D_YPositive | 439 PM3Render2D_YPositive |
413 PM3Render2D_Operation_Normal | 440 PM3Render2D_Operation_Normal |
414 PM3Render2D_SpanOperation | 441 PM3Render2D_SpanOperation |
415 (PM3Render2D_Width(modded.width)) | 442 PM3Render2D_Width(modded.width) |
416 (PM3Render2D_Height(modded.height))); 443 PM3Render2D_Height(modded.height));
444}
445
446static void pm3fb_copyarea(struct fb_info *info,
447 const struct fb_copyarea *area)
448{
449 struct pm3_par *par = info->par;
450 struct fb_copyarea modded;
451 u32 vxres, vyres;
452 int x_align, o_x, o_y;
453
454 if (info->state != FBINFO_STATE_RUNNING)
455 return;
456 if (info->flags & FBINFO_HWACCEL_DISABLED) {
457 cfb_copyarea(info, area);
458 return;
459 }
460
461 memcpy(&modded, area, sizeof(struct fb_copyarea));
462
463 vxres = info->var.xres_virtual;
464 vyres = info->var.yres_virtual;
465
466 if (!modded.width || !modded.height ||
467 modded.sx >= vxres || modded.sy >= vyres ||
468 modded.dx >= vxres || modded.dy >= vyres)
469 return;
470
471 if (modded.sx + modded.width > vxres)
472 modded.width = vxres - modded.sx;
473 if (modded.dx + modded.width > vxres)
474 modded.width = vxres - modded.dx;
475 if (modded.sy + modded.height > vyres)
476 modded.height = vyres - modded.sy;
477 if (modded.dy + modded.height > vyres)
478 modded.height = vyres - modded.dy;
479
480 o_x = modded.sx - modded.dx; /*(sx > dx ) ? (sx - dx) : (dx - sx); */
481 o_y = modded.sy - modded.dy; /*(sy > dy ) ? (sy - dy) : (dy - sy); */
482
483 x_align = (modded.sx & 0x1f);
484
485 PM3_WAIT(par, 6);
486
487 PM3_WRITE_REG(par, PM3Config2D,
488 PM3Config2D_UserScissorEnable |
489 PM3Config2D_ForegroundROPEnable |
490 PM3Config2D_Blocking |
491 PM3Config2D_ForegroundROP(0x3) | /* Ox3 is GXcopy */
492 PM3Config2D_FBWriteEnable);
493
494 PM3_WRITE_REG(par, PM3ScissorMinXY,
495 ((modded.dy & 0x0fff) << 16) | (modded.dx & 0x0fff));
496 PM3_WRITE_REG(par, PM3ScissorMaxXY,
497 (((modded.dy + modded.height) & 0x0fff) << 16) |
498 ((modded.dx + modded.width) & 0x0fff));
499
500 PM3_WRITE_REG(par, PM3FBSourceReadBufferOffset,
501 PM3FBSourceReadBufferOffset_XOffset(o_x) |
502 PM3FBSourceReadBufferOffset_YOffset(o_y));
503
504 PM3_WRITE_REG(par, PM3RectanglePosition,
505 PM3RectanglePosition_XOffset(modded.dx - x_align) |
506 PM3RectanglePosition_YOffset(modded.dy));
507
508 PM3_WRITE_REG(par, PM3Render2D,
509 ((modded.sx > modded.dx) ? PM3Render2D_XPositive : 0) |
510 ((modded.sy > modded.dy) ? PM3Render2D_YPositive : 0) |
511 PM3Render2D_Operation_Normal |
512 PM3Render2D_SpanOperation |
513 PM3Render2D_FBSourceReadEnable |
514 PM3Render2D_Width(modded.width + x_align) |
515 PM3Render2D_Height(modded.height));
516}
517
518static void pm3fb_imageblit(struct fb_info *info, const struct fb_image *image)
519{
520 struct pm3_par *par = info->par;
521 u32 height = image->height;
522 u32 fgx, bgx;
523 const u32 *src = (const u32 *)image->data;
524
525 if (info->state != FBINFO_STATE_RUNNING)
526 return;
527 if (info->flags & FBINFO_HWACCEL_DISABLED) {
528 cfb_imageblit(info, image);
529 return;
530 }
531 switch (info->fix.visual) {
532 case FB_VISUAL_PSEUDOCOLOR:
533 fgx = image->fg_color;
534 bgx = image->bg_color;
535 break;
536 case FB_VISUAL_TRUECOLOR:
537 default:
538 fgx = par->palette[image->fg_color];
539 bgx = par->palette[image->bg_color];
540 break;
541 }
542 if (image->depth != 1)
543 return cfb_imageblit(info, image);
544
545 if (info->var.bits_per_pixel == 8) {
546 fgx |= fgx << 8;
547 bgx |= bgx << 8;
548 }
549 if (info->var.bits_per_pixel <= 16) {
550 fgx |= fgx << 16;
551 bgx |= bgx << 16;
552 }
553
554 PM3_WAIT(par, 7);
555
556 PM3_WRITE_REG(par, PM3ForegroundColor, fgx);
557 PM3_WRITE_REG(par, PM3BackgroundColor, bgx);
558
559 /* ROP Ox3 is GXcopy */
560 PM3_WRITE_REG(par, PM3Config2D,
561 PM3Config2D_UserScissorEnable |
562 PM3Config2D_UseConstantSource |
563 PM3Config2D_ForegroundROPEnable |
564 PM3Config2D_ForegroundROP(0x3) |
565 PM3Config2D_OpaqueSpan |
566 PM3Config2D_FBWriteEnable);
567 PM3_WRITE_REG(par, PM3ScissorMinXY,
568 ((image->dy & 0x0fff) << 16) | (image->dx & 0x0fff));
569 PM3_WRITE_REG(par, PM3ScissorMaxXY,
570 (((image->dy + image->height) & 0x0fff) << 16) |
571 ((image->dx + image->width) & 0x0fff));
572 PM3_WRITE_REG(par, PM3RectanglePosition,
573 PM3RectanglePosition_XOffset(image->dx) |
574 PM3RectanglePosition_YOffset(image->dy));
575 PM3_WRITE_REG(par, PM3Render2D,
576 PM3Render2D_XPositive |
577 PM3Render2D_YPositive |
578 PM3Render2D_Operation_SyncOnBitMask |
579 PM3Render2D_SpanOperation |
580 PM3Render2D_Width(image->width) |
581 PM3Render2D_Height(image->height));
582
583
584 while (height--) {
585 int width = ((image->width + 7) >> 3)
586 + info->pixmap.scan_align - 1;
587 width >>= 2;
588
589 while (width >= PM3_FIFO_SIZE) {
590 int i = PM3_FIFO_SIZE - 1;
591
592 PM3_WAIT(par, PM3_FIFO_SIZE);
593 while (i--) {
594 PM3_WRITE_REG(par, PM3BitMaskPattern, *src);
595 src++;
596 }
597 width -= PM3_FIFO_SIZE - 1;
598 }
599
600 PM3_WAIT(par, width + 1);
601 while (width--) {
602 PM3_WRITE_REG(par, PM3BitMaskPattern, *src);
603 src++;
604 }
605 }
417} 606}
418/* end of acceleration functions */ 607/* end of acceleration functions */
419 608
609/*
610 * Hardware Cursor support.
611 */
612static const u8 cursor_bits_lookup[16] = {
613 0x00, 0x40, 0x10, 0x50, 0x04, 0x44, 0x14, 0x54,
614 0x01, 0x41, 0x11, 0x51, 0x05, 0x45, 0x15, 0x55
615};
616
617static int pm3fb_cursor(struct fb_info *info, struct fb_cursor *cursor)
618{
619 struct pm3_par *par = info->par;
620 u8 mode;
621
622 if (!hwcursor)
623 return -EINVAL; /* just to force soft_cursor() call */
624
625 /* Too large of a cursor or wrong bpp :-( */
626 if (cursor->image.width > 64 ||
627 cursor->image.height > 64 ||
628 cursor->image.depth > 1)
629 return -EINVAL;
630
631 mode = PM3RD_CursorMode_TYPE_X;
632 if (cursor->enable)
633 mode |= PM3RD_CursorMode_CURSOR_ENABLE;
634
635 PM3_WRITE_DAC_REG(par, PM3RD_CursorMode, mode);
636
637 /*
638 * If the cursor is not be changed this means either we want the
639 * current cursor state (if enable is set) or we want to query what
640 * we can do with the cursor (if enable is not set)
641 */
642 if (!cursor->set)
643 return 0;
644
645 if (cursor->set & FB_CUR_SETPOS) {
646 int x = cursor->image.dx - info->var.xoffset;
647 int y = cursor->image.dy - info->var.yoffset;
648
649 PM3_WRITE_DAC_REG(par, PM3RD_CursorXLow, x & 0xff);
650 PM3_WRITE_DAC_REG(par, PM3RD_CursorXHigh, (x >> 8) & 0xf);
651 PM3_WRITE_DAC_REG(par, PM3RD_CursorYLow, y & 0xff);
652 PM3_WRITE_DAC_REG(par, PM3RD_CursorYHigh, (y >> 8) & 0xf);
653 }
654
655 if (cursor->set & FB_CUR_SETHOT) {
656 PM3_WRITE_DAC_REG(par, PM3RD_CursorHotSpotX,
657 cursor->hot.x & 0x3f);
658 PM3_WRITE_DAC_REG(par, PM3RD_CursorHotSpotY,
659 cursor->hot.y & 0x3f);
660 }
661
662 if (cursor->set & FB_CUR_SETCMAP) {
663 u32 fg_idx = cursor->image.fg_color;
664 u32 bg_idx = cursor->image.bg_color;
665 struct fb_cmap cmap = info->cmap;
666
667 /* the X11 driver says one should use these color registers */
668 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(39),
669 cmap.red[fg_idx] >> 8 );
670 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(40),
671 cmap.green[fg_idx] >> 8 );
672 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(41),
673 cmap.blue[fg_idx] >> 8 );
674
675 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(42),
676 cmap.red[bg_idx] >> 8 );
677 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(43),
678 cmap.green[bg_idx] >> 8 );
679 PM3_WRITE_DAC_REG(par, PM3RD_CursorPalette(44),
680 cmap.blue[bg_idx] >> 8 );
681 }
682
683 if (cursor->set & (FB_CUR_SETSHAPE | FB_CUR_SETIMAGE)) {
684 u8 *bitmap = (u8 *)cursor->image.data;
685 u8 *mask = (u8 *)cursor->mask;
686 int i;
687 int pos = PM3RD_CursorPattern(0);
688
689 for (i = 0; i < cursor->image.height; i++) {
690 int j = (cursor->image.width + 7) >> 3;
691 int k = 8 - j;
692
693 for (; j > 0; j--) {
694 u8 data = *bitmap ^ *mask;
695
696 if (cursor->rop == ROP_COPY)
697 data = *mask & *bitmap;
698 /* Upper 4 bits of bitmap data */
699 PM3_WRITE_DAC_REG(par, pos++,
700 cursor_bits_lookup[data >> 4] |
701 (cursor_bits_lookup[*mask >> 4] << 1));
702 /* Lower 4 bits of bitmap */
703 PM3_WRITE_DAC_REG(par, pos++,
704 cursor_bits_lookup[data & 0xf] |
705 (cursor_bits_lookup[*mask & 0xf] << 1));
706 bitmap++;
707 mask++;
708 }
709 for (; k > 0; k--) {
710 PM3_WRITE_DAC_REG(par, pos++, 0);
711 PM3_WRITE_DAC_REG(par, pos++, 0);
712 }
713 }
714 while (pos < PM3RD_CursorPattern(1024))
715 PM3_WRITE_DAC_REG(par, pos++, 0);
716 }
717 return 0;
718}
719
420/* write the mode to registers */ 720/* write the mode to registers */
421static void pm3fb_write_mode(struct fb_info *info) 721static void pm3fb_write_mode(struct fb_info *info)
422{ 722{
423 struct pm3_par *par = info->par; 723 struct pm3_par *par = info->par;
424 char tempsync = 0x00, tempmisc = 0x00; 724 char tempsync = 0x00;
725 char tempmisc = 0x00;
425 const u32 hsstart = info->var.right_margin; 726 const u32 hsstart = info->var.right_margin;
426 const u32 hsend = hsstart + info->var.hsync_len; 727 const u32 hsend = hsstart + info->var.hsync_len;
427 const u32 hbend = hsend + info->var.left_margin; 728 const u32 hbend = hsend + info->var.left_margin;
@@ -618,47 +919,57 @@ static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
618 unsigned bpp = var->red.length + var->green.length 919 unsigned bpp = var->red.length + var->green.length
619 + var->blue.length + var->transp.length; 920 + var->blue.length + var->transp.length;
620 921
621 if ( bpp != var->bits_per_pixel ) { 922 if (bpp != var->bits_per_pixel) {
622 /* set predefined mode for bits_per_pixel settings */ 923 /* set predefined mode for bits_per_pixel settings */
623 924
624 switch(var->bits_per_pixel) { 925 switch (var->bits_per_pixel) {
625 case 8: 926 case 8:
626 var->red.length = var->green.length = var->blue.length = 8; 927 var->red.length = 8;
627 var->red.offset = var->green.offset = var->blue.offset = 0; 928 var->green.length = 8;
929 var->blue.length = 8;
930 var->red.offset = 0;
931 var->green.offset = 0;
932 var->blue.offset = 0;
628 var->transp.offset = 0; 933 var->transp.offset = 0;
629 var->transp.length = 0; 934 var->transp.length = 0;
630 break; 935 break;
631 case 16: 936 case 16:
632 var->red.length = var->blue.length = 5; 937 var->red.length = 5;
938 var->blue.length = 5;
633 var->green.length = 6; 939 var->green.length = 6;
634 var->transp.length = 0; 940 var->transp.length = 0;
635 break; 941 break;
636 case 32: 942 case 32:
637 var->red.length = var->green.length = var->blue.length = 8; 943 var->red.length = 8;
944 var->green.length = 8;
945 var->blue.length = 8;
638 var->transp.length = 8; 946 var->transp.length = 8;
639 break; 947 break;
640 default: 948 default:
641 DPRINTK("depth not supported: %u\n", var->bits_per_pixel); 949 DPRINTK("depth not supported: %u\n",
950 var->bits_per_pixel);
642 return -EINVAL; 951 return -EINVAL;
643 } 952 }
644 } 953 }
645 /* it is assumed BGRA order */ 954 /* it is assumed BGRA order */
646 if (var->bits_per_pixel > 8 ) 955 if (var->bits_per_pixel > 8 ) {
647 {
648 var->blue.offset = 0; 956 var->blue.offset = 0;
649 var->green.offset = var->blue.length; 957 var->green.offset = var->blue.length;
650 var->red.offset = var->green.offset + var->green.length; 958 var->red.offset = var->green.offset + var->green.length;
651 var->transp.offset = var->red.offset + var->red.length; 959 var->transp.offset = var->red.offset + var->red.length;
652 } 960 }
653 var->height = var->width = -1; 961 var->height = -1;
962 var->width = -1;
654 963
655 if (var->xres != var->xres_virtual) { 964 if (var->xres != var->xres_virtual) {
656 DPRINTK("virtual x resolution != physical x resolution not supported\n"); 965 DPRINTK("virtual x resolution != "
966 "physical x resolution not supported\n");
657 return -EINVAL; 967 return -EINVAL;
658 } 968 }
659 969
660 if (var->yres > var->yres_virtual) { 970 if (var->yres > var->yres_virtual) {
661 DPRINTK("virtual y resolution < physical y resolution not possible\n"); 971 DPRINTK("virtual y resolution < "
972 "physical y resolution not possible\n");
662 return -EINVAL; 973 return -EINVAL;
663 } 974 }
664 975
@@ -673,7 +984,7 @@ static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
673 } 984 }
674 985
675 var->xres = (var->xres + 31) & ~31; /* could sometimes be 8 */ 986 var->xres = (var->xres + 31) & ~31; /* could sometimes be 8 */
676 lpitch = var->xres * ((var->bits_per_pixel + 7)>>3); 987 lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3);
677 988
678 if (var->xres < 200 || var->xres > 2048) { 989 if (var->xres < 200 || var->xres > 2048) {
679 DPRINTK("width not supported: %u\n", var->xres); 990 DPRINTK("width not supported: %u\n", var->xres);
@@ -692,7 +1003,8 @@ static int pm3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
692 } 1003 }
693 1004
694 if (PICOS2KHZ(var->pixclock) > PM3_MAX_PIXCLOCK) { 1005 if (PICOS2KHZ(var->pixclock) > PM3_MAX_PIXCLOCK) {
695 DPRINTK("pixclock too high (%ldKHz)\n", PICOS2KHZ(var->pixclock)); 1006 DPRINTK("pixclock too high (%ldKHz)\n",
1007 PICOS2KHZ(var->pixclock));
696 return -EINVAL; 1008 return -EINVAL;
697 } 1009 }
698 1010
@@ -709,7 +1021,7 @@ static int pm3fb_set_par(struct fb_info *info)
709 const u32 xres = (info->var.xres + 31) & ~31; 1021 const u32 xres = (info->var.xres + 31) & ~31;
710 const unsigned bpp = info->var.bits_per_pixel; 1022 const unsigned bpp = info->var.bits_per_pixel;
711 1023
712 par->base = pm3fb_shift_bpp(bpp,(info->var.yoffset * xres) 1024 par->base = pm3fb_shift_bpp(bpp, (info->var.yoffset * xres)
713 + info->var.xoffset); 1025 + info->var.xoffset);
714 par->video = 0; 1026 par->video = 0;
715 1027
@@ -725,15 +1037,12 @@ static int pm3fb_set_par(struct fb_info *info)
725 1037
726 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) 1038 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE)
727 par->video |= PM3VideoControl_LINE_DOUBLE_ON; 1039 par->video |= PM3VideoControl_LINE_DOUBLE_ON;
728 else
729 par->video |= PM3VideoControl_LINE_DOUBLE_OFF;
730 1040
731 if ((info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW) 1041 if ((info->var.activate & FB_ACTIVATE_MASK) == FB_ACTIVATE_NOW)
732 par->video |= PM3VideoControl_ENABLE; 1042 par->video |= PM3VideoControl_ENABLE;
733 else { 1043 else
734 par->video |= PM3VideoControl_DISABLE;
735 DPRINTK("PM3Video disabled\n"); 1044 DPRINTK("PM3Video disabled\n");
736 } 1045
737 switch (bpp) { 1046 switch (bpp) {
738 case 8: 1047 case 8:
739 par->video |= PM3VideoControl_PIXELSIZE_8BIT; 1048 par->video |= PM3VideoControl_PIXELSIZE_8BIT;
@@ -751,13 +1060,11 @@ static int pm3fb_set_par(struct fb_info *info)
751 1060
752 info->fix.visual = 1061 info->fix.visual =
753 (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 1062 (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
754 info->fix.line_length = ((info->var.xres_virtual + 7) & ~7) 1063 info->fix.line_length = ((info->var.xres_virtual + 7) >> 3) * bpp;
755 * bpp / 8;
756 1064
757/* pm3fb_clear_memory(info, 0);*/ 1065/* pm3fb_clear_memory(info, 0);*/
758 pm3fb_clear_colormap(par, 0, 0, 0); 1066 pm3fb_clear_colormap(par, 0, 0, 0);
759 PM3_WRITE_DAC_REG(par, PM3RD_CursorMode, 1067 PM3_WRITE_DAC_REG(par, PM3RD_CursorMode, 0);
760 PM3RD_CursorMode_CURSOR_DISABLE);
761 pm3fb_init_engine(info); 1068 pm3fb_init_engine(info);
762 pm3fb_write_mode(info); 1069 pm3fb_write_mode(info);
763 return 0; 1070 return 0;
@@ -773,10 +1080,9 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
773 return -EINVAL; 1080 return -EINVAL;
774 1081
775 /* grayscale works only partially under directcolor */ 1082 /* grayscale works only partially under directcolor */
776 if (info->var.grayscale) { 1083 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
777 /* grayscale = 0.30*R + 0.59*G + 0.11*B */ 1084 if (info->var.grayscale)
778 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8; 1085 red = green = blue = (red * 77 + green * 151 + blue * 28) >> 8;
779 }
780 1086
781 /* Directcolor: 1087 /* Directcolor:
782 * var->{color}.offset contains start of bitfield 1088 * var->{color}.offset contains start of bitfield
@@ -790,8 +1096,8 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
790 * 1096 *
791 * Pseudocolor: 1097 * Pseudocolor:
792 * var->{color}.offset is 0 1098 * var->{color}.offset is 0
793 * var->{color}.length contains width of DAC or the number of unique 1099 * var->{color}.length contains width of DAC or the number
794 * colors available (color depth) 1100 * of unique colors available (color depth)
795 * pseudo_palette is not used 1101 * pseudo_palette is not used
796 * RAMDAC[X] is programmed to (red, green, blue) 1102 * RAMDAC[X] is programmed to (red, green, blue)
797 * color depth = var->{color}.length 1103 * color depth = var->{color}.length
@@ -801,7 +1107,7 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
801 * This is the point where the color is converted to something that 1107 * This is the point where the color is converted to something that
802 * is acceptable by the hardware. 1108 * is acceptable by the hardware.
803 */ 1109 */
804#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) 1110#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
805 red = CNVT_TOHW(red, info->var.red.length); 1111 red = CNVT_TOHW(red, info->var.red.length);
806 green = CNVT_TOHW(green, info->var.green.length); 1112 green = CNVT_TOHW(green, info->var.green.length);
807 blue = CNVT_TOHW(blue, info->var.blue.length); 1113 blue = CNVT_TOHW(blue, info->var.blue.length);
@@ -825,12 +1131,11 @@ static int pm3fb_setcolreg(unsigned regno, unsigned red, unsigned green,
825 break; 1131 break;
826 case 16: 1132 case 16:
827 case 32: 1133 case 32:
828 ((u32*)(info->pseudo_palette))[regno] = v; 1134 ((u32 *)(info->pseudo_palette))[regno] = v;
829 break; 1135 break;
830 } 1136 }
831 return 0; 1137 return 0;
832 } 1138 } else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
833 else if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR)
834 pm3fb_set_color(par, regno, red, green, blue); 1139 pm3fb_set_color(par, regno, red, green, blue);
835 1140
836 return 0; 1141 return 0;
@@ -871,7 +1176,7 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)
871 video |= PM3VideoControl_ENABLE; 1176 video |= PM3VideoControl_ENABLE;
872 break; 1177 break;
873 case FB_BLANK_NORMAL: 1178 case FB_BLANK_NORMAL:
874 video &= ~(PM3VideoControl_ENABLE); 1179 video &= ~PM3VideoControl_ENABLE;
875 break; 1180 break;
876 case FB_BLANK_HSYNC_SUSPEND: 1181 case FB_BLANK_HSYNC_SUSPEND:
877 video &= ~(PM3VideoControl_HSYNC_MASK | 1182 video &= ~(PM3VideoControl_HSYNC_MASK |
@@ -892,7 +1197,7 @@ static int pm3fb_blank(int blank_mode, struct fb_info *info)
892 } 1197 }
893 1198
894 PM3_WAIT(par, 1); 1199 PM3_WAIT(par, 1);
895 PM3_WRITE_REG(par,PM3VideoControl, video); 1200 PM3_WRITE_REG(par, PM3VideoControl, video);
896 return 0; 1201 return 0;
897} 1202}
898 1203
@@ -907,10 +1212,11 @@ static struct fb_ops pm3fb_ops = {
907 .fb_setcolreg = pm3fb_setcolreg, 1212 .fb_setcolreg = pm3fb_setcolreg,
908 .fb_pan_display = pm3fb_pan_display, 1213 .fb_pan_display = pm3fb_pan_display,
909 .fb_fillrect = pm3fb_fillrect, 1214 .fb_fillrect = pm3fb_fillrect,
910 .fb_copyarea = cfb_copyarea, 1215 .fb_copyarea = pm3fb_copyarea,
911 .fb_imageblit = cfb_imageblit, 1216 .fb_imageblit = pm3fb_imageblit,
912 .fb_blank = pm3fb_blank, 1217 .fb_blank = pm3fb_blank,
913 .fb_sync = pm3fb_sync, 1218 .fb_sync = pm3fb_sync,
1219 .fb_cursor = pm3fb_cursor,
914}; 1220};
915 1221
916/* ------------------------------------------------------------------------- */ 1222/* ------------------------------------------------------------------------- */
@@ -923,7 +1229,8 @@ static struct fb_ops pm3fb_ops = {
923/* the pm3fb_fix.smem_start is also set */ 1229/* the pm3fb_fix.smem_start is also set */
924static unsigned long pm3fb_size_memory(struct pm3_par *par) 1230static unsigned long pm3fb_size_memory(struct pm3_par *par)
925{ 1231{
926 unsigned long memsize = 0, tempBypass, i, temp1, temp2; 1232 unsigned long memsize = 0;
1233 unsigned long tempBypass, i, temp1, temp2;
927 unsigned char __iomem *screen_mem; 1234 unsigned char __iomem *screen_mem;
928 1235
929 pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */ 1236 pm3fb_fix.smem_len = 64 * 1024l * 1024; /* request full aperture size */
@@ -951,7 +1258,9 @@ static unsigned long pm3fb_size_memory(struct pm3_par *par)
951 PM3_WAIT(par, 1); 1258 PM3_WAIT(par, 1);
952 PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF); 1259 PM3_WRITE_REG(par, PM3MemBypassWriteMask, 0xFFFFFFFF);
953 1260
954 /* pm3 split up memory, replicates, and do a lot of nasty stuff IMHO ;-) */ 1261 /* pm3 split up memory, replicates, and do a lot of
1262 * nasty stuff IMHO ;-)
1263 */
955 for (i = 0; i < 32; i++) { 1264 for (i = 0; i < 32; i++) {
956 fb_writel(i * 0x00345678, 1265 fb_writel(i * 0x00345678,
957 (screen_mem + (i * 1048576))); 1266 (screen_mem + (i * 1048576)));
@@ -1008,8 +1317,9 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1008{ 1317{
1009 struct fb_info *info; 1318 struct fb_info *info;
1010 struct pm3_par *par; 1319 struct pm3_par *par;
1011 struct device* device = &dev->dev; /* for pci drivers */ 1320 struct device *device = &dev->dev; /* for pci drivers */
1012 int err, retval = -ENXIO; 1321 int err;
1322 int retval = -ENXIO;
1013 1323
1014 err = pci_enable_device(dev); 1324 err = pci_enable_device(dev);
1015 if (err) { 1325 if (err) {
@@ -1031,6 +1341,10 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1031 */ 1341 */
1032 pm3fb_fix.mmio_start = pci_resource_start(dev, 0); 1342 pm3fb_fix.mmio_start = pci_resource_start(dev, 0);
1033 pm3fb_fix.mmio_len = PM3_REGS_SIZE; 1343 pm3fb_fix.mmio_len = PM3_REGS_SIZE;
1344#if defined(__BIG_ENDIAN)
1345 pm3fb_fix.mmio_start += PM3_REGS_SIZE;
1346 DPRINTK("Adjusting register base for big-endian.\n");
1347#endif
1034 1348
1035 /* Registers - request region and map it. */ 1349 /* Registers - request region and map it. */
1036 if (!request_mem_region(pm3fb_fix.mmio_start, pm3fb_fix.mmio_len, 1350 if (!request_mem_region(pm3fb_fix.mmio_start, pm3fb_fix.mmio_len,
@@ -1047,15 +1361,10 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1047 goto err_exit_neither; 1361 goto err_exit_neither;
1048 } 1362 }
1049 1363
1050#if defined(__BIG_ENDIAN)
1051 pm3fb_fix.mmio_start += PM3_REGS_SIZE;
1052 DPRINTK("Adjusting register base for big-endian.\n");
1053#endif
1054 /* Linear frame buffer - request region and map it. */ 1364 /* Linear frame buffer - request region and map it. */
1055 pm3fb_fix.smem_start = pci_resource_start(dev, 1); 1365 pm3fb_fix.smem_start = pci_resource_start(dev, 1);
1056 pm3fb_fix.smem_len = pm3fb_size_memory(par); 1366 pm3fb_fix.smem_len = pm3fb_size_memory(par);
1057 if (!pm3fb_fix.smem_len) 1367 if (!pm3fb_fix.smem_len) {
1058 {
1059 printk(KERN_WARNING "pm3fb: Can't find memory on board.\n"); 1368 printk(KERN_WARNING "pm3fb: Can't find memory on board.\n");
1060 goto err_exit_mmio; 1369 goto err_exit_mmio;
1061 } 1370 }
@@ -1073,6 +1382,12 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1073 } 1382 }
1074 info->screen_size = pm3fb_fix.smem_len; 1383 info->screen_size = pm3fb_fix.smem_len;
1075 1384
1385#ifdef CONFIG_MTRR
1386 if (!nomtrr)
1387 par->mtrr_handle = mtrr_add(pm3fb_fix.smem_start,
1388 pm3fb_fix.smem_len,
1389 MTRR_TYPE_WRCOMB, 1);
1390#endif
1076 info->fbops = &pm3fb_ops; 1391 info->fbops = &pm3fb_ops;
1077 1392
1078 par->video = PM3_READ_REG(par, PM3VideoControl); 1393 par->video = PM3_READ_REG(par, PM3VideoControl);
@@ -1080,7 +1395,26 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1080 info->fix = pm3fb_fix; 1395 info->fix = pm3fb_fix;
1081 info->pseudo_palette = par->palette; 1396 info->pseudo_palette = par->palette;
1082 info->flags = FBINFO_DEFAULT | 1397 info->flags = FBINFO_DEFAULT |
1083 FBINFO_HWACCEL_FILLRECT;/* | FBINFO_HWACCEL_YPAN;*/ 1398 FBINFO_HWACCEL_XPAN |
1399 FBINFO_HWACCEL_YPAN |
1400 FBINFO_HWACCEL_COPYAREA |
1401 FBINFO_HWACCEL_IMAGEBLIT |
1402 FBINFO_HWACCEL_FILLRECT;
1403
1404 if (noaccel) {
1405 printk(KERN_DEBUG "disabling acceleration\n");
1406 info->flags |= FBINFO_HWACCEL_DISABLED;
1407 }
1408 info->pixmap.addr = kmalloc(PM3_PIXMAP_SIZE, GFP_KERNEL);
1409 if (!info->pixmap.addr) {
1410 retval = -ENOMEM;
1411 goto err_exit_pixmap;
1412 }
1413 info->pixmap.size = PM3_PIXMAP_SIZE;
1414 info->pixmap.buf_align = 4;
1415 info->pixmap.scan_align = 4;
1416 info->pixmap.access_align = 32;
1417 info->pixmap.flags = FB_PIXMAP_SYSTEM;
1084 1418
1085 /* 1419 /*
1086 * This should give a reasonable default video mode. The following is 1420 * This should give a reasonable default video mode. The following is
@@ -1118,6 +1452,8 @@ static int __devinit pm3fb_probe(struct pci_dev *dev,
1118 err_exit_all: 1452 err_exit_all:
1119 fb_dealloc_cmap(&info->cmap); 1453 fb_dealloc_cmap(&info->cmap);
1120 err_exit_both: 1454 err_exit_both:
1455 kfree(info->pixmap.addr);
1456 err_exit_pixmap:
1121 iounmap(info->screen_base); 1457 iounmap(info->screen_base);
1122 release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len); 1458 release_mem_region(pm3fb_fix.smem_start, pm3fb_fix.smem_len);
1123 err_exit_mmio: 1459 err_exit_mmio:
@@ -1142,12 +1478,18 @@ static void __devexit pm3fb_remove(struct pci_dev *dev)
1142 unregister_framebuffer(info); 1478 unregister_framebuffer(info);
1143 fb_dealloc_cmap(&info->cmap); 1479 fb_dealloc_cmap(&info->cmap);
1144 1480
1481#ifdef CONFIG_MTRR
1482 if (par->mtrr_handle >= 0)
1483 mtrr_del(par->mtrr_handle, info->fix.smem_start,
1484 info->fix.smem_len);
1485#endif /* CONFIG_MTRR */
1145 iounmap(info->screen_base); 1486 iounmap(info->screen_base);
1146 release_mem_region(fix->smem_start, fix->smem_len); 1487 release_mem_region(fix->smem_start, fix->smem_len);
1147 iounmap(par->v_regs); 1488 iounmap(par->v_regs);
1148 release_mem_region(fix->mmio_start, fix->mmio_len); 1489 release_mem_region(fix->mmio_start, fix->mmio_len);
1149 1490
1150 pci_set_drvdata(dev, NULL); 1491 pci_set_drvdata(dev, NULL);
1492 kfree(info->pixmap.addr);
1151 framebuffer_release(info); 1493 framebuffer_release(info);
1152 } 1494 }
1153} 1495}
@@ -1168,21 +1510,76 @@ static struct pci_driver pm3fb_driver = {
1168 1510
1169MODULE_DEVICE_TABLE(pci, pm3fb_id_table); 1511MODULE_DEVICE_TABLE(pci, pm3fb_id_table);
1170 1512
1513#ifndef MODULE
1514 /*
1515 * Setup
1516 */
1517
1518/*
1519 * Only necessary if your driver takes special options,
1520 * otherwise we fall back on the generic fb_setup().
1521 */
1522static int __init pm3fb_setup(char *options)
1523{
1524 char *this_opt;
1525
1526 /* Parse user speficied options (`video=pm3fb:') */
1527 if (!options || !*options)
1528 return 0;
1529
1530 while ((this_opt = strsep(&options, ",")) != NULL) {
1531 if (!*this_opt)
1532 continue;
1533 else if (!strncmp(this_opt, "noaccel", 7))
1534 noaccel = 1;
1535 else if (!strncmp(this_opt, "hwcursor=", 9))
1536 hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
1537#ifdef CONFIG_MTRR
1538 else if (!strncmp(this_opt, "nomtrr", 6))
1539 nomtrr = 1;
1540#endif
1541 else
1542 mode_option = this_opt;
1543 }
1544 return 0;
1545}
1546#endif /* MODULE */
1547
1171static int __init pm3fb_init(void) 1548static int __init pm3fb_init(void)
1172{ 1549{
1550 /*
1551 * For kernel boot options (in 'video=pm3fb:<options>' format)
1552 */
1173#ifndef MODULE 1553#ifndef MODULE
1174 if (fb_get_options("pm3fb", NULL)) 1554 char *option = NULL;
1555
1556 if (fb_get_options("pm3fb", &option))
1175 return -ENODEV; 1557 return -ENODEV;
1558 pm3fb_setup(option);
1176#endif 1559#endif
1560
1177 return pci_register_driver(&pm3fb_driver); 1561 return pci_register_driver(&pm3fb_driver);
1178} 1562}
1179 1563
1564#ifdef MODULE
1180static void __exit pm3fb_exit(void) 1565static void __exit pm3fb_exit(void)
1181{ 1566{
1182 pci_unregister_driver(&pm3fb_driver); 1567 pci_unregister_driver(&pm3fb_driver);
1183} 1568}
1184 1569
1185module_init(pm3fb_init);
1186module_exit(pm3fb_exit); 1570module_exit(pm3fb_exit);
1571#endif
1572module_init(pm3fb_init);
1573
1574module_param(noaccel, bool, 0);
1575MODULE_PARM_DESC(noaccel, "Disable acceleration");
1576module_param(hwcursor, int, 0644);
1577MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
1578 "(1=enable, 0=disable, default=1)");
1579#ifdef CONFIG_MTRR
1580module_param(nomtrr, bool, 0);
1581MODULE_PARM_DESC(nomtrr, "Disable MTRR support (0 or 1=disabled) (default=0)");
1582#endif
1187 1583
1584MODULE_DESCRIPTION("Permedia3 framebuffer device driver");
1188MODULE_LICENSE("GPL"); 1585MODULE_LICENSE("GPL");
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/pmag-ba-fb.c
index 264d37243fad..3a3f80f65219 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/pmag-ba-fb.c
@@ -147,16 +147,23 @@ static int __init pmagbafb_probe(struct device *dev)
147 resource_size_t start, len; 147 resource_size_t start, len;
148 struct fb_info *info; 148 struct fb_info *info;
149 struct pmagbafb_par *par; 149 struct pmagbafb_par *par;
150 int err;
150 151
151 info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev); 152 info = framebuffer_alloc(sizeof(struct pmagbafb_par), dev);
152 if (!info) 153 if (!info) {
154 printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
153 return -ENOMEM; 155 return -ENOMEM;
156 }
154 157
155 par = info->par; 158 par = info->par;
156 dev_set_drvdata(dev, info); 159 dev_set_drvdata(dev, info);
157 160
158 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) 161 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
162 printk(KERN_ERR "%s: Cannot allocate color map\n",
163 dev->bus_id);
164 err = -ENOMEM;
159 goto err_alloc; 165 goto err_alloc;
166 }
160 167
161 info->fbops = &pmagbafb_ops; 168 info->fbops = &pmagbafb_ops;
162 info->fix = pmagbafb_fix; 169 info->fix = pmagbafb_fix;
@@ -166,28 +173,41 @@ static int __init pmagbafb_probe(struct device *dev)
166 /* Request the I/O MEM resource. */ 173 /* Request the I/O MEM resource. */
167 start = tdev->resource.start; 174 start = tdev->resource.start;
168 len = tdev->resource.end - start + 1; 175 len = tdev->resource.end - start + 1;
169 if (!request_mem_region(start, len, dev->bus_id)) 176 if (!request_mem_region(start, len, dev->bus_id)) {
177 printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
178 err = -EBUSY;
170 goto err_cmap; 179 goto err_cmap;
180 }
171 181
172 /* MMIO mapping setup. */ 182 /* MMIO mapping setup. */
173 info->fix.mmio_start = start; 183 info->fix.mmio_start = start;
174 par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); 184 par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
175 if (!par->mmio) 185 if (!par->mmio) {
186 printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
187 err = -ENOMEM;
176 goto err_resource; 188 goto err_resource;
189 }
177 par->dac = par->mmio + PMAG_BA_BT459; 190 par->dac = par->mmio + PMAG_BA_BT459;
178 191
179 /* Frame buffer mapping setup. */ 192 /* Frame buffer mapping setup. */
180 info->fix.smem_start = start + PMAG_BA_FBMEM; 193 info->fix.smem_start = start + PMAG_BA_FBMEM;
181 info->screen_base = ioremap_nocache(info->fix.smem_start, 194 info->screen_base = ioremap_nocache(info->fix.smem_start,
182 info->fix.smem_len); 195 info->fix.smem_len);
183 if (!info->screen_base) 196 if (!info->screen_base) {
197 printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
198 err = -ENOMEM;
184 goto err_mmio_map; 199 goto err_mmio_map;
200 }
185 info->screen_size = info->fix.smem_len; 201 info->screen_size = info->fix.smem_len;
186 202
187 pmagbafb_erase_cursor(info); 203 pmagbafb_erase_cursor(info);
188 204
189 if (register_framebuffer(info) < 0) 205 err = register_framebuffer(info);
206 if (err < 0) {
207 printk(KERN_ERR "%s: Cannot register framebuffer\n",
208 dev->bus_id);
190 goto err_smem_map; 209 goto err_smem_map;
210 }
191 211
192 get_device(dev); 212 get_device(dev);
193 213
@@ -211,7 +231,7 @@ err_cmap:
211 231
212err_alloc: 232err_alloc:
213 framebuffer_release(info); 233 framebuffer_release(info);
214 return -ENXIO; 234 return err;
215} 235}
216 236
217static int __exit pmagbafb_remove(struct device *dev) 237static int __exit pmagbafb_remove(struct device *dev)
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/pmagb-b-fb.c
index 7a0ce7d5af6b..9b80597241b0 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/pmagb-b-fb.c
@@ -254,16 +254,23 @@ static int __init pmagbbfb_probe(struct device *dev)
254 struct pmagbbfb_par *par; 254 struct pmagbbfb_par *par;
255 char freq0[12], freq1[12]; 255 char freq0[12], freq1[12];
256 u32 vid_base; 256 u32 vid_base;
257 int err;
257 258
258 info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev); 259 info = framebuffer_alloc(sizeof(struct pmagbbfb_par), dev);
259 if (!info) 260 if (!info) {
261 printk(KERN_ERR "%s: Cannot allocate memory\n", dev->bus_id);
260 return -ENOMEM; 262 return -ENOMEM;
263 }
261 264
262 par = info->par; 265 par = info->par;
263 dev_set_drvdata(dev, info); 266 dev_set_drvdata(dev, info);
264 267
265 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) 268 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
269 printk(KERN_ERR "%s: Cannot allocate color map\n",
270 dev->bus_id);
271 err = -ENOMEM;
266 goto err_alloc; 272 goto err_alloc;
273 }
267 274
268 info->fbops = &pmagbbfb_ops; 275 info->fbops = &pmagbbfb_ops;
269 info->fix = pmagbbfb_fix; 276 info->fix = pmagbbfb_fix;
@@ -273,22 +280,31 @@ static int __init pmagbbfb_probe(struct device *dev)
273 /* Request the I/O MEM resource. */ 280 /* Request the I/O MEM resource. */
274 start = tdev->resource.start; 281 start = tdev->resource.start;
275 len = tdev->resource.end - start + 1; 282 len = tdev->resource.end - start + 1;
276 if (!request_mem_region(start, len, dev->bus_id)) 283 if (!request_mem_region(start, len, dev->bus_id)) {
284 printk(KERN_ERR "%s: Cannot reserve FB region\n", dev->bus_id);
285 err = -EBUSY;
277 goto err_cmap; 286 goto err_cmap;
287 }
278 288
279 /* MMIO mapping setup. */ 289 /* MMIO mapping setup. */
280 info->fix.mmio_start = start; 290 info->fix.mmio_start = start;
281 par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len); 291 par->mmio = ioremap_nocache(info->fix.mmio_start, info->fix.mmio_len);
282 if (!par->mmio) 292 if (!par->mmio) {
293 printk(KERN_ERR "%s: Cannot map MMIO\n", dev->bus_id);
294 err = -ENOMEM;
283 goto err_resource; 295 goto err_resource;
296 }
284 par->sfb = par->mmio + PMAGB_B_SFB; 297 par->sfb = par->mmio + PMAGB_B_SFB;
285 par->dac = par->mmio + PMAGB_B_BT459; 298 par->dac = par->mmio + PMAGB_B_BT459;
286 299
287 /* Frame buffer mapping setup. */ 300 /* Frame buffer mapping setup. */
288 info->fix.smem_start = start + PMAGB_B_FBMEM; 301 info->fix.smem_start = start + PMAGB_B_FBMEM;
289 par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len); 302 par->smem = ioremap_nocache(info->fix.smem_start, info->fix.smem_len);
290 if (!par->smem) 303 if (!par->smem) {
304 printk(KERN_ERR "%s: Cannot map FB\n", dev->bus_id);
305 err = -ENOMEM;
291 goto err_mmio_map; 306 goto err_mmio_map;
307 }
292 vid_base = sfb_read(par, SFB_REG_VID_BASE); 308 vid_base = sfb_read(par, SFB_REG_VID_BASE);
293 info->screen_base = (void __iomem *)par->smem + vid_base * 0x1000; 309 info->screen_base = (void __iomem *)par->smem + vid_base * 0x1000;
294 info->screen_size = info->fix.smem_len - 2 * vid_base * 0x1000; 310 info->screen_size = info->fix.smem_len - 2 * vid_base * 0x1000;
@@ -297,8 +313,12 @@ static int __init pmagbbfb_probe(struct device *dev)
297 pmagbbfb_screen_setup(info); 313 pmagbbfb_screen_setup(info);
298 pmagbbfb_osc_setup(info); 314 pmagbbfb_osc_setup(info);
299 315
300 if (register_framebuffer(info) < 0) 316 err = register_framebuffer(info);
317 if (err < 0) {
318 printk(KERN_ERR "%s: Cannot register framebuffer\n",
319 dev->bus_id);
301 goto err_smem_map; 320 goto err_smem_map;
321 }
302 322
303 get_device(dev); 323 get_device(dev);
304 324
@@ -330,7 +350,7 @@ err_cmap:
330 350
331err_alloc: 351err_alloc:
332 framebuffer_release(info); 352 framebuffer_release(info);
333 return -ENXIO; 353 return err;
334} 354}
335 355
336static int __exit pmagbbfb_remove(struct device *dev) 356static int __exit pmagbbfb_remove(struct device *dev)
diff --git a/drivers/video/pnx4008/pnxrgbfb.c b/drivers/video/pnx4008/pnxrgbfb.c
index f29e66e2d774..685761a0732c 100644
--- a/drivers/video/pnx4008/pnxrgbfb.c
+++ b/drivers/video/pnx4008/pnxrgbfb.c
@@ -26,7 +26,6 @@
26#include <linux/init.h> 26#include <linux/init.h>
27#include <linux/platform_device.h> 27#include <linux/platform_device.h>
28 28
29#include <asm/uaccess.h>
30#include "sdum.h" 29#include "sdum.h"
31#include "fbcommon.h" 30#include "fbcommon.h"
32 31
diff --git a/drivers/video/ps3fb.c b/drivers/video/ps3fb.c
index 646ec823c168..b3463ddcfd60 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/ps3fb.c
@@ -22,22 +22,14 @@
22#include <linux/errno.h> 22#include <linux/errno.h>
23#include <linux/string.h> 23#include <linux/string.h>
24#include <linux/mm.h> 24#include <linux/mm.h>
25#include <linux/tty.h>
26#include <linux/slab.h>
27#include <linux/vmalloc.h>
28#include <linux/delay.h>
29#include <linux/interrupt.h> 25#include <linux/interrupt.h>
30#include <linux/console.h> 26#include <linux/console.h>
31#include <linux/ioctl.h> 27#include <linux/ioctl.h>
32#include <linux/notifier.h>
33#include <linux/reboot.h>
34#include <linux/kthread.h> 28#include <linux/kthread.h>
35#include <linux/freezer.h> 29#include <linux/freezer.h>
36 30#include <linux/uaccess.h>
37#include <asm/uaccess.h>
38#include <linux/fb.h> 31#include <linux/fb.h>
39#include <linux/init.h> 32#include <linux/init.h>
40#include <asm/time.h>
41 33
42#include <asm/abs_addr.h> 34#include <asm/abs_addr.h>
43#include <asm/lv1call.h> 35#include <asm/lv1call.h>
@@ -48,12 +40,6 @@
48 40
49#define DEVICE_NAME "ps3fb" 41#define DEVICE_NAME "ps3fb"
50 42
51#ifdef PS3FB_DEBUG
52#define DPRINTK(fmt, args...) printk("%s: " fmt, __func__ , ##args)
53#else
54#define DPRINTK(fmt, args...)
55#endif
56
57#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101 43#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC 0x101
58#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102 44#define L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP 0x102
59#define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600 45#define L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP 0x600
@@ -66,8 +52,10 @@
66#define L1GPU_DISPLAY_SYNC_VSYNC 2 52#define L1GPU_DISPLAY_SYNC_VSYNC 2
67 53
68#define DDR_SIZE (0) /* used no ddr */ 54#define DDR_SIZE (0) /* used no ddr */
69#define GPU_OFFSET (64 * 1024) 55#define GPU_CMD_BUF_SIZE (64 * 1024)
70#define GPU_IOIF (0x0d000000UL) 56#define GPU_IOIF (0x0d000000UL)
57#define GPU_ALIGN_UP(x) _ALIGN_UP((x), 64)
58#define GPU_MAX_LINE_LENGTH (65536 - 64)
71 59
72#define PS3FB_FULL_MODE_BIT 0x80 60#define PS3FB_FULL_MODE_BIT 0x80
73 61
@@ -131,13 +119,12 @@ struct ps3fb_priv {
131 119
132 u64 context_handle, memory_handle; 120 u64 context_handle, memory_handle;
133 void *xdr_ea; 121 void *xdr_ea;
122 size_t xdr_size;
134 struct gpu_driver_info *dinfo; 123 struct gpu_driver_info *dinfo;
135 u32 res_index;
136 124
137 u64 vblank_count; /* frame count */ 125 u64 vblank_count; /* frame count */
138 wait_queue_head_t wait_vsync; 126 wait_queue_head_t wait_vsync;
139 127
140 u32 num_frames; /* num of frame buffers */
141 atomic_t ext_flip; /* on/off flip with vsync */ 128 atomic_t ext_flip; /* on/off flip with vsync */
142 atomic_t f_count; /* fb_open count */ 129 atomic_t f_count; /* fb_open count */
143 int is_blanked; 130 int is_blanked;
@@ -146,6 +133,18 @@ struct ps3fb_priv {
146}; 133};
147static struct ps3fb_priv ps3fb; 134static struct ps3fb_priv ps3fb;
148 135
136struct ps3fb_par {
137 u32 pseudo_palette[16];
138 int mode_id, new_mode_id;
139 int res_index;
140 unsigned int num_frames; /* num of frame buffers */
141 unsigned int width;
142 unsigned int height;
143 unsigned long full_offset; /* start of fullscreen DDR fb */
144 unsigned long fb_offset; /* start of actual DDR fb */
145 unsigned long pan_offset;
146};
147
149struct ps3fb_res_table { 148struct ps3fb_res_table {
150 u32 xres; 149 u32 xres;
151 u32 yres; 150 u32 yres;
@@ -294,29 +293,31 @@ static const struct fb_videomode ps3fb_modedb[] = {
294#define Y_OFF(i) (ps3fb_res[i].yoff) /* top/bottom margin (pixel) */ 293#define Y_OFF(i) (ps3fb_res[i].yoff) /* top/bottom margin (pixel) */
295#define WIDTH(i) (ps3fb_res[i].xres) /* width of FB */ 294#define WIDTH(i) (ps3fb_res[i].xres) /* width of FB */
296#define HEIGHT(i) (ps3fb_res[i].yres) /* height of FB */ 295#define HEIGHT(i) (ps3fb_res[i].yres) /* height of FB */
297#define BPP 4 /* number of bytes per pixel */ 296#define BPP 4 /* number of bytes per pixel */
298#define VP_OFF(i) (WIDTH(i) * Y_OFF(i) * BPP + X_OFF(i) * BPP) 297
299#define FB_OFF(i) (GPU_OFFSET - VP_OFF(i) % GPU_OFFSET) 298/* Start of the virtual frame buffer (relative to fullscreen ) */
299#define VP_OFF(i) ((WIDTH(i) * Y_OFF(i) + X_OFF(i)) * BPP)
300
300 301
301static int ps3fb_mode; 302static int ps3fb_mode;
302module_param(ps3fb_mode, int, 0); 303module_param(ps3fb_mode, int, 0);
303 304
304static char *mode_option __devinitdata; 305static char *mode_option __devinitdata;
305 306
306static int ps3fb_get_res_table(u32 xres, u32 yres) 307static int ps3fb_get_res_table(u32 xres, u32 yres, int mode)
307{ 308{
308 int full_mode; 309 int full_mode;
309 unsigned int i; 310 unsigned int i;
310 u32 x, y, f; 311 u32 x, y, f;
311 312
312 full_mode = (ps3fb_mode & PS3FB_FULL_MODE_BIT) ? PS3FB_RES_FULL : 0; 313 full_mode = (mode & PS3FB_FULL_MODE_BIT) ? PS3FB_RES_FULL : 0;
313 for (i = 0;; i++) { 314 for (i = 0;; i++) {
314 x = ps3fb_res[i].xres; 315 x = ps3fb_res[i].xres;
315 y = ps3fb_res[i].yres; 316 y = ps3fb_res[i].yres;
316 f = ps3fb_res[i].type; 317 f = ps3fb_res[i].type;
317 318
318 if (!x) { 319 if (!x) {
319 DPRINTK("ERROR: ps3fb_get_res_table()\n"); 320 pr_debug("ERROR: ps3fb_get_res_table()\n");
320 return -1; 321 return -1;
321 } 322 }
322 323
@@ -335,7 +336,7 @@ static int ps3fb_get_res_table(u32 xres, u32 yres)
335} 336}
336 337
337static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var, 338static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var,
338 u32 *line_length) 339 u32 *ddr_line_length, u32 *xdr_line_length)
339{ 340{
340 unsigned int i, mode; 341 unsigned int i, mode;
341 342
@@ -350,31 +351,41 @@ static unsigned int ps3fb_find_mode(const struct fb_var_screeninfo *var,
350 var->upper_margin == ps3fb_modedb[i].upper_margin && 351 var->upper_margin == ps3fb_modedb[i].upper_margin &&
351 var->lower_margin == ps3fb_modedb[i].lower_margin && 352 var->lower_margin == ps3fb_modedb[i].lower_margin &&
352 var->sync == ps3fb_modedb[i].sync && 353 var->sync == ps3fb_modedb[i].sync &&
353 (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode) { 354 (var->vmode & FB_VMODE_MASK) == ps3fb_modedb[i].vmode)
354 /* Cropped broadcast modes use the full line_length */ 355 goto found;
355 *line_length =
356 ps3fb_modedb[i < 10 ? i + 13 : i].xres * 4;
357 /* Full broadcast modes have the full mode bit set */
358 mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1;
359
360 DPRINTK("ps3fb_find_mode: mode %u\n", mode);
361 return mode;
362 }
363 356
364 DPRINTK("ps3fb_find_mode: mode not found\n"); 357 pr_debug("ps3fb_find_mode: mode not found\n");
365 return 0; 358 return 0;
366 359
360found:
361 /* Cropped broadcast modes use the full line length */
362 *ddr_line_length = ps3fb_modedb[i < 10 ? i + 13 : i].xres * BPP;
363
364 if (ps3_compare_firmware_version(1, 9, 0) >= 0) {
365 *xdr_line_length = GPU_ALIGN_UP(max(var->xres,
366 var->xres_virtual) * BPP);
367 if (*xdr_line_length > GPU_MAX_LINE_LENGTH)
368 *xdr_line_length = GPU_MAX_LINE_LENGTH;
369 } else
370 *xdr_line_length = *ddr_line_length;
371
372 /* Full broadcast modes have the full mode bit set */
373 mode = i > 12 ? (i - 12) | PS3FB_FULL_MODE_BIT : i + 1;
374
375 pr_debug("ps3fb_find_mode: mode %u\n", mode);
376
377 return mode;
367} 378}
368 379
369static const struct fb_videomode *ps3fb_default_mode(void) 380static const struct fb_videomode *ps3fb_default_mode(int id)
370{ 381{
371 u32 mode = ps3fb_mode & PS3AV_MODE_MASK; 382 u32 mode = id & PS3AV_MODE_MASK;
372 u32 flags; 383 u32 flags;
373 384
374 if (mode < 1 || mode > 13) 385 if (mode < 1 || mode > 13)
375 return NULL; 386 return NULL;
376 387
377 flags = ps3fb_mode & ~PS3AV_MODE_MASK; 388 flags = id & ~PS3AV_MODE_MASK;
378 389
379 if (mode <= 10 && flags & PS3FB_FULL_MODE_BIT) { 390 if (mode <= 10 && flags & PS3FB_FULL_MODE_BIT) {
380 /* Full broadcast mode */ 391 /* Full broadcast mode */
@@ -384,55 +395,77 @@ static const struct fb_videomode *ps3fb_default_mode(void)
384 return &ps3fb_modedb[mode - 1]; 395 return &ps3fb_modedb[mode - 1];
385} 396}
386 397
387static int ps3fb_sync(u32 frame) 398static void ps3fb_sync_image(struct device *dev, u64 frame_offset,
399 u64 dst_offset, u64 src_offset, u32 width,
400 u32 height, u32 dst_line_length,
401 u32 src_line_length)
388{ 402{
389 int i, status; 403 int status;
390 u32 xres, yres; 404 u64 line_length;
391 u64 fb_ioif, offset;
392
393 i = ps3fb.res_index;
394 xres = ps3fb_res[i].xres;
395 yres = ps3fb_res[i].yres;
396 405
397 if (frame > ps3fb.num_frames - 1) { 406 line_length = dst_line_length;
398 printk(KERN_WARNING "%s: invalid frame number (%u)\n", 407 if (src_line_length != dst_line_length)
399 __func__, frame); 408 line_length |= (u64)src_line_length << 32;
400 return -EINVAL;
401 }
402 offset = xres * yres * BPP * frame;
403 409
404 fb_ioif = GPU_IOIF + FB_OFF(i) + offset;
405 status = lv1_gpu_context_attribute(ps3fb.context_handle, 410 status = lv1_gpu_context_attribute(ps3fb.context_handle,
406 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT, 411 L1GPU_CONTEXT_ATTRIBUTE_FB_BLIT,
407 offset, fb_ioif, 412 dst_offset, GPU_IOIF + src_offset,
408 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION | 413 L1GPU_FB_BLIT_WAIT_FOR_COMPLETION |
409 (xres << 16) | yres, 414 (width << 16) | height,
410 xres * BPP); /* line_length */ 415 line_length);
411 if (status) 416 if (status)
412 printk(KERN_ERR 417 dev_err(dev,
413 "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n", 418 "%s: lv1_gpu_context_attribute FB_BLIT failed: %d\n",
414 __func__, status); 419 __func__, status);
415#ifdef HEAD_A 420#ifdef HEAD_A
416 status = lv1_gpu_context_attribute(ps3fb.context_handle, 421 status = lv1_gpu_context_attribute(ps3fb.context_handle,
417 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 422 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
418 0, offset, 0, 0); 423 0, frame_offset, 0, 0);
419 if (status) 424 if (status)
420 printk(KERN_ERR 425 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
421 "%s: lv1_gpu_context_attribute FLIP failed: %d\n", 426 __func__, status);
422 __func__, status);
423#endif 427#endif
424#ifdef HEAD_B 428#ifdef HEAD_B
425 status = lv1_gpu_context_attribute(ps3fb.context_handle, 429 status = lv1_gpu_context_attribute(ps3fb.context_handle,
426 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP, 430 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_FLIP,
427 1, offset, 0, 0); 431 1, frame_offset, 0, 0);
428 if (status) 432 if (status)
429 printk(KERN_ERR 433 dev_err(dev, "%s: lv1_gpu_context_attribute FLIP failed: %d\n",
430 "%s: lv1_gpu_context_attribute FLIP failed: %d\n", 434 __func__, status);
431 __func__, status);
432#endif 435#endif
433 return 0;
434} 436}
435 437
438static int ps3fb_sync(struct fb_info *info, u32 frame)
439{
440 struct ps3fb_par *par = info->par;
441 int i, error = 0;
442 u32 ddr_line_length, xdr_line_length;
443 u64 ddr_base, xdr_base;
444
445 acquire_console_sem();
446
447 if (frame > par->num_frames - 1) {
448 dev_dbg(info->device, "%s: invalid frame number (%u)\n",
449 __func__, frame);
450 error = -EINVAL;
451 goto out;
452 }
453
454 i = par->res_index;
455 xdr_line_length = info->fix.line_length;
456 ddr_line_length = ps3fb_res[i].xres * BPP;
457 xdr_base = frame * info->var.yres_virtual * xdr_line_length;
458 ddr_base = frame * ps3fb_res[i].yres * ddr_line_length;
459
460 ps3fb_sync_image(info->device, ddr_base + par->full_offset,
461 ddr_base + par->fb_offset, xdr_base + par->pan_offset,
462 par->width, par->height, ddr_line_length,
463 xdr_line_length);
464
465out:
466 release_console_sem();
467 return error;
468}
436 469
437static int ps3fb_open(struct fb_info *info, int user) 470static int ps3fb_open(struct fb_info *info, int user)
438{ 471{
@@ -445,7 +478,7 @@ static int ps3fb_release(struct fb_info *info, int user)
445 if (atomic_dec_and_test(&ps3fb.f_count)) { 478 if (atomic_dec_and_test(&ps3fb.f_count)) {
446 if (atomic_read(&ps3fb.ext_flip)) { 479 if (atomic_read(&ps3fb.ext_flip)) {
447 atomic_set(&ps3fb.ext_flip, 0); 480 atomic_set(&ps3fb.ext_flip, 0);
448 ps3fb_sync(0); /* single buffer */ 481 ps3fb_sync(info, 0); /* single buffer */
449 } 482 }
450 } 483 }
451 return 0; 484 return 0;
@@ -461,39 +494,37 @@ static int ps3fb_release(struct fb_info *info, int user)
461 494
462static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 495static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
463{ 496{
464 u32 line_length; 497 u32 xdr_line_length, ddr_line_length;
465 int mode; 498 int mode;
466 int i;
467 499
468 DPRINTK("var->xres:%u info->var.xres:%u\n", var->xres, info->var.xres); 500 dev_dbg(info->device, "var->xres:%u info->var.xres:%u\n", var->xres,
469 DPRINTK("var->yres:%u info->var.yres:%u\n", var->yres, info->var.yres); 501 info->var.xres);
502 dev_dbg(info->device, "var->yres:%u info->var.yres:%u\n", var->yres,
503 info->var.yres);
470 504
471 /* FIXME For now we do exact matches only */ 505 /* FIXME For now we do exact matches only */
472 mode = ps3fb_find_mode(var, &line_length); 506 mode = ps3fb_find_mode(var, &ddr_line_length, &xdr_line_length);
473 if (!mode) 507 if (!mode)
474 return -EINVAL; 508 return -EINVAL;
475 509
476 /* 510 /* Virtual screen */
477 * FB_VMODE_CONUPDATE and FB_VMODE_SMOOTH_XPAN are equal! 511 if (var->xres_virtual < var->xres)
478 * as FB_VMODE_SMOOTH_XPAN is only used internally 512 var->xres_virtual = var->xres;
479 */ 513 if (var->yres_virtual < var->yres)
514 var->yres_virtual = var->yres;
480 515
481 if (var->vmode & FB_VMODE_CONUPDATE) { 516 if (var->xres_virtual > xdr_line_length / BPP) {
482 var->vmode |= FB_VMODE_YWRAP; 517 dev_dbg(info->device,
483 var->xoffset = info->var.xoffset; 518 "Horizontal virtual screen size too large\n");
484 var->yoffset = info->var.yoffset; 519 return -EINVAL;
485 } 520 }
486 521
487 /* Virtual screen and panning are not supported */ 522 if (var->xoffset + var->xres > var->xres_virtual ||
488 if (var->xres_virtual > var->xres || var->yres_virtual > var->yres || 523 var->yoffset + var->yres > var->yres_virtual) {
489 var->xoffset || var->yoffset) { 524 dev_dbg(info->device, "panning out-of-range\n");
490 DPRINTK("Virtual screen and panning are not supported\n");
491 return -EINVAL; 525 return -EINVAL;
492 } 526 }
493 527
494 var->xres_virtual = var->xres;
495 var->yres_virtual = var->yres;
496
497 /* We support ARGB8888 only */ 528 /* We support ARGB8888 only */
498 if (var->bits_per_pixel > 32 || var->grayscale || 529 if (var->bits_per_pixel > 32 || var->grayscale ||
499 var->red.offset > 16 || var->green.offset > 8 || 530 var->red.offset > 16 || var->green.offset > 8 ||
@@ -502,7 +533,7 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
502 var->blue.length > 8 || var->transp.length > 8 || 533 var->blue.length > 8 || var->transp.length > 8 ||
503 var->red.msb_right || var->green.msb_right || 534 var->red.msb_right || var->green.msb_right ||
504 var->blue.msb_right || var->transp.msb_right || var->nonstd) { 535 var->blue.msb_right || var->transp.msb_right || var->nonstd) {
505 DPRINTK("We support ARGB8888 only\n"); 536 dev_dbg(info->device, "We support ARGB8888 only\n");
506 return -EINVAL; 537 return -EINVAL;
507 } 538 }
508 539
@@ -522,14 +553,13 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
522 553
523 /* Rotation is not supported */ 554 /* Rotation is not supported */
524 if (var->rotate) { 555 if (var->rotate) {
525 DPRINTK("Rotation is not supported\n"); 556 dev_dbg(info->device, "Rotation is not supported\n");
526 return -EINVAL; 557 return -EINVAL;
527 } 558 }
528 559
529 /* Memory limit */ 560 /* Memory limit */
530 i = ps3fb_get_res_table(var->xres, var->yres); 561 if (var->yres_virtual * xdr_line_length > ps3fb.xdr_size) {
531 if (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP > ps3fb_videomemory.size) { 562 dev_dbg(info->device, "Not enough memory\n");
532 DPRINTK("Not enough memory\n");
533 return -ENOMEM; 563 return -ENOMEM;
534 } 564 }
535 565
@@ -545,36 +575,69 @@ static int ps3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
545 575
546static int ps3fb_set_par(struct fb_info *info) 576static int ps3fb_set_par(struct fb_info *info)
547{ 577{
548 unsigned int mode; 578 struct ps3fb_par *par = info->par;
579 unsigned int mode, ddr_line_length, xdr_line_length, lines, maxlines;
549 int i; 580 int i;
550 unsigned long offset; 581 unsigned long offset;
551 static int first = 1; 582 u64 dst;
552 583
553 DPRINTK("xres:%d xv:%d yres:%d yv:%d clock:%d\n", 584 dev_dbg(info->device, "xres:%d xv:%d yres:%d yv:%d clock:%d\n",
554 info->var.xres, info->var.xres_virtual, 585 info->var.xres, info->var.xres_virtual,
555 info->var.yres, info->var.yres_virtual, info->var.pixclock); 586 info->var.yres, info->var.yres_virtual, info->var.pixclock);
556 i = ps3fb_get_res_table(info->var.xres, info->var.yres);
557 ps3fb.res_index = i;
558 587
559 mode = ps3fb_find_mode(&info->var, &info->fix.line_length); 588 mode = ps3fb_find_mode(&info->var, &ddr_line_length, &xdr_line_length);
560 if (!mode) 589 if (!mode)
561 return -EINVAL; 590 return -EINVAL;
562 591
563 offset = FB_OFF(i) + VP_OFF(i); 592 i = ps3fb_get_res_table(info->var.xres, info->var.yres, mode);
564 info->fix.smem_len = ps3fb_videomemory.size - offset; 593 par->res_index = i;
565 info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset; 594
566 memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size); 595 info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
596 info->fix.smem_len = ps3fb.xdr_size;
597 info->fix.xpanstep = info->var.xres_virtual > info->var.xres ? 1 : 0;
598 info->fix.ypanstep = info->var.yres_virtual > info->var.yres ? 1 : 0;
599 info->fix.line_length = xdr_line_length;
600
601 info->screen_base = (char __iomem *)ps3fb.xdr_ea;
567 602
568 ps3fb.num_frames = ps3fb_videomemory.size/ 603 par->num_frames = ps3fb.xdr_size /
569 (ps3fb_res[i].xres*ps3fb_res[i].yres*BPP); 604 max(ps3fb_res[i].yres * ddr_line_length,
605 info->var.yres_virtual * xdr_line_length);
570 606
571 /* Keep the special bits we cannot set using fb_var_screeninfo */ 607 /* Keep the special bits we cannot set using fb_var_screeninfo */
572 ps3fb_mode = (ps3fb_mode & ~PS3AV_MODE_MASK) | mode; 608 par->new_mode_id = (par->new_mode_id & ~PS3AV_MODE_MASK) | mode;
609
610 par->width = info->var.xres;
611 par->height = info->var.yres;
612 offset = VP_OFF(i);
613 par->fb_offset = GPU_ALIGN_UP(offset);
614 par->full_offset = par->fb_offset - offset;
615 par->pan_offset = info->var.yoffset * xdr_line_length +
616 info->var.xoffset * BPP;
617
618 if (par->new_mode_id != par->mode_id) {
619 if (ps3av_set_video_mode(par->new_mode_id)) {
620 par->new_mode_id = par->mode_id;
621 return -EINVAL;
622 }
623 par->mode_id = par->new_mode_id;
624 }
573 625
574 if (ps3av_set_video_mode(ps3fb_mode, first)) 626 /* Clear XDR frame buffer memory */
575 return -EINVAL; 627 memset(ps3fb.xdr_ea, 0, ps3fb.xdr_size);
628
629 /* Clear DDR frame buffer memory */
630 lines = ps3fb_res[i].yres * par->num_frames;
631 if (par->full_offset)
632 lines++;
633 maxlines = ps3fb.xdr_size / ddr_line_length;
634 for (dst = 0; lines; dst += maxlines * ddr_line_length) {
635 unsigned int l = min(lines, maxlines);
636 ps3fb_sync_image(info->device, 0, dst, 0, ps3fb_res[i].xres, l,
637 ddr_line_length, ddr_line_length);
638 lines -= l;
639 }
576 640
577 first = 0;
578 return 0; 641 return 0;
579} 642}
580 643
@@ -601,6 +664,16 @@ static int ps3fb_setcolreg(unsigned int regno, unsigned int red,
601 return 0; 664 return 0;
602} 665}
603 666
667static int ps3fb_pan_display(struct fb_var_screeninfo *var,
668 struct fb_info *info)
669{
670 struct ps3fb_par *par = info->par;
671
672 par->pan_offset = var->yoffset * info->fix.line_length +
673 var->xoffset * BPP;
674 return 0;
675}
676
604 /* 677 /*
605 * As we have a virtual frame buffer, we need our own mmap function 678 * As we have a virtual frame buffer, we need our own mmap function
606 */ 679 */
@@ -608,24 +681,19 @@ static int ps3fb_setcolreg(unsigned int regno, unsigned int red,
608static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma) 681static int ps3fb_mmap(struct fb_info *info, struct vm_area_struct *vma)
609{ 682{
610 unsigned long size, offset; 683 unsigned long size, offset;
611 int i;
612
613 i = ps3fb_get_res_table(info->var.xres, info->var.yres);
614 if (i == -1)
615 return -EINVAL;
616 684
617 size = vma->vm_end - vma->vm_start; 685 size = vma->vm_end - vma->vm_start;
618 offset = vma->vm_pgoff << PAGE_SHIFT; 686 offset = vma->vm_pgoff << PAGE_SHIFT;
619 if (offset + size > info->fix.smem_len) 687 if (offset + size > info->fix.smem_len)
620 return -EINVAL; 688 return -EINVAL;
621 689
622 offset += info->fix.smem_start + FB_OFF(i) + VP_OFF(i); 690 offset += info->fix.smem_start;
623 if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT, 691 if (remap_pfn_range(vma, vma->vm_start, offset >> PAGE_SHIFT,
624 size, vma->vm_page_prot)) 692 size, vma->vm_page_prot))
625 return -EAGAIN; 693 return -EAGAIN;
626 694
627 printk(KERN_DEBUG "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n", offset, 695 dev_dbg(info->device, "ps3fb: mmap framebuffer P(%lx)->V(%lx)\n",
628 vma->vm_start); 696 offset, vma->vm_start);
629 return 0; 697 return 0;
630} 698}
631 699
@@ -637,7 +705,7 @@ static int ps3fb_blank(int blank, struct fb_info *info)
637{ 705{
638 int retval; 706 int retval;
639 707
640 DPRINTK("%s: blank:%d\n", __func__, blank); 708 dev_dbg(info->device, "%s: blank:%d\n", __func__, blank);
641 switch (blank) { 709 switch (blank) {
642 case FB_BLANK_POWERDOWN: 710 case FB_BLANK_POWERDOWN:
643 case FB_BLANK_HSYNC_SUSPEND: 711 case FB_BLANK_HSYNC_SUSPEND:
@@ -664,7 +732,7 @@ static int ps3fb_get_vblank(struct fb_vblank *vblank)
664 return 0; 732 return 0;
665} 733}
666 734
667int ps3fb_wait_for_vsync(u32 crtc) 735static int ps3fb_wait_for_vsync(u32 crtc)
668{ 736{
669 int ret; 737 int ret;
670 u64 count; 738 u64 count;
@@ -679,9 +747,7 @@ int ps3fb_wait_for_vsync(u32 crtc)
679 return 0; 747 return 0;
680} 748}
681 749
682EXPORT_SYMBOL_GPL(ps3fb_wait_for_vsync); 750static void ps3fb_flip_ctl(int on, void *data)
683
684void ps3fb_flip_ctl(int on, void *data)
685{ 751{
686 struct ps3fb_priv *priv = data; 752 struct ps3fb_priv *priv = data;
687 if (on) 753 if (on)
@@ -699,14 +765,14 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
699 unsigned long arg) 765 unsigned long arg)
700{ 766{
701 void __user *argp = (void __user *)arg; 767 void __user *argp = (void __user *)arg;
702 u32 val, old_mode; 768 u32 val;
703 int retval = -EFAULT; 769 int retval = -EFAULT;
704 770
705 switch (cmd) { 771 switch (cmd) {
706 case FBIOGET_VBLANK: 772 case FBIOGET_VBLANK:
707 { 773 {
708 struct fb_vblank vblank; 774 struct fb_vblank vblank;
709 DPRINTK("FBIOGET_VBLANK:\n"); 775 dev_dbg(info->device, "FBIOGET_VBLANK:\n");
710 retval = ps3fb_get_vblank(&vblank); 776 retval = ps3fb_get_vblank(&vblank);
711 if (retval) 777 if (retval)
712 break; 778 break;
@@ -719,7 +785,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
719 case FBIO_WAITFORVSYNC: 785 case FBIO_WAITFORVSYNC:
720 { 786 {
721 u32 crt; 787 u32 crt;
722 DPRINTK("FBIO_WAITFORVSYNC:\n"); 788 dev_dbg(info->device, "FBIO_WAITFORVSYNC:\n");
723 if (get_user(crt, (u32 __user *) arg)) 789 if (get_user(crt, (u32 __user *) arg))
724 break; 790 break;
725 791
@@ -729,6 +795,7 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
729 795
730 case PS3FB_IOCTL_SETMODE: 796 case PS3FB_IOCTL_SETMODE:
731 { 797 {
798 struct ps3fb_par *par = info->par;
732 const struct fb_videomode *mode; 799 const struct fb_videomode *mode;
733 struct fb_var_screeninfo var; 800 struct fb_var_screeninfo var;
734 801
@@ -736,15 +803,13 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
736 break; 803 break;
737 804
738 if (!(val & PS3AV_MODE_MASK)) { 805 if (!(val & PS3AV_MODE_MASK)) {
739 u32 id = ps3av_get_auto_mode(0); 806 u32 id = ps3av_get_auto_mode();
740 if (id > 0) 807 if (id > 0)
741 val = (val & ~PS3AV_MODE_MASK) | id; 808 val = (val & ~PS3AV_MODE_MASK) | id;
742 } 809 }
743 DPRINTK("PS3FB_IOCTL_SETMODE:%x\n", val); 810 dev_dbg(info->device, "PS3FB_IOCTL_SETMODE:%x\n", val);
744 retval = -EINVAL; 811 retval = -EINVAL;
745 old_mode = ps3fb_mode; 812 mode = ps3fb_default_mode(val);
746 ps3fb_mode = val;
747 mode = ps3fb_default_mode();
748 if (mode) { 813 if (mode) {
749 var = info->var; 814 var = info->var;
750 fb_videomode_to_var(&var, mode); 815 fb_videomode_to_var(&var, mode);
@@ -752,45 +817,44 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
752 info->flags |= FBINFO_MISC_USEREVENT; 817 info->flags |= FBINFO_MISC_USEREVENT;
753 /* Force, in case only special bits changed */ 818 /* Force, in case only special bits changed */
754 var.activate |= FB_ACTIVATE_FORCE; 819 var.activate |= FB_ACTIVATE_FORCE;
820 par->new_mode_id = val;
755 retval = fb_set_var(info, &var); 821 retval = fb_set_var(info, &var);
756 info->flags &= ~FBINFO_MISC_USEREVENT; 822 info->flags &= ~FBINFO_MISC_USEREVENT;
757 release_console_sem(); 823 release_console_sem();
758 } 824 }
759 if (retval)
760 ps3fb_mode = old_mode;
761 break; 825 break;
762 } 826 }
763 827
764 case PS3FB_IOCTL_GETMODE: 828 case PS3FB_IOCTL_GETMODE:
765 val = ps3av_get_mode(); 829 val = ps3av_get_mode();
766 DPRINTK("PS3FB_IOCTL_GETMODE:%x\n", val); 830 dev_dbg(info->device, "PS3FB_IOCTL_GETMODE:%x\n", val);
767 if (!copy_to_user(argp, &val, sizeof(val))) 831 if (!copy_to_user(argp, &val, sizeof(val)))
768 retval = 0; 832 retval = 0;
769 break; 833 break;
770 834
771 case PS3FB_IOCTL_SCREENINFO: 835 case PS3FB_IOCTL_SCREENINFO:
772 { 836 {
837 struct ps3fb_par *par = info->par;
773 struct ps3fb_ioctl_res res; 838 struct ps3fb_ioctl_res res;
774 int i = ps3fb.res_index; 839 dev_dbg(info->device, "PS3FB_IOCTL_SCREENINFO:\n");
775 DPRINTK("PS3FB_IOCTL_SCREENINFO:\n"); 840 res.xres = info->fix.line_length / BPP;
776 res.xres = ps3fb_res[i].xres; 841 res.yres = info->var.yres_virtual;
777 res.yres = ps3fb_res[i].yres; 842 res.xoff = (res.xres - info->var.xres) / 2;
778 res.xoff = ps3fb_res[i].xoff; 843 res.yoff = (res.yres - info->var.yres) / 2;
779 res.yoff = ps3fb_res[i].yoff; 844 res.num_frames = par->num_frames;
780 res.num_frames = ps3fb.num_frames;
781 if (!copy_to_user(argp, &res, sizeof(res))) 845 if (!copy_to_user(argp, &res, sizeof(res)))
782 retval = 0; 846 retval = 0;
783 break; 847 break;
784 } 848 }
785 849
786 case PS3FB_IOCTL_ON: 850 case PS3FB_IOCTL_ON:
787 DPRINTK("PS3FB_IOCTL_ON:\n"); 851 dev_dbg(info->device, "PS3FB_IOCTL_ON:\n");
788 atomic_inc(&ps3fb.ext_flip); 852 atomic_inc(&ps3fb.ext_flip);
789 retval = 0; 853 retval = 0;
790 break; 854 break;
791 855
792 case PS3FB_IOCTL_OFF: 856 case PS3FB_IOCTL_OFF:
793 DPRINTK("PS3FB_IOCTL_OFF:\n"); 857 dev_dbg(info->device, "PS3FB_IOCTL_OFF:\n");
794 atomic_dec_if_positive(&ps3fb.ext_flip); 858 atomic_dec_if_positive(&ps3fb.ext_flip);
795 retval = 0; 859 retval = 0;
796 break; 860 break;
@@ -799,8 +863,8 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
799 if (copy_from_user(&val, argp, sizeof(val))) 863 if (copy_from_user(&val, argp, sizeof(val)))
800 break; 864 break;
801 865
802 DPRINTK("PS3FB_IOCTL_FSEL:%d\n", val); 866 dev_dbg(info->device, "PS3FB_IOCTL_FSEL:%d\n", val);
803 retval = ps3fb_sync(val); 867 retval = ps3fb_sync(info, val);
804 break; 868 break;
805 869
806 default: 870 default:
@@ -812,13 +876,15 @@ static int ps3fb_ioctl(struct fb_info *info, unsigned int cmd,
812 876
813static int ps3fbd(void *arg) 877static int ps3fbd(void *arg)
814{ 878{
879 struct fb_info *info = arg;
880
815 set_freezable(); 881 set_freezable();
816 while (!kthread_should_stop()) { 882 while (!kthread_should_stop()) {
817 try_to_freeze(); 883 try_to_freeze();
818 set_current_state(TASK_INTERRUPTIBLE); 884 set_current_state(TASK_INTERRUPTIBLE);
819 if (ps3fb.is_kicked) { 885 if (ps3fb.is_kicked) {
820 ps3fb.is_kicked = 0; 886 ps3fb.is_kicked = 0;
821 ps3fb_sync(0); /* single buffer */ 887 ps3fb_sync(info, 0); /* single buffer */
822 } 888 }
823 schedule(); 889 schedule();
824 } 890 }
@@ -827,14 +893,15 @@ static int ps3fbd(void *arg)
827 893
828static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr) 894static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
829{ 895{
896 struct device *dev = ptr;
830 u64 v1; 897 u64 v1;
831 int status; 898 int status;
832 struct display_head *head = &ps3fb.dinfo->display_head[1]; 899 struct display_head *head = &ps3fb.dinfo->display_head[1];
833 900
834 status = lv1_gpu_context_intr(ps3fb.context_handle, &v1); 901 status = lv1_gpu_context_intr(ps3fb.context_handle, &v1);
835 if (status) { 902 if (status) {
836 printk(KERN_ERR "%s: lv1_gpu_context_intr failed: %d\n", 903 dev_err(dev, "%s: lv1_gpu_context_intr failed: %d\n", __func__,
837 __func__, status); 904 status);
838 return IRQ_NONE; 905 return IRQ_NONE;
839 } 906 }
840 907
@@ -854,35 +921,35 @@ static irqreturn_t ps3fb_vsync_interrupt(int irq, void *ptr)
854 921
855 922
856static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo, 923static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
857 struct ps3_system_bus_device *dev) 924 struct device *dev)
858{ 925{
859 int error; 926 int error;
860 927
861 DPRINTK("version_driver:%x\n", dinfo->version_driver); 928 dev_dbg(dev, "version_driver:%x\n", dinfo->version_driver);
862 DPRINTK("irq outlet:%x\n", dinfo->irq.irq_outlet); 929 dev_dbg(dev, "irq outlet:%x\n", dinfo->irq.irq_outlet);
863 DPRINTK("version_gpu:%x memory_size:%x ch:%x core_freq:%d mem_freq:%d\n", 930 dev_dbg(dev,
931 "version_gpu: %x memory_size: %x ch: %x core_freq: %d "
932 "mem_freq:%d\n",
864 dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel, 933 dinfo->version_gpu, dinfo->memory_size, dinfo->hardware_channel,
865 dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000); 934 dinfo->nvcore_frequency/1000000, dinfo->memory_frequency/1000000);
866 935
867 if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) { 936 if (dinfo->version_driver != GPU_DRIVER_INFO_VERSION) {
868 printk(KERN_ERR "%s: version_driver err:%x\n", __func__, 937 dev_err(dev, "%s: version_driver err:%x\n", __func__,
869 dinfo->version_driver); 938 dinfo->version_driver);
870 return -EINVAL; 939 return -EINVAL;
871 } 940 }
872 941
873 error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet, 942 error = ps3_irq_plug_setup(PS3_BINDING_CPU_ANY, dinfo->irq.irq_outlet,
874 &ps3fb.irq_no); 943 &ps3fb.irq_no);
875 if (error) { 944 if (error) {
876 printk(KERN_ERR "%s: ps3_alloc_irq failed %d\n", __func__, 945 dev_err(dev, "%s: ps3_alloc_irq failed %d\n", __func__, error);
877 error);
878 return error; 946 return error;
879 } 947 }
880 948
881 error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED, 949 error = request_irq(ps3fb.irq_no, ps3fb_vsync_interrupt, IRQF_DISABLED,
882 DEVICE_NAME, dev); 950 DEVICE_NAME, dev);
883 if (error) { 951 if (error) {
884 printk(KERN_ERR "%s: request_irq failed %d\n", __func__, 952 dev_err(dev, "%s: request_irq failed %d\n", __func__, error);
885 error);
886 ps3_irq_plug_destroy(ps3fb.irq_no); 953 ps3_irq_plug_destroy(ps3fb.irq_no);
887 return error; 954 return error;
888 } 955 }
@@ -892,29 +959,31 @@ static int ps3fb_vsync_settings(struct gpu_driver_info *dinfo,
892 return 0; 959 return 0;
893} 960}
894 961
895static int ps3fb_xdr_settings(u64 xdr_lpar) 962static int ps3fb_xdr_settings(u64 xdr_lpar, struct device *dev)
896{ 963{
897 int status; 964 int status;
898 965
899 status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF, 966 status = lv1_gpu_context_iomap(ps3fb.context_handle, GPU_IOIF,
900 xdr_lpar, ps3fb_videomemory.size, 0); 967 xdr_lpar, ps3fb_videomemory.size, 0);
901 if (status) { 968 if (status) {
902 printk(KERN_ERR "%s: lv1_gpu_context_iomap failed: %d\n", 969 dev_err(dev, "%s: lv1_gpu_context_iomap failed: %d\n",
903 __func__, status); 970 __func__, status);
904 return -ENXIO; 971 return -ENXIO;
905 } 972 }
906 DPRINTK("video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n", 973 dev_dbg(dev,
974 "video:%p xdr_ea:%p ioif:%lx lpar:%lx phys:%lx size:%lx\n",
907 ps3fb_videomemory.address, ps3fb.xdr_ea, GPU_IOIF, xdr_lpar, 975 ps3fb_videomemory.address, ps3fb.xdr_ea, GPU_IOIF, xdr_lpar,
908 virt_to_abs(ps3fb.xdr_ea), ps3fb_videomemory.size); 976 virt_to_abs(ps3fb.xdr_ea), ps3fb_videomemory.size);
909 977
910 status = lv1_gpu_context_attribute(ps3fb.context_handle, 978 status = lv1_gpu_context_attribute(ps3fb.context_handle,
911 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP, 979 L1GPU_CONTEXT_ATTRIBUTE_FB_SETUP,
912 xdr_lpar, ps3fb_videomemory.size, 980 xdr_lpar + ps3fb.xdr_size,
913 GPU_IOIF, 0); 981 GPU_CMD_BUF_SIZE,
982 GPU_IOIF + ps3fb.xdr_size, 0);
914 if (status) { 983 if (status) {
915 printk(KERN_ERR 984 dev_err(dev,
916 "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n", 985 "%s: lv1_gpu_context_attribute FB_SETUP failed: %d\n",
917 __func__, status); 986 __func__, status);
918 return -ENXIO; 987 return -ENXIO;
919 } 988 }
920 return 0; 989 return 0;
@@ -928,6 +997,7 @@ static struct fb_ops ps3fb_ops = {
928 .fb_check_var = ps3fb_check_var, 997 .fb_check_var = ps3fb_check_var,
929 .fb_set_par = ps3fb_set_par, 998 .fb_set_par = ps3fb_set_par,
930 .fb_setcolreg = ps3fb_setcolreg, 999 .fb_setcolreg = ps3fb_setcolreg,
1000 .fb_pan_display = ps3fb_pan_display,
931 .fb_fillrect = sys_fillrect, 1001 .fb_fillrect = sys_fillrect,
932 .fb_copyarea = sys_copyarea, 1002 .fb_copyarea = sys_copyarea,
933 .fb_imageblit = sys_imageblit, 1003 .fb_imageblit = sys_imageblit,
@@ -944,7 +1014,7 @@ static struct fb_fix_screeninfo ps3fb_fix __initdata = {
944 .accel = FB_ACCEL_NONE, 1014 .accel = FB_ACCEL_NONE,
945}; 1015};
946 1016
947static int ps3fb_set_sync(void) 1017static int ps3fb_set_sync(struct device *dev)
948{ 1018{
949 int status; 1019 int status;
950 1020
@@ -953,8 +1023,10 @@ static int ps3fb_set_sync(void)
953 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC, 1023 L1GPU_CONTEXT_ATTRIBUTE_DISPLAY_SYNC,
954 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); 1024 0, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
955 if (status) { 1025 if (status) {
956 printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_SYNC " 1026 dev_err(dev,
957 "failed: %d\n", __func__, status); 1027 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
1028 "%d\n",
1029 __func__, status);
958 return -1; 1030 return -1;
959 } 1031 }
960#endif 1032#endif
@@ -964,8 +1036,10 @@ static int ps3fb_set_sync(void)
964 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0); 1036 1, L1GPU_DISPLAY_SYNC_VSYNC, 0, 0);
965 1037
966 if (status) { 1038 if (status) {
967 printk(KERN_ERR "%s: lv1_gpu_context_attribute DISPLAY_MODE " 1039 dev_err(dev,
968 "failed: %d\n", __func__, status); 1040 "%s: lv1_gpu_context_attribute DISPLAY_SYNC failed: "
1041 "%d\n",
1042 __func__, status);
969 return -1; 1043 return -1;
970 } 1044 }
971#endif 1045#endif
@@ -975,6 +1049,7 @@ static int ps3fb_set_sync(void)
975static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev) 1049static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
976{ 1050{
977 struct fb_info *info; 1051 struct fb_info *info;
1052 struct ps3fb_par *par;
978 int retval = -ENOMEM; 1053 int retval = -ENOMEM;
979 u32 xres, yres; 1054 u32 xres, yres;
980 u64 ddr_lpar = 0; 1055 u64 ddr_lpar = 0;
@@ -983,98 +1058,106 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
983 u64 lpar_reports = 0; 1058 u64 lpar_reports = 0;
984 u64 lpar_reports_size = 0; 1059 u64 lpar_reports_size = 0;
985 u64 xdr_lpar; 1060 u64 xdr_lpar;
986 int status; 1061 int status, res_index;
987 unsigned long offset;
988 struct task_struct *task; 1062 struct task_struct *task;
989 1063
990 status = ps3_open_hv_device(dev); 1064 status = ps3_open_hv_device(dev);
991 if (status) { 1065 if (status) {
992 printk(KERN_ERR "%s: ps3_open_hv_device failed\n", __func__); 1066 dev_err(&dev->core, "%s: ps3_open_hv_device failed\n",
1067 __func__);
993 goto err; 1068 goto err;
994 } 1069 }
995 1070
996 if (!ps3fb_mode) 1071 if (!ps3fb_mode)
997 ps3fb_mode = ps3av_get_mode(); 1072 ps3fb_mode = ps3av_get_mode();
998 DPRINTK("ps3av_mode:%d\n", ps3fb_mode); 1073 dev_dbg(&dev->core, "ps3av_mode:%d\n", ps3fb_mode);
999 1074
1000 if (ps3fb_mode > 0 && 1075 if (ps3fb_mode > 0 &&
1001 !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) { 1076 !ps3av_video_mode2res(ps3fb_mode, &xres, &yres)) {
1002 ps3fb.res_index = ps3fb_get_res_table(xres, yres); 1077 res_index = ps3fb_get_res_table(xres, yres, ps3fb_mode);
1003 DPRINTK("res_index:%d\n", ps3fb.res_index); 1078 dev_dbg(&dev->core, "res_index:%d\n", res_index);
1004 } else 1079 } else
1005 ps3fb.res_index = GPU_RES_INDEX; 1080 res_index = GPU_RES_INDEX;
1006 1081
1007 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */ 1082 atomic_set(&ps3fb.f_count, -1); /* fbcon opens ps3fb */
1008 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */ 1083 atomic_set(&ps3fb.ext_flip, 0); /* for flip with vsync */
1009 init_waitqueue_head(&ps3fb.wait_vsync); 1084 init_waitqueue_head(&ps3fb.wait_vsync);
1010 ps3fb.num_frames = 1;
1011 1085
1012 ps3fb_set_sync(); 1086 ps3fb_set_sync(&dev->core);
1013 1087
1014 /* get gpu context handle */ 1088 /* get gpu context handle */
1015 status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0, 1089 status = lv1_gpu_memory_allocate(DDR_SIZE, 0, 0, 0, 0,
1016 &ps3fb.memory_handle, &ddr_lpar); 1090 &ps3fb.memory_handle, &ddr_lpar);
1017 if (status) { 1091 if (status) {
1018 printk(KERN_ERR "%s: lv1_gpu_memory_allocate failed: %d\n", 1092 dev_err(&dev->core, "%s: lv1_gpu_memory_allocate failed: %d\n",
1019 __func__, status); 1093 __func__, status);
1020 goto err; 1094 goto err;
1021 } 1095 }
1022 DPRINTK("ddr:lpar:0x%lx\n", ddr_lpar); 1096 dev_dbg(&dev->core, "ddr:lpar:0x%lx\n", ddr_lpar);
1023 1097
1024 status = lv1_gpu_context_allocate(ps3fb.memory_handle, 0, 1098 status = lv1_gpu_context_allocate(ps3fb.memory_handle, 0,
1025 &ps3fb.context_handle, 1099 &ps3fb.context_handle,
1026 &lpar_dma_control, &lpar_driver_info, 1100 &lpar_dma_control, &lpar_driver_info,
1027 &lpar_reports, &lpar_reports_size); 1101 &lpar_reports, &lpar_reports_size);
1028 if (status) { 1102 if (status) {
1029 printk(KERN_ERR "%s: lv1_gpu_context_attribute failed: %d\n", 1103 dev_err(&dev->core,
1030 __func__, status); 1104 "%s: lv1_gpu_context_attribute failed: %d\n", __func__,
1105 status);
1031 goto err_gpu_memory_free; 1106 goto err_gpu_memory_free;
1032 } 1107 }
1033 1108
1034 /* vsync interrupt */ 1109 /* vsync interrupt */
1035 ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024); 1110 ps3fb.dinfo = ioremap(lpar_driver_info, 128 * 1024);
1036 if (!ps3fb.dinfo) { 1111 if (!ps3fb.dinfo) {
1037 printk(KERN_ERR "%s: ioremap failed\n", __func__); 1112 dev_err(&dev->core, "%s: ioremap failed\n", __func__);
1038 goto err_gpu_context_free; 1113 goto err_gpu_context_free;
1039 } 1114 }
1040 1115
1041 retval = ps3fb_vsync_settings(ps3fb.dinfo, dev); 1116 retval = ps3fb_vsync_settings(ps3fb.dinfo, &dev->core);
1042 if (retval) 1117 if (retval)
1043 goto err_iounmap_dinfo; 1118 goto err_iounmap_dinfo;
1044 1119
1045 /* xdr frame buffer */ 1120 /* XDR frame buffer */
1046 ps3fb.xdr_ea = ps3fb_videomemory.address; 1121 ps3fb.xdr_ea = ps3fb_videomemory.address;
1047 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb.xdr_ea)); 1122 xdr_lpar = ps3_mm_phys_to_lpar(__pa(ps3fb.xdr_ea));
1048 retval = ps3fb_xdr_settings(xdr_lpar); 1123
1124 /* Clear memory to prevent kernel info leakage into userspace */
1125 memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
1126
1127 /* The GPU command buffer is at the end of video memory */
1128 ps3fb.xdr_size = ps3fb_videomemory.size - GPU_CMD_BUF_SIZE;
1129
1130 retval = ps3fb_xdr_settings(xdr_lpar, &dev->core);
1049 if (retval) 1131 if (retval)
1050 goto err_free_irq; 1132 goto err_free_irq;
1051 1133
1052 /* 1134 info = framebuffer_alloc(sizeof(struct ps3fb_par), &dev->core);
1053 * ps3fb must clear memory to prevent kernel info
1054 * leakage into userspace
1055 */
1056 memset(ps3fb.xdr_ea, 0, ps3fb_videomemory.size);
1057 info = framebuffer_alloc(sizeof(u32) * 16, &dev->core);
1058 if (!info) 1135 if (!info)
1059 goto err_free_irq; 1136 goto err_free_irq;
1060 1137
1061 offset = FB_OFF(ps3fb.res_index) + VP_OFF(ps3fb.res_index); 1138 par = info->par;
1062 info->screen_base = (char __iomem *)ps3fb.xdr_ea + offset; 1139 par->mode_id = ~ps3fb_mode; /* != ps3fb_mode, to trigger change */
1140 par->new_mode_id = ps3fb_mode;
1141 par->res_index = res_index;
1142 par->num_frames = 1;
1143
1144 info->screen_base = (char __iomem *)ps3fb.xdr_ea;
1063 info->fbops = &ps3fb_ops; 1145 info->fbops = &ps3fb_ops;
1064 1146
1065 info->fix = ps3fb_fix; 1147 info->fix = ps3fb_fix;
1066 info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea); 1148 info->fix.smem_start = virt_to_abs(ps3fb.xdr_ea);
1067 info->fix.smem_len = ps3fb_videomemory.size - offset; 1149 info->fix.smem_len = ps3fb.xdr_size;
1068 info->pseudo_palette = info->par; 1150 info->pseudo_palette = par->pseudo_palette;
1069 info->par = NULL; 1151 info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST |
1070 info->flags = FBINFO_DEFAULT | FBINFO_READS_FAST; 1152 FBINFO_HWACCEL_XPAN | FBINFO_HWACCEL_YPAN;
1071 1153
1072 retval = fb_alloc_cmap(&info->cmap, 256, 0); 1154 retval = fb_alloc_cmap(&info->cmap, 256, 0);
1073 if (retval < 0) 1155 if (retval < 0)
1074 goto err_framebuffer_release; 1156 goto err_framebuffer_release;
1075 1157
1076 if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb, 1158 if (!fb_find_mode(&info->var, info, mode_option, ps3fb_modedb,
1077 ARRAY_SIZE(ps3fb_modedb), ps3fb_default_mode(), 32)) { 1159 ARRAY_SIZE(ps3fb_modedb),
1160 ps3fb_default_mode(par->new_mode_id), 32)) {
1078 retval = -EINVAL; 1161 retval = -EINVAL;
1079 goto err_fb_dealloc; 1162 goto err_fb_dealloc;
1080 } 1163 }
@@ -1088,9 +1171,9 @@ static int __devinit ps3fb_probe(struct ps3_system_bus_device *dev)
1088 1171
1089 dev->core.driver_data = info; 1172 dev->core.driver_data = info;
1090 1173
1091 printk(KERN_INFO 1174 dev_info(info->device, "%s %s, using %lu KiB of video memory\n",
1092 "fb%d: PS3 frame buffer device, using %ld KiB of video memory\n", 1175 dev_driver_string(info->dev), info->dev->bus_id,
1093 info->node, ps3fb_videomemory.size >> 10); 1176 ps3fb.xdr_size >> 10);
1094 1177
1095 task = kthread_run(ps3fbd, info, DEVICE_NAME); 1178 task = kthread_run(ps3fbd, info, DEVICE_NAME);
1096 if (IS_ERR(task)) { 1179 if (IS_ERR(task)) {
@@ -1127,7 +1210,7 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1127 int status; 1210 int status;
1128 struct fb_info *info = dev->core.driver_data; 1211 struct fb_info *info = dev->core.driver_data;
1129 1212
1130 DPRINTK(" -> %s:%d\n", __func__, __LINE__); 1213 dev_dbg(&dev->core, " -> %s:%d\n", __func__, __LINE__);
1131 1214
1132 ps3fb_flip_ctl(0, &ps3fb); /* flip off */ 1215 ps3fb_flip_ctl(0, &ps3fb); /* flip off */
1133 ps3fb.dinfo->irq.mask = 0; 1216 ps3fb.dinfo->irq.mask = 0;
@@ -1152,14 +1235,16 @@ static int ps3fb_shutdown(struct ps3_system_bus_device *dev)
1152 1235
1153 status = lv1_gpu_context_free(ps3fb.context_handle); 1236 status = lv1_gpu_context_free(ps3fb.context_handle);
1154 if (status) 1237 if (status)
1155 DPRINTK("lv1_gpu_context_free failed: %d\n", status); 1238 dev_dbg(&dev->core, "lv1_gpu_context_free failed: %d\n",
1239 status);
1156 1240
1157 status = lv1_gpu_memory_free(ps3fb.memory_handle); 1241 status = lv1_gpu_memory_free(ps3fb.memory_handle);
1158 if (status) 1242 if (status)
1159 DPRINTK("lv1_gpu_memory_free failed: %d\n", status); 1243 dev_dbg(&dev->core, "lv1_gpu_memory_free failed: %d\n",
1244 status);
1160 1245
1161 ps3_close_hv_device(dev); 1246 ps3_close_hv_device(dev);
1162 DPRINTK(" <- %s:%d\n", __func__, __LINE__); 1247 dev_dbg(&dev->core, " <- %s:%d\n", __func__, __LINE__);
1163 1248
1164 return 0; 1249 return 0;
1165} 1250}
@@ -1212,9 +1297,9 @@ static int __init ps3fb_init(void)
1212 1297
1213static void __exit ps3fb_exit(void) 1298static void __exit ps3fb_exit(void)
1214{ 1299{
1215 DPRINTK(" -> %s:%d\n", __func__, __LINE__); 1300 pr_debug(" -> %s:%d\n", __func__, __LINE__);
1216 ps3_system_bus_driver_unregister(&ps3fb_driver); 1301 ps3_system_bus_driver_unregister(&ps3fb_driver);
1217 DPRINTK(" <- %s:%d\n", __func__, __LINE__); 1302 pr_debug(" <- %s:%d\n", __func__, __LINE__);
1218} 1303}
1219 1304
1220module_init(ps3fb_init); 1305module_init(ps3fb_init);
diff --git a/drivers/video/pvr2fb.c b/drivers/video/pvr2fb.c
index 06805c9b237b..6a3d0b574897 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/pvr2fb.c
@@ -72,7 +72,7 @@
72#endif 72#endif
73 73
74#ifdef CONFIG_SH_STORE_QUEUES 74#ifdef CONFIG_SH_STORE_QUEUES
75#include <asm/uaccess.h> 75#include <linux/uaccess.h>
76#include <asm/cpu/sq.h> 76#include <asm/cpu/sq.h>
77#endif 77#endif
78 78
diff --git a/drivers/video/pxafb.c b/drivers/video/pxafb.c
index f9b12ab59642..10f912df2dad 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/pxafb.c
@@ -43,7 +43,6 @@
43#include <asm/hardware.h> 43#include <asm/hardware.h>
44#include <asm/io.h> 44#include <asm/io.h>
45#include <asm/irq.h> 45#include <asm/irq.h>
46#include <asm/uaccess.h>
47#include <asm/div64.h> 46#include <asm/div64.h>
48#include <asm/arch/pxa-regs.h> 47#include <asm/arch/pxa-regs.h>
49#include <asm/arch/bitfield.h> 48#include <asm/arch/bitfield.h>
@@ -108,20 +107,38 @@ pxafb_setpalettereg(u_int regno, u_int red, u_int green, u_int blue,
108 u_int trans, struct fb_info *info) 107 u_int trans, struct fb_info *info)
109{ 108{
110 struct pxafb_info *fbi = (struct pxafb_info *)info; 109 struct pxafb_info *fbi = (struct pxafb_info *)info;
111 u_int val, ret = 1; 110 u_int val;
112 111
113 if (regno < fbi->palette_size) { 112 if (regno >= fbi->palette_size)
114 if (fbi->fb.var.grayscale) { 113 return 1;
115 val = ((blue >> 8) & 0x00ff); 114
116 } else { 115 if (fbi->fb.var.grayscale) {
117 val = ((red >> 0) & 0xf800); 116 fbi->palette_cpu[regno] = ((blue >> 8) & 0x00ff);
118 val |= ((green >> 5) & 0x07e0); 117 return 0;
119 val |= ((blue >> 11) & 0x001f); 118 }
120 } 119
120 switch (fbi->lccr4 & LCCR4_PAL_FOR_MASK) {
121 case LCCR4_PAL_FOR_0:
122 val = ((red >> 0) & 0xf800);
123 val |= ((green >> 5) & 0x07e0);
124 val |= ((blue >> 11) & 0x001f);
121 fbi->palette_cpu[regno] = val; 125 fbi->palette_cpu[regno] = val;
122 ret = 0; 126 break;
127 case LCCR4_PAL_FOR_1:
128 val = ((red << 8) & 0x00f80000);
129 val |= ((green >> 0) & 0x0000fc00);
130 val |= ((blue >> 8) & 0x000000f8);
131 ((u32*)(fbi->palette_cpu))[regno] = val;
132 break;
133 case LCCR4_PAL_FOR_2:
134 val = ((red << 8) & 0x00fc0000);
135 val |= ((green >> 0) & 0x0000fc00);
136 val |= ((blue >> 8) & 0x000000fc);
137 ((u32*)(fbi->palette_cpu))[regno] = val;
138 break;
123 } 139 }
124 return ret; 140
141 return 0;
125} 142}
126 143
127static int 144static int
@@ -363,7 +380,10 @@ static int pxafb_set_par(struct fb_info *info)
363 else 380 else
364 fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel; 381 fbi->palette_size = var->bits_per_pixel == 1 ? 4 : 1 << var->bits_per_pixel;
365 382
366 palette_mem_size = fbi->palette_size * sizeof(u16); 383 if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
384 palette_mem_size = fbi->palette_size * sizeof(u16);
385 else
386 palette_mem_size = fbi->palette_size * sizeof(u32);
367 387
368 pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size); 388 pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
369 389
@@ -680,7 +700,13 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
680 700
681 fbi->dmadesc_palette_cpu->fsadr = fbi->palette_dma; 701 fbi->dmadesc_palette_cpu->fsadr = fbi->palette_dma;
682 fbi->dmadesc_palette_cpu->fidr = 0; 702 fbi->dmadesc_palette_cpu->fidr = 0;
683 fbi->dmadesc_palette_cpu->ldcmd = (fbi->palette_size * 2) | LDCMD_PAL; 703 if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
704 fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
705 sizeof(u16);
706 else
707 fbi->dmadesc_palette_cpu->ldcmd = fbi->palette_size *
708 sizeof(u32);
709 fbi->dmadesc_palette_cpu->ldcmd |= LDCMD_PAL;
684 710
685 if (var->bits_per_pixel == 16) { 711 if (var->bits_per_pixel == 16) {
686 /* palette shouldn't be loaded in true-color mode */ 712 /* palette shouldn't be loaded in true-color mode */
@@ -719,6 +745,8 @@ static int pxafb_activate_var(struct fb_var_screeninfo *var, struct pxafb_info *
719 fbi->reg_lccr1 = new_regs.lccr1; 745 fbi->reg_lccr1 = new_regs.lccr1;
720 fbi->reg_lccr2 = new_regs.lccr2; 746 fbi->reg_lccr2 = new_regs.lccr2;
721 fbi->reg_lccr3 = new_regs.lccr3; 747 fbi->reg_lccr3 = new_regs.lccr3;
748 fbi->reg_lccr4 = LCCR4 & (~LCCR4_PAL_FOR_MASK);
749 fbi->reg_lccr4 |= (fbi->lccr4 & LCCR4_PAL_FOR_MASK);
722 set_hsync_time(fbi, pcd); 750 set_hsync_time(fbi, pcd);
723 local_irq_restore(flags); 751 local_irq_restore(flags);
724 752
@@ -825,6 +853,7 @@ static void pxafb_enable_controller(struct pxafb_info *fbi)
825 pr_debug("LCCR1 0x%08x\n", (unsigned int) LCCR1); 853 pr_debug("LCCR1 0x%08x\n", (unsigned int) LCCR1);
826 pr_debug("LCCR2 0x%08x\n", (unsigned int) LCCR2); 854 pr_debug("LCCR2 0x%08x\n", (unsigned int) LCCR2);
827 pr_debug("LCCR3 0x%08x\n", (unsigned int) LCCR3); 855 pr_debug("LCCR3 0x%08x\n", (unsigned int) LCCR3);
856 pr_debug("LCCR4 0x%08x\n", (unsigned int) LCCR4);
828} 857}
829 858
830static void pxafb_disable_controller(struct pxafb_info *fbi) 859static void pxafb_disable_controller(struct pxafb_info *fbi)
@@ -1094,10 +1123,13 @@ static int __init pxafb_map_video_memory(struct pxafb_info *fbi)
1094 * dma_writecombine_mmap) 1123 * dma_writecombine_mmap)
1095 */ 1124 */
1096 fbi->fb.fix.smem_start = fbi->screen_dma; 1125 fbi->fb.fix.smem_start = fbi->screen_dma;
1097
1098 fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16; 1126 fbi->palette_size = fbi->fb.var.bits_per_pixel == 8 ? 256 : 16;
1099 1127
1100 palette_mem_size = fbi->palette_size * sizeof(u16); 1128 if ((fbi->lccr4 & LCCR4_PAL_FOR_MASK) == LCCR4_PAL_FOR_0)
1129 palette_mem_size = fbi->palette_size * sizeof(u16);
1130 else
1131 palette_mem_size = fbi->palette_size * sizeof(u32);
1132
1101 pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size); 1133 pr_debug("pxafb: palette_mem_size = 0x%08lx\n", palette_mem_size);
1102 1134
1103 fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size); 1135 fbi->palette_cpu = (u16 *)(fbi->map_cpu + PAGE_SIZE - palette_mem_size);
@@ -1160,6 +1192,7 @@ static struct pxafb_info * __init pxafb_init_fbinfo(struct device *dev)
1160 1192
1161 fbi->lccr0 = inf->lccr0; 1193 fbi->lccr0 = inf->lccr0;
1162 fbi->lccr3 = inf->lccr3; 1194 fbi->lccr3 = inf->lccr3;
1195 fbi->lccr4 = inf->lccr4;
1163 fbi->state = C_STARTUP; 1196 fbi->state = C_STARTUP;
1164 fbi->task_state = (u_char)-1; 1197 fbi->task_state = (u_char)-1;
1165 1198
diff --git a/drivers/video/pxafb.h b/drivers/video/pxafb.h
index f8605b807b0a..d920b8a14c35 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/pxafb.h
@@ -71,6 +71,7 @@ struct pxafb_info {
71 71
72 u_int lccr0; 72 u_int lccr0;
73 u_int lccr3; 73 u_int lccr3;
74 u_int lccr4;
74 u_int cmap_inverse:1, 75 u_int cmap_inverse:1,
75 cmap_static:1, 76 cmap_static:1,
76 unused:30; 77 unused:30;
@@ -79,6 +80,7 @@ struct pxafb_info {
79 u_int reg_lccr1; 80 u_int reg_lccr1;
80 u_int reg_lccr2; 81 u_int reg_lccr2;
81 u_int reg_lccr3; 82 u_int reg_lccr3;
83 u_int reg_lccr4;
82 84
83 unsigned long hsync_time; 85 unsigned long hsync_time;
84 86
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/s3c2410fb.c
index 8a4c6470d799..ae08d4587091 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/s3c2410fb.c
@@ -20,7 +20,7 @@
20 * 20 *
21 * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org> 21 * 2004-12-04: Arnaud Patard <arnaud.patard@rtp-net.org>
22 * - Added the possibility to set on or off the 22 * - Added the possibility to set on or off the
23 * debugging mesaages 23 * debugging messages
24 * - Replaced 0 and 1 by on or off when reading the 24 * - Replaced 0 and 1 by on or off when reading the
25 * /sys files 25 * /sys files
26 * 26 *
@@ -31,8 +31,8 @@
31 * - add pixel clock divisor control 31 * - add pixel clock divisor control
32 * 32 *
33 * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org> 33 * 2004-11-11: Arnaud Patard <arnaud.patard@rtp-net.org>
34 * - Removed the use of currcon as it no more exist 34 * - Removed the use of currcon as it no more exists
35 * - Added LCD power sysfs interface 35 * - Added LCD power sysfs interface
36 * 36 *
37 * 2004-11-03: Ben Dooks <ben-linux@fluff.org> 37 * 2004-11-03: Ben Dooks <ben-linux@fluff.org>
38 * - minor cleanups 38 * - minor cleanups
@@ -49,12 +49,12 @@
49 * - Suppress command line options 49 * - Suppress command line options
50 * 50 *
51 * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org> 51 * 2004-09-15: Arnaud Patard <arnaud.patard@rtp-net.org>
52 * - code cleanup 52 * - code cleanup
53 * 53 *
54 * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org> 54 * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
55 * - Renamed from h1940fb.c to s3c2410fb.c 55 * - Renamed from h1940fb.c to s3c2410fb.c
56 * - Add support for different devices 56 * - Add support for different devices
57 * - Backlight support 57 * - Backlight support
58 * 58 *
59 * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at> 59 * 2004-09-05: Herbert Pötzl <herbert@13thfloor.at>
60 * - added clock (de-)allocation code 60 * - added clock (de-)allocation code
@@ -82,13 +82,10 @@
82#include <linux/init.h> 82#include <linux/init.h>
83#include <linux/dma-mapping.h> 83#include <linux/dma-mapping.h>
84#include <linux/interrupt.h> 84#include <linux/interrupt.h>
85#include <linux/workqueue.h>
86#include <linux/wait.h>
87#include <linux/platform_device.h> 85#include <linux/platform_device.h>
88#include <linux/clk.h> 86#include <linux/clk.h>
89 87
90#include <asm/io.h> 88#include <asm/io.h>
91#include <asm/uaccess.h>
92#include <asm/div64.h> 89#include <asm/div64.h>
93 90
94#include <asm/mach/map.h> 91#include <asm/mach/map.h>
@@ -102,14 +99,11 @@
102 99
103#include "s3c2410fb.h" 100#include "s3c2410fb.h"
104 101
105
106static struct s3c2410fb_mach_info *mach_info;
107
108/* Debugging stuff */ 102/* Debugging stuff */
109#ifdef CONFIG_FB_S3C2410_DEBUG 103#ifdef CONFIG_FB_S3C2410_DEBUG
110static int debug = 1; 104static int debug = 1;
111#else 105#else
112static int debug = 0; 106static int debug = 0;
113#endif 107#endif
114 108
115#define dprintk(msg...) if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); } 109#define dprintk(msg...) if (debug) { printk(KERN_DEBUG "s3c2410fb: " msg); }
@@ -119,48 +113,48 @@ static int debug = 0;
119/* s3c2410fb_set_lcdaddr 113/* s3c2410fb_set_lcdaddr
120 * 114 *
121 * initialise lcd controller address pointers 115 * initialise lcd controller address pointers
122*/ 116 */
123 117static void s3c2410fb_set_lcdaddr(struct fb_info *info)
124static void s3c2410fb_set_lcdaddr(struct s3c2410fb_info *fbi)
125{ 118{
126 struct fb_var_screeninfo *var = &fbi->fb->var;
127 unsigned long saddr1, saddr2, saddr3; 119 unsigned long saddr1, saddr2, saddr3;
120 struct s3c2410fb_info *fbi = info->par;
121 void __iomem *regs = fbi->io;
128 122
129 saddr1 = fbi->fb->fix.smem_start >> 1; 123 saddr1 = info->fix.smem_start >> 1;
130 saddr2 = fbi->fb->fix.smem_start; 124 saddr2 = info->fix.smem_start;
131 saddr2 += (var->xres * var->yres * var->bits_per_pixel)/8; 125 saddr2 += info->fix.line_length * info->var.yres;
132 saddr2>>= 1; 126 saddr2 >>= 1;
133 127
134 saddr3 = S3C2410_OFFSIZE(0) | S3C2410_PAGEWIDTH((var->xres * var->bits_per_pixel / 16) & 0x3ff); 128 saddr3 = S3C2410_OFFSIZE(0) |
129 S3C2410_PAGEWIDTH((info->fix.line_length / 2) & 0x3ff);
135 130
136 dprintk("LCDSADDR1 = 0x%08lx\n", saddr1); 131 dprintk("LCDSADDR1 = 0x%08lx\n", saddr1);
137 dprintk("LCDSADDR2 = 0x%08lx\n", saddr2); 132 dprintk("LCDSADDR2 = 0x%08lx\n", saddr2);
138 dprintk("LCDSADDR3 = 0x%08lx\n", saddr3); 133 dprintk("LCDSADDR3 = 0x%08lx\n", saddr3);
139 134
140 writel(saddr1, S3C2410_LCDSADDR1); 135 writel(saddr1, regs + S3C2410_LCDSADDR1);
141 writel(saddr2, S3C2410_LCDSADDR2); 136 writel(saddr2, regs + S3C2410_LCDSADDR2);
142 writel(saddr3, S3C2410_LCDSADDR3); 137 writel(saddr3, regs + S3C2410_LCDSADDR3);
143} 138}
144 139
145/* s3c2410fb_calc_pixclk() 140/* s3c2410fb_calc_pixclk()
146 * 141 *
147 * calculate divisor for clk->pixclk 142 * calculate divisor for clk->pixclk
148*/ 143 */
149
150static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi, 144static unsigned int s3c2410fb_calc_pixclk(struct s3c2410fb_info *fbi,
151 unsigned long pixclk) 145 unsigned long pixclk)
152{ 146{
153 unsigned long clk = clk_get_rate(fbi->clk); 147 unsigned long clk = clk_get_rate(fbi->clk);
154 unsigned long long div; 148 unsigned long long div;
155 149
156 /* pixclk is in picoseoncds, our clock is in Hz 150 /* pixclk is in picoseconds, our clock is in Hz
157 * 151 *
158 * Hz -> picoseconds is / 10^-12 152 * Hz -> picoseconds is / 10^-12
159 */ 153 */
160 154
161 div = (unsigned long long)clk * pixclk; 155 div = (unsigned long long)clk * pixclk;
162 do_div(div,1000000UL); 156 div >>= 12; /* div / 2^12 */
163 do_div(div,1000000UL); 157 do_div(div, 625 * 625UL * 625); /* div / 5^12 */
164 158
165 dprintk("pixclk %ld, divisor is %ld\n", pixclk, (long)div); 159 dprintk("pixclk %ld, divisor is %ld\n", pixclk, (long)div);
166 return div; 160 return div;
@@ -176,246 +170,278 @@ static int s3c2410fb_check_var(struct fb_var_screeninfo *var,
176 struct fb_info *info) 170 struct fb_info *info)
177{ 171{
178 struct s3c2410fb_info *fbi = info->par; 172 struct s3c2410fb_info *fbi = info->par;
173 struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data;
174 struct s3c2410fb_display *display = NULL;
175 struct s3c2410fb_display *default_display = mach_info->displays +
176 mach_info->default_display;
177 int type = default_display->type;
178 unsigned i;
179 179
180 dprintk("check_var(var=%p, info=%p)\n", var, info); 180 dprintk("check_var(var=%p, info=%p)\n", var, info);
181 181
182 /* validate x/y resolution */ 182 /* validate x/y resolution */
183 /* choose default mode if possible */
184 if (var->yres == default_display->yres &&
185 var->xres == default_display->xres &&
186 var->bits_per_pixel == default_display->bpp)
187 display = default_display;
188 else
189 for (i = 0; i < mach_info->num_displays; i++)
190 if (type == mach_info->displays[i].type &&
191 var->yres == mach_info->displays[i].yres &&
192 var->xres == mach_info->displays[i].xres &&
193 var->bits_per_pixel == mach_info->displays[i].bpp) {
194 display = mach_info->displays + i;
195 break;
196 }
183 197
184 if (var->yres > fbi->mach_info->yres.max) 198 if (!display) {
185 var->yres = fbi->mach_info->yres.max; 199 dprintk("wrong resolution or depth %dx%d at %d bpp\n",
186 else if (var->yres < fbi->mach_info->yres.min) 200 var->xres, var->yres, var->bits_per_pixel);
187 var->yres = fbi->mach_info->yres.min; 201 return -EINVAL;
188 202 }
189 if (var->xres > fbi->mach_info->xres.max)
190 var->yres = fbi->mach_info->xres.max;
191 else if (var->xres < fbi->mach_info->xres.min)
192 var->xres = fbi->mach_info->xres.min;
193
194 /* validate bpp */
195
196 if (var->bits_per_pixel > fbi->mach_info->bpp.max)
197 var->bits_per_pixel = fbi->mach_info->bpp.max;
198 else if (var->bits_per_pixel < fbi->mach_info->bpp.min)
199 var->bits_per_pixel = fbi->mach_info->bpp.min;
200 203
204 /* it is always the size as the display */
205 var->xres_virtual = display->xres;
206 var->yres_virtual = display->yres;
207 var->height = display->height;
208 var->width = display->width;
209
210 /* copy lcd settings */
211 var->pixclock = display->pixclock;
212 var->left_margin = display->left_margin;
213 var->right_margin = display->right_margin;
214 var->upper_margin = display->upper_margin;
215 var->lower_margin = display->lower_margin;
216 var->vsync_len = display->vsync_len;
217 var->hsync_len = display->hsync_len;
218
219 fbi->regs.lcdcon5 = display->lcdcon5;
220 /* set display type */
221 fbi->regs.lcdcon1 = display->type;
222
223 var->transp.offset = 0;
224 var->transp.length = 0;
201 /* set r/g/b positions */ 225 /* set r/g/b positions */
202 switch (var->bits_per_pixel) { 226 switch (var->bits_per_pixel) {
203 case 1: 227 case 1:
204 case 2: 228 case 2:
205 case 4: 229 case 4:
206 var->red.offset = 0; 230 var->red.offset = 0;
207 var->red.length = var->bits_per_pixel; 231 var->red.length = var->bits_per_pixel;
208 var->green = var->red; 232 var->green = var->red;
209 var->blue = var->red; 233 var->blue = var->red;
210 var->transp.offset = 0; 234 break;
211 var->transp.length = 0; 235 case 8:
212 break; 236 if (display->type != S3C2410_LCDCON1_TFT) {
213 case 8: 237 /* 8 bpp 332 */
214 if ( fbi->mach_info->type != S3C2410_LCDCON1_TFT ) { 238 var->red.length = 3;
215 /* 8 bpp 332 */ 239 var->red.offset = 5;
216 var->red.length = 3; 240 var->green.length = 3;
217 var->red.offset = 5; 241 var->green.offset = 2;
218 var->green.length = 3; 242 var->blue.length = 2;
219 var->green.offset = 2;
220 var->blue.length = 2;
221 var->blue.offset = 0;
222 var->transp.length = 0;
223 } else {
224 var->red.offset = 0;
225 var->red.length = var->bits_per_pixel;
226 var->green = var->red;
227 var->blue = var->red;
228 var->transp.offset = 0;
229 var->transp.length = 0;
230 }
231 break;
232 case 12:
233 /* 12 bpp 444 */
234 var->red.length = 4;
235 var->red.offset = 8;
236 var->green.length = 4;
237 var->green.offset = 4;
238 var->blue.length = 4;
239 var->blue.offset = 0; 243 var->blue.offset = 0;
240 var->transp.length = 0; 244 } else {
241 break; 245 var->red.offset = 0;
242
243 default:
244 case 16:
245 if (fbi->regs.lcdcon5 & S3C2410_LCDCON5_FRM565 ) {
246 /* 16 bpp, 565 format */
247 var->red.offset = 11;
248 var->green.offset = 5;
249 var->blue.offset = 0;
250 var->red.length = 5;
251 var->green.length = 6;
252 var->blue.length = 5;
253 var->transp.length = 0;
254 } else {
255 /* 16 bpp, 5551 format */
256 var->red.offset = 11;
257 var->green.offset = 6;
258 var->blue.offset = 1;
259 var->red.length = 5;
260 var->green.length = 5;
261 var->blue.length = 5;
262 var->transp.length = 0;
263 }
264 break;
265 case 24:
266 /* 24 bpp 888 */
267 var->red.length = 8; 246 var->red.length = 8;
268 var->red.offset = 16; 247 var->green = var->red;
269 var->green.length = 8; 248 var->blue = var->red;
270 var->green.offset = 8; 249 }
271 var->blue.length = 8; 250 break;
272 var->blue.offset = 0; 251 case 12:
273 var->transp.length = 0; 252 /* 12 bpp 444 */
274 break; 253 var->red.length = 4;
275 254 var->red.offset = 8;
255 var->green.length = 4;
256 var->green.offset = 4;
257 var->blue.length = 4;
258 var->blue.offset = 0;
259 break;
276 260
261 default:
262 case 16:
263 if (display->lcdcon5 & S3C2410_LCDCON5_FRM565) {
264 /* 16 bpp, 565 format */
265 var->red.offset = 11;
266 var->green.offset = 5;
267 var->blue.offset = 0;
268 var->red.length = 5;
269 var->green.length = 6;
270 var->blue.length = 5;
271 } else {
272 /* 16 bpp, 5551 format */
273 var->red.offset = 11;
274 var->green.offset = 6;
275 var->blue.offset = 1;
276 var->red.length = 5;
277 var->green.length = 5;
278 var->blue.length = 5;
279 }
280 break;
281 case 32:
282 /* 24 bpp 888 and 8 dummy */
283 var->red.length = 8;
284 var->red.offset = 16;
285 var->green.length = 8;
286 var->green.offset = 8;
287 var->blue.length = 8;
288 var->blue.offset = 0;
289 break;
277 } 290 }
278 return 0; 291 return 0;
279} 292}
280 293
281 294/* s3c2410fb_calculate_stn_lcd_regs
282/* s3c2410fb_activate_var
283 * 295 *
284 * activate (set) the controller from the given framebuffer 296 * calculate register values from var settings
285 * information 297 */
286*/ 298static void s3c2410fb_calculate_stn_lcd_regs(const struct fb_info *info,
287 299 struct s3c2410fb_hw *regs)
288static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
289 struct fb_var_screeninfo *var)
290{ 300{
291 int hs; 301 const struct s3c2410fb_info *fbi = info->par;
302 const struct fb_var_screeninfo *var = &info->var;
303 int type = regs->lcdcon1 & ~S3C2410_LCDCON1_TFT;
304 int hs = var->xres >> 2;
305 unsigned wdly = (var->left_margin >> 4) - 1;
306 unsigned wlh = (var->hsync_len >> 4) - 1;
292 307
293 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_MODEMASK; 308 if (type != S3C2410_LCDCON1_STN4)
294 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_TFT; 309 hs >>= 1;
295 310
296 dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres); 311 switch (var->bits_per_pixel) {
297 dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres); 312 case 1:
298 dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel); 313 regs->lcdcon1 |= S3C2410_LCDCON1_STN1BPP;
314 break;
315 case 2:
316 regs->lcdcon1 |= S3C2410_LCDCON1_STN2GREY;
317 break;
318 case 4:
319 regs->lcdcon1 |= S3C2410_LCDCON1_STN4GREY;
320 break;
321 case 8:
322 regs->lcdcon1 |= S3C2410_LCDCON1_STN8BPP;
323 hs *= 3;
324 break;
325 case 12:
326 regs->lcdcon1 |= S3C2410_LCDCON1_STN12BPP;
327 hs *= 3;
328 break;
299 329
300 fbi->regs.lcdcon1 |= fbi->mach_info->type; 330 default:
301 331 /* invalid pixel depth */
302 if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) 332 dev_err(fbi->dev, "invalid bpp %d\n",
303 switch (var->bits_per_pixel) { 333 var->bits_per_pixel);
304 case 1: 334 }
305 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT1BPP; 335 /* update X/Y info */
306 break; 336 dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
307 case 2: 337 var->left_margin, var->right_margin, var->hsync_len);
308 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
309 break;
310 case 4:
311 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
312 break;
313 case 8:
314 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
315 break;
316 case 16:
317 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
318 break;
319
320 default:
321 /* invalid pixel depth */
322 dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel);
323 }
324 else
325 switch (var->bits_per_pixel) {
326 case 1:
327 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN1BPP;
328 break;
329 case 2:
330 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN2GREY;
331 break;
332 case 4:
333 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN4GREY;
334 break;
335 case 8:
336 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN8BPP;
337 break;
338 case 12:
339 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_STN12BPP;
340 break;
341
342 default:
343 /* invalid pixel depth */
344 dev_err(fbi->dev, "invalid bpp %d\n", var->bits_per_pixel);
345 }
346 338
347 /* check to see if we need to update sync/borders */ 339 regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1);
348 340
349 if (!fbi->mach_info->fixed_syncs) { 341 if (wdly > 3)
350 dprintk("setting vert: up=%d, low=%d, sync=%d\n", 342 wdly = 3;
351 var->upper_margin, var->lower_margin,
352 var->vsync_len);
353 343
354 dprintk("setting horz: lft=%d, rt=%d, sync=%d\n", 344 if (wlh > 3)
355 var->left_margin, var->right_margin, 345 wlh = 3;
356 var->hsync_len);
357 346
358 fbi->regs.lcdcon2 = 347 regs->lcdcon3 = S3C2410_LCDCON3_WDLY(wdly) |
359 S3C2410_LCDCON2_VBPD(var->upper_margin - 1) | 348 S3C2410_LCDCON3_LINEBLANK(var->right_margin / 8) |
360 S3C2410_LCDCON2_VFPD(var->lower_margin - 1) | 349 S3C2410_LCDCON3_HOZVAL(hs - 1);
361 S3C2410_LCDCON2_VSPW(var->vsync_len - 1);
362 350
363 fbi->regs.lcdcon3 = 351 regs->lcdcon4 = S3C2410_LCDCON4_WLH(wlh);
364 S3C2410_LCDCON3_HBPD(var->right_margin - 1) | 352}
365 S3C2410_LCDCON3_HFPD(var->left_margin - 1);
366 353
367 fbi->regs.lcdcon4 &= ~S3C2410_LCDCON4_HSPW(0xff); 354/* s3c2410fb_calculate_tft_lcd_regs
368 fbi->regs.lcdcon4 |= S3C2410_LCDCON4_HSPW(var->hsync_len - 1); 355 *
369 } 356 * calculate register values from var settings
357 */
358static void s3c2410fb_calculate_tft_lcd_regs(const struct fb_info *info,
359 struct s3c2410fb_hw *regs)
360{
361 const struct s3c2410fb_info *fbi = info->par;
362 const struct fb_var_screeninfo *var = &info->var;
370 363
364 switch (var->bits_per_pixel) {
365 case 1:
366 regs->lcdcon1 |= S3C2410_LCDCON1_TFT1BPP;
367 break;
368 case 2:
369 regs->lcdcon1 |= S3C2410_LCDCON1_TFT2BPP;
370 break;
371 case 4:
372 regs->lcdcon1 |= S3C2410_LCDCON1_TFT4BPP;
373 break;
374 case 8:
375 regs->lcdcon1 |= S3C2410_LCDCON1_TFT8BPP;
376 regs->lcdcon5 |= S3C2410_LCDCON5_BSWP |
377 S3C2410_LCDCON5_FRM565;
378 regs->lcdcon5 &= ~S3C2410_LCDCON5_HWSWP;
379 break;
380 case 16:
381 regs->lcdcon1 |= S3C2410_LCDCON1_TFT16BPP;
382 regs->lcdcon5 &= ~S3C2410_LCDCON5_BSWP;
383 regs->lcdcon5 |= S3C2410_LCDCON5_HWSWP;
384 break;
385 case 32:
386 regs->lcdcon1 |= S3C2410_LCDCON1_TFT24BPP;
387 regs->lcdcon5 &= ~(S3C2410_LCDCON5_BSWP |
388 S3C2410_LCDCON5_HWSWP |
389 S3C2410_LCDCON5_BPP24BL);
390 break;
391 default:
392 /* invalid pixel depth */
393 dev_err(fbi->dev, "invalid bpp %d\n",
394 var->bits_per_pixel);
395 }
371 /* update X/Y info */ 396 /* update X/Y info */
397 dprintk("setting vert: up=%d, low=%d, sync=%d\n",
398 var->upper_margin, var->lower_margin, var->vsync_len);
372 399
373 fbi->regs.lcdcon2 &= ~S3C2410_LCDCON2_LINEVAL(0x3ff); 400 dprintk("setting horz: lft=%d, rt=%d, sync=%d\n",
374 fbi->regs.lcdcon2 |= S3C2410_LCDCON2_LINEVAL(var->yres - 1); 401 var->left_margin, var->right_margin, var->hsync_len);
375
376 switch(fbi->mach_info->type) {
377 case S3C2410_LCDCON1_DSCAN4:
378 case S3C2410_LCDCON1_STN8:
379 hs = var->xres / 8;
380 break;
381 case S3C2410_LCDCON1_STN4:
382 hs = var->xres / 4;
383 break;
384 default:
385 case S3C2410_LCDCON1_TFT:
386 hs = var->xres;
387 break;
388
389 }
390 402
391 /* Special cases : STN color displays */ 403 regs->lcdcon2 = S3C2410_LCDCON2_LINEVAL(var->yres - 1) |
392 if ( ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN8BPP) \ 404 S3C2410_LCDCON2_VBPD(var->upper_margin - 1) |
393 || ((fbi->regs.lcdcon1 & S3C2410_LCDCON1_MODEMASK) == S3C2410_LCDCON1_STN12BPP) ) { 405 S3C2410_LCDCON2_VFPD(var->lower_margin - 1) |
394 hs = hs * 3; 406 S3C2410_LCDCON2_VSPW(var->vsync_len - 1);
395 }
396 407
408 regs->lcdcon3 = S3C2410_LCDCON3_HBPD(var->right_margin - 1) |
409 S3C2410_LCDCON3_HFPD(var->left_margin - 1) |
410 S3C2410_LCDCON3_HOZVAL(var->xres - 1);
397 411
398 fbi->regs.lcdcon3 &= ~S3C2410_LCDCON3_HOZVAL(0x7ff); 412 regs->lcdcon4 = S3C2410_LCDCON4_HSPW(var->hsync_len - 1);
399 fbi->regs.lcdcon3 |= S3C2410_LCDCON3_HOZVAL(hs - 1); 413}
400 414
401 if (var->pixclock > 0) { 415/* s3c2410fb_activate_var
402 int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock); 416 *
417 * activate (set) the controller from the given framebuffer
418 * information
419 */
420static void s3c2410fb_activate_var(struct fb_info *info)
421{
422 struct s3c2410fb_info *fbi = info->par;
423 void __iomem *regs = fbi->io;
424 int type = fbi->regs.lcdcon1 & S3C2410_LCDCON1_TFT;
425 struct fb_var_screeninfo *var = &info->var;
426 int clkdiv = s3c2410fb_calc_pixclk(fbi, var->pixclock) / 2;
403 427
404 if (fbi->mach_info->type == S3C2410_LCDCON1_TFT) { 428 dprintk("%s: var->xres = %d\n", __FUNCTION__, var->xres);
405 clkdiv = (clkdiv / 2) -1; 429 dprintk("%s: var->yres = %d\n", __FUNCTION__, var->yres);
406 if (clkdiv < 0) 430 dprintk("%s: var->bpp = %d\n", __FUNCTION__, var->bits_per_pixel);
407 clkdiv = 0;
408 }
409 else {
410 clkdiv = (clkdiv / 2);
411 if (clkdiv < 2)
412 clkdiv = 2;
413 }
414 431
415 fbi->regs.lcdcon1 &= ~S3C2410_LCDCON1_CLKVAL(0x3ff); 432 if (type == S3C2410_LCDCON1_TFT) {
416 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv); 433 s3c2410fb_calculate_tft_lcd_regs(info, &fbi->regs);
434 --clkdiv;
435 if (clkdiv < 0)
436 clkdiv = 0;
437 } else {
438 s3c2410fb_calculate_stn_lcd_regs(info, &fbi->regs);
439 if (clkdiv < 2)
440 clkdiv = 2;
417 } 441 }
418 442
443 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_CLKVAL(clkdiv);
444
419 /* write new registers */ 445 /* write new registers */
420 446
421 dprintk("new register set:\n"); 447 dprintk("new register set:\n");
@@ -425,47 +451,48 @@ static void s3c2410fb_activate_var(struct s3c2410fb_info *fbi,
425 dprintk("lcdcon[4] = 0x%08lx\n", fbi->regs.lcdcon4); 451 dprintk("lcdcon[4] = 0x%08lx\n", fbi->regs.lcdcon4);
426 dprintk("lcdcon[5] = 0x%08lx\n", fbi->regs.lcdcon5); 452 dprintk("lcdcon[5] = 0x%08lx\n", fbi->regs.lcdcon5);
427 453
428 writel(fbi->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID, S3C2410_LCDCON1); 454 writel(fbi->regs.lcdcon1 & ~S3C2410_LCDCON1_ENVID,
429 writel(fbi->regs.lcdcon2, S3C2410_LCDCON2); 455 regs + S3C2410_LCDCON1);
430 writel(fbi->regs.lcdcon3, S3C2410_LCDCON3); 456 writel(fbi->regs.lcdcon2, regs + S3C2410_LCDCON2);
431 writel(fbi->regs.lcdcon4, S3C2410_LCDCON4); 457 writel(fbi->regs.lcdcon3, regs + S3C2410_LCDCON3);
432 writel(fbi->regs.lcdcon5, S3C2410_LCDCON5); 458 writel(fbi->regs.lcdcon4, regs + S3C2410_LCDCON4);
459 writel(fbi->regs.lcdcon5, regs + S3C2410_LCDCON5);
433 460
434 /* set lcd address pointers */ 461 /* set lcd address pointers */
435 s3c2410fb_set_lcdaddr(fbi); 462 s3c2410fb_set_lcdaddr(info);
436 463
437 writel(fbi->regs.lcdcon1, S3C2410_LCDCON1); 464 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID,
465 writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1);
438} 466}
439 467
440
441/* 468/*
442 * s3c2410fb_set_par - Optional function. Alters the hardware state. 469 * s3c2410fb_set_par - Alters the hardware state.
443 * @info: frame buffer structure that represents a single frame buffer 470 * @info: frame buffer structure that represents a single frame buffer
444 * 471 *
445 */ 472 */
446static int s3c2410fb_set_par(struct fb_info *info) 473static int s3c2410fb_set_par(struct fb_info *info)
447{ 474{
448 struct s3c2410fb_info *fbi = info->par;
449 struct fb_var_screeninfo *var = &info->var; 475 struct fb_var_screeninfo *var = &info->var;
450 476
451 switch (var->bits_per_pixel) 477 switch (var->bits_per_pixel) {
452 { 478 case 32:
453 case 16: 479 case 16:
454 fbi->fb->fix.visual = FB_VISUAL_TRUECOLOR; 480 case 12:
455 break; 481 info->fix.visual = FB_VISUAL_TRUECOLOR;
456 case 1: 482 break;
457 fbi->fb->fix.visual = FB_VISUAL_MONO01; 483 case 1:
458 break; 484 info->fix.visual = FB_VISUAL_MONO01;
459 default: 485 break;
460 fbi->fb->fix.visual = FB_VISUAL_PSEUDOCOLOR; 486 default:
461 break; 487 info->fix.visual = FB_VISUAL_PSEUDOCOLOR;
488 break;
462 } 489 }
463 490
464 fbi->fb->fix.line_length = (var->width*var->bits_per_pixel)/8; 491 info->fix.line_length = (var->width * var->bits_per_pixel) / 8;
465 492
466 /* activate this new configuration */ 493 /* activate this new configuration */
467 494
468 s3c2410fb_activate_var(fbi, var); 495 s3c2410fb_activate_var(info);
469 return 0; 496 return 0;
470} 497}
471 498
@@ -493,7 +520,8 @@ static void schedule_palette_update(struct s3c2410fb_info *fbi,
493} 520}
494 521
495/* from pxafb.c */ 522/* from pxafb.c */
496static inline unsigned int chan_to_field(unsigned int chan, struct fb_bitfield *bf) 523static inline unsigned int chan_to_field(unsigned int chan,
524 struct fb_bitfield *bf)
497{ 525{
498 chan &= 0xffff; 526 chan &= 0xffff;
499 chan >>= 16 - bf->length; 527 chan >>= 16 - bf->length;
@@ -505,20 +533,22 @@ static int s3c2410fb_setcolreg(unsigned regno,
505 unsigned transp, struct fb_info *info) 533 unsigned transp, struct fb_info *info)
506{ 534{
507 struct s3c2410fb_info *fbi = info->par; 535 struct s3c2410fb_info *fbi = info->par;
536 void __iomem *regs = fbi->io;
508 unsigned int val; 537 unsigned int val;
509 538
510 /* dprintk("setcol: regno=%d, rgb=%d,%d,%d\n", regno, red, green, blue); */ 539 /* dprintk("setcol: regno=%d, rgb=%d,%d,%d\n",
540 regno, red, green, blue); */
511 541
512 switch (fbi->fb->fix.visual) { 542 switch (info->fix.visual) {
513 case FB_VISUAL_TRUECOLOR: 543 case FB_VISUAL_TRUECOLOR:
514 /* true-colour, use pseuo-palette */ 544 /* true-colour, use pseudo-palette */
515 545
516 if (regno < 16) { 546 if (regno < 16) {
517 u32 *pal = fbi->fb->pseudo_palette; 547 u32 *pal = info->pseudo_palette;
518 548
519 val = chan_to_field(red, &fbi->fb->var.red); 549 val = chan_to_field(red, &info->var.red);
520 val |= chan_to_field(green, &fbi->fb->var.green); 550 val |= chan_to_field(green, &info->var.green);
521 val |= chan_to_field(blue, &fbi->fb->var.blue); 551 val |= chan_to_field(blue, &info->var.blue);
522 552
523 pal[regno] = val; 553 pal[regno] = val;
524 } 554 }
@@ -528,25 +558,24 @@ static int s3c2410fb_setcolreg(unsigned regno,
528 if (regno < 256) { 558 if (regno < 256) {
529 /* currently assume RGB 5-6-5 mode */ 559 /* currently assume RGB 5-6-5 mode */
530 560
531 val = ((red >> 0) & 0xf800); 561 val = (red >> 0) & 0xf800;
532 val |= ((green >> 5) & 0x07e0); 562 val |= (green >> 5) & 0x07e0;
533 val |= ((blue >> 11) & 0x001f); 563 val |= (blue >> 11) & 0x001f;
534 564
535 writel(val, S3C2410_TFTPAL(regno)); 565 writel(val, regs + S3C2410_TFTPAL(regno));
536 schedule_palette_update(fbi, regno, val); 566 schedule_palette_update(fbi, regno, val);
537 } 567 }
538 568
539 break; 569 break;
540 570
541 default: 571 default:
542 return 1; /* unknown type */ 572 return 1; /* unknown type */
543 } 573 }
544 574
545 return 0; 575 return 0;
546} 576}
547 577
548 578/*
549/**
550 * s3c2410fb_blank 579 * s3c2410fb_blank
551 * @blank_mode: the blank mode we want. 580 * @blank_mode: the blank mode we want.
552 * @info: frame buffer structure that represents a single frame buffer 581 * @info: frame buffer structure that represents a single frame buffer
@@ -564,31 +593,31 @@ static int s3c2410fb_setcolreg(unsigned regno,
564 */ 593 */
565static int s3c2410fb_blank(int blank_mode, struct fb_info *info) 594static int s3c2410fb_blank(int blank_mode, struct fb_info *info)
566{ 595{
567 dprintk("blank(mode=%d, info=%p)\n", blank_mode, info); 596 struct s3c2410fb_info *fbi = info->par;
597 void __iomem *regs = fbi->io;
568 598
569 if (mach_info == NULL) 599 dprintk("blank(mode=%d, info=%p)\n", blank_mode, info);
570 return -EINVAL;
571 600
572 if (blank_mode == FB_BLANK_UNBLANK) 601 if (blank_mode == FB_BLANK_UNBLANK)
573 writel(0x0, S3C2410_TPAL); 602 writel(0x0, regs + S3C2410_TPAL);
574 else { 603 else {
575 dprintk("setting TPAL to output 0x000000\n"); 604 dprintk("setting TPAL to output 0x000000\n");
576 writel(S3C2410_TPAL_EN, S3C2410_TPAL); 605 writel(S3C2410_TPAL_EN, regs + S3C2410_TPAL);
577 } 606 }
578 607
579 return 0; 608 return 0;
580} 609}
581 610
582static int s3c2410fb_debug_show(struct device *dev, struct device_attribute *attr, char *buf) 611static int s3c2410fb_debug_show(struct device *dev,
612 struct device_attribute *attr, char *buf)
583{ 613{
584 return snprintf(buf, PAGE_SIZE, "%s\n", debug ? "on" : "off"); 614 return snprintf(buf, PAGE_SIZE, "%s\n", debug ? "on" : "off");
585} 615}
586static int s3c2410fb_debug_store(struct device *dev, struct device_attribute *attr,
587 const char *buf, size_t len)
588{
589 if (mach_info == NULL)
590 return -EINVAL;
591 616
617static int s3c2410fb_debug_store(struct device *dev,
618 struct device_attribute *attr,
619 const char *buf, size_t len)
620{
592 if (len < 1) 621 if (len < 1)
593 return -EINVAL; 622 return -EINVAL;
594 623
@@ -607,10 +636,7 @@ static int s3c2410fb_debug_store(struct device *dev, struct device_attribute *at
607 return len; 636 return len;
608} 637}
609 638
610 639static DEVICE_ATTR(debug, 0666, s3c2410fb_debug_show, s3c2410fb_debug_store);
611static DEVICE_ATTR(debug, 0666,
612 s3c2410fb_debug_show,
613 s3c2410fb_debug_store);
614 640
615static struct fb_ops s3c2410fb_ops = { 641static struct fb_ops s3c2410fb_ops = {
616 .owner = THIS_MODULE, 642 .owner = THIS_MODULE,
@@ -623,7 +649,6 @@ static struct fb_ops s3c2410fb_ops = {
623 .fb_imageblit = cfb_imageblit, 649 .fb_imageblit = cfb_imageblit,
624}; 650};
625 651
626
627/* 652/*
628 * s3c2410fb_map_video_memory(): 653 * s3c2410fb_map_video_memory():
629 * Allocates the DRAM memory for the frame buffer. This buffer is 654 * Allocates the DRAM memory for the frame buffer. This buffer is
@@ -632,36 +657,38 @@ static struct fb_ops s3c2410fb_ops = {
632 * cache. Once this area is remapped, all virtual memory 657 * cache. Once this area is remapped, all virtual memory
633 * access to the video memory should occur at the new region. 658 * access to the video memory should occur at the new region.
634 */ 659 */
635static int __init s3c2410fb_map_video_memory(struct s3c2410fb_info *fbi) 660static int __init s3c2410fb_map_video_memory(struct fb_info *info)
636{ 661{
637 dprintk("map_video_memory(fbi=%p)\n", fbi); 662 struct s3c2410fb_info *fbi = info->par;
663 dma_addr_t map_dma;
664 unsigned map_size = PAGE_ALIGN(info->fix.smem_len);
638 665
639 fbi->map_size = PAGE_ALIGN(fbi->fb->fix.smem_len + PAGE_SIZE); 666 dprintk("map_video_memory(fbi=%p)\n", fbi);
640 fbi->map_cpu = dma_alloc_writecombine(fbi->dev, fbi->map_size,
641 &fbi->map_dma, GFP_KERNEL);
642 667
643 fbi->map_size = fbi->fb->fix.smem_len; 668 info->screen_base = dma_alloc_writecombine(fbi->dev, map_size,
669 &map_dma, GFP_KERNEL);
644 670
645 if (fbi->map_cpu) { 671 if (info->screen_base) {
646 /* prevent initial garbage on screen */ 672 /* prevent initial garbage on screen */
647 dprintk("map_video_memory: clear %p:%08x\n", 673 dprintk("map_video_memory: clear %p:%08x\n",
648 fbi->map_cpu, fbi->map_size); 674 info->screen_base, map_size);
649 memset(fbi->map_cpu, 0xf0, fbi->map_size); 675 memset(info->screen_base, 0xf0, map_size);
650 676
651 fbi->screen_dma = fbi->map_dma; 677 info->fix.smem_start = map_dma;
652 fbi->fb->screen_base = fbi->map_cpu;
653 fbi->fb->fix.smem_start = fbi->screen_dma;
654 678
655 dprintk("map_video_memory: dma=%08x cpu=%p size=%08x\n", 679 dprintk("map_video_memory: dma=%08lx cpu=%p size=%08x\n",
656 fbi->map_dma, fbi->map_cpu, fbi->fb->fix.smem_len); 680 info->fix.smem_start, info->screen_base, map_size);
657 } 681 }
658 682
659 return fbi->map_cpu ? 0 : -ENOMEM; 683 return info->screen_base ? 0 : -ENOMEM;
660} 684}
661 685
662static inline void s3c2410fb_unmap_video_memory(struct s3c2410fb_info *fbi) 686static inline void s3c2410fb_unmap_video_memory(struct fb_info *info)
663{ 687{
664 dma_free_writecombine(fbi->dev,fbi->map_size,fbi->map_cpu, fbi->map_dma); 688 struct s3c2410fb_info *fbi = info->par;
689
690 dma_free_writecombine(fbi->dev, PAGE_ALIGN(info->fix.smem_len),
691 info->screen_base, info->fix.smem_start);
665} 692}
666 693
667static inline void modify_gpio(void __iomem *reg, 694static inline void modify_gpio(void __iomem *reg,
@@ -673,13 +700,13 @@ static inline void modify_gpio(void __iomem *reg,
673 writel(tmp | set, reg); 700 writel(tmp | set, reg);
674} 701}
675 702
676
677/* 703/*
678 * s3c2410fb_init_registers - Initialise all LCD-related registers 704 * s3c2410fb_init_registers - Initialise all LCD-related registers
679 */ 705 */
680 706static int s3c2410fb_init_registers(struct fb_info *info)
681static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
682{ 707{
708 struct s3c2410fb_info *fbi = info->par;
709 struct s3c2410fb_mach_info *mach_info = fbi->dev->platform_data;
683 unsigned long flags; 710 unsigned long flags;
684 void __iomem *regs = fbi->io; 711 void __iomem *regs = fbi->io;
685 712
@@ -696,14 +723,6 @@ static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
696 723
697 local_irq_restore(flags); 724 local_irq_restore(flags);
698 725
699 writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1);
700 writel(fbi->regs.lcdcon2, regs + S3C2410_LCDCON2);
701 writel(fbi->regs.lcdcon3, regs + S3C2410_LCDCON3);
702 writel(fbi->regs.lcdcon4, regs + S3C2410_LCDCON4);
703 writel(fbi->regs.lcdcon5, regs + S3C2410_LCDCON5);
704
705 s3c2410fb_set_lcdaddr(fbi);
706
707 dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel); 726 dprintk("LPCSEL = 0x%08lx\n", mach_info->lpcsel);
708 writel(mach_info->lpcsel, regs + S3C2410_LPCSEL); 727 writel(mach_info->lpcsel, regs + S3C2410_LPCSEL);
709 728
@@ -712,22 +731,19 @@ static int s3c2410fb_init_registers(struct s3c2410fb_info *fbi)
712 /* ensure temporary palette disabled */ 731 /* ensure temporary palette disabled */
713 writel(0x00, regs + S3C2410_TPAL); 732 writel(0x00, regs + S3C2410_TPAL);
714 733
715 /* Enable video by setting the ENVID bit to 1 */
716 fbi->regs.lcdcon1 |= S3C2410_LCDCON1_ENVID;
717 writel(fbi->regs.lcdcon1, regs + S3C2410_LCDCON1);
718 return 0; 734 return 0;
719} 735}
720 736
721static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi) 737static void s3c2410fb_write_palette(struct s3c2410fb_info *fbi)
722{ 738{
723 unsigned int i; 739 unsigned int i;
724 unsigned long ent;
725 void __iomem *regs = fbi->io; 740 void __iomem *regs = fbi->io;
726 741
727 fbi->palette_ready = 0; 742 fbi->palette_ready = 0;
728 743
729 for (i = 0; i < 256; i++) { 744 for (i = 0; i < 256; i++) {
730 if ((ent = fbi->palette_buffer[i]) == PALETTE_BUFF_CLEAR) 745 unsigned long ent = fbi->palette_buffer[i];
746 if (ent == PALETTE_BUFF_CLEAR)
731 continue; 747 continue;
732 748
733 writel(ent, regs + S3C2410_TFTPAL(i)); 749 writel(ent, regs + S3C2410_TFTPAL(i));
@@ -761,13 +777,14 @@ static irqreturn_t s3c2410fb_irq(int irq, void *dev_id)
761 return IRQ_HANDLED; 777 return IRQ_HANDLED;
762} 778}
763 779
764static char driver_name[]="s3c2410fb"; 780static char driver_name[] = "s3c2410fb";
765 781
766static int __init s3c2410fb_probe(struct platform_device *pdev) 782static int __init s3c2410fb_probe(struct platform_device *pdev)
767{ 783{
768 struct s3c2410fb_info *info; 784 struct s3c2410fb_info *info;
769 struct fb_info *fbinfo; 785 struct s3c2410fb_display *display;
770 struct s3c2410fb_hw *mregs; 786 struct fb_info *fbinfo;
787 struct s3c2410fb_mach_info *mach_info;
771 struct resource *res; 788 struct resource *res;
772 int ret; 789 int ret;
773 int irq; 790 int irq;
@@ -777,11 +794,12 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
777 794
778 mach_info = pdev->dev.platform_data; 795 mach_info = pdev->dev.platform_data;
779 if (mach_info == NULL) { 796 if (mach_info == NULL) {
780 dev_err(&pdev->dev,"no platform data for lcd, cannot attach\n"); 797 dev_err(&pdev->dev,
798 "no platform data for lcd, cannot attach\n");
781 return -EINVAL; 799 return -EINVAL;
782 } 800 }
783 801
784 mregs = &mach_info->regs; 802 display = mach_info->displays + mach_info->default_display;
785 803
786 irq = platform_get_irq(pdev, 0); 804 irq = platform_get_irq(pdev, 0);
787 if (irq < 0) { 805 if (irq < 0) {
@@ -790,22 +808,22 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
790 } 808 }
791 809
792 fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev); 810 fbinfo = framebuffer_alloc(sizeof(struct s3c2410fb_info), &pdev->dev);
793 if (!fbinfo) { 811 if (!fbinfo)
794 return -ENOMEM; 812 return -ENOMEM;
795 } 813
814 platform_set_drvdata(pdev, fbinfo);
796 815
797 info = fbinfo->par; 816 info = fbinfo->par;
798 info->fb = fbinfo;
799 info->dev = &pdev->dev; 817 info->dev = &pdev->dev;
800 818
801 res = platform_get_resource(pdev, IORESOURCE_MEM, 0); 819 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
802 if (res == NULL) { 820 if (res == NULL) {
803 dev_err(&pdev->dev, "failed to get memory registersn"); 821 dev_err(&pdev->dev, "failed to get memory registers\n");
804 ret = -ENXIO; 822 ret = -ENXIO;
805 goto dealloc_fb; 823 goto dealloc_fb;
806 } 824 }
807 825
808 size = (res->end - res->start)+1; 826 size = (res->end - res->start) + 1;
809 info->mem = request_mem_region(res->start, size, pdev->name); 827 info->mem = request_mem_region(res->start, size, pdev->name);
810 if (info->mem == NULL) { 828 if (info->mem == NULL) {
811 dev_err(&pdev->dev, "failed to get memory region\n"); 829 dev_err(&pdev->dev, "failed to get memory region\n");
@@ -820,21 +838,14 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
820 goto release_mem; 838 goto release_mem;
821 } 839 }
822 840
823 platform_set_drvdata(pdev, fbinfo);
824
825 dprintk("devinit\n"); 841 dprintk("devinit\n");
826 842
827 strcpy(fbinfo->fix.id, driver_name); 843 strcpy(fbinfo->fix.id, driver_name);
828 844
829 memcpy(&info->regs, &mach_info->regs, sizeof(info->regs)); 845 /* Stop the video */
830
831 /* Stop the video and unset ENVID if set */
832 info->regs.lcdcon1 &= ~S3C2410_LCDCON1_ENVID;
833 lcdcon1 = readl(info->io + S3C2410_LCDCON1); 846 lcdcon1 = readl(info->io + S3C2410_LCDCON1);
834 writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1); 847 writel(lcdcon1 & ~S3C2410_LCDCON1_ENVID, info->io + S3C2410_LCDCON1);
835 848
836 info->mach_info = pdev->dev.platform_data;
837
838 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS; 849 fbinfo->fix.type = FB_TYPE_PACKED_PIXELS;
839 fbinfo->fix.type_aux = 0; 850 fbinfo->fix.type_aux = 0;
840 fbinfo->fix.xpanstep = 0; 851 fbinfo->fix.xpanstep = 0;
@@ -844,8 +855,6 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
844 855
845 fbinfo->var.nonstd = 0; 856 fbinfo->var.nonstd = 0;
846 fbinfo->var.activate = FB_ACTIVATE_NOW; 857 fbinfo->var.activate = FB_ACTIVATE_NOW;
847 fbinfo->var.height = mach_info->height;
848 fbinfo->var.width = mach_info->width;
849 fbinfo->var.accel_flags = 0; 858 fbinfo->var.accel_flags = 0;
850 fbinfo->var.vmode = FB_VMODE_NONINTERLACED; 859 fbinfo->var.vmode = FB_VMODE_NONINTERLACED;
851 860
@@ -853,32 +862,6 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
853 fbinfo->flags = FBINFO_FLAG_DEFAULT; 862 fbinfo->flags = FBINFO_FLAG_DEFAULT;
854 fbinfo->pseudo_palette = &info->pseudo_pal; 863 fbinfo->pseudo_palette = &info->pseudo_pal;
855 864
856 fbinfo->var.xres = mach_info->xres.defval;
857 fbinfo->var.xres_virtual = mach_info->xres.defval;
858 fbinfo->var.yres = mach_info->yres.defval;
859 fbinfo->var.yres_virtual = mach_info->yres.defval;
860 fbinfo->var.bits_per_pixel = mach_info->bpp.defval;
861
862 fbinfo->var.upper_margin = S3C2410_LCDCON2_GET_VBPD(mregs->lcdcon2) + 1;
863 fbinfo->var.lower_margin = S3C2410_LCDCON2_GET_VFPD(mregs->lcdcon2) + 1;
864 fbinfo->var.vsync_len = S3C2410_LCDCON2_GET_VSPW(mregs->lcdcon2) + 1;
865
866 fbinfo->var.left_margin = S3C2410_LCDCON3_GET_HFPD(mregs->lcdcon3) + 1;
867 fbinfo->var.right_margin = S3C2410_LCDCON3_GET_HBPD(mregs->lcdcon3) + 1;
868 fbinfo->var.hsync_len = S3C2410_LCDCON4_GET_HSPW(mregs->lcdcon4) + 1;
869
870 fbinfo->var.red.offset = 11;
871 fbinfo->var.green.offset = 5;
872 fbinfo->var.blue.offset = 0;
873 fbinfo->var.transp.offset = 0;
874 fbinfo->var.red.length = 5;
875 fbinfo->var.green.length = 6;
876 fbinfo->var.blue.length = 5;
877 fbinfo->var.transp.length = 0;
878 fbinfo->fix.smem_len = mach_info->xres.max *
879 mach_info->yres.max *
880 mach_info->bpp.max / 8;
881
882 for (i = 0; i < 256; i++) 865 for (i = 0; i < 256; i++)
883 info->palette_buffer[i] = PALETTE_BUFF_CLEAR; 866 info->palette_buffer[i] = PALETTE_BUFF_CLEAR;
884 867
@@ -901,23 +884,39 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
901 884
902 msleep(1); 885 msleep(1);
903 886
887 /* find maximum required memory size for display */
888 for (i = 0; i < mach_info->num_displays; i++) {
889 unsigned long smem_len = mach_info->displays[i].xres;
890
891 smem_len *= mach_info->displays[i].yres;
892 smem_len *= mach_info->displays[i].bpp;
893 smem_len >>= 3;
894 if (fbinfo->fix.smem_len < smem_len)
895 fbinfo->fix.smem_len = smem_len;
896 }
897
904 /* Initialize video memory */ 898 /* Initialize video memory */
905 ret = s3c2410fb_map_video_memory(info); 899 ret = s3c2410fb_map_video_memory(fbinfo);
906 if (ret) { 900 if (ret) {
907 printk( KERN_ERR "Failed to allocate video RAM: %d\n", ret); 901 printk(KERN_ERR "Failed to allocate video RAM: %d\n", ret);
908 ret = -ENOMEM; 902 ret = -ENOMEM;
909 goto release_clock; 903 goto release_clock;
910 } 904 }
911 905
912 dprintk("got video memory\n"); 906 dprintk("got video memory\n");
913 907
914 ret = s3c2410fb_init_registers(info); 908 fbinfo->var.xres = display->xres;
909 fbinfo->var.yres = display->yres;
910 fbinfo->var.bits_per_pixel = display->bpp;
911
912 s3c2410fb_init_registers(fbinfo);
915 913
916 ret = s3c2410fb_check_var(&fbinfo->var, fbinfo); 914 s3c2410fb_check_var(&fbinfo->var, fbinfo);
917 915
918 ret = register_framebuffer(fbinfo); 916 ret = register_framebuffer(fbinfo);
919 if (ret < 0) { 917 if (ret < 0) {
920 printk(KERN_ERR "Failed to register framebuffer device: %d\n", ret); 918 printk(KERN_ERR "Failed to register framebuffer device: %d\n",
919 ret);
921 goto free_video_memory; 920 goto free_video_memory;
922 } 921 }
923 922
@@ -930,18 +929,19 @@ static int __init s3c2410fb_probe(struct platform_device *pdev)
930 return 0; 929 return 0;
931 930
932free_video_memory: 931free_video_memory:
933 s3c2410fb_unmap_video_memory(info); 932 s3c2410fb_unmap_video_memory(fbinfo);
934release_clock: 933release_clock:
935 clk_disable(info->clk); 934 clk_disable(info->clk);
936 clk_put(info->clk); 935 clk_put(info->clk);
937release_irq: 936release_irq:
938 free_irq(irq,info); 937 free_irq(irq, info);
939release_regs: 938release_regs:
940 iounmap(info->io); 939 iounmap(info->io);
941release_mem: 940release_mem:
942 release_resource(info->mem); 941 release_resource(info->mem);
943 kfree(info->mem); 942 kfree(info->mem);
944dealloc_fb: 943dealloc_fb:
944 platform_set_drvdata(pdev, NULL);
945 framebuffer_release(fbinfo); 945 framebuffer_release(fbinfo);
946 return ret; 946 return ret;
947} 947}
@@ -949,8 +949,7 @@ dealloc_fb:
949/* s3c2410fb_stop_lcd 949/* s3c2410fb_stop_lcd
950 * 950 *
951 * shutdown the lcd controller 951 * shutdown the lcd controller
952*/ 952 */
953
954static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi) 953static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi)
955{ 954{
956 unsigned long flags; 955 unsigned long flags;
@@ -968,28 +967,33 @@ static void s3c2410fb_stop_lcd(struct s3c2410fb_info *fbi)
968 */ 967 */
969static int s3c2410fb_remove(struct platform_device *pdev) 968static int s3c2410fb_remove(struct platform_device *pdev)
970{ 969{
971 struct fb_info *fbinfo = platform_get_drvdata(pdev); 970 struct fb_info *fbinfo = platform_get_drvdata(pdev);
972 struct s3c2410fb_info *info = fbinfo->par; 971 struct s3c2410fb_info *info = fbinfo->par;
973 int irq; 972 int irq;
974 973
974 unregister_framebuffer(fbinfo);
975
975 s3c2410fb_stop_lcd(info); 976 s3c2410fb_stop_lcd(info);
976 msleep(1); 977 msleep(1);
977 978
978 s3c2410fb_unmap_video_memory(info); 979 s3c2410fb_unmap_video_memory(fbinfo);
979 980
980 if (info->clk) { 981 if (info->clk) {
981 clk_disable(info->clk); 982 clk_disable(info->clk);
982 clk_put(info->clk); 983 clk_put(info->clk);
983 info->clk = NULL; 984 info->clk = NULL;
984 } 985 }
985 986
986 irq = platform_get_irq(pdev, 0); 987 irq = platform_get_irq(pdev, 0);
987 free_irq(irq,info); 988 free_irq(irq, info);
989
990 iounmap(info->io);
988 991
989 release_resource(info->mem); 992 release_resource(info->mem);
990 kfree(info->mem); 993 kfree(info->mem);
991 iounmap(info->io); 994
992 unregister_framebuffer(fbinfo); 995 platform_set_drvdata(pdev, NULL);
996 framebuffer_release(fbinfo);
993 997
994 return 0; 998 return 0;
995} 999}
@@ -997,7 +1001,6 @@ static int s3c2410fb_remove(struct platform_device *pdev)
997#ifdef CONFIG_PM 1001#ifdef CONFIG_PM
998 1002
999/* suspend and resume support for the lcd controller */ 1003/* suspend and resume support for the lcd controller */
1000
1001static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state) 1004static int s3c2410fb_suspend(struct platform_device *dev, pm_message_t state)
1002{ 1005{
1003 struct fb_info *fbinfo = platform_get_drvdata(dev); 1006 struct fb_info *fbinfo = platform_get_drvdata(dev);
@@ -1044,7 +1047,7 @@ static struct platform_driver s3c2410fb_driver = {
1044 }, 1047 },
1045}; 1048};
1046 1049
1047int __devinit s3c2410fb_init(void) 1050int __init s3c2410fb_init(void)
1048{ 1051{
1049 return platform_driver_register(&s3c2410fb_driver); 1052 return platform_driver_register(&s3c2410fb_driver);
1050} 1053}
@@ -1054,10 +1057,10 @@ static void __exit s3c2410fb_cleanup(void)
1054 platform_driver_unregister(&s3c2410fb_driver); 1057 platform_driver_unregister(&s3c2410fb_driver);
1055} 1058}
1056 1059
1057
1058module_init(s3c2410fb_init); 1060module_init(s3c2410fb_init);
1059module_exit(s3c2410fb_cleanup); 1061module_exit(s3c2410fb_cleanup);
1060 1062
1061MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, Ben Dooks <ben-linux@fluff.org>"); 1063MODULE_AUTHOR("Arnaud Patard <arnaud.patard@rtp-net.org>, "
1064 "Ben Dooks <ben-linux@fluff.org>");
1062MODULE_DESCRIPTION("Framebuffer driver for the s3c2410"); 1065MODULE_DESCRIPTION("Framebuffer driver for the s3c2410");
1063MODULE_LICENSE("GPL"); 1066MODULE_LICENSE("GPL");
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/s3c2410fb.h
index 17c7915b7acd..6ce5dc26c5f7 100644
--- a/drivers/video/s3c2410fb.h
+++ b/drivers/video/s3c2410fb.h
@@ -16,7 +16,7 @@
16 * 16 *
17 * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org> 17 * 2004-09-07: Arnaud Patard <arnaud.patard@rtp-net.org>
18 * - Renamed from h1940fb.h to s3c2410fb.h 18 * - Renamed from h1940fb.h to s3c2410fb.h
19 * - Chenged h1940 to s3c2410 19 * - Changed h1940 to s3c2410
20 * 20 *
21 * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org> 21 * 2004-07-15: Arnaud Patard <arnaud.patard@rtp-net.org>
22 * - First version 22 * - First version
@@ -26,25 +26,14 @@
26#define __S3C2410FB_H 26#define __S3C2410FB_H
27 27
28struct s3c2410fb_info { 28struct s3c2410fb_info {
29 struct fb_info *fb;
30 struct device *dev; 29 struct device *dev;
31 struct clk *clk; 30 struct clk *clk;
32 31
33 struct resource *mem; 32 struct resource *mem;
34 void __iomem *io; 33 void __iomem *io;
35 34
36 struct s3c2410fb_mach_info *mach_info;
37
38 /* raw memory addresses */
39 dma_addr_t map_dma; /* physical */
40 u_char * map_cpu; /* virtual */
41 u_int map_size;
42
43 struct s3c2410fb_hw regs; 35 struct s3c2410fb_hw regs;
44 36
45 /* addresses of pieces placed in raw buffer */
46 u_char * screen_cpu; /* virtual address of buffer */
47 dma_addr_t screen_dma; /* physical address of buffer */
48 unsigned int palette_ready; 37 unsigned int palette_ready;
49 38
50 /* keep these registers in case we need to re-write palette */ 39 /* keep these registers in case we need to re-write palette */
diff --git a/drivers/video/s3fb.c b/drivers/video/s3fb.c
index d11735895a01..7d53bc23b9c7 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/s3fb.c
@@ -400,11 +400,17 @@ static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
400{ 400{
401 struct s3fb_info *par = info->par; 401 struct s3fb_info *par = info->par;
402 int rv, mem, step; 402 int rv, mem, step;
403 u16 m, n, r;
403 404
404 /* Find appropriate format */ 405 /* Find appropriate format */
405 rv = svga_match_format (s3fb_formats, var, NULL); 406 rv = svga_match_format (s3fb_formats, var, NULL);
406 if ((rv < 0) || ((par->chip == CHIP_988_VIRGE_VX) ? (rv == 7) : (rv == 6))) 407
407 { /* 24bpp on VIRGE VX, 32bpp on others */ 408 /* 32bpp mode is not supported on VIRGE VX,
409 24bpp is not supported on others */
410 if ((par->chip == CHIP_988_VIRGE_VX) ? (rv == 7) : (rv == 6))
411 rv = -EINVAL;
412
413 if (rv < 0) {
408 printk(KERN_ERR "fb%d: unsupported mode requested\n", info->node); 414 printk(KERN_ERR "fb%d: unsupported mode requested\n", info->node);
409 return rv; 415 return rv;
410 } 416 }
@@ -422,20 +428,26 @@ static int s3fb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
422 428
423 /* Check whether have enough memory */ 429 /* Check whether have enough memory */
424 mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual; 430 mem = ((var->bits_per_pixel * var->xres_virtual) >> 3) * var->yres_virtual;
425 if (mem > info->screen_size) 431 if (mem > info->screen_size) {
426 {
427 printk(KERN_ERR "fb%d: not enough framebuffer memory (%d kB requested , %d kB available)\n", 432 printk(KERN_ERR "fb%d: not enough framebuffer memory (%d kB requested , %d kB available)\n",
428 info->node, mem >> 10, (unsigned int) (info->screen_size >> 10)); 433 info->node, mem >> 10, (unsigned int) (info->screen_size >> 10));
429 return -EINVAL; 434 return -EINVAL;
430 } 435 }
431 436
432 rv = svga_check_timings (&s3_timing_regs, var, info->node); 437 rv = svga_check_timings (&s3_timing_regs, var, info->node);
433 if (rv < 0) 438 if (rv < 0) {
434 {
435 printk(KERN_ERR "fb%d: invalid timings requested\n", info->node); 439 printk(KERN_ERR "fb%d: invalid timings requested\n", info->node);
436 return rv; 440 return rv;
437 } 441 }
438 442
443 rv = svga_compute_pll(&s3_pll, PICOS2KHZ(var->pixclock), &m, &n, &r,
444 info->node);
445 if (rv < 0) {
446 printk(KERN_ERR "fb%d: invalid pixclock value requested\n",
447 info->node);
448 return rv;
449 }
450
439 return 0; 451 return 0;
440} 452}
441 453
diff --git a/drivers/video/sa1100fb.c b/drivers/video/sa1100fb.c
index 5d2a4a4b731c..ab2b2110478b 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/sa1100fb.c
@@ -178,7 +178,6 @@
178#include <asm/hardware.h> 178#include <asm/hardware.h>
179#include <asm/io.h> 179#include <asm/io.h>
180#include <asm/mach-types.h> 180#include <asm/mach-types.h>
181#include <asm/uaccess.h>
182#include <asm/arch/assabet.h> 181#include <asm/arch/assabet.h>
183#include <asm/arch/shannon.h> 182#include <asm/arch/shannon.h>
184 183
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/savage/savagefb_driver.c
index b855f4a34afe..37b135d5d12e 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/savage/savagefb_driver.c
@@ -57,7 +57,6 @@
57#include <asm/irq.h> 57#include <asm/irq.h>
58#include <asm/pgtable.h> 58#include <asm/pgtable.h>
59#include <asm/system.h> 59#include <asm/system.h>
60#include <asm/uaccess.h>
61 60
62#ifdef CONFIG_MTRR 61#ifdef CONFIG_MTRR
63#include <asm/mtrr.h> 62#include <asm/mtrr.h>
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/sis/sis_main.c
index e8ccace01252..bc7d23683735 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/sis/sis_main.c
@@ -58,7 +58,7 @@
58#include <linux/capability.h> 58#include <linux/capability.h>
59#include <linux/fs.h> 59#include <linux/fs.h>
60#include <linux/types.h> 60#include <linux/types.h>
61#include <asm/uaccess.h> 61#include <linux/uaccess.h>
62#include <asm/io.h> 62#include <asm/io.h>
63#ifdef CONFIG_MTRR 63#ifdef CONFIG_MTRR
64#include <asm/mtrr.h> 64#include <asm/mtrr.h>
diff --git a/drivers/video/skeletonfb.c b/drivers/video/skeletonfb.c
index 64779e70408f..62321458f71a 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/skeletonfb.c
@@ -780,7 +780,7 @@ static int __devinit xxxfb_probe(struct pci_dev *dev,
780 * 780 *
781 * NOTE: This field is currently unused. 781 * NOTE: This field is currently unused.
782 */ 782 */
783 info->pixmap.scan_align = 32; 783 info->pixmap.access_align = 32;
784/***************************** End optional stage ***************************/ 784/***************************** End optional stage ***************************/
785 785
786 /* 786 /*
diff --git a/drivers/video/sm501fb.c b/drivers/video/sm501fb.c
index c86df126f93a..1be95a68d696 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/sm501fb.c
@@ -28,6 +28,7 @@
28#include <linux/wait.h> 28#include <linux/wait.h>
29#include <linux/platform_device.h> 29#include <linux/platform_device.h>
30#include <linux/clk.h> 30#include <linux/clk.h>
31#include <linux/console.h>
31 32
32#include <asm/io.h> 33#include <asm/io.h>
33#include <asm/uaccess.h> 34#include <asm/uaccess.h>
@@ -62,6 +63,8 @@ struct sm501fb_info {
62 struct resource *regs_res; /* registers resource */ 63 struct resource *regs_res; /* registers resource */
63 struct sm501_platdata_fb *pdata; /* our platform data */ 64 struct sm501_platdata_fb *pdata; /* our platform data */
64 65
66 unsigned long pm_crt_ctrl; /* pm: crt ctrl save */
67
65 int irq; 68 int irq;
66 int swap_endian; /* set to swap rgb=>bgr */ 69 int swap_endian; /* set to swap rgb=>bgr */
67 void __iomem *regs; /* remapped registers */ 70 void __iomem *regs; /* remapped registers */
@@ -774,6 +777,11 @@ static int sm501fb_set_par_pnl(struct fb_info *info)
774 writel(control, fbi->regs + SM501_DC_PANEL_CONTROL); 777 writel(control, fbi->regs + SM501_DC_PANEL_CONTROL);
775 sm501fb_sync_regs(fbi); 778 sm501fb_sync_regs(fbi);
776 779
780 /* ensure the panel interface is not tristated at this point */
781
782 sm501_modify_reg(fbi->dev->parent, SM501_SYSTEM_CONTROL,
783 0, SM501_SYSCTRL_PANEL_TRISTATE);
784
777 /* power the panel up */ 785 /* power the panel up */
778 sm501fb_panel_power(fbi, 1); 786 sm501fb_panel_power(fbi, 1);
779 return 0; 787 return 0;
@@ -1687,19 +1695,25 @@ static int sm501fb_suspend_fb(struct sm501fb_info *info,
1687 goto err_nocursor; 1695 goto err_nocursor;
1688 } 1696 }
1689 1697
1698 dev_dbg(info->dev, "suspending screen to %p\n", par->store_fb);
1699 dev_dbg(info->dev, "suspending cursor to %p\n", par->store_cursor);
1700
1690 memcpy_fromio(par->store_fb, par->screen.k_addr, par->screen.size); 1701 memcpy_fromio(par->store_fb, par->screen.k_addr, par->screen.size);
1691 memcpy_fromio(par->store_cursor, par->cursor.k_addr, par->cursor.size); 1702 memcpy_fromio(par->store_cursor, par->cursor.k_addr, par->cursor.size);
1692
1693 /* blank the relevant interface to ensure unit power minimised */ 1703 /* blank the relevant interface to ensure unit power minimised */
1694 (par->ops.fb_blank)(FB_BLANK_POWERDOWN, fbi); 1704 (par->ops.fb_blank)(FB_BLANK_POWERDOWN, fbi);
1695 1705
1706 acquire_console_sem();
1707 fb_set_suspend(fbi, 1);
1708 release_console_sem();
1709
1696 return 0; 1710 return 0;
1697 1711
1698 err_nocursor: 1712 err_nocursor:
1699 vfree(par->store_fb); 1713 vfree(par->store_fb);
1714 par->store_fb = NULL;
1700 1715
1701 return -ENOMEM; 1716 return -ENOMEM;
1702
1703} 1717}
1704 1718
1705static void sm501fb_resume_fb(struct sm501fb_info *info, 1719static void sm501fb_resume_fb(struct sm501fb_info *info,
@@ -1717,8 +1731,20 @@ static void sm501fb_resume_fb(struct sm501fb_info *info,
1717 1731
1718 /* restore the data */ 1732 /* restore the data */
1719 1733
1720 memcpy_toio(par->screen.k_addr, par->store_fb, par->screen.size); 1734 dev_dbg(info->dev, "restoring screen from %p\n", par->store_fb);
1721 memcpy_toio(par->cursor.k_addr, par->store_cursor, par->cursor.size); 1735 dev_dbg(info->dev, "restoring cursor from %p\n", par->store_cursor);
1736
1737 if (par->store_fb)
1738 memcpy_toio(par->screen.k_addr, par->store_fb,
1739 par->screen.size);
1740
1741 if (par->store_cursor)
1742 memcpy_toio(par->cursor.k_addr, par->store_cursor,
1743 par->cursor.size);
1744
1745 acquire_console_sem();
1746 fb_set_suspend(fbi, 0);
1747 release_console_sem();
1722 1748
1723 vfree(par->store_fb); 1749 vfree(par->store_fb);
1724 vfree(par->store_cursor); 1750 vfree(par->store_cursor);
@@ -1731,6 +1757,9 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
1731{ 1757{
1732 struct sm501fb_info *info = platform_get_drvdata(pdev); 1758 struct sm501fb_info *info = platform_get_drvdata(pdev);
1733 1759
1760 /* store crt control to resume with */
1761 info->pm_crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
1762
1734 sm501fb_suspend_fb(info, HEAD_CRT); 1763 sm501fb_suspend_fb(info, HEAD_CRT);
1735 sm501fb_suspend_fb(info, HEAD_PANEL); 1764 sm501fb_suspend_fb(info, HEAD_PANEL);
1736 1765
@@ -1740,12 +1769,24 @@ static int sm501fb_suspend(struct platform_device *pdev, pm_message_t state)
1740 return 0; 1769 return 0;
1741} 1770}
1742 1771
1772#define SM501_CRT_CTRL_SAVE (SM501_DC_CRT_CONTROL_TVP | \
1773 SM501_DC_CRT_CONTROL_SEL)
1774
1775
1743static int sm501fb_resume(struct platform_device *pdev) 1776static int sm501fb_resume(struct platform_device *pdev)
1744{ 1777{
1745 struct sm501fb_info *info = platform_get_drvdata(pdev); 1778 struct sm501fb_info *info = platform_get_drvdata(pdev);
1779 unsigned long crt_ctrl;
1746 1780
1747 sm501_unit_power(info->dev->parent, SM501_GATE_DISPLAY, 1); 1781 sm501_unit_power(info->dev->parent, SM501_GATE_DISPLAY, 1);
1748 1782
1783 /* restore the items we want to be saved for crt control */
1784
1785 crt_ctrl = readl(info->regs + SM501_DC_CRT_CONTROL);
1786 crt_ctrl &= ~SM501_CRT_CTRL_SAVE;
1787 crt_ctrl |= info->pm_crt_ctrl & SM501_CRT_CTRL_SAVE;
1788 writel(crt_ctrl, info->regs + SM501_DC_CRT_CONTROL);
1789
1749 sm501fb_resume_fb(info, HEAD_CRT); 1790 sm501fb_resume_fb(info, HEAD_CRT);
1750 sm501fb_resume_fb(info, HEAD_PANEL); 1791 sm501fb_resume_fb(info, HEAD_PANEL);
1751 1792
diff --git a/drivers/video/sstfb.c b/drivers/video/sstfb.c
index 5eff28ce4f4d..97784f9c184d 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/sstfb.c
@@ -88,7 +88,7 @@
88#include <linux/init.h> 88#include <linux/init.h>
89#include <linux/slab.h> 89#include <linux/slab.h>
90#include <asm/io.h> 90#include <asm/io.h>
91#include <asm/uaccess.h> 91#include <linux/uaccess.h>
92#include <video/sstfb.h> 92#include <video/sstfb.h>
93 93
94 94
diff --git a/drivers/video/svgalib.c b/drivers/video/svgalib.c
index 25df928d37d8..9c7106701572 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/svgalib.c
@@ -598,9 +598,11 @@ void svga_set_timings(const struct svga_timing_regs *tm, struct fb_var_screeninf
598/* ------------------------------------------------------------------------- */ 598/* ------------------------------------------------------------------------- */
599 599
600 600
601int svga_match_format(const struct svga_fb_format *frm, struct fb_var_screeninfo *var, struct fb_fix_screeninfo *fix) 601static inline int match_format(const struct svga_fb_format *frm,
602 struct fb_var_screeninfo *var)
602{ 603{
603 int i = 0; 604 int i = 0;
605 int stored = -EINVAL;
604 606
605 while (frm->bits_per_pixel != SVGA_FORMAT_END_VAL) 607 while (frm->bits_per_pixel != SVGA_FORMAT_END_VAL)
606 { 608 {
@@ -609,25 +611,38 @@ int svga_match_format(const struct svga_fb_format *frm, struct fb_var_screeninfo
609 (var->green.length <= frm->green.length) && 611 (var->green.length <= frm->green.length) &&
610 (var->blue.length <= frm->blue.length) && 612 (var->blue.length <= frm->blue.length) &&
611 (var->transp.length <= frm->transp.length) && 613 (var->transp.length <= frm->transp.length) &&
612 (var->nonstd == frm->nonstd)) { 614 (var->nonstd == frm->nonstd))
613 var->bits_per_pixel = frm->bits_per_pixel;
614 var->red = frm->red;
615 var->green = frm->green;
616 var->blue = frm->blue;
617 var->transp = frm->transp;
618 var->nonstd = frm->nonstd;
619 if (fix != NULL) {
620 fix->type = frm->type;
621 fix->type_aux = frm->type_aux;
622 fix->visual = frm->visual;
623 fix->xpanstep = frm->xpanstep;
624 }
625 return i; 615 return i;
626 } 616 if (var->bits_per_pixel == frm->bits_per_pixel)
617 stored = i;
627 i++; 618 i++;
628 frm++; 619 frm++;
629 } 620 }
630 return -EINVAL; 621 return stored;
622}
623
624int svga_match_format(const struct svga_fb_format *frm,
625 struct fb_var_screeninfo *var,
626 struct fb_fix_screeninfo *fix)
627{
628 int i = match_format(frm, var);
629
630 if (i >= 0) {
631 var->bits_per_pixel = frm[i].bits_per_pixel;
632 var->red = frm[i].red;
633 var->green = frm[i].green;
634 var->blue = frm[i].blue;
635 var->transp = frm[i].transp;
636 var->nonstd = frm[i].nonstd;
637 if (fix != NULL) {
638 fix->type = frm[i].type;
639 fix->type_aux = frm[i].type_aux;
640 fix->visual = frm[i].visual;
641 fix->xpanstep = frm[i].xpanstep;
642 }
643 }
644
645 return i;
631} 646}
632 647
633 648
diff --git a/drivers/video/tdfxfb.c b/drivers/video/tdfxfb.c
index 689ce0270b81..057bdd593800 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/tdfxfb.c
@@ -4,13 +4,13 @@
4 * 4 *
5 * Author: Hannu Mallat <hmallat@cc.hut.fi> 5 * Author: Hannu Mallat <hmallat@cc.hut.fi>
6 * 6 *
7 * Copyright © 1999 Hannu Mallat 7 * Copyright © 1999 Hannu Mallat
8 * All rights reserved 8 * All rights reserved
9 * 9 *
10 * Created : Thu Sep 23 18:17:43 1999, hmallat 10 * Created : Thu Sep 23 18:17:43 1999, hmallat
11 * Last modified: Tue Nov 2 21:19:47 1999, hmallat 11 * Last modified: Tue Nov 2 21:19:47 1999, hmallat
12 * 12 *
13 * Lots of the information here comes from the Daryll Strauss' Banshee 13 * Lots of the information here comes from the Daryll Strauss' Banshee
14 * patches to the XF86 server, and the rest comes from the 3dfx 14 * patches to the XF86 server, and the rest comes from the 3dfx
15 * Banshee specification. I'm very much indebted to Daryll for his 15 * Banshee specification. I'm very much indebted to Daryll for his
16 * work on the X server. 16 * work on the X server.
@@ -23,7 +23,7 @@
23 * behave very differently from the Voodoo3/4/5. For anyone wanting to 23 * behave very differently from the Voodoo3/4/5. For anyone wanting to
24 * use frame buffer on the Voodoo1/2, see the sstfb driver (which is 24 * use frame buffer on the Voodoo1/2, see the sstfb driver (which is
25 * located at http://www.sourceforge.net/projects/sstfb). 25 * located at http://www.sourceforge.net/projects/sstfb).
26 * 26 *
27 * While I _am_ grateful to 3Dfx for releasing the specs for Banshee, 27 * While I _am_ grateful to 3Dfx for releasing the specs for Banshee,
28 * I do wish the next version is a bit more complete. Without the XF86 28 * I do wish the next version is a bit more complete. Without the XF86
29 * patches I couldn't have gotten even this far... for instance, the 29 * patches I couldn't have gotten even this far... for instance, the
@@ -33,9 +33,8 @@
33 * 33 *
34 * The structure of this driver comes pretty much from the Permedia 34 * The structure of this driver comes pretty much from the Permedia
35 * driver by Ilario Nardinocchi, which in turn is based on skeletonfb. 35 * driver by Ilario Nardinocchi, which in turn is based on skeletonfb.
36 * 36 *
37 * TODO: 37 * TODO:
38 * - support for 16/32 bpp needs fixing (funky bootup penguin)
39 * - multihead support (basically need to support an array of fb_infos) 38 * - multihead support (basically need to support an array of fb_infos)
40 * - support other architectures (PPC, Alpha); does the fact that the VGA 39 * - support other architectures (PPC, Alpha); does the fact that the VGA
41 * core can be accessed only thru I/O (not memory mapped) complicate 40 * core can be accessed only thru I/O (not memory mapped) complicate
@@ -43,18 +42,18 @@
43 * 42 *
44 * Version history: 43 * Version history:
45 * 44 *
46 * 0.1.4 (released 2002-05-28) ported over to new fbdev api by James Simmons 45 * 0.1.4 (released 2002-05-28) ported over to new fbdev api by James Simmons
47 * 46 *
48 * 0.1.3 (released 1999-11-02) added Attila's panning support, code 47 * 0.1.3 (released 1999-11-02) added Attila's panning support, code
49 * reorg, hwcursor address page size alignment 48 * reorg, hwcursor address page size alignment
50 * (for mmaping both frame buffer and regs), 49 * (for mmaping both frame buffer and regs),
51 * and my changes to get rid of hardcoded 50 * and my changes to get rid of hardcoded
52 * VGA i/o register locations (uses PCI 51 * VGA i/o register locations (uses PCI
53 * configuration info now) 52 * configuration info now)
54 * 0.1.2 (released 1999-10-19) added Attila Kesmarki's bug fixes and 53 * 0.1.2 (released 1999-10-19) added Attila Kesmarki's bug fixes and
55 * improvements 54 * improvements
56 * 0.1.1 (released 1999-10-07) added Voodoo3 support by Harold Oga. 55 * 0.1.1 (released 1999-10-07) added Voodoo3 support by Harold Oga.
57 * 0.1.0 (released 1999-10-06) initial version 56 * 0.1.0 (released 1999-10-06) initial version
58 * 57 *
59 */ 58 */
60 59
@@ -64,24 +63,32 @@
64#include <linux/string.h> 63#include <linux/string.h>
65#include <linux/mm.h> 64#include <linux/mm.h>
66#include <linux/slab.h> 65#include <linux/slab.h>
67#include <linux/delay.h>
68#include <linux/interrupt.h>
69#include <linux/fb.h> 66#include <linux/fb.h>
70#include <linux/init.h> 67#include <linux/init.h>
71#include <linux/pci.h> 68#include <linux/pci.h>
72#include <linux/nvram.h>
73#include <asm/io.h> 69#include <asm/io.h>
74#include <linux/timer.h>
75#include <linux/spinlock.h>
76 70
77#include <video/tdfx.h> 71#include <video/tdfx.h>
78 72
79#undef TDFXFB_DEBUG 73#define DPRINTK(a, b...) pr_debug("fb: %s: " a, __FUNCTION__ , ## b)
80#ifdef TDFXFB_DEBUG 74
81#define DPRINTK(a,b...) printk(KERN_DEBUG "fb: %s: " a, __FUNCTION__ , ## b) 75#ifdef CONFIG_MTRR
76#include <asm/mtrr.h>
82#else 77#else
83#define DPRINTK(a,b...) 78/* duplicate asm/mtrr.h defines to work on archs without mtrr */
84#endif 79#define MTRR_TYPE_WRCOMB 1
80
81static inline int mtrr_add(unsigned long base, unsigned long size,
82 unsigned int type, char increment)
83{
84 return -ENODEV;
85}
86static inline int mtrr_del(int reg, unsigned long base,
87 unsigned long size)
88{
89 return -ENODEV;
90}
91#endif
85 92
86#define BANSHEE_MAX_PIXCLOCK 270000 93#define BANSHEE_MAX_PIXCLOCK 270000
87#define VOODOO3_MAX_PIXCLOCK 300000 94#define VOODOO3_MAX_PIXCLOCK 300000
@@ -90,9 +97,9 @@
90static struct fb_fix_screeninfo tdfx_fix __devinitdata = { 97static struct fb_fix_screeninfo tdfx_fix __devinitdata = {
91 .id = "3Dfx", 98 .id = "3Dfx",
92 .type = FB_TYPE_PACKED_PIXELS, 99 .type = FB_TYPE_PACKED_PIXELS,
93 .visual = FB_VISUAL_PSEUDOCOLOR, 100 .visual = FB_VISUAL_PSEUDOCOLOR,
94 .ypanstep = 1, 101 .ypanstep = 1,
95 .ywrapstep = 1, 102 .ywrapstep = 1,
96 .accel = FB_ACCEL_3DFX_BANSHEE 103 .accel = FB_ACCEL_3DFX_BANSHEE
97}; 104};
98 105
@@ -102,7 +109,7 @@ static struct fb_var_screeninfo tdfx_var __devinitdata = {
102 .yres = 480, 109 .yres = 480,
103 .xres_virtual = 640, 110 .xres_virtual = 640,
104 .yres_virtual = 1024, 111 .yres_virtual = 1024,
105 .bits_per_pixel =8, 112 .bits_per_pixel = 8,
106 .red = {0, 8, 0}, 113 .red = {0, 8, 0},
107 .blue = {0, 8, 0}, 114 .blue = {0, 8, 0},
108 .green = {0, 8, 0}, 115 .green = {0, 8, 0},
@@ -142,103 +149,79 @@ static struct pci_device_id tdfxfb_id_table[] = {
142 149
143static struct pci_driver tdfxfb_driver = { 150static struct pci_driver tdfxfb_driver = {
144 .name = "tdfxfb", 151 .name = "tdfxfb",
145 .id_table = tdfxfb_id_table, 152 .id_table = tdfxfb_id_table,
146 .probe = tdfxfb_probe, 153 .probe = tdfxfb_probe,
147 .remove = __devexit_p(tdfxfb_remove), 154 .remove = __devexit_p(tdfxfb_remove),
148}; 155};
149 156
150MODULE_DEVICE_TABLE(pci, tdfxfb_id_table); 157MODULE_DEVICE_TABLE(pci, tdfxfb_id_table);
151 158
152/* 159/*
153 * Frame buffer device API 160 * Driver data
154 */ 161 */
155static int tdfxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *fb); 162static int nopan;
156static int tdfxfb_set_par(struct fb_info *info); 163static int nowrap = 1; /* not implemented (yet) */
157static int tdfxfb_setcolreg(u_int regno, u_int red, u_int green, u_int blue, 164static int hwcursor = 1;
158 u_int transp, struct fb_info *info); 165static char *mode_option __devinitdata;
159static int tdfxfb_blank(int blank, struct fb_info *info); 166/* mtrr option */
160static int tdfxfb_pan_display(struct fb_var_screeninfo *var, struct fb_info *info); 167static int nomtrr __devinitdata;
161static int banshee_wait_idle(struct fb_info *info); 168
162#ifdef CONFIG_FB_3DFX_ACCEL 169/* -------------------------------------------------------------------------
163static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect); 170 * Hardware-specific funcions
164static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area);
165static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image);
166#endif /* CONFIG_FB_3DFX_ACCEL */
167
168static struct fb_ops tdfxfb_ops = {
169 .owner = THIS_MODULE,
170 .fb_check_var = tdfxfb_check_var,
171 .fb_set_par = tdfxfb_set_par,
172 .fb_setcolreg = tdfxfb_setcolreg,
173 .fb_blank = tdfxfb_blank,
174 .fb_pan_display = tdfxfb_pan_display,
175 .fb_sync = banshee_wait_idle,
176#ifdef CONFIG_FB_3DFX_ACCEL
177 .fb_fillrect = tdfxfb_fillrect,
178 .fb_copyarea = tdfxfb_copyarea,
179 .fb_imageblit = tdfxfb_imageblit,
180#else
181 .fb_fillrect = cfb_fillrect,
182 .fb_copyarea = cfb_copyarea,
183 .fb_imageblit = cfb_imageblit,
184#endif
185};
186
187/*
188 * do_xxx: Hardware-specific functions
189 */
190static u32 do_calc_pll(int freq, int *freq_out);
191static void do_write_regs(struct fb_info *info, struct banshee_reg *reg);
192static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short);
193
194/*
195 * Driver data
196 */
197static int nopan = 0;
198static int nowrap = 1; // not implemented (yet)
199static char *mode_option __devinitdata = NULL;
200
201/* -------------------------------------------------------------------------
202 * Hardware-specific funcions
203 * ------------------------------------------------------------------------- */ 171 * ------------------------------------------------------------------------- */
204 172
205#ifdef VGA_REG_IO 173static inline u8 vga_inb(struct tdfx_par *par, u32 reg)
206static inline u8 vga_inb(struct tdfx_par *par, u32 reg) { return inb(reg); } 174{
207 175 return inb(par->iobase + reg - 0x300);
208static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val) { outb(val, reg); }
209#else
210static inline u8 vga_inb(struct tdfx_par *par, u32 reg) {
211 return inb(par->iobase + reg - 0x300);
212} 176}
213static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val) { 177
214 outb(val, par->iobase + reg - 0x300); 178static inline void vga_outb(struct tdfx_par *par, u32 reg, u8 val)
179{
180 outb(val, par->iobase + reg - 0x300);
215} 181}
216#endif
217 182
218static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val) { 183static inline void gra_outb(struct tdfx_par *par, u32 idx, u8 val)
219 vga_outb(par, GRA_I, idx); vga_outb(par, GRA_D, val); 184{
185 vga_outb(par, GRA_I, idx);
186 wmb();
187 vga_outb(par, GRA_D, val);
188 wmb();
220} 189}
221 190
222static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val) { 191static inline void seq_outb(struct tdfx_par *par, u32 idx, u8 val)
223 vga_outb(par, SEQ_I, idx); vga_outb(par, SEQ_D, val); 192{
193 vga_outb(par, SEQ_I, idx);
194 wmb();
195 vga_outb(par, SEQ_D, val);
196 wmb();
224} 197}
225 198
226static inline u8 seq_inb(struct tdfx_par *par, u32 idx) { 199static inline u8 seq_inb(struct tdfx_par *par, u32 idx)
227 vga_outb(par, SEQ_I, idx); return vga_inb(par, SEQ_D); 200{
201 vga_outb(par, SEQ_I, idx);
202 mb();
203 return vga_inb(par, SEQ_D);
228} 204}
229 205
230static inline void crt_outb(struct tdfx_par *par, u32 idx, u8 val) { 206static inline void crt_outb(struct tdfx_par *par, u32 idx, u8 val)
231 vga_outb(par, CRT_I, idx); vga_outb(par, CRT_D, val); 207{
208 vga_outb(par, CRT_I, idx);
209 wmb();
210 vga_outb(par, CRT_D, val);
211 wmb();
232} 212}
233 213
234static inline u8 crt_inb(struct tdfx_par *par, u32 idx) { 214static inline u8 crt_inb(struct tdfx_par *par, u32 idx)
235 vga_outb(par, CRT_I, idx); return vga_inb(par, CRT_D); 215{
216 vga_outb(par, CRT_I, idx);
217 mb();
218 return vga_inb(par, CRT_D);
236} 219}
237 220
238static inline void att_outb(struct tdfx_par *par, u32 idx, u8 val) 221static inline void att_outb(struct tdfx_par *par, u32 idx, u8 val)
239{ 222{
240 unsigned char tmp; 223 unsigned char tmp;
241 224
242 tmp = vga_inb(par, IS1_R); 225 tmp = vga_inb(par, IS1_R);
243 vga_outb(par, ATT_IW, idx); 226 vga_outb(par, ATT_IW, idx);
244 vga_outb(par, ATT_IW, val); 227 vga_outb(par, ATT_IW, val);
@@ -267,10 +250,11 @@ static inline void vga_enable_video(struct tdfx_par *par)
267static inline void vga_enable_palette(struct tdfx_par *par) 250static inline void vga_enable_palette(struct tdfx_par *par)
268{ 251{
269 vga_inb(par, IS1_R); 252 vga_inb(par, IS1_R);
253 mb();
270 vga_outb(par, ATT_IW, 0x20); 254 vga_outb(par, ATT_IW, 0x20);
271} 255}
272 256
273static inline u32 tdfx_inl(struct tdfx_par *par, unsigned int reg) 257static inline u32 tdfx_inl(struct tdfx_par *par, unsigned int reg)
274{ 258{
275 return readl(par->regbase_virt + reg); 259 return readl(par->regbase_virt + reg);
276} 260}
@@ -284,9 +268,10 @@ static inline void banshee_make_room(struct tdfx_par *par, int size)
284{ 268{
285 /* Note: The Voodoo3's onboard FIFO has 32 slots. This loop 269 /* Note: The Voodoo3's onboard FIFO has 32 slots. This loop
286 * won't quit if you ask for more. */ 270 * won't quit if you ask for more. */
287 while((tdfx_inl(par, STATUS) & 0x1f) < size-1); 271 while ((tdfx_inl(par, STATUS) & 0x1f) < size - 1)
272 cpu_relax();
288} 273}
289 274
290static int banshee_wait_idle(struct fb_info *info) 275static int banshee_wait_idle(struct fb_info *info)
291{ 276{
292 struct tdfx_par *par = info->par; 277 struct tdfx_par *par = info->par;
@@ -295,28 +280,31 @@ static int banshee_wait_idle(struct fb_info *info)
295 banshee_make_room(par, 1); 280 banshee_make_room(par, 1);
296 tdfx_outl(par, COMMAND_3D, COMMAND_3D_NOP); 281 tdfx_outl(par, COMMAND_3D, COMMAND_3D_NOP);
297 282
298 while(1) { 283 do {
299 i = (tdfx_inl(par, STATUS) & STATUS_BUSY) ? 0 : i + 1; 284 if ((tdfx_inl(par, STATUS) & STATUS_BUSY) == 0)
300 if(i == 3) break; 285 i++;
301 } 286 } while (i < 3);
287
302 return 0; 288 return 0;
303} 289}
304 290
305/* 291/*
306 * Set the color of a palette entry in 8bpp mode 292 * Set the color of a palette entry in 8bpp mode
307 */ 293 */
308static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c) 294static inline void do_setpalentry(struct tdfx_par *par, unsigned regno, u32 c)
309{ 295{
310 banshee_make_room(par, 2); 296 banshee_make_room(par, 2);
311 tdfx_outl(par, DACADDR, regno); 297 tdfx_outl(par, DACADDR, regno);
298 /* read after write makes it working */
299 tdfx_inl(par, DACADDR);
312 tdfx_outl(par, DACDATA, c); 300 tdfx_outl(par, DACDATA, c);
313} 301}
314 302
315static u32 do_calc_pll(int freq, int* freq_out) 303static u32 do_calc_pll(int freq, int *freq_out)
316{ 304{
317 int m, n, k, best_m, best_n, best_k, best_error; 305 int m, n, k, best_m, best_n, best_k, best_error;
318 int fref = 14318; 306 int fref = 14318;
319 307
320 best_error = freq; 308 best_error = freq;
321 best_n = best_m = best_k = 0; 309 best_n = best_m = best_k = 0;
322 310
@@ -326,27 +314,28 @@ static u32 do_calc_pll(int freq, int* freq_out)
326 * Estimate value of n that produces target frequency 314 * Estimate value of n that produces target frequency
327 * with current m and k 315 * with current m and k
328 */ 316 */
329 int n_estimated = (freq * (m + 2) * (1 << k) / fref) - 2; 317 int n_estimated = ((freq * (m + 2) << k) / fref) - 2;
330 318
331 /* Search neighborhood of estimated n */ 319 /* Search neighborhood of estimated n */
332 for (n = max(0, n_estimated - 1); 320 for (n = max(0, n_estimated);
333 n <= min(255, n_estimated + 1); n++) { 321 n <= min(255, n_estimated + 1);
322 n++) {
334 /* 323 /*
335 * Calculate PLL freqency with current m, k and 324 * Calculate PLL freqency with current m, k and
336 * estimated n 325 * estimated n
337 */ 326 */
338 int f = fref * (n + 2) / (m + 2) / (1 << k); 327 int f = (fref * (n + 2) / (m + 2)) >> k;
339 int error = abs (f - freq); 328 int error = abs(f - freq);
340 329
341 /* 330 /*
342 * If this is the closest we've come to the 331 * If this is the closest we've come to the
343 * target frequency then remember n, m and k 332 * target frequency then remember n, m and k
344 */ 333 */
345 if (error < best_error) { 334 if (error < best_error) {
346 best_error = error; 335 best_error = error;
347 best_n = n; 336 best_n = n;
348 best_m = m; 337 best_m = m;
349 best_k = k; 338 best_k = k;
350 } 339 }
351 } 340 }
352 } 341 }
@@ -355,12 +344,12 @@ static u32 do_calc_pll(int freq, int* freq_out)
355 n = best_n; 344 n = best_n;
356 m = best_m; 345 m = best_m;
357 k = best_k; 346 k = best_k;
358 *freq_out = fref*(n + 2)/(m + 2)/(1 << k); 347 *freq_out = (fref * (n + 2) / (m + 2)) >> k;
359 348
360 return (n << 8) | (m << 2) | k; 349 return (n << 8) | (m << 2) | k;
361} 350}
362 351
363static void do_write_regs(struct fb_info *info, struct banshee_reg* reg) 352static void do_write_regs(struct fb_info *info, struct banshee_reg *reg)
364{ 353{
365 struct tdfx_par *par = info->par; 354 struct tdfx_par *par = info->par;
366 int i; 355 int i;
@@ -372,13 +361,13 @@ static void do_write_regs(struct fb_info *info, struct banshee_reg* reg)
372 crt_outb(par, 0x11, crt_inb(par, 0x11) & 0x7f); /* CRT unprotect */ 361 crt_outb(par, 0x11, crt_inb(par, 0x11) & 0x7f); /* CRT unprotect */
373 362
374 banshee_make_room(par, 3); 363 banshee_make_room(par, 3);
375 tdfx_outl(par, VGAINIT1, reg->vgainit1 & 0x001FFFFF); 364 tdfx_outl(par, VGAINIT1, reg->vgainit1 & 0x001FFFFF);
376 tdfx_outl(par, VIDPROCCFG, reg->vidcfg & ~0x00000001); 365 tdfx_outl(par, VIDPROCCFG, reg->vidcfg & ~0x00000001);
377#if 0 366#if 0
378 tdfx_outl(par, PLLCTRL1, reg->mempll); 367 tdfx_outl(par, PLLCTRL1, reg->mempll);
379 tdfx_outl(par, PLLCTRL2, reg->gfxpll); 368 tdfx_outl(par, PLLCTRL2, reg->gfxpll);
380#endif 369#endif
381 tdfx_outl(par, PLLCTRL0, reg->vidpll); 370 tdfx_outl(par, PLLCTRL0, reg->vidpll);
382 371
383 vga_outb(par, MISC_W, reg->misc[0x00] | 0x01); 372 vga_outb(par, MISC_W, reg->misc[0x00] | 0x01);
384 373
@@ -400,72 +389,65 @@ static void do_write_regs(struct fb_info *info, struct banshee_reg* reg)
400 vga_enable_palette(par); 389 vga_enable_palette(par);
401 vga_enable_video(par); 390 vga_enable_video(par);
402 391
403 banshee_make_room(par, 11); 392 banshee_make_room(par, 9);
404 tdfx_outl(par, VGAINIT0, reg->vgainit0); 393 tdfx_outl(par, VGAINIT0, reg->vgainit0);
405 tdfx_outl(par, DACMODE, reg->dacmode); 394 tdfx_outl(par, DACMODE, reg->dacmode);
406 tdfx_outl(par, VIDDESKSTRIDE, reg->stride); 395 tdfx_outl(par, VIDDESKSTRIDE, reg->stride);
407 tdfx_outl(par, HWCURPATADDR, 0); 396 tdfx_outl(par, HWCURPATADDR, reg->curspataddr);
408 397
409 tdfx_outl(par, VIDSCREENSIZE,reg->screensize); 398 tdfx_outl(par, VIDSCREENSIZE, reg->screensize);
410 tdfx_outl(par, VIDDESKSTART, reg->startaddr); 399 tdfx_outl(par, VIDDESKSTART, reg->startaddr);
411 tdfx_outl(par, VIDPROCCFG, reg->vidcfg); 400 tdfx_outl(par, VIDPROCCFG, reg->vidcfg);
412 tdfx_outl(par, VGAINIT1, reg->vgainit1); 401 tdfx_outl(par, VGAINIT1, reg->vgainit1);
413 tdfx_outl(par, MISCINIT0, reg->miscinit0); 402 tdfx_outl(par, MISCINIT0, reg->miscinit0);
414 403
415 banshee_make_room(par, 8); 404 banshee_make_room(par, 8);
416 tdfx_outl(par, SRCBASE, reg->srcbase); 405 tdfx_outl(par, SRCBASE, reg->startaddr);
417 tdfx_outl(par, DSTBASE, reg->dstbase); 406 tdfx_outl(par, DSTBASE, reg->startaddr);
418 tdfx_outl(par, COMMANDEXTRA_2D, 0); 407 tdfx_outl(par, COMMANDEXTRA_2D, 0);
419 tdfx_outl(par, CLIP0MIN, 0); 408 tdfx_outl(par, CLIP0MIN, 0);
420 tdfx_outl(par, CLIP0MAX, 0x0fff0fff); 409 tdfx_outl(par, CLIP0MAX, 0x0fff0fff);
421 tdfx_outl(par, CLIP1MIN, 0); 410 tdfx_outl(par, CLIP1MIN, 0);
422 tdfx_outl(par, CLIP1MAX, 0x0fff0fff); 411 tdfx_outl(par, CLIP1MAX, 0x0fff0fff);
423 tdfx_outl(par, SRCXY, 0); 412 tdfx_outl(par, SRCXY, 0);
424 413
425 banshee_wait_idle(info); 414 banshee_wait_idle(info);
426} 415}
427 416
428static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id) 417static unsigned long do_lfb_size(struct tdfx_par *par, unsigned short dev_id)
429{ 418{
430 u32 draminit0; 419 u32 draminit0 = tdfx_inl(par, DRAMINIT0);
431 u32 draminit1; 420 u32 draminit1 = tdfx_inl(par, DRAMINIT1);
432 u32 miscinit1; 421 u32 miscinit1;
433 422 int num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4;
434 int num_chips;
435 int chip_size; /* in MB */ 423 int chip_size; /* in MB */
436 u32 lfbsize; 424 int has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM;
437 int has_sgram;
438 425
439 draminit0 = tdfx_inl(par, DRAMINIT0);
440 draminit1 = tdfx_inl(par, DRAMINIT1);
441
442 num_chips = (draminit0 & DRAMINIT0_SGRAM_NUM) ? 8 : 4;
443
444 if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) { 426 if (dev_id < PCI_DEVICE_ID_3DFX_VOODOO5) {
445 /* Banshee/Voodoo3 */ 427 /* Banshee/Voodoo3 */
446 has_sgram = draminit1 & DRAMINIT1_MEM_SDRAM; 428 chip_size = 2;
447 chip_size = has_sgram ? ((draminit0 & DRAMINIT0_SGRAM_TYPE) ? 2 : 1) 429 if (has_sgram && (draminit0 & DRAMINIT0_SGRAM_TYPE))
448 : 2; 430 chip_size = 1;
449 } else { 431 } else {
450 /* Voodoo4/5 */ 432 /* Voodoo4/5 */
451 has_sgram = 0; 433 has_sgram = 0;
452 chip_size = 1 << ((draminit0 & DRAMINIT0_SGRAM_TYPE_MASK) >> DRAMINIT0_SGRAM_TYPE_SHIFT); 434 chip_size = draminit0 & DRAMINIT0_SGRAM_TYPE_MASK;
435 chip_size = 1 << (chip_size >> DRAMINIT0_SGRAM_TYPE_SHIFT);
453 } 436 }
454 lfbsize = num_chips * chip_size * 1024 * 1024;
455 437
456 /* disable block writes for SDRAM */ 438 /* disable block writes for SDRAM */
457 miscinit1 = tdfx_inl(par, MISCINIT1); 439 miscinit1 = tdfx_inl(par, MISCINIT1);
458 miscinit1 |= has_sgram ? 0 : MISCINIT1_2DBLOCK_DIS; 440 miscinit1 |= has_sgram ? 0 : MISCINIT1_2DBLOCK_DIS;
459 miscinit1 |= MISCINIT1_CLUT_INV; 441 miscinit1 |= MISCINIT1_CLUT_INV;
460 442
461 banshee_make_room(par, 1); 443 banshee_make_room(par, 1);
462 tdfx_outl(par, MISCINIT1, miscinit1); 444 tdfx_outl(par, MISCINIT1, miscinit1);
463 return lfbsize; 445 return num_chips * chip_size * 1024l * 1024;
464} 446}
465 447
466/* ------------------------------------------------------------------------- */ 448/* ------------------------------------------------------------------------- */
467 449
468static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info) 450static int tdfxfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info)
469{ 451{
470 struct tdfx_par *par = info->par; 452 struct tdfx_par *par = info->par;
471 u32 lpitch; 453 u32 lpitch;
@@ -486,103 +468,113 @@ static int tdfxfb_check_var(struct fb_var_screeninfo *var,struct fb_info *info)
486 DPRINTK("xoffset not supported\n"); 468 DPRINTK("xoffset not supported\n");
487 return -EINVAL; 469 return -EINVAL;
488 } 470 }
471 var->yoffset = 0;
489 472
490 /* Banshee doesn't support interlace, but Voodoo4/5 and probably Voodoo3 do. */ 473 /*
491 /* no direct information about device id now? use max_pixclock for this... */ 474 * Banshee doesn't support interlace, but Voodoo4/5 and probably
475 * Voodoo3 do.
476 * no direct information about device id now?
477 * use max_pixclock for this...
478 */
492 if (((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) && 479 if (((var->vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) &&
493 (par->max_pixclock < VOODOO3_MAX_PIXCLOCK)) { 480 (par->max_pixclock < VOODOO3_MAX_PIXCLOCK)) {
494 DPRINTK("interlace not supported\n"); 481 DPRINTK("interlace not supported\n");
495 return -EINVAL; 482 return -EINVAL;
496 } 483 }
497 484
498 var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */ 485 var->xres = (var->xres + 15) & ~15; /* could sometimes be 8 */
499 lpitch = var->xres * ((var->bits_per_pixel + 7)>>3); 486 lpitch = var->xres * ((var->bits_per_pixel + 7) >> 3);
500 487
501 if (var->xres < 320 || var->xres > 2048) { 488 if (var->xres < 320 || var->xres > 2048) {
502 DPRINTK("width not supported: %u\n", var->xres); 489 DPRINTK("width not supported: %u\n", var->xres);
503 return -EINVAL; 490 return -EINVAL;
504 } 491 }
505 492
506 if (var->yres < 200 || var->yres > 2048) { 493 if (var->yres < 200 || var->yres > 2048) {
507 DPRINTK("height not supported: %u\n", var->yres); 494 DPRINTK("height not supported: %u\n", var->yres);
508 return -EINVAL; 495 return -EINVAL;
509 } 496 }
510 497
511 if (lpitch * var->yres_virtual > info->fix.smem_len) { 498 if (lpitch * var->yres_virtual > info->fix.smem_len) {
512 var->yres_virtual = info->fix.smem_len/lpitch; 499 var->yres_virtual = info->fix.smem_len / lpitch;
513 if (var->yres_virtual < var->yres) { 500 if (var->yres_virtual < var->yres) {
514 DPRINTK("no memory for screen (%ux%ux%u)\n", 501 DPRINTK("no memory for screen (%ux%ux%u)\n",
515 var->xres, var->yres_virtual, var->bits_per_pixel); 502 var->xres, var->yres_virtual,
503 var->bits_per_pixel);
516 return -EINVAL; 504 return -EINVAL;
517 } 505 }
518 } 506 }
519 507
520 if (PICOS2KHZ(var->pixclock) > par->max_pixclock) { 508 if (PICOS2KHZ(var->pixclock) > par->max_pixclock) {
521 DPRINTK("pixclock too high (%ldKHz)\n",PICOS2KHZ(var->pixclock)); 509 DPRINTK("pixclock too high (%ldKHz)\n",
510 PICOS2KHZ(var->pixclock));
522 return -EINVAL; 511 return -EINVAL;
523 } 512 }
524 513
525 switch(var->bits_per_pixel) { 514 var->transp.offset = 0;
526 case 8: 515 var->transp.length = 0;
527 var->red.length = var->green.length = var->blue.length = 8; 516 switch (var->bits_per_pixel) {
528 break; 517 case 8:
529 case 16: 518 var->red.length = 8;
530 var->red.offset = 11; 519 var->red.offset = 0;
531 var->red.length = 5; 520 var->green = var->red;
532 var->green.offset = 5; 521 var->blue = var->red;
533 var->green.length = 6; 522 break;
534 var->blue.offset = 0; 523 case 16:
535 var->blue.length = 5; 524 var->red.offset = 11;
536 break; 525 var->red.length = 5;
537 case 24: 526 var->green.offset = 5;
538 var->red.offset=16; 527 var->green.length = 6;
539 var->green.offset=8; 528 var->blue.offset = 0;
540 var->blue.offset=0; 529 var->blue.length = 5;
541 var->red.length = var->green.length = var->blue.length = 8; 530 break;
542 case 32: 531 case 32:
543 var->red.offset = 16; 532 var->transp.offset = 24;
544 var->green.offset = 8; 533 var->transp.length = 8;
545 var->blue.offset = 0; 534 case 24:
546 var->red.length = var->green.length = var->blue.length = 8; 535 var->red.offset = 16;
547 break; 536 var->green.offset = 8;
537 var->blue.offset = 0;
538 var->red.length = var->green.length = var->blue.length = 8;
539 break;
548 } 540 }
549 var->height = var->width = -1; 541 var->width = -1;
550 542 var->height = -1;
543
551 var->accel_flags = FB_ACCELF_TEXT; 544 var->accel_flags = FB_ACCELF_TEXT;
552 545
553 DPRINTK("Checking graphics mode at %dx%d depth %d\n", var->xres, var->yres, var->bits_per_pixel); 546 DPRINTK("Checking graphics mode at %dx%d depth %d\n",
547 var->xres, var->yres, var->bits_per_pixel);
554 return 0; 548 return 0;
555} 549}
556 550
557static int tdfxfb_set_par(struct fb_info *info) 551static int tdfxfb_set_par(struct fb_info *info)
558{ 552{
559 struct tdfx_par *par = info->par; 553 struct tdfx_par *par = info->par;
560 u32 hdispend, hsyncsta, hsyncend, htotal; 554 u32 hdispend = info->var.xres;
555 u32 hsyncsta = hdispend + info->var.right_margin;
556 u32 hsyncend = hsyncsta + info->var.hsync_len;
557 u32 htotal = hsyncend + info->var.left_margin;
561 u32 hd, hs, he, ht, hbs, hbe; 558 u32 hd, hs, he, ht, hbs, hbe;
562 u32 vd, vs, ve, vt, vbs, vbe; 559 u32 vd, vs, ve, vt, vbs, vbe;
563 struct banshee_reg reg; 560 struct banshee_reg reg;
564 int fout, freq; 561 int fout, freq;
565 u32 wd, cpp; 562 u32 wd;
566 563 u32 cpp = (info->var.bits_per_pixel + 7) >> 3;
567 par->baseline = 0; 564
568
569 memset(&reg, 0, sizeof(reg)); 565 memset(&reg, 0, sizeof(reg));
570 cpp = (info->var.bits_per_pixel + 7)/8; 566
571 567 reg.vidcfg = VIDCFG_VIDPROC_ENABLE | VIDCFG_DESK_ENABLE |
572 reg.vidcfg = VIDCFG_VIDPROC_ENABLE | VIDCFG_DESK_ENABLE | VIDCFG_CURS_X11 | ((cpp - 1) << VIDCFG_PIXFMT_SHIFT) | (cpp != 1 ? VIDCFG_CLUT_BYPASS : 0); 568 VIDCFG_CURS_X11 |
569 ((cpp - 1) << VIDCFG_PIXFMT_SHIFT) |
570 (cpp != 1 ? VIDCFG_CLUT_BYPASS : 0);
573 571
574 /* PLL settings */ 572 /* PLL settings */
575 freq = PICOS2KHZ(info->var.pixclock); 573 freq = PICOS2KHZ(info->var.pixclock);
576 574
577 reg.dacmode = 0; 575 reg.vidcfg &= ~VIDCFG_2X;
578 reg.vidcfg &= ~VIDCFG_2X;
579
580 hdispend = info->var.xres;
581 hsyncsta = hdispend + info->var.right_margin;
582 hsyncend = hsyncsta + info->var.hsync_len;
583 htotal = hsyncend + info->var.left_margin;
584 576
585 if (freq > par->max_pixclock/2) { 577 if (freq > par->max_pixclock / 2) {
586 freq = freq > par->max_pixclock ? par->max_pixclock : freq; 578 freq = freq > par->max_pixclock ? par->max_pixclock : freq;
587 reg.dacmode |= DACMODE_2X; 579 reg.dacmode |= DACMODE_2X;
588 reg.vidcfg |= VIDCFG_2X; 580 reg.vidcfg |= VIDCFG_2X;
@@ -591,8 +583,9 @@ static int tdfxfb_set_par(struct fb_info *info)
591 hsyncend >>= 1; 583 hsyncend >>= 1;
592 htotal >>= 1; 584 htotal >>= 1;
593 } 585 }
594 586
595 hd = wd = (hdispend >> 3) - 1; 587 wd = (hdispend >> 3) - 1;
588 hd = wd;
596 hs = (hsyncsta >> 3) - 1; 589 hs = (hsyncsta >> 3) - 1;
597 he = (hsyncend >> 3) - 1; 590 he = (hsyncend >> 3) - 1;
598 ht = (htotal >> 3) - 1; 591 ht = (htotal >> 3) - 1;
@@ -600,28 +593,30 @@ static int tdfxfb_set_par(struct fb_info *info)
600 hbe = ht; 593 hbe = ht;
601 594
602 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) { 595 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
603 vbs = vd = (info->var.yres << 1) - 1; 596 vd = (info->var.yres << 1) - 1;
604 vs = vd + (info->var.lower_margin << 1); 597 vs = vd + (info->var.lower_margin << 1);
605 ve = vs + (info->var.vsync_len << 1); 598 ve = vs + (info->var.vsync_len << 1);
606 vbe = vt = ve + (info->var.upper_margin << 1) - 1; 599 vt = ve + (info->var.upper_margin << 1) - 1;
600 reg.screensize = info->var.xres | (info->var.yres << 13);
601 reg.vidcfg |= VIDCFG_HALF_MODE;
602 reg.crt[0x09] = 0x80;
607 } else { 603 } else {
608 vbs = vd = info->var.yres - 1; 604 vd = info->var.yres - 1;
609 vs = vd + info->var.lower_margin; 605 vs = vd + info->var.lower_margin;
610 ve = vs + info->var.vsync_len; 606 ve = vs + info->var.vsync_len;
611 vbe = vt = ve + info->var.upper_margin - 1; 607 vt = ve + info->var.upper_margin - 1;
608 reg.screensize = info->var.xres | (info->var.yres << 12);
609 reg.vidcfg &= ~VIDCFG_HALF_MODE;
612 } 610 }
613 611 vbs = vd;
612 vbe = vt;
613
614 /* this is all pretty standard VGA register stuffing */ 614 /* this is all pretty standard VGA register stuffing */
615 reg.misc[0x00] = 0x0f | 615 reg.misc[0x00] = 0x0f |
616 (info->var.xres < 400 ? 0xa0 : 616 (info->var.xres < 400 ? 0xa0 :
617 info->var.xres < 480 ? 0x60 : 617 info->var.xres < 480 ? 0x60 :
618 info->var.xres < 768 ? 0xe0 : 0x20); 618 info->var.xres < 768 ? 0xe0 : 0x20);
619 619
620 reg.gra[0x00] = 0x00;
621 reg.gra[0x01] = 0x00;
622 reg.gra[0x02] = 0x00;
623 reg.gra[0x03] = 0x00;
624 reg.gra[0x04] = 0x00;
625 reg.gra[0x05] = 0x40; 620 reg.gra[0x05] = 0x40;
626 reg.gra[0x06] = 0x05; 621 reg.gra[0x06] = 0x05;
627 reg.gra[0x07] = 0x0f; 622 reg.gra[0x07] = 0x0f;
@@ -644,10 +639,7 @@ static int tdfxfb_set_par(struct fb_info *info)
644 reg.att[0x0e] = 0x0e; 639 reg.att[0x0e] = 0x0e;
645 reg.att[0x0f] = 0x0f; 640 reg.att[0x0f] = 0x0f;
646 reg.att[0x10] = 0x41; 641 reg.att[0x10] = 0x41;
647 reg.att[0x11] = 0x00;
648 reg.att[0x12] = 0x0f; 642 reg.att[0x12] = 0x0f;
649 reg.att[0x13] = 0x00;
650 reg.att[0x14] = 0x00;
651 643
652 reg.seq[0x00] = 0x03; 644 reg.seq[0x00] = 0x03;
653 reg.seq[0x01] = 0x01; /* fixme: clkdiv2? */ 645 reg.seq[0x01] = 0x01; /* fixme: clkdiv2? */
@@ -660,146 +652,133 @@ static int tdfxfb_set_par(struct fb_info *info)
660 reg.crt[0x02] = hbs; 652 reg.crt[0x02] = hbs;
661 reg.crt[0x03] = 0x80 | (hbe & 0x1f); 653 reg.crt[0x03] = 0x80 | (hbe & 0x1f);
662 reg.crt[0x04] = hs; 654 reg.crt[0x04] = hs;
663 reg.crt[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f); 655 reg.crt[0x05] = ((hbe & 0x20) << 2) | (he & 0x1f);
664 reg.crt[0x06] = vt; 656 reg.crt[0x06] = vt;
665 reg.crt[0x07] = ((vs & 0x200) >> 2) | 657 reg.crt[0x07] = ((vs & 0x200) >> 2) |
666 ((vd & 0x200) >> 3) | 658 ((vd & 0x200) >> 3) |
667 ((vt & 0x200) >> 4) | 0x10 | 659 ((vt & 0x200) >> 4) | 0x10 |
668 ((vbs & 0x100) >> 5) | 660 ((vbs & 0x100) >> 5) |
669 ((vs & 0x100) >> 6) | 661 ((vs & 0x100) >> 6) |
670 ((vd & 0x100) >> 7) | 662 ((vd & 0x100) >> 7) |
671 ((vt & 0x100) >> 8); 663 ((vt & 0x100) >> 8);
672 reg.crt[0x08] = 0x00; 664 reg.crt[0x09] |= 0x40 | ((vbs & 0x200) >> 4);
673 reg.crt[0x09] = 0x40 | ((vbs & 0x200) >> 4);
674 reg.crt[0x0a] = 0x00;
675 reg.crt[0x0b] = 0x00;
676 reg.crt[0x0c] = 0x00;
677 reg.crt[0x0d] = 0x00;
678 reg.crt[0x0e] = 0x00;
679 reg.crt[0x0f] = 0x00;
680 reg.crt[0x10] = vs; 665 reg.crt[0x10] = vs;
681 reg.crt[0x11] = (ve & 0x0f) | 0x20; 666 reg.crt[0x11] = (ve & 0x0f) | 0x20;
682 reg.crt[0x12] = vd; 667 reg.crt[0x12] = vd;
683 reg.crt[0x13] = wd; 668 reg.crt[0x13] = wd;
684 reg.crt[0x14] = 0x00;
685 reg.crt[0x15] = vbs; 669 reg.crt[0x15] = vbs;
686 reg.crt[0x16] = vbe + 1; 670 reg.crt[0x16] = vbe + 1;
687 reg.crt[0x17] = 0xc3; 671 reg.crt[0x17] = 0xc3;
688 reg.crt[0x18] = 0xff; 672 reg.crt[0x18] = 0xff;
689 673
690 /* Banshee's nonvga stuff */ 674 /* Banshee's nonvga stuff */
691 reg.ext[0x00] = (((ht & 0x100) >> 8) | 675 reg.ext[0x00] = (((ht & 0x100) >> 8) |
692 ((hd & 0x100) >> 6) | 676 ((hd & 0x100) >> 6) |
693 ((hbs & 0x100) >> 4) | 677 ((hbs & 0x100) >> 4) |
694 ((hbe & 0x40) >> 1) | 678 ((hbe & 0x40) >> 1) |
695 ((hs & 0x100) >> 2) | 679 ((hs & 0x100) >> 2) |
696 ((he & 0x20) << 2)); 680 ((he & 0x20) << 2));
697 reg.ext[0x01] = (((vt & 0x400) >> 10) | 681 reg.ext[0x01] = (((vt & 0x400) >> 10) |
698 ((vd & 0x400) >> 8) | 682 ((vd & 0x400) >> 8) |
699 ((vbs & 0x400) >> 6) | 683 ((vbs & 0x400) >> 6) |
700 ((vbe & 0x400) >> 4)); 684 ((vbe & 0x400) >> 4));
701 685
702 reg.vgainit0 = VGAINIT0_8BIT_DAC | 686 reg.vgainit0 = VGAINIT0_8BIT_DAC |
703 VGAINIT0_EXT_ENABLE | 687 VGAINIT0_EXT_ENABLE |
704 VGAINIT0_WAKEUP_3C3 | 688 VGAINIT0_WAKEUP_3C3 |
705 VGAINIT0_ALT_READBACK | 689 VGAINIT0_ALT_READBACK |
706 VGAINIT0_EXTSHIFTOUT; 690 VGAINIT0_EXTSHIFTOUT;
707 reg.vgainit1 = tdfx_inl(par, VGAINIT1) & 0x1fffff; 691 reg.vgainit1 = tdfx_inl(par, VGAINIT1) & 0x1fffff;
708 692
693 if (hwcursor)
694 reg.curspataddr = info->fix.smem_len;
695
709 reg.cursloc = 0; 696 reg.cursloc = 0;
710 697
711 reg.cursc0 = 0; 698 reg.cursc0 = 0;
712 reg.cursc1 = 0xffffff; 699 reg.cursc1 = 0xffffff;
713
714 reg.stride = info->var.xres * cpp;
715 reg.startaddr = par->baseline * reg.stride;
716 reg.srcbase = reg.startaddr;
717 reg.dstbase = reg.startaddr;
718 700
719 /* PLL settings */ 701 reg.stride = info->var.xres * cpp;
720 freq = PICOS2KHZ(info->var.pixclock); 702 reg.startaddr = info->var.yoffset * reg.stride
703 + info->var.xoffset * cpp;
721 704
722 reg.dacmode &= ~DACMODE_2X;
723 reg.vidcfg &= ~VIDCFG_2X;
724 if (freq > par->max_pixclock/2) {
725 freq = freq > par->max_pixclock ? par->max_pixclock : freq;
726 reg.dacmode |= DACMODE_2X;
727 reg.vidcfg |= VIDCFG_2X;
728 }
729 reg.vidpll = do_calc_pll(freq, &fout); 705 reg.vidpll = do_calc_pll(freq, &fout);
730#if 0 706#if 0
731 reg.mempll = do_calc_pll(..., &fout); 707 reg.mempll = do_calc_pll(..., &fout);
732 reg.gfxpll = do_calc_pll(..., &fout); 708 reg.gfxpll = do_calc_pll(..., &fout);
733#endif 709#endif
734 710
735 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_DOUBLE) {
736 reg.screensize = info->var.xres | (info->var.yres << 13);
737 reg.vidcfg |= VIDCFG_HALF_MODE;
738 reg.crt[0x09] |= 0x80;
739 } else {
740 reg.screensize = info->var.xres | (info->var.yres << 12);
741 reg.vidcfg &= ~VIDCFG_HALF_MODE;
742 }
743 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED) 711 if ((info->var.vmode & FB_VMODE_MASK) == FB_VMODE_INTERLACED)
744 reg.vidcfg |= VIDCFG_INTERLACE; 712 reg.vidcfg |= VIDCFG_INTERLACE;
745 reg.miscinit0 = tdfx_inl(par, MISCINIT0); 713 reg.miscinit0 = tdfx_inl(par, MISCINIT0);
746 714
747#if defined(__BIG_ENDIAN) 715#if defined(__BIG_ENDIAN)
748 switch (info->var.bits_per_pixel) { 716 switch (info->var.bits_per_pixel) {
749 case 8: 717 case 8:
750 case 24: 718 case 24:
751 reg.miscinit0 &= ~(1 << 30); 719 reg.miscinit0 &= ~(1 << 30);
752 reg.miscinit0 &= ~(1 << 31); 720 reg.miscinit0 &= ~(1 << 31);
753 break; 721 break;
754 case 16: 722 case 16:
755 reg.miscinit0 |= (1 << 30); 723 reg.miscinit0 |= (1 << 30);
756 reg.miscinit0 |= (1 << 31); 724 reg.miscinit0 |= (1 << 31);
757 break; 725 break;
758 case 32: 726 case 32:
759 reg.miscinit0 |= (1 << 30); 727 reg.miscinit0 |= (1 << 30);
760 reg.miscinit0 &= ~(1 << 31); 728 reg.miscinit0 &= ~(1 << 31);
761 break; 729 break;
762 } 730 }
763#endif 731#endif
764 do_write_regs(info, &reg); 732 do_write_regs(info, &reg);
765 733
766 /* Now change fb_fix_screeninfo according to changes in par */ 734 /* Now change fb_fix_screeninfo according to changes in par */
767 info->fix.line_length = info->var.xres * ((info->var.bits_per_pixel + 7)>>3); 735 info->fix.line_length = reg.stride;
768 info->fix.visual = (info->var.bits_per_pixel == 8) 736 info->fix.visual = (info->var.bits_per_pixel == 8)
769 ? FB_VISUAL_PSEUDOCOLOR 737 ? FB_VISUAL_PSEUDOCOLOR
770 : FB_VISUAL_TRUECOLOR; 738 : FB_VISUAL_TRUECOLOR;
771 DPRINTK("Graphics mode is now set at %dx%d depth %d\n", info->var.xres, info->var.yres, info->var.bits_per_pixel); 739 DPRINTK("Graphics mode is now set at %dx%d depth %d\n",
772 return 0; 740 info->var.xres, info->var.yres, info->var.bits_per_pixel);
741 return 0;
773} 742}
774 743
775/* A handy macro shamelessly pinched from matroxfb */ 744/* A handy macro shamelessly pinched from matroxfb */
776#define CNVT_TOHW(val,width) ((((val)<<(width))+0x7FFF-(val))>>16) 745#define CNVT_TOHW(val, width) ((((val) << (width)) + 0x7FFF - (val)) >> 16)
777 746
778static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green, 747static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
779 unsigned blue,unsigned transp,struct fb_info *info) 748 unsigned blue, unsigned transp,
749 struct fb_info *info)
780{ 750{
781 struct tdfx_par *par = info->par; 751 struct tdfx_par *par = info->par;
782 u32 rgbcol; 752 u32 rgbcol;
783 753
784 if (regno >= info->cmap.len || regno > 255) return 1; 754 if (regno >= info->cmap.len || regno > 255)
785 755 return 1;
756
757 /* grayscale works only partially under directcolor */
758 if (info->var.grayscale) {
759 /* grayscale = 0.30*R + 0.59*G + 0.11*B */
760 blue = (red * 77 + green * 151 + blue * 28) >> 8;
761 green = blue;
762 red = blue;
763 }
764
786 switch (info->fix.visual) { 765 switch (info->fix.visual) {
787 case FB_VISUAL_PSEUDOCOLOR: 766 case FB_VISUAL_PSEUDOCOLOR:
788 rgbcol =(((u32)red & 0xff00) << 8) | 767 rgbcol = (((u32)red & 0xff00) << 8) |
789 (((u32)green & 0xff00) << 0) | 768 (((u32)green & 0xff00) << 0) |
790 (((u32)blue & 0xff00) >> 8); 769 (((u32)blue & 0xff00) >> 8);
791 do_setpalentry(par, regno, rgbcol); 770 do_setpalentry(par, regno, rgbcol);
792 break; 771 break;
793 /* Truecolor has no hardware color palettes. */ 772 /* Truecolor has no hardware color palettes. */
794 case FB_VISUAL_TRUECOLOR: 773 case FB_VISUAL_TRUECOLOR:
795 if (regno < 16) { 774 if (regno < 16) {
796 rgbcol = (CNVT_TOHW( red, info->var.red.length) << 775 rgbcol = (CNVT_TOHW(red, info->var.red.length) <<
797 info->var.red.offset) | 776 info->var.red.offset) |
798 (CNVT_TOHW( green, info->var.green.length) << 777 (CNVT_TOHW(green, info->var.green.length) <<
799 info->var.green.offset) | 778 info->var.green.offset) |
800 (CNVT_TOHW( blue, info->var.blue.length) << 779 (CNVT_TOHW(blue, info->var.blue.length) <<
801 info->var.blue.offset) | 780 info->var.blue.offset) |
802 (CNVT_TOHW( transp, info->var.transp.length) << 781 (CNVT_TOHW(transp, info->var.transp.length) <<
803 info->var.transp.offset); 782 info->var.transp.offset);
804 par->palette[regno] = rgbcol; 783 par->palette[regno] = rgbcol;
805 } 784 }
@@ -815,287 +794,325 @@ static int tdfxfb_setcolreg(unsigned regno, unsigned red, unsigned green,
815 794
816/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */ 795/* 0 unblank, 1 blank, 2 no vsync, 3 no hsync, 4 off */
817static int tdfxfb_blank(int blank, struct fb_info *info) 796static int tdfxfb_blank(int blank, struct fb_info *info)
818{ 797{
819 struct tdfx_par *par = info->par; 798 struct tdfx_par *par = info->par;
820 u32 dacmode, state = 0, vgablank = 0; 799 int vgablank = 1;
800 u32 dacmode = tdfx_inl(par, DACMODE);
821 801
822 dacmode = tdfx_inl(par, DACMODE); 802 dacmode &= ~(BIT(1) | BIT(3));
823 803
824 switch (blank) { 804 switch (blank) {
825 case FB_BLANK_UNBLANK: /* Screen: On; HSync: On, VSync: On */ 805 case FB_BLANK_UNBLANK: /* Screen: On; HSync: On, VSync: On */
826 state = 0; 806 vgablank = 0;
827 vgablank = 0; 807 break;
828 break; 808 case FB_BLANK_NORMAL: /* Screen: Off; HSync: On, VSync: On */
829 case FB_BLANK_NORMAL: /* Screen: Off; HSync: On, VSync: On */ 809 break;
830 state = 0; 810 case FB_BLANK_VSYNC_SUSPEND: /* Screen: Off; HSync: On, VSync: Off */
831 vgablank = 1; 811 dacmode |= BIT(3);
832 break; 812 break;
833 case FB_BLANK_VSYNC_SUSPEND: /* Screen: Off; HSync: On, VSync: Off */ 813 case FB_BLANK_HSYNC_SUSPEND: /* Screen: Off; HSync: Off, VSync: On */
834 state = BIT(3); 814 dacmode |= BIT(1);
835 vgablank = 1; 815 break;
836 break; 816 case FB_BLANK_POWERDOWN: /* Screen: Off; HSync: Off, VSync: Off */
837 case FB_BLANK_HSYNC_SUSPEND: /* Screen: Off; HSync: Off, VSync: On */ 817 dacmode |= BIT(1) | BIT(3);
838 state = BIT(1); 818 break;
839 vgablank = 1;
840 break;
841 case FB_BLANK_POWERDOWN: /* Screen: Off; HSync: Off, VSync: Off */
842 state = BIT(1) | BIT(3);
843 vgablank = 1;
844 break;
845 } 819 }
846 820
847 dacmode &= ~(BIT(1) | BIT(3)); 821 banshee_make_room(par, 1);
848 dacmode |= state;
849 banshee_make_room(par, 1);
850 tdfx_outl(par, DACMODE, dacmode); 822 tdfx_outl(par, DACMODE, dacmode);
851 if (vgablank) 823 if (vgablank)
852 vga_disable_video(par); 824 vga_disable_video(par);
853 else 825 else
854 vga_enable_video(par); 826 vga_enable_video(par);
855 return 0; 827 return 0;
856} 828}
857 829
858/* 830/*
859 * Set the starting position of the visible screen to var->yoffset 831 * Set the starting position of the visible screen to var->yoffset
860 */ 832 */
861static int tdfxfb_pan_display(struct fb_var_screeninfo *var, 833static int tdfxfb_pan_display(struct fb_var_screeninfo *var,
862 struct fb_info *info) 834 struct fb_info *info)
863{ 835{
864 struct tdfx_par *par = info->par; 836 struct tdfx_par *par = info->par;
865 u32 addr; 837 u32 addr = var->yoffset * info->fix.line_length;
866 838
867 if (nopan || var->xoffset || (var->yoffset > var->yres_virtual)) 839 if (nopan || var->xoffset || (var->yoffset > var->yres_virtual))
868 return -EINVAL; 840 return -EINVAL;
869 if ((var->yoffset + var->yres > var->yres_virtual && nowrap)) 841 if ((var->yoffset + var->yres > var->yres_virtual && nowrap))
870 return -EINVAL; 842 return -EINVAL;
871 843
872 addr = var->yoffset * info->fix.line_length;
873 banshee_make_room(par, 1); 844 banshee_make_room(par, 1);
874 tdfx_outl(par, VIDDESKSTART, addr); 845 tdfx_outl(par, VIDDESKSTART, addr);
875 846
876 info->var.xoffset = var->xoffset; 847 info->var.xoffset = var->xoffset;
877 info->var.yoffset = var->yoffset; 848 info->var.yoffset = var->yoffset;
878 return 0; 849 return 0;
879} 850}
880 851
881#ifdef CONFIG_FB_3DFX_ACCEL 852#ifdef CONFIG_FB_3DFX_ACCEL
882/* 853/*
883 * FillRect 2D command (solidfill or invert (via ROP_XOR)) 854 * FillRect 2D command (solidfill or invert (via ROP_XOR))
884 */ 855 */
885static void tdfxfb_fillrect(struct fb_info *info, const struct fb_fillrect *rect) 856static void tdfxfb_fillrect(struct fb_info *info,
857 const struct fb_fillrect *rect)
886{ 858{
887 struct tdfx_par *par = info->par; 859 struct tdfx_par *par = info->par;
888 u32 bpp = info->var.bits_per_pixel; 860 u32 bpp = info->var.bits_per_pixel;
889 u32 stride = info->fix.line_length; 861 u32 stride = info->fix.line_length;
890 u32 fmt= stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 862 u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
891 int tdfx_rop; 863 int tdfx_rop;
892 864 u32 dx = rect->dx;
893 if (rect->rop == ROP_COPY) 865 u32 dy = rect->dy;
866 u32 dstbase = 0;
867
868 if (rect->rop == ROP_COPY)
894 tdfx_rop = TDFX_ROP_COPY; 869 tdfx_rop = TDFX_ROP_COPY;
895 else 870 else
896 tdfx_rop = TDFX_ROP_XOR; 871 tdfx_rop = TDFX_ROP_XOR;
897 872
898 banshee_make_room(par, 5); 873 /* asume always rect->height < 4096 */
899 tdfx_outl(par, DSTFORMAT, fmt); 874 if (dy + rect->height > 4095) {
875 dstbase = stride * dy;
876 dy = 0;
877 }
878 /* asume always rect->width < 4096 */
879 if (dx + rect->width > 4095) {
880 dstbase += dx * bpp >> 3;
881 dx = 0;
882 }
883 banshee_make_room(par, 6);
884 tdfx_outl(par, DSTFORMAT, fmt);
900 if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) { 885 if (info->fix.visual == FB_VISUAL_PSEUDOCOLOR) {
901 tdfx_outl(par, COLORFORE, rect->color); 886 tdfx_outl(par, COLORFORE, rect->color);
902 } else { /* FB_VISUAL_TRUECOLOR */ 887 } else { /* FB_VISUAL_TRUECOLOR */
903 tdfx_outl(par, COLORFORE, par->palette[rect->color]); 888 tdfx_outl(par, COLORFORE, par->palette[rect->color]);
904 } 889 }
905 tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24)); 890 tdfx_outl(par, COMMAND_2D, COMMAND_2D_FILLRECT | (tdfx_rop << 24));
906 tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16)); 891 tdfx_outl(par, DSTBASE, dstbase);
907 tdfx_outl(par, LAUNCH_2D, rect->dx | (rect->dy << 16)); 892 tdfx_outl(par, DSTSIZE, rect->width | (rect->height << 16));
893 tdfx_outl(par, LAUNCH_2D, dx | (dy << 16));
908} 894}
909 895
910/* 896/*
911 * Screen-to-Screen BitBlt 2D command (for the bmove fb op.) 897 * Screen-to-Screen BitBlt 2D command (for the bmove fb op.)
912 */ 898 */
913static void tdfxfb_copyarea(struct fb_info *info, const struct fb_copyarea *area) 899static void tdfxfb_copyarea(struct fb_info *info,
900 const struct fb_copyarea *area)
914{ 901{
915 struct tdfx_par *par = info->par; 902 struct tdfx_par *par = info->par;
916 u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy; 903 u32 sx = area->sx, sy = area->sy, dx = area->dx, dy = area->dy;
917 u32 bpp = info->var.bits_per_pixel; 904 u32 bpp = info->var.bits_per_pixel;
918 u32 stride = info->fix.line_length; 905 u32 stride = info->fix.line_length;
919 u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24); 906 u32 blitcmd = COMMAND_2D_S2S_BITBLT | (TDFX_ROP_COPY << 24);
920 u32 fmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 907 u32 fmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
921 908 u32 dstbase = 0;
909 u32 srcbase = 0;
910
911 /* asume always area->height < 4096 */
912 if (sy + area->height > 4095) {
913 srcbase = stride * sy;
914 sy = 0;
915 }
916 /* asume always area->width < 4096 */
917 if (sx + area->width > 4095) {
918 srcbase += sx * bpp >> 3;
919 sx = 0;
920 }
921 /* asume always area->height < 4096 */
922 if (dy + area->height > 4095) {
923 dstbase = stride * dy;
924 dy = 0;
925 }
926 /* asume always area->width < 4096 */
927 if (dx + area->width > 4095) {
928 dstbase += dx * bpp >> 3;
929 dx = 0;
930 }
931
922 if (area->sx <= area->dx) { 932 if (area->sx <= area->dx) {
923 //-X 933 /* -X */
924 blitcmd |= BIT(14); 934 blitcmd |= BIT(14);
925 sx += area->width - 1; 935 sx += area->width - 1;
926 dx += area->width - 1; 936 dx += area->width - 1;
927 } 937 }
928 if (area->sy <= area->dy) { 938 if (area->sy <= area->dy) {
929 //-Y 939 /* -Y */
930 blitcmd |= BIT(15); 940 blitcmd |= BIT(15);
931 sy += area->height - 1; 941 sy += area->height - 1;
932 dy += area->height - 1; 942 dy += area->height - 1;
933 } 943 }
934
935 banshee_make_room(par, 6);
936 944
937 tdfx_outl(par, SRCFORMAT, fmt); 945 banshee_make_room(par, 8);
938 tdfx_outl(par, DSTFORMAT, fmt); 946
939 tdfx_outl(par, COMMAND_2D, blitcmd); 947 tdfx_outl(par, SRCFORMAT, fmt);
940 tdfx_outl(par, DSTSIZE, area->width | (area->height << 16)); 948 tdfx_outl(par, DSTFORMAT, fmt);
941 tdfx_outl(par, DSTXY, dx | (dy << 16)); 949 tdfx_outl(par, COMMAND_2D, blitcmd);
942 tdfx_outl(par, LAUNCH_2D, sx | (sy << 16)); 950 tdfx_outl(par, DSTSIZE, area->width | (area->height << 16));
951 tdfx_outl(par, DSTXY, dx | (dy << 16));
952 tdfx_outl(par, SRCBASE, srcbase);
953 tdfx_outl(par, DSTBASE, dstbase);
954 tdfx_outl(par, LAUNCH_2D, sx | (sy << 16));
943} 955}
944 956
945static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image) 957static void tdfxfb_imageblit(struct fb_info *info, const struct fb_image *image)
946{ 958{
947 struct tdfx_par *par = info->par; 959 struct tdfx_par *par = info->par;
948 int size = image->height * ((image->width * image->depth + 7)>>3); 960 int size = image->height * ((image->width * image->depth + 7) >> 3);
949 int fifo_free; 961 int fifo_free;
950 int i, stride = info->fix.line_length; 962 int i, stride = info->fix.line_length;
951 u32 bpp = info->var.bits_per_pixel; 963 u32 bpp = info->var.bits_per_pixel;
952 u32 dstfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13); 964 u32 dstfmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13);
953 u8 *chardata = (u8 *) image->data; 965 u8 *chardata = (u8 *) image->data;
954 u32 srcfmt; 966 u32 srcfmt;
967 u32 dx = image->dx;
968 u32 dy = image->dy;
969 u32 dstbase = 0;
955 970
956 if (image->depth != 1) { 971 if (image->depth != 1) {
957 //banshee_make_room(par, 6 + ((size + 3) >> 2)); 972#ifdef BROKEN_CODE
958 //srcfmt = stride | ((bpp+((bpp==8) ? 0 : 8)) << 13) | 0x400000; 973 banshee_make_room(par, 6 + ((size + 3) >> 2));
974 srcfmt = stride | ((bpp + ((bpp == 8) ? 0 : 8)) << 13) |
975 0x400000;
976#else
959 cfb_imageblit(info, image); 977 cfb_imageblit(info, image);
978#endif
960 return; 979 return;
961 } else { 980 }
962 banshee_make_room(par, 8); 981 banshee_make_room(par, 9);
963 switch (info->fix.visual) { 982 switch (info->fix.visual) {
964 case FB_VISUAL_PSEUDOCOLOR: 983 case FB_VISUAL_PSEUDOCOLOR:
965 tdfx_outl(par, COLORFORE, image->fg_color); 984 tdfx_outl(par, COLORFORE, image->fg_color);
966 tdfx_outl(par, COLORBACK, image->bg_color); 985 tdfx_outl(par, COLORBACK, image->bg_color);
967 break; 986 break;
968 case FB_VISUAL_TRUECOLOR: 987 case FB_VISUAL_TRUECOLOR:
969 default: 988 default:
970 tdfx_outl(par, COLORFORE, 989 tdfx_outl(par, COLORFORE,
971 par->palette[image->fg_color]); 990 par->palette[image->fg_color]);
972 tdfx_outl(par, COLORBACK, 991 tdfx_outl(par, COLORBACK,
973 par->palette[image->bg_color]); 992 par->palette[image->bg_color]);
974 } 993 }
975#ifdef __BIG_ENDIAN 994#ifdef __BIG_ENDIAN
976 srcfmt = 0x400000 | BIT(20); 995 srcfmt = 0x400000 | BIT(20);
977#else 996#else
978 srcfmt = 0x400000; 997 srcfmt = 0x400000;
979#endif 998#endif
980 } 999 /* asume always image->height < 4096 */
1000 if (dy + image->height > 4095) {
1001 dstbase = stride * dy;
1002 dy = 0;
1003 }
1004 /* asume always image->width < 4096 */
1005 if (dx + image->width > 4095) {
1006 dstbase += dx * bpp >> 3;
1007 dx = 0;
1008 }
981 1009
982 tdfx_outl(par, SRCXY, 0); 1010 tdfx_outl(par, DSTBASE, dstbase);
983 tdfx_outl(par, DSTXY, image->dx | (image->dy << 16)); 1011 tdfx_outl(par, SRCXY, 0);
984 tdfx_outl(par, COMMAND_2D, COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24)); 1012 tdfx_outl(par, DSTXY, dx | (dy << 16));
985 tdfx_outl(par, SRCFORMAT, srcfmt); 1013 tdfx_outl(par, COMMAND_2D,
986 tdfx_outl(par, DSTFORMAT, dstfmt); 1014 COMMAND_2D_H2S_BITBLT | (TDFX_ROP_COPY << 24));
987 tdfx_outl(par, DSTSIZE, image->width | (image->height << 16)); 1015 tdfx_outl(par, SRCFORMAT, srcfmt);
1016 tdfx_outl(par, DSTFORMAT, dstfmt);
1017 tdfx_outl(par, DSTSIZE, image->width | (image->height << 16));
988 1018
989 /* A count of how many free FIFO entries we've requested. 1019 /* A count of how many free FIFO entries we've requested.
990 * When this goes negative, we need to request more. */ 1020 * When this goes negative, we need to request more. */
991 fifo_free = 0; 1021 fifo_free = 0;
992 1022
993 /* Send four bytes at a time of data */ 1023 /* Send four bytes at a time of data */
994 for (i = (size >> 2) ; i > 0; i--) { 1024 for (i = (size >> 2); i > 0; i--) {
995 if(--fifo_free < 0) { 1025 if (--fifo_free < 0) {
996 fifo_free=31; 1026 fifo_free = 31;
997 banshee_make_room(par,fifo_free); 1027 banshee_make_room(par, fifo_free);
998 } 1028 }
999 tdfx_outl(par, LAUNCH_2D,*(u32*)chardata); 1029 tdfx_outl(par, LAUNCH_2D, *(u32 *)chardata);
1000 chardata += 4; 1030 chardata += 4;
1001 } 1031 }
1002 1032
1003 /* Send the leftovers now */ 1033 /* Send the leftovers now */
1004 banshee_make_room(par,3); 1034 banshee_make_room(par, 3);
1005 i = size%4; 1035 switch (size % 4) {
1006 switch (i) { 1036 case 0:
1007 case 0: break; 1037 break;
1008 case 1: tdfx_outl(par, LAUNCH_2D,*chardata); break; 1038 case 1:
1009 case 2: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata); break; 1039 tdfx_outl(par, LAUNCH_2D, *chardata);
1010 case 3: tdfx_outl(par, LAUNCH_2D,*(u16*)chardata | ((chardata[3]) << 24)); break; 1040 break;
1041 case 2:
1042 tdfx_outl(par, LAUNCH_2D, *(u16 *)chardata);
1043 break;
1044 case 3:
1045 tdfx_outl(par, LAUNCH_2D,
1046 *(u16 *)chardata | (chardata[3] << 24));
1047 break;
1011 } 1048 }
1012} 1049}
1013#endif /* CONFIG_FB_3DFX_ACCEL */ 1050#endif /* CONFIG_FB_3DFX_ACCEL */
1014 1051
1015#ifdef TDFX_HARDWARE_CURSOR
1016static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor) 1052static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1017{ 1053{
1018 struct tdfx_par *par = info->par; 1054 struct tdfx_par *par = info->par;
1019 unsigned long flags; 1055 u32 vidcfg;
1020 1056
1021 /* 1057 if (!hwcursor)
1022 * If the cursor is not be changed this means either we want the 1058 return -EINVAL; /* just to force soft_cursor() call */
1023 * current cursor state (if enable is set) or we want to query what
1024 * we can do with the cursor (if enable is not set)
1025 */
1026 if (!cursor->set) return 0;
1027 1059
1028 /* Too large of a cursor :-( */ 1060 /* Too large of a cursor or wrong bpp :-( */
1029 if (cursor->image.width > 64 || cursor->image.height > 64) 1061 if (cursor->image.width > 64 ||
1030 return -ENXIO; 1062 cursor->image.height > 64 ||
1063 cursor->image.depth > 1)
1064 return -EINVAL;
1031 1065
1032 /* 1066 vidcfg = tdfx_inl(par, VIDPROCCFG);
1033 * If we are going to be changing things we should disable 1067 if (cursor->enable)
1034 * the cursor first 1068 tdfx_outl(par, VIDPROCCFG, vidcfg | VIDCFG_HWCURSOR_ENABLE);
1035 */ 1069 else
1036 if (info->cursor.enable) { 1070 tdfx_outl(par, VIDPROCCFG, vidcfg & ~VIDCFG_HWCURSOR_ENABLE);
1037 spin_lock_irqsave(&par->DAClock, flags);
1038 info->cursor.enable = 0;
1039 del_timer(&(par->hwcursor.timer));
1040 tdfx_outl(par, VIDPROCCFG, par->hwcursor.disable);
1041 spin_unlock_irqrestore(&par->DAClock, flags);
1042 }
1043 1071
1044 /* Disable the Cursor */ 1072 /*
1045 if ((cursor->set && FB_CUR_SETCUR) && !cursor->enable) 1073 * If the cursor is not be changed this means either we want the
1074 * current cursor state (if enable is set) or we want to query what
1075 * we can do with the cursor (if enable is not set)
1076 */
1077 if (!cursor->set)
1046 return 0; 1078 return 0;
1047 1079
1048 /* fix cursor color - XFree86 forgets to restore it properly */ 1080 /* fix cursor color - XFree86 forgets to restore it properly */
1049 if (cursor->set && FB_CUR_SETCMAP) { 1081 if (cursor->set & FB_CUR_SETCMAP) {
1050 struct fb_cmap cmap = cursor->image.cmap; 1082 struct fb_cmap cmap = info->cmap;
1083 u32 bg_idx = cursor->image.bg_color;
1084 u32 fg_idx = cursor->image.fg_color;
1051 unsigned long bg_color, fg_color; 1085 unsigned long bg_color, fg_color;
1052 1086
1053 cmap.len = 2; /* Voodoo 3+ only support 2 color cursors */ 1087 fg_color = (((u32)cmap.red[fg_idx] & 0xff00) << 8) |
1054 fg_color = ((cmap.red[cmap.start] << 16) | 1088 (((u32)cmap.green[fg_idx] & 0xff00) << 0) |
1055 (cmap.green[cmap.start] << 8) | 1089 (((u32)cmap.blue[fg_idx] & 0xff00) >> 8);
1056 (cmap.blue[cmap.start])); 1090 bg_color = (((u32)cmap.red[bg_idx] & 0xff00) << 8) |
1057 bg_color = ((cmap.red[cmap.start+1] << 16) | 1091 (((u32)cmap.green[bg_idx] & 0xff00) << 0) |
1058 (cmap.green[cmap.start+1] << 8) | 1092 (((u32)cmap.blue[bg_idx] & 0xff00) >> 8);
1059 (cmap.blue[cmap.start+1]));
1060 fb_copy_cmap(&cmap, &info->cursor.image.cmap);
1061 spin_lock_irqsave(&par->DAClock, flags);
1062 banshee_make_room(par, 2); 1093 banshee_make_room(par, 2);
1063 tdfx_outl(par, HWCURC0, bg_color); 1094 tdfx_outl(par, HWCURC0, bg_color);
1064 tdfx_outl(par, HWCURC1, fg_color); 1095 tdfx_outl(par, HWCURC1, fg_color);
1065 spin_unlock_irqrestore(&par->DAClock, flags);
1066 } 1096 }
1067 1097
1068 if (cursor->set && FB_CUR_SETPOS) { 1098 if (cursor->set & FB_CUR_SETPOS) {
1069 int x, y; 1099 int x = cursor->image.dx;
1100 int y = cursor->image.dy - info->var.yoffset;
1070 1101
1071 x = cursor->image.dx;
1072 y = cursor->image.dy;
1073 y -= info->var.yoffset;
1074 info->cursor.image.dx = x;
1075 info->cursor.image.dy = y;
1076 x += 63; 1102 x += 63;
1077 y += 63; 1103 y += 63;
1078 spin_lock_irqsave(&par->DAClock, flags);
1079 banshee_make_room(par, 1); 1104 banshee_make_room(par, 1);
1080 tdfx_outl(par, HWCURLOC, (y << 16) + x); 1105 tdfx_outl(par, HWCURLOC, (y << 16) + x);
1081 spin_unlock_irqrestore(&par->DAClock, flags);
1082 } 1106 }
1083 1107 if (cursor->set & (FB_CUR_SETIMAGE | FB_CUR_SETSHAPE)) {
1084 /* Not supported so we fake it */
1085 if (cursor->set && FB_CUR_SETHOT) {
1086 info->cursor.hot.x = cursor->hot.x;
1087 info->cursor.hot.y = cursor->hot.y;
1088 }
1089
1090 if (cursor->set && FB_CUR_SETSHAPE) {
1091 /* 1108 /*
1092 * Voodoo 3 and above cards use 2 monochrome cursor patterns. 1109 * Voodoo 3 and above cards use 2 monochrome cursor patterns.
1093 * The reason is so the card can fetch 8 words at a time 1110 * The reason is so the card can fetch 8 words at a time
1094 * and are stored on chip for use for the next 8 scanlines. 1111 * and are stored on chip for use for the next 8 scanlines.
1095 * This reduces the number of times for access to draw the 1112 * This reduces the number of times for access to draw the
1096 * cursor for each screen refresh. 1113 * cursor for each screen refresh.
1097 * Each pattern is a bitmap of 64 bit wide and 64 bit high 1114 * Each pattern is a bitmap of 64 bit wide and 64 bit high
1098 * (total of 8192 bits or 1024 Kbytes). The two patterns are 1115 * (total of 8192 bits or 1024 bytes). The two patterns are
1099 * stored in such a way that pattern 0 always resides in the 1116 * stored in such a way that pattern 0 always resides in the
1100 * lower half (least significant 64 bits) of a 128 bit word 1117 * lower half (least significant 64 bits) of a 128 bit word
1101 * and pattern 1 the upper half. If you examine the data of 1118 * and pattern 1 the upper half. If you examine the data of
@@ -1106,50 +1123,54 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1106 * (128 bits) which is the maximum cursor width times two for 1123 * (128 bits) which is the maximum cursor width times two for
1107 * the two monochrome patterns. 1124 * the two monochrome patterns.
1108 */ 1125 */
1109 u8 *cursorbase = (u8 *) info->cursor.image.data; 1126 u8 __iomem *cursorbase = info->screen_base + info->fix.smem_len;
1110 char *bitmap = (char *)cursor->image.data; 1127 u8 *bitmap = (u8 *)cursor->image.data;
1111 char *mask = (char *) cursor->mask; 1128 u8 *mask = (u8 *)cursor->mask;
1112 int i, j, k, h = 0; 1129 int i;
1113 1130
1114 for (i = 0; i < 64; i++) { 1131 fb_memset(cursorbase, 0, 1024);
1115 if (i < cursor->image.height) { 1132
1116 j = (cursor->image.width + 7) >> 3; 1133 for (i = 0; i < cursor->image.height; i++) {
1117 k = 8 - j; 1134 int h = 0;
1118 1135 int j = (cursor->image.width + 7) >> 3;
1119 for (;j > 0; j--) { 1136
1120 /* Pattern 0. Copy the cursor bitmap to it */ 1137 for (; j > 0; j--) {
1121 fb_writeb(*bitmap, cursorbase + h); 1138 u8 data = *mask ^ *bitmap;
1122 bitmap++; 1139 if (cursor->rop == ROP_COPY)
1123 /* Pattern 1. Copy the cursor mask to it */ 1140 data = *mask & *bitmap;
1124 fb_writeb(*mask, cursorbase + h + 8); 1141 /* Pattern 0. Copy the cursor mask to it */
1125 mask++; 1142 fb_writeb(*mask, cursorbase + h);
1126 h++; 1143 mask++;
1127 } 1144 /* Pattern 1. Copy the cursor bitmap to it */
1128 for (;k > 0; k--) { 1145 fb_writeb(data, cursorbase + h + 8);
1129 fb_writeb(0, cursorbase + h); 1146 bitmap++;
1130 fb_writeb(~0, cursorbase + h + 8); 1147 h++;
1131 h++;
1132 }
1133 } else {
1134 fb_writel(0, cursorbase + h);
1135 fb_writel(0, cursorbase + h + 4);
1136 fb_writel(~0, cursorbase + h + 8);
1137 fb_writel(~0, cursorbase + h + 12);
1138 h += 16;
1139 } 1148 }
1149 cursorbase += 16;
1140 } 1150 }
1141 } 1151 }
1142 /* Turn the cursor on */
1143 cursor->enable = 1;
1144 info->cursor = *cursor;
1145 mod_timer(&par->hwcursor.timer, jiffies+HZ/2);
1146 spin_lock_irqsave(&par->DAClock, flags);
1147 banshee_make_room(par, 1);
1148 tdfx_outl(par, VIDPROCCFG, par->hwcursor.enable);
1149 spin_unlock_irqrestore(&par->DAClock, flags);
1150 return 0; 1152 return 0;
1151} 1153}
1154
1155static struct fb_ops tdfxfb_ops = {
1156 .owner = THIS_MODULE,
1157 .fb_check_var = tdfxfb_check_var,
1158 .fb_set_par = tdfxfb_set_par,
1159 .fb_setcolreg = tdfxfb_setcolreg,
1160 .fb_blank = tdfxfb_blank,
1161 .fb_pan_display = tdfxfb_pan_display,
1162 .fb_sync = banshee_wait_idle,
1163 .fb_cursor = tdfxfb_cursor,
1164#ifdef CONFIG_FB_3DFX_ACCEL
1165 .fb_fillrect = tdfxfb_fillrect,
1166 .fb_copyarea = tdfxfb_copyarea,
1167 .fb_imageblit = tdfxfb_imageblit,
1168#else
1169 .fb_fillrect = cfb_fillrect,
1170 .fb_copyarea = cfb_copyarea,
1171 .fb_imageblit = cfb_imageblit,
1152#endif 1172#endif
1173};
1153 1174
1154/** 1175/**
1155 * tdfxfb_probe - Device Initializiation 1176 * tdfxfb_probe - Device Initializiation
@@ -1161,14 +1182,15 @@ static int tdfxfb_cursor(struct fb_info *info, struct fb_cursor *cursor)
1161 * 1182 *
1162 */ 1183 */
1163static int __devinit tdfxfb_probe(struct pci_dev *pdev, 1184static int __devinit tdfxfb_probe(struct pci_dev *pdev,
1164 const struct pci_device_id *id) 1185 const struct pci_device_id *id)
1165{ 1186{
1166 struct tdfx_par *default_par; 1187 struct tdfx_par *default_par;
1167 struct fb_info *info; 1188 struct fb_info *info;
1168 int err, lpitch; 1189 int err, lpitch;
1169 1190
1170 if ((err = pci_enable_device(pdev))) { 1191 err = pci_enable_device(pdev);
1171 printk(KERN_WARNING "tdfxfb: Can't enable pdev: %d\n", err); 1192 if (err) {
1193 printk(KERN_ERR "tdfxfb: Can't enable pdev: %d\n", err);
1172 return err; 1194 return err;
1173 } 1195 }
1174 1196
@@ -1176,139 +1198,145 @@ static int __devinit tdfxfb_probe(struct pci_dev *pdev,
1176 1198
1177 if (!info) 1199 if (!info)
1178 return -ENOMEM; 1200 return -ENOMEM;
1179 1201
1180 default_par = info->par; 1202 default_par = info->par;
1181 1203
1182 /* Configure the default fb_fix_screeninfo first */ 1204 /* Configure the default fb_fix_screeninfo first */
1183 switch (pdev->device) { 1205 switch (pdev->device) {
1184 case PCI_DEVICE_ID_3DFX_BANSHEE: 1206 case PCI_DEVICE_ID_3DFX_BANSHEE:
1185 strcat(tdfx_fix.id, " Banshee"); 1207 strcat(tdfx_fix.id, " Banshee");
1186 default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK; 1208 default_par->max_pixclock = BANSHEE_MAX_PIXCLOCK;
1187 break; 1209 break;
1188 case PCI_DEVICE_ID_3DFX_VOODOO3: 1210 case PCI_DEVICE_ID_3DFX_VOODOO3:
1189 strcat(tdfx_fix.id, " Voodoo3"); 1211 strcat(tdfx_fix.id, " Voodoo3");
1190 default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK; 1212 default_par->max_pixclock = VOODOO3_MAX_PIXCLOCK;
1191 break; 1213 break;
1192 case PCI_DEVICE_ID_3DFX_VOODOO5: 1214 case PCI_DEVICE_ID_3DFX_VOODOO5:
1193 strcat(tdfx_fix.id, " Voodoo5"); 1215 strcat(tdfx_fix.id, " Voodoo5");
1194 default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK; 1216 default_par->max_pixclock = VOODOO5_MAX_PIXCLOCK;
1195 break; 1217 break;
1196 } 1218 }
1197 1219
1198 tdfx_fix.mmio_start = pci_resource_start(pdev, 0); 1220 tdfx_fix.mmio_start = pci_resource_start(pdev, 0);
1199 tdfx_fix.mmio_len = pci_resource_len(pdev, 0); 1221 tdfx_fix.mmio_len = pci_resource_len(pdev, 0);
1200 default_par->regbase_virt = ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len); 1222 if (!request_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len,
1201 if (!default_par->regbase_virt) { 1223 "tdfx regbase")) {
1202 printk("fb: Can't remap %s register area.\n", tdfx_fix.id); 1224 printk(KERN_ERR "tdfxfb: Can't reserve regbase\n");
1203 goto out_err; 1225 goto out_err;
1204 } 1226 }
1205 1227
1206 if (!request_mem_region(pci_resource_start(pdev, 0), 1228 default_par->regbase_virt =
1207 pci_resource_len(pdev, 0), "tdfx regbase")) { 1229 ioremap_nocache(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
1208 printk(KERN_WARNING "tdfxfb: Can't reserve regbase\n"); 1230 if (!default_par->regbase_virt) {
1209 goto out_err; 1231 printk(KERN_ERR "fb: Can't remap %s register area.\n",
1210 } 1232 tdfx_fix.id);
1233 goto out_err_regbase;
1234 }
1211 1235
1212 tdfx_fix.smem_start = pci_resource_start(pdev, 1); 1236 tdfx_fix.smem_start = pci_resource_start(pdev, 1);
1213 if (!(tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device))) { 1237 tdfx_fix.smem_len = do_lfb_size(default_par, pdev->device);
1214 printk("fb: Can't count %s memory.\n", tdfx_fix.id); 1238 if (!tdfx_fix.smem_len) {
1215 release_mem_region(pci_resource_start(pdev, 0), 1239 printk(KERN_ERR "fb: Can't count %s memory.\n", tdfx_fix.id);
1216 pci_resource_len(pdev, 0)); 1240 goto out_err_regbase;
1217 goto out_err;
1218 } 1241 }
1219 1242
1220 if (!request_mem_region(pci_resource_start(pdev, 1), 1243 if (!request_mem_region(tdfx_fix.smem_start,
1221 pci_resource_len(pdev, 1), "tdfx smem")) { 1244 pci_resource_len(pdev, 1), "tdfx smem")) {
1222 printk(KERN_WARNING "tdfxfb: Can't reserve smem\n"); 1245 printk(KERN_ERR "tdfxfb: Can't reserve smem\n");
1223 release_mem_region(pci_resource_start(pdev, 0), 1246 goto out_err_regbase;
1224 pci_resource_len(pdev, 0));
1225 goto out_err;
1226 } 1247 }
1227 1248
1228 info->screen_base = ioremap_nocache(tdfx_fix.smem_start, 1249 info->screen_base = ioremap_nocache(tdfx_fix.smem_start,
1229 tdfx_fix.smem_len); 1250 tdfx_fix.smem_len);
1230 if (!info->screen_base) { 1251 if (!info->screen_base) {
1231 printk("fb: Can't remap %s framebuffer.\n", tdfx_fix.id); 1252 printk(KERN_ERR "fb: Can't remap %s framebuffer.\n",
1232 release_mem_region(pci_resource_start(pdev, 1), 1253 tdfx_fix.id);
1233 pci_resource_len(pdev, 1)); 1254 goto out_err_screenbase;
1234 release_mem_region(pci_resource_start(pdev, 0),
1235 pci_resource_len(pdev, 0));
1236 goto out_err;
1237 } 1255 }
1238 1256
1239 default_par->iobase = pci_resource_start(pdev, 2); 1257 default_par->iobase = pci_resource_start(pdev, 2);
1240 1258
1241 if (!request_region(pci_resource_start(pdev, 2), 1259 if (!request_region(pci_resource_start(pdev, 2),
1242 pci_resource_len(pdev, 2), "tdfx iobase")) { 1260 pci_resource_len(pdev, 2), "tdfx iobase")) {
1243 printk(KERN_WARNING "tdfxfb: Can't reserve iobase\n"); 1261 printk(KERN_ERR "tdfxfb: Can't reserve iobase\n");
1244 release_mem_region(pci_resource_start(pdev, 1), 1262 goto out_err_screenbase;
1245 pci_resource_len(pdev, 1));
1246 release_mem_region(pci_resource_start(pdev, 0),
1247 pci_resource_len(pdev, 0));
1248 goto out_err;
1249 } 1263 }
1250 1264
1251 printk("fb: %s memory = %dK\n", tdfx_fix.id, tdfx_fix.smem_len >> 10); 1265 printk(KERN_INFO "fb: %s memory = %dK\n", tdfx_fix.id,
1266 tdfx_fix.smem_len >> 10);
1267
1268 default_par->mtrr_handle = -1;
1269 if (!nomtrr)
1270 default_par->mtrr_handle =
1271 mtrr_add(tdfx_fix.smem_start, tdfx_fix.smem_len,
1272 MTRR_TYPE_WRCOMB, 1);
1252 1273
1253 tdfx_fix.ypanstep = nopan ? 0 : 1; 1274 tdfx_fix.ypanstep = nopan ? 0 : 1;
1254 tdfx_fix.ywrapstep = nowrap ? 0 : 1; 1275 tdfx_fix.ywrapstep = nowrap ? 0 : 1;
1255 1276
1256 info->fbops = &tdfxfb_ops; 1277 info->fbops = &tdfxfb_ops;
1257 info->fix = tdfx_fix; 1278 info->fix = tdfx_fix;
1258 info->pseudo_palette = default_par->palette; 1279 info->pseudo_palette = default_par->palette;
1259 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN; 1280 info->flags = FBINFO_DEFAULT | FBINFO_HWACCEL_YPAN;
1260#ifdef CONFIG_FB_3DFX_ACCEL 1281#ifdef CONFIG_FB_3DFX_ACCEL
1261 info->flags |= FBINFO_HWACCEL_FILLRECT | 1282 info->flags |= FBINFO_HWACCEL_FILLRECT |
1262 FBINFO_HWACCEL_COPYAREA | FBINFO_HWACCEL_IMAGEBLIT; 1283 FBINFO_HWACCEL_COPYAREA |
1284 FBINFO_HWACCEL_IMAGEBLIT |
1285 FBINFO_READS_FAST;
1263#endif 1286#endif
1287 /* reserve 8192 bits for cursor */
1288 /* the 2.4 driver says PAGE_MASK boundary is not enough for Voodoo4 */
1289 if (hwcursor)
1290 info->fix.smem_len = (info->fix.smem_len - 1024) &
1291 (PAGE_MASK << 1);
1264 1292
1265 if (!mode_option) 1293 if (!mode_option)
1266 mode_option = "640x480@60"; 1294 mode_option = "640x480@60";
1267 1295
1268 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8); 1296 err = fb_find_mode(&info->var, info, mode_option, NULL, 0, NULL, 8);
1269 if (!err || err == 4) 1297 if (!err || err == 4)
1270 info->var = tdfx_var; 1298 info->var = tdfx_var;
1271 1299
1272 /* maximize virtual vertical length */ 1300 /* maximize virtual vertical length */
1273 lpitch = info->var.xres_virtual * ((info->var.bits_per_pixel + 7) >> 3); 1301 lpitch = info->var.xres_virtual * ((info->var.bits_per_pixel + 7) >> 3);
1274 info->var.yres_virtual = info->fix.smem_len/lpitch; 1302 info->var.yres_virtual = info->fix.smem_len / lpitch;
1275 if (info->var.yres_virtual < info->var.yres) 1303 if (info->var.yres_virtual < info->var.yres)
1276 goto out_err; 1304 goto out_err_iobase;
1277
1278#ifdef CONFIG_FB_3DFX_ACCEL
1279 /*
1280 * FIXME: Limit var->yres_virtual to 4096 because of screen artifacts
1281 * during scrolling. This is only present if 2D acceleration is
1282 * enabled.
1283 */
1284 if (info->var.yres_virtual > 4096)
1285 info->var.yres_virtual = 4096;
1286#endif /* CONFIG_FB_3DFX_ACCEL */
1287 1305
1288 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) { 1306 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
1289 printk(KERN_WARNING "tdfxfb: Can't allocate color map\n"); 1307 printk(KERN_ERR "tdfxfb: Can't allocate color map\n");
1290 goto out_err; 1308 goto out_err_iobase;
1291 } 1309 }
1292 1310
1293 if (register_framebuffer(info) < 0) { 1311 if (register_framebuffer(info) < 0) {
1294 printk("tdfxfb: can't register framebuffer\n"); 1312 printk(KERN_ERR "tdfxfb: can't register framebuffer\n");
1295 fb_dealloc_cmap(&info->cmap); 1313 fb_dealloc_cmap(&info->cmap);
1296 goto out_err; 1314 goto out_err_iobase;
1297 } 1315 }
1298 /* 1316 /*
1299 * Our driver data 1317 * Our driver data
1300 */ 1318 */
1301 pci_set_drvdata(pdev, info); 1319 pci_set_drvdata(pdev, info);
1302 return 0; 1320 return 0;
1303 1321
1304out_err: 1322out_err_iobase:
1323 if (default_par->mtrr_handle >= 0)
1324 mtrr_del(default_par->mtrr_handle, info->fix.smem_start,
1325 info->fix.smem_len);
1326 release_mem_region(pci_resource_start(pdev, 2),
1327 pci_resource_len(pdev, 2));
1328out_err_screenbase:
1329 if (info->screen_base)
1330 iounmap(info->screen_base);
1331 release_mem_region(tdfx_fix.smem_start, pci_resource_len(pdev, 1));
1332out_err_regbase:
1305 /* 1333 /*
1306 * Cleanup after anything that was remapped/allocated. 1334 * Cleanup after anything that was remapped/allocated.
1307 */ 1335 */
1308 if (default_par->regbase_virt) 1336 if (default_par->regbase_virt)
1309 iounmap(default_par->regbase_virt); 1337 iounmap(default_par->regbase_virt);
1310 if (info->screen_base) 1338 release_mem_region(tdfx_fix.mmio_start, tdfx_fix.mmio_len);
1311 iounmap(info->screen_base); 1339out_err:
1312 framebuffer_release(info); 1340 framebuffer_release(info);
1313 return -ENXIO; 1341 return -ENXIO;
1314} 1342}
@@ -1316,7 +1344,7 @@ out_err:
1316#ifndef MODULE 1344#ifndef MODULE
1317static void tdfxfb_setup(char *options) 1345static void tdfxfb_setup(char *options)
1318{ 1346{
1319 char* this_opt; 1347 char *this_opt;
1320 1348
1321 if (!options || !*options) 1349 if (!options || !*options)
1322 return; 1350 return;
@@ -1324,10 +1352,16 @@ static void tdfxfb_setup(char *options)
1324 while ((this_opt = strsep(&options, ",")) != NULL) { 1352 while ((this_opt = strsep(&options, ",")) != NULL) {
1325 if (!*this_opt) 1353 if (!*this_opt)
1326 continue; 1354 continue;
1327 if(!strcmp(this_opt, "nopan")) { 1355 if (!strcmp(this_opt, "nopan")) {
1328 nopan = 1; 1356 nopan = 1;
1329 } else if(!strcmp(this_opt, "nowrap")) { 1357 } else if (!strcmp(this_opt, "nowrap")) {
1330 nowrap = 1; 1358 nowrap = 1;
1359 } else if (!strncmp(this_opt, "hwcursor=", 9)) {
1360 hwcursor = simple_strtoul(this_opt + 9, NULL, 0);
1361#ifdef CONFIG_MTRR
1362 } else if (!strncmp(this_opt, "nomtrr", 6)) {
1363 nomtrr = 1;
1364#endif
1331 } else { 1365 } else {
1332 mode_option = this_opt; 1366 mode_option = this_opt;
1333 } 1367 }
@@ -1350,6 +1384,9 @@ static void __devexit tdfxfb_remove(struct pci_dev *pdev)
1350 struct tdfx_par *par = info->par; 1384 struct tdfx_par *par = info->par;
1351 1385
1352 unregister_framebuffer(info); 1386 unregister_framebuffer(info);
1387 if (par->mtrr_handle >= 0)
1388 mtrr_del(par->mtrr_handle, info->fix.smem_start,
1389 info->fix.smem_len);
1353 iounmap(par->regbase_virt); 1390 iounmap(par->regbase_virt);
1354 iounmap(info->screen_base); 1391 iounmap(info->screen_base);
1355 1392
@@ -1374,17 +1411,25 @@ static int __init tdfxfb_init(void)
1374 1411
1375 tdfxfb_setup(option); 1412 tdfxfb_setup(option);
1376#endif 1413#endif
1377 return pci_register_driver(&tdfxfb_driver); 1414 return pci_register_driver(&tdfxfb_driver);
1378} 1415}
1379 1416
1380static void __exit tdfxfb_exit(void) 1417static void __exit tdfxfb_exit(void)
1381{ 1418{
1382 pci_unregister_driver(&tdfxfb_driver); 1419 pci_unregister_driver(&tdfxfb_driver);
1383} 1420}
1384 1421
1385MODULE_AUTHOR("Hannu Mallat <hmallat@cc.hut.fi>"); 1422MODULE_AUTHOR("Hannu Mallat <hmallat@cc.hut.fi>");
1386MODULE_DESCRIPTION("3Dfx framebuffer device driver"); 1423MODULE_DESCRIPTION("3Dfx framebuffer device driver");
1387MODULE_LICENSE("GPL"); 1424MODULE_LICENSE("GPL");
1388 1425
1426module_param(hwcursor, int, 0644);
1427MODULE_PARM_DESC(hwcursor, "Enable hardware cursor "
1428 "(1=enable, 0=disable, default=1)");
1429#ifdef CONFIG_MTRR
1430module_param(nomtrr, bool, 0);
1431MODULE_PARM_DESC(nomtrr, "Disable MTRR support (default: enabled)");
1432#endif
1433
1389module_init(tdfxfb_init); 1434module_init(tdfxfb_init);
1390module_exit(tdfxfb_exit); 1435module_exit(tdfxfb_exit);
diff --git a/drivers/video/tgafb.c b/drivers/video/tgafb.c
index d292a37ec7d6..680642c089c9 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/tgafb.c
@@ -5,7 +5,7 @@
5 * Copyright (C) 1997 Geert Uytterhoeven 5 * Copyright (C) 1997 Geert Uytterhoeven
6 * Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha 6 * Copyright (C) 1999,2000 Martin Lucina, Tom Zerucha
7 * Copyright (C) 2002 Richard Henderson 7 * Copyright (C) 2002 Richard Henderson
8 * Copyright (C) 2006 Maciej W. Rozycki 8 * Copyright (C) 2006, 2007 Maciej W. Rozycki
9 * 9 *
10 * This file is subject to the terms and conditions of the GNU General Public 10 * This file is subject to the terms and conditions of the GNU General Public
11 * License. See the file COPYING in the main directory of this archive for 11 * License. See the file COPYING in the main directory of this archive for
@@ -13,6 +13,7 @@
13 */ 13 */
14 14
15#include <linux/bitrev.h> 15#include <linux/bitrev.h>
16#include <linux/compiler.h>
16#include <linux/delay.h> 17#include <linux/delay.h>
17#include <linux/device.h> 18#include <linux/device.h>
18#include <linux/errno.h> 19#include <linux/errno.h>
@@ -636,15 +637,6 @@ tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
636 637
637 is8bpp = info->var.bits_per_pixel == 8; 638 is8bpp = info->var.bits_per_pixel == 8;
638 639
639 /* For copies that aren't pixel expansion, there's little we
640 can do better than the generic code. */
641 /* ??? There is a DMA write mode; I wonder if that could be
642 made to pull the data from the image buffer... */
643 if (image->depth > 1) {
644 cfb_imageblit(info, image);
645 return;
646 }
647
648 dx = image->dx; 640 dx = image->dx;
649 dy = image->dy; 641 dy = image->dy;
650 width = image->width; 642 width = image->width;
@@ -654,6 +646,9 @@ tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
654 line_length = info->fix.line_length; 646 line_length = info->fix.line_length;
655 rincr = (width + 7) / 8; 647 rincr = (width + 7) / 8;
656 648
649 /* A shift below cannot cope with. */
650 if (unlikely(width == 0))
651 return;
657 /* Crop the image to the screen. */ 652 /* Crop the image to the screen. */
658 if (dx > vxres || dy > vyres) 653 if (dx > vxres || dy > vyres)
659 return; 654 return;
@@ -709,9 +704,10 @@ tgafb_mono_imageblit(struct fb_info *info, const struct fb_image *image)
709 unsigned long bwidth; 704 unsigned long bwidth;
710 705
711 /* Handle common case of imaging a single character, in 706 /* Handle common case of imaging a single character, in
712 a font less than 32 pixels wide. */ 707 a font less than or 32 pixels wide. */
713 708
714 pixelmask = (1 << width) - 1; 709 /* Avoid a shift by 32; width > 0 implied. */
710 pixelmask = (2ul << (width - 1)) - 1;
715 pixelmask <<= shift; 711 pixelmask <<= shift;
716 __raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG); 712 __raw_writel(pixelmask, regs_base + TGA_PIXELMASK_REG);
717 wmb(); 713 wmb();
diff --git a/drivers/video/tridentfb.c b/drivers/video/tridentfb.c
index c699864b6f4a..70fb4ee2b421 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/tridentfb.c
@@ -1,18 +1,19 @@
1/* 1/*
2 * Frame buffer driver for Trident Blade and Image series 2 * Frame buffer driver for Trident Blade and Image series
3 * 3 *
4 * Copyright 2001,2002 - Jani Monoses <jani@iv.ro> 4 * Copyright 2001, 2002 - Jani Monoses <jani@iv.ro>
5 * 5 *
6 * 6 *
7 * CREDITS:(in order of appearance) 7 * CREDITS:(in order of appearance)
8 * skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video 8 * skeletonfb.c by Geert Uytterhoeven and other fb code in drivers/video
9 * Special thanks ;) to Mattia Crivellini <tia@mclink.it> 9 * Special thanks ;) to Mattia Crivellini <tia@mclink.it>
10 * much inspired by the XFree86 4.x Trident driver sources by Alan Hourihane 10 * much inspired by the XFree86 4.x Trident driver sources
11 * the FreeVGA project 11 * by Alan Hourihane the FreeVGA project
12 * Francesco Salvestrini <salvestrini@users.sf.net> XP support,code,suggestions 12 * Francesco Salvestrini <salvestrini@users.sf.net> XP support,
13 * code, suggestions
13 * TODO: 14 * TODO:
14 * timing value tweaking so it looks good on every monitor in every mode 15 * timing value tweaking so it looks good on every monitor in every mode
15 * TGUI acceleration 16 * TGUI acceleration
16 */ 17 */
17 18
18#include <linux/module.h> 19#include <linux/module.h>
@@ -26,11 +27,11 @@
26#define VERSION "0.7.8-NEWAPI" 27#define VERSION "0.7.8-NEWAPI"
27 28
28struct tridentfb_par { 29struct tridentfb_par {
29 int vclk; //in MHz 30 int vclk; /* in MHz */
30 void __iomem * io_virt; //iospace virtual memory address 31 void __iomem *io_virt; /* iospace virtual memory address */
31}; 32};
32 33
33static unsigned char eng_oper; //engine operation... 34static unsigned char eng_oper; /* engine operation... */
34static struct fb_ops tridentfb_ops; 35static struct fb_ops tridentfb_ops;
35 36
36static struct tridentfb_par default_par; 37static struct tridentfb_par default_par;
@@ -39,11 +40,10 @@ static struct tridentfb_par default_par;
39static struct fb_info fb_info; 40static struct fb_info fb_info;
40static u32 pseudo_pal[16]; 41static u32 pseudo_pal[16];
41 42
42
43static struct fb_var_screeninfo default_var; 43static struct fb_var_screeninfo default_var;
44 44
45static struct fb_fix_screeninfo tridentfb_fix = { 45static struct fb_fix_screeninfo tridentfb_fix = {
46 .id = "Trident", 46 .id = "Trident",
47 .type = FB_TYPE_PACKED_PIXELS, 47 .type = FB_TYPE_PACKED_PIXELS,
48 .ypanstep = 1, 48 .ypanstep = 1,
49 .visual = FB_VISUAL_PSEUDOCOLOR, 49 .visual = FB_VISUAL_PSEUDOCOLOR,
@@ -55,11 +55,10 @@ static int chip_id;
55static int defaultaccel; 55static int defaultaccel;
56static int displaytype; 56static int displaytype;
57 57
58
59/* defaults which are normally overriden by user values */ 58/* defaults which are normally overriden by user values */
60 59
61/* video mode */ 60/* video mode */
62static char * mode = "640x480"; 61static char *mode = "640x480";
63static int bpp = 8; 62static int bpp = 8;
64 63
65static int noaccel; 64static int noaccel;
@@ -74,7 +73,6 @@ static int memsize;
74static int memdiff; 73static int memdiff;
75static int nativex; 74static int nativex;
76 75
77
78module_param(mode, charp, 0); 76module_param(mode, charp, 0);
79module_param(bpp, int, 0); 77module_param(bpp, int, 0);
80module_param(center, int, 0); 78module_param(center, int, 0);
@@ -86,88 +84,85 @@ module_param(nativex, int, 0);
86module_param(fp, int, 0); 84module_param(fp, int, 0);
87module_param(crt, int, 0); 85module_param(crt, int, 0);
88 86
89
90static int chip3D; 87static int chip3D;
91static int chipcyber; 88static int chipcyber;
92 89
93static int is3Dchip(int id) 90static int is3Dchip(int id)
94{ 91{
95 return ((id == BLADE3D) || (id == CYBERBLADEE4) || 92 return ((id == BLADE3D) || (id == CYBERBLADEE4) ||
96 (id == CYBERBLADEi7) || (id == CYBERBLADEi7D) || 93 (id == CYBERBLADEi7) || (id == CYBERBLADEi7D) ||
97 (id == CYBER9397) || (id == CYBER9397DVD) || 94 (id == CYBER9397) || (id == CYBER9397DVD) ||
98 (id == CYBER9520) || (id == CYBER9525DVD) || 95 (id == CYBER9520) || (id == CYBER9525DVD) ||
99 (id == IMAGE975) || (id == IMAGE985) || 96 (id == IMAGE975) || (id == IMAGE985) ||
100 (id == CYBERBLADEi1) || (id == CYBERBLADEi1D) || 97 (id == CYBERBLADEi1) || (id == CYBERBLADEi1D) ||
101 (id == CYBERBLADEAi1) || (id == CYBERBLADEAi1D) || 98 (id == CYBERBLADEAi1) || (id == CYBERBLADEAi1D) ||
102 (id == CYBERBLADEXPm8) || (id == CYBERBLADEXPm16) || 99 (id == CYBERBLADEXPm8) || (id == CYBERBLADEXPm16) ||
103 (id == CYBERBLADEXPAi1)); 100 (id == CYBERBLADEXPAi1));
104} 101}
105 102
106static int iscyber(int id) 103static int iscyber(int id)
107{ 104{
108 switch (id) { 105 switch (id) {
109 case CYBER9388: 106 case CYBER9388:
110 case CYBER9382: 107 case CYBER9382:
111 case CYBER9385: 108 case CYBER9385:
112 case CYBER9397: 109 case CYBER9397:
113 case CYBER9397DVD: 110 case CYBER9397DVD:
114 case CYBER9520: 111 case CYBER9520:
115 case CYBER9525DVD: 112 case CYBER9525DVD:
116 case CYBERBLADEE4: 113 case CYBERBLADEE4:
117 case CYBERBLADEi7D: 114 case CYBERBLADEi7D:
118 case CYBERBLADEi1: 115 case CYBERBLADEi1:
119 case CYBERBLADEi1D: 116 case CYBERBLADEi1D:
120 case CYBERBLADEAi1: 117 case CYBERBLADEAi1:
121 case CYBERBLADEAi1D: 118 case CYBERBLADEAi1D:
122 case CYBERBLADEXPAi1: 119 case CYBERBLADEXPAi1:
123 return 1; 120 return 1;
124
125 case CYBER9320:
126 case TGUI9660:
127 case IMAGE975:
128 case IMAGE985:
129 case BLADE3D:
130 case CYBERBLADEi7: /* VIA MPV4 integrated version */
131 121
132 default: 122 case CYBER9320:
133 /* case CYBERBLDAEXPm8: Strange */ 123 case TGUI9660:
134 /* case CYBERBLDAEXPm16: Strange */ 124 case IMAGE975:
135 return 0; 125 case IMAGE985:
126 case BLADE3D:
127 case CYBERBLADEi7: /* VIA MPV4 integrated version */
128
129 default:
130 /* case CYBERBLDAEXPm8: Strange */
131 /* case CYBERBLDAEXPm16: Strange */
132 return 0;
136 } 133 }
137} 134}
138 135
139#define CRT 0x3D0 //CRTC registers offset for color display 136#define CRT 0x3D0 /* CRTC registers offset for color display */
140 137
141#ifndef TRIDENT_MMIO 138#ifndef TRIDENT_MMIO
142 #define TRIDENT_MMIO 1 139 #define TRIDENT_MMIO 1
143#endif 140#endif
144 141
145#if TRIDENT_MMIO 142#if TRIDENT_MMIO
146 #define t_outb(val,reg) writeb(val,((struct tridentfb_par *)(fb_info.par))->io_virt + reg) 143 #define t_outb(val, reg) writeb(val,((struct tridentfb_par *)(fb_info.par))->io_virt + reg)
147 #define t_inb(reg) readb(((struct tridentfb_par*)(fb_info.par))->io_virt + reg) 144 #define t_inb(reg) readb(((struct tridentfb_par*)(fb_info.par))->io_virt + reg)
148#else 145#else
149 #define t_outb(val,reg) outb(val,reg) 146 #define t_outb(val, reg) outb(val, reg)
150 #define t_inb(reg) inb(reg) 147 #define t_inb(reg) inb(reg)
151#endif 148#endif
152 149
153 150
154static struct accel_switch { 151static struct accel_switch {
155 void (*init_accel)(int,int); 152 void (*init_accel) (int, int);
156 void (*wait_engine)(void); 153 void (*wait_engine) (void);
157 void (*fill_rect)(__u32,__u32,__u32,__u32,__u32,__u32); 154 void (*fill_rect) (u32, u32, u32, u32, u32, u32);
158 void (*copy_rect)(__u32,__u32,__u32,__u32,__u32,__u32); 155 void (*copy_rect) (u32, u32, u32, u32, u32, u32);
159} *acc; 156} *acc;
160 157
161#define writemmr(r,v) writel(v, ((struct tridentfb_par *)fb_info.par)->io_virt + r) 158#define writemmr(r, v) writel(v, ((struct tridentfb_par *)fb_info.par)->io_virt + r)
162#define readmmr(r) readl(((struct tridentfb_par *)fb_info.par)->io_virt + r) 159#define readmmr(r) readl(((struct tridentfb_par *)fb_info.par)->io_virt + r)
163 160
164
165
166/* 161/*
167 * Blade specific acceleration. 162 * Blade specific acceleration.
168 */ 163 */
169 164
170#define point(x,y) ((y)<<16|(x)) 165#define point(x, y) ((y) << 16 | (x))
171#define STA 0x2120 166#define STA 0x2120
172#define CMD 0x2144 167#define CMD 0x2144
173#define ROP 0x2148 168#define ROP 0x2148
@@ -179,64 +174,71 @@ static struct accel_switch {
179 174
180#define ROP_S 0xCC 175#define ROP_S 0xCC
181 176
182static void blade_init_accel(int pitch,int bpp) 177static void blade_init_accel(int pitch, int bpp)
183{ 178{
184 int v1 = (pitch>>3)<<20; 179 int v1 = (pitch >> 3) << 20;
185 int tmp = 0,v2; 180 int tmp = 0, v2;
186 switch (bpp) { 181 switch (bpp) {
187 case 8:tmp = 0;break; 182 case 8:
188 case 15:tmp = 5;break; 183 tmp = 0;
189 case 16:tmp = 1;break; 184 break;
190 case 24: 185 case 15:
191 case 32:tmp = 2;break; 186 tmp = 5;
187 break;
188 case 16:
189 tmp = 1;
190 break;
191 case 24:
192 case 32:
193 tmp = 2;
194 break;
192 } 195 }
193 v2 = v1 | (tmp<<29); 196 v2 = v1 | (tmp << 29);
194 writemmr(0x21C0,v2); 197 writemmr(0x21C0, v2);
195 writemmr(0x21C4,v2); 198 writemmr(0x21C4, v2);
196 writemmr(0x21B8,v2); 199 writemmr(0x21B8, v2);
197 writemmr(0x21BC,v2); 200 writemmr(0x21BC, v2);
198 writemmr(0x21D0,v1); 201 writemmr(0x21D0, v1);
199 writemmr(0x21D4,v1); 202 writemmr(0x21D4, v1);
200 writemmr(0x21C8,v1); 203 writemmr(0x21C8, v1);
201 writemmr(0x21CC,v1); 204 writemmr(0x21CC, v1);
202 writemmr(0x216C,0); 205 writemmr(0x216C, 0);
203} 206}
204 207
205static void blade_wait_engine(void) 208static void blade_wait_engine(void)
206{ 209{
207 while(readmmr(STA) & 0xFA800000); 210 while (readmmr(STA) & 0xFA800000) ;
208} 211}
209 212
210static void blade_fill_rect(__u32 x,__u32 y,__u32 w,__u32 h,__u32 c,__u32 rop) 213static void blade_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
211{ 214{
212 writemmr(CLR,c); 215 writemmr(CLR, c);
213 writemmr(ROP,rop ? 0x66:ROP_S); 216 writemmr(ROP, rop ? 0x66 : ROP_S);
214 writemmr(CMD,0x20000000|1<<19|1<<4|2<<2); 217 writemmr(CMD, 0x20000000 | 1 << 19 | 1 << 4 | 2 << 2);
215 218
216 writemmr(DR1,point(x,y)); 219 writemmr(DR1, point(x, y));
217 writemmr(DR2,point(x+w-1,y+h-1)); 220 writemmr(DR2, point(x + w - 1, y + h - 1));
218} 221}
219 222
220static void blade_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h) 223static void blade_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
221{ 224{
222 __u32 s1,s2,d1,d2; 225 u32 s1, s2, d1, d2;
223 int direction = 2; 226 int direction = 2;
224 s1 = point(x1,y1); 227 s1 = point(x1, y1);
225 s2 = point(x1+w-1,y1+h-1); 228 s2 = point(x1 + w - 1, y1 + h - 1);
226 d1 = point(x2,y2); 229 d1 = point(x2, y2);
227 d2 = point(x2+w-1,y2+h-1); 230 d2 = point(x2 + w - 1, y2 + h - 1);
228 231
229 if ((y1 > y2) || ((y1 == y2) && (x1 > x2))) 232 if ((y1 > y2) || ((y1 == y2) && (x1 > x2)))
230 direction = 0; 233 direction = 0;
231
232 234
233 writemmr(ROP,ROP_S); 235 writemmr(ROP, ROP_S);
234 writemmr(CMD,0xE0000000|1<<19|1<<4|1<<2|direction); 236 writemmr(CMD, 0xE0000000 | 1 << 19 | 1 << 4 | 1 << 2 | direction);
235 237
236 writemmr(SR1,direction?s2:s1); 238 writemmr(SR1, direction ? s2 : s1);
237 writemmr(SR2,direction?s1:s2); 239 writemmr(SR2, direction ? s1 : s2);
238 writemmr(DR1,direction?d2:d1); 240 writemmr(DR1, direction ? d2 : d1);
239 writemmr(DR2,direction?d1:d2); 241 writemmr(DR2, direction ? d1 : d2);
240} 242}
241 243
242static struct accel_switch accel_blade = { 244static struct accel_switch accel_blade = {
@@ -246,51 +248,72 @@ static struct accel_switch accel_blade = {
246 blade_copy_rect, 248 blade_copy_rect,
247}; 249};
248 250
249
250/* 251/*
251 * BladeXP specific acceleration functions 252 * BladeXP specific acceleration functions
252 */ 253 */
253 254
254#define ROP_P 0xF0 255#define ROP_P 0xF0
255#define masked_point(x,y) ((y & 0xffff)<<16|(x & 0xffff)) 256#define masked_point(x, y) ((y & 0xffff)<<16|(x & 0xffff))
256 257
257static void xp_init_accel(int pitch,int bpp) 258static void xp_init_accel(int pitch, int bpp)
258{ 259{
259 int tmp = 0,v1; 260 int tmp = 0, v1;
260 unsigned char x = 0; 261 unsigned char x = 0;
261 262
262 switch (bpp) { 263 switch (bpp) {
263 case 8: x = 0; break; 264 case 8:
264 case 16: x = 1; break; 265 x = 0;
265 case 24: x = 3; break; 266 break;
266 case 32: x = 2; break; 267 case 16:
268 x = 1;
269 break;
270 case 24:
271 x = 3;
272 break;
273 case 32:
274 x = 2;
275 break;
267 } 276 }
268 277
269 switch (pitch << (bpp >> 3)) { 278 switch (pitch << (bpp >> 3)) {
270 case 8192: 279 case 8192:
271 case 512: x |= 0x00; break; 280 case 512:
272 case 1024: x |= 0x04; break; 281 x |= 0x00;
273 case 2048: x |= 0x08; break; 282 break;
274 case 4096: x |= 0x0C; break; 283 case 1024:
284 x |= 0x04;
285 break;
286 case 2048:
287 x |= 0x08;
288 break;
289 case 4096:
290 x |= 0x0C;
291 break;
275 } 292 }
276 293
277 t_outb(x,0x2125); 294 t_outb(x, 0x2125);
278 295
279 eng_oper = x | 0x40; 296 eng_oper = x | 0x40;
280 297
281 switch (bpp) { 298 switch (bpp) {
282 case 8: tmp = 18; break; 299 case 8:
283 case 15: 300 tmp = 18;
284 case 16: tmp = 19; break; 301 break;
285 case 24: 302 case 15:
286 case 32: tmp = 20; break; 303 case 16:
304 tmp = 19;
305 break;
306 case 24:
307 case 32:
308 tmp = 20;
309 break;
287 } 310 }
288 311
289 v1 = pitch << tmp; 312 v1 = pitch << tmp;
290 313
291 writemmr(0x2154,v1); 314 writemmr(0x2154, v1);
292 writemmr(0x2150,v1); 315 writemmr(0x2150, v1);
293 t_outb(3,0x2126); 316 t_outb(3, 0x2126);
294} 317}
295 318
296static void xp_wait_engine(void) 319static void xp_wait_engine(void)
@@ -318,24 +341,24 @@ static void xp_wait_engine(void)
318 } 341 }
319} 342}
320 343
321static void xp_fill_rect(__u32 x,__u32 y,__u32 w,__u32 h,__u32 c,__u32 rop) 344static void xp_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
322{ 345{
323 writemmr(0x2127,ROP_P); 346 writemmr(0x2127, ROP_P);
324 writemmr(0x2158,c); 347 writemmr(0x2158, c);
325 writemmr(0x2128,0x4000); 348 writemmr(0x2128, 0x4000);
326 writemmr(0x2140,masked_point(h,w)); 349 writemmr(0x2140, masked_point(h, w));
327 writemmr(0x2138,masked_point(y,x)); 350 writemmr(0x2138, masked_point(y, x));
328 t_outb(0x01,0x2124); 351 t_outb(0x01, 0x2124);
329 t_outb(eng_oper,0x2125); 352 t_outb(eng_oper, 0x2125);
330} 353}
331 354
332static void xp_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h) 355static void xp_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
333{ 356{
334 int direction; 357 int direction;
335 __u32 x1_tmp, x2_tmp, y1_tmp, y2_tmp; 358 u32 x1_tmp, x2_tmp, y1_tmp, y2_tmp;
336 359
337 direction = 0x0004; 360 direction = 0x0004;
338 361
339 if ((x1 < x2) && (y1 == y2)) { 362 if ((x1 < x2) && (y1 == y2)) {
340 direction |= 0x0200; 363 direction |= 0x0200;
341 x1_tmp = x1 + w - 1; 364 x1_tmp = x1 + w - 1;
@@ -344,53 +367,60 @@ static void xp_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h)
344 x1_tmp = x1; 367 x1_tmp = x1;
345 x2_tmp = x2; 368 x2_tmp = x2;
346 } 369 }
347 370
348 if (y1 < y2) { 371 if (y1 < y2) {
349 direction |= 0x0100; 372 direction |= 0x0100;
350 y1_tmp = y1 + h - 1; 373 y1_tmp = y1 + h - 1;
351 y2_tmp = y2 + h - 1; 374 y2_tmp = y2 + h - 1;
352 } else { 375 } else {
353 y1_tmp = y1; 376 y1_tmp = y1;
354 y2_tmp = y2; 377 y2_tmp = y2;
355 } 378 }
356 379
357 writemmr(0x2128,direction); 380 writemmr(0x2128, direction);
358 t_outb(ROP_S,0x2127); 381 t_outb(ROP_S, 0x2127);
359 writemmr(0x213C,masked_point(y1_tmp,x1_tmp)); 382 writemmr(0x213C, masked_point(y1_tmp, x1_tmp));
360 writemmr(0x2138,masked_point(y2_tmp,x2_tmp)); 383 writemmr(0x2138, masked_point(y2_tmp, x2_tmp));
361 writemmr(0x2140,masked_point(h,w)); 384 writemmr(0x2140, masked_point(h, w));
362 t_outb(0x01,0x2124); 385 t_outb(0x01, 0x2124);
363} 386}
364 387
365static struct accel_switch accel_xp = { 388static struct accel_switch accel_xp = {
366 xp_init_accel, 389 xp_init_accel,
367 xp_wait_engine, 390 xp_wait_engine,
368 xp_fill_rect, 391 xp_fill_rect,
369 xp_copy_rect, 392 xp_copy_rect,
370}; 393};
371 394
372
373/* 395/*
374 * Image specific acceleration functions 396 * Image specific acceleration functions
375 */ 397 */
376static void image_init_accel(int pitch,int bpp) 398static void image_init_accel(int pitch, int bpp)
377{ 399{
378 int tmp = 0; 400 int tmp = 0;
379 switch (bpp) { 401 switch (bpp) {
380 case 8:tmp = 0;break; 402 case 8:
381 case 15:tmp = 5;break; 403 tmp = 0;
382 case 16:tmp = 1;break; 404 break;
383 case 24: 405 case 15:
384 case 32:tmp = 2;break; 406 tmp = 5;
407 break;
408 case 16:
409 tmp = 1;
410 break;
411 case 24:
412 case 32:
413 tmp = 2;
414 break;
385 } 415 }
386 writemmr(0x2120, 0xF0000000); 416 writemmr(0x2120, 0xF0000000);
387 writemmr(0x2120, 0x40000000|tmp); 417 writemmr(0x2120, 0x40000000 | tmp);
388 writemmr(0x2120, 0x80000000); 418 writemmr(0x2120, 0x80000000);
389 writemmr(0x2144, 0x00000000); 419 writemmr(0x2144, 0x00000000);
390 writemmr(0x2148, 0x00000000); 420 writemmr(0x2148, 0x00000000);
391 writemmr(0x2150, 0x00000000); 421 writemmr(0x2150, 0x00000000);
392 writemmr(0x2154, 0x00000000); 422 writemmr(0x2154, 0x00000000);
393 writemmr(0x2120, 0x60000000|(pitch<<16) |pitch); 423 writemmr(0x2120, 0x60000000 | (pitch << 16) | pitch);
394 writemmr(0x216C, 0x00000000); 424 writemmr(0x216C, 0x00000000);
395 writemmr(0x2170, 0x00000000); 425 writemmr(0x2170, 0x00000000);
396 writemmr(0x217C, 0x00000000); 426 writemmr(0x217C, 0x00000000);
@@ -400,44 +430,43 @@ static void image_init_accel(int pitch,int bpp)
400 430
401static void image_wait_engine(void) 431static void image_wait_engine(void)
402{ 432{
403 while(readmmr(0x2164) & 0xF0000000); 433 while (readmmr(0x2164) & 0xF0000000) ;
404} 434}
405 435
406static void image_fill_rect(__u32 x, __u32 y, __u32 w, __u32 h, __u32 c, __u32 rop) 436static void image_fill_rect(u32 x, u32 y, u32 w, u32 h, u32 c, u32 rop)
407{ 437{
408 writemmr(0x2120,0x80000000); 438 writemmr(0x2120, 0x80000000);
409 writemmr(0x2120,0x90000000|ROP_S); 439 writemmr(0x2120, 0x90000000 | ROP_S);
410 440
411 writemmr(0x2144,c); 441 writemmr(0x2144, c);
412 442
413 writemmr(DR1,point(x,y)); 443 writemmr(DR1, point(x, y));
414 writemmr(DR2,point(x+w-1,y+h-1)); 444 writemmr(DR2, point(x + w - 1, y + h - 1));
415 445
416 writemmr(0x2124,0x80000000|3<<22|1<<10|1<<9); 446 writemmr(0x2124, 0x80000000 | 3 << 22 | 1 << 10 | 1 << 9);
417} 447}
418 448
419static void image_copy_rect(__u32 x1,__u32 y1,__u32 x2,__u32 y2,__u32 w,__u32 h) 449static void image_copy_rect(u32 x1, u32 y1, u32 x2, u32 y2, u32 w, u32 h)
420{ 450{
421 __u32 s1,s2,d1,d2; 451 u32 s1, s2, d1, d2;
422 int direction = 2; 452 int direction = 2;
423 s1 = point(x1,y1); 453 s1 = point(x1, y1);
424 s2 = point(x1+w-1,y1+h-1); 454 s2 = point(x1 + w - 1, y1 + h - 1);
425 d1 = point(x2,y2); 455 d1 = point(x2, y2);
426 d2 = point(x2+w-1,y2+h-1); 456 d2 = point(x2 + w - 1, y2 + h - 1);
427
428 if ((y1 > y2) || ((y1 == y2) && (x1 >x2)))
429 direction = 0;
430
431 writemmr(0x2120,0x80000000);
432 writemmr(0x2120,0x90000000|ROP_S);
433
434 writemmr(SR1,direction?s2:s1);
435 writemmr(SR2,direction?s1:s2);
436 writemmr(DR1,direction?d2:d1);
437 writemmr(DR2,direction?d1:d2);
438 writemmr(0x2124,0x80000000|1<<22|1<<10|1<<7|direction);
439}
440 457
458 if ((y1 > y2) || ((y1 == y2) && (x1 > x2)))
459 direction = 0;
460
461 writemmr(0x2120, 0x80000000);
462 writemmr(0x2120, 0x90000000 | ROP_S);
463
464 writemmr(SR1, direction ? s2 : s1);
465 writemmr(SR2, direction ? s1 : s2);
466 writemmr(DR1, direction ? d2 : d1);
467 writemmr(DR2, direction ? d1 : d2);
468 writemmr(0x2124, 0x80000000 | 1 << 22 | 1 << 10 | 1 << 7 | direction);
469}
441 470
442static struct accel_switch accel_image = { 471static struct accel_switch accel_image = {
443 image_init_accel, 472 image_init_accel,
@@ -450,30 +479,34 @@ static struct accel_switch accel_image = {
450 * Accel functions called by the upper layers 479 * Accel functions called by the upper layers
451 */ 480 */
452#ifdef CONFIG_FB_TRIDENT_ACCEL 481#ifdef CONFIG_FB_TRIDENT_ACCEL
453static void tridentfb_fillrect(struct fb_info * info, const struct fb_fillrect *fr) 482static void tridentfb_fillrect(struct fb_info *info,
483 const struct fb_fillrect *fr)
454{ 484{
455 int bpp = info->var.bits_per_pixel; 485 int bpp = info->var.bits_per_pixel;
456 int col = 0; 486 int col = 0;
457 487
458 switch (bpp) { 488 switch (bpp) {
459 default: 489 default:
460 case 8: col |= fr->color; 490 case 8:
461 col |= col << 8; 491 col |= fr->color;
462 col |= col << 16; 492 col |= col << 8;
463 break; 493 col |= col << 16;
464 case 16: col = ((u32 *)(info->pseudo_palette))[fr->color]; 494 break;
465 495 case 16:
466 break; 496 col = ((u32 *)(info->pseudo_palette))[fr->color];
467 case 32: col = ((u32 *)(info->pseudo_palette))[fr->color]; 497 break;
468 break; 498 case 32:
469 } 499 col = ((u32 *)(info->pseudo_palette))[fr->color];
470 500 break;
501 }
502
471 acc->fill_rect(fr->dx, fr->dy, fr->width, fr->height, col, fr->rop); 503 acc->fill_rect(fr->dx, fr->dy, fr->width, fr->height, col, fr->rop);
472 acc->wait_engine(); 504 acc->wait_engine();
473} 505}
474static void tridentfb_copyarea(struct fb_info *info, const struct fb_copyarea *ca) 506static void tridentfb_copyarea(struct fb_info *info,
507 const struct fb_copyarea *ca)
475{ 508{
476 acc->copy_rect(ca->sx,ca->sy,ca->dx,ca->dy,ca->width,ca->height); 509 acc->copy_rect(ca->sx, ca->sy, ca->dx, ca->dy, ca->width, ca->height);
477 acc->wait_engine(); 510 acc->wait_engine();
478} 511}
479#else /* !CONFIG_FB_TRIDENT_ACCEL */ 512#else /* !CONFIG_FB_TRIDENT_ACCEL */
@@ -488,14 +521,14 @@ static void tridentfb_copyarea(struct fb_info *info, const struct fb_copyarea *c
488 521
489static inline unsigned char read3X4(int reg) 522static inline unsigned char read3X4(int reg)
490{ 523{
491 struct tridentfb_par * par = (struct tridentfb_par *)fb_info.par; 524 struct tridentfb_par *par = (struct tridentfb_par *)fb_info.par;
492 writeb(reg, par->io_virt + CRT + 4); 525 writeb(reg, par->io_virt + CRT + 4);
493 return readb( par->io_virt + CRT + 5); 526 return readb(par->io_virt + CRT + 5);
494} 527}
495 528
496static inline void write3X4(int reg, unsigned char val) 529static inline void write3X4(int reg, unsigned char val)
497{ 530{
498 struct tridentfb_par * par = (struct tridentfb_par *)fb_info.par; 531 struct tridentfb_par *par = (struct tridentfb_par *)fb_info.par;
499 writeb(reg, par->io_virt + CRT + 4); 532 writeb(reg, par->io_virt + CRT + 4);
500 writeb(val, par->io_virt + CRT + 5); 533 writeb(val, par->io_virt + CRT + 5);
501} 534}
@@ -520,7 +553,7 @@ static inline unsigned char read3CE(int reg)
520 553
521static inline void writeAttr(int reg, unsigned char val) 554static inline void writeAttr(int reg, unsigned char val)
522{ 555{
523 readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A); //flip-flop to index 556 readb(((struct tridentfb_par *)fb_info.par)->io_virt + CRT + 0x0A); /* flip-flop to index */
524 t_outb(reg, 0x3C0); 557 t_outb(reg, 0x3C0);
525 t_outb(val, 0x3C0); 558 t_outb(val, 0x3C0);
526} 559}
@@ -540,32 +573,41 @@ static inline void enable_mmio(void)
540 /* Unprotect registers */ 573 /* Unprotect registers */
541 outb(NewMode1, 0x3C4); 574 outb(NewMode1, 0x3C4);
542 outb(0x80, 0x3C5); 575 outb(0x80, 0x3C5);
543 576
544 /* Enable MMIO */ 577 /* Enable MMIO */
545 outb(PCIReg, 0x3D4); 578 outb(PCIReg, 0x3D4);
546 outb(inb(0x3D5) | 0x01, 0x3D5); 579 outb(inb(0x3D5) | 0x01, 0x3D5);
547} 580}
548 581
549
550#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F) 582#define crtc_unlock() write3X4(CRTVSyncEnd, read3X4(CRTVSyncEnd) & 0x7F)
551 583
552/* Return flat panel's maximum x resolution */ 584/* Return flat panel's maximum x resolution */
553static int __devinit get_nativex(void) 585static int __devinit get_nativex(void)
554{ 586{
555 int x,y,tmp; 587 int x, y, tmp;
556 588
557 if (nativex) 589 if (nativex)
558 return nativex; 590 return nativex;
559 591
560 tmp = (read3CE(VertStretch) >> 4) & 3; 592 tmp = (read3CE(VertStretch) >> 4) & 3;
561 593
562 switch (tmp) { 594 switch (tmp) {
563 case 0: x = 1280; y = 1024; break; 595 case 0:
564 case 2: x = 1024; y = 768; break; 596 x = 1280; y = 1024;
565 case 3: x = 800; y = 600; break; 597 break;
566 case 4: x = 1400; y = 1050; break; 598 case 2:
567 case 1: 599 x = 1024; y = 768;
568 default:x = 640; y = 480; break; 600 break;
601 case 3:
602 x = 800; y = 600;
603 break;
604 case 4:
605 x = 1400; y = 1050;
606 break;
607 case 1:
608 default:
609 x = 640; y = 480;
610 break;
569 } 611 }
570 612
571 output("%dx%d flat panel found\n", x, y); 613 output("%dx%d flat panel found\n", x, y);
@@ -576,25 +618,26 @@ static int __devinit get_nativex(void)
576static void set_lwidth(int width) 618static void set_lwidth(int width)
577{ 619{
578 write3X4(Offset, width & 0xFF); 620 write3X4(Offset, width & 0xFF);
579 write3X4(AddColReg, (read3X4(AddColReg) & 0xCF) | ((width & 0x300) >>4)); 621 write3X4(AddColReg,
622 (read3X4(AddColReg) & 0xCF) | ((width & 0x300) >> 4));
580} 623}
581 624
582/* For resolutions smaller than FP resolution stretch */ 625/* For resolutions smaller than FP resolution stretch */
583static void screen_stretch(void) 626static void screen_stretch(void)
584{ 627{
585 if (chip_id != CYBERBLADEXPAi1) 628 if (chip_id != CYBERBLADEXPAi1)
586 write3CE(BiosReg,0); 629 write3CE(BiosReg, 0);
587 else 630 else
588 write3CE(BiosReg,8); 631 write3CE(BiosReg, 8);
589 write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 1); 632 write3CE(VertStretch, (read3CE(VertStretch) & 0x7C) | 1);
590 write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 1); 633 write3CE(HorStretch, (read3CE(HorStretch) & 0x7C) | 1);
591} 634}
592 635
593/* For resolutions smaller than FP resolution center */ 636/* For resolutions smaller than FP resolution center */
594static void screen_center(void) 637static void screen_center(void)
595{ 638{
596 write3CE(VertStretch,(read3CE(VertStretch) & 0x7C) | 0x80); 639 write3CE(VertStretch, (read3CE(VertStretch) & 0x7C) | 0x80);
597 write3CE(HorStretch,(read3CE(HorStretch) & 0x7C) | 0x80); 640 write3CE(HorStretch, (read3CE(HorStretch) & 0x7C) | 0x80);
598} 641}
599 642
600/* Address of first shown pixel in display memory */ 643/* Address of first shown pixel in display memory */
@@ -602,40 +645,42 @@ static void set_screen_start(int base)
602{ 645{
603 write3X4(StartAddrLow, base & 0xFF); 646 write3X4(StartAddrLow, base & 0xFF);
604 write3X4(StartAddrHigh, (base & 0xFF00) >> 8); 647 write3X4(StartAddrHigh, (base & 0xFF00) >> 8);
605 write3X4(CRTCModuleTest, (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >> 11)); 648 write3X4(CRTCModuleTest,
606 write3X4(CRTHiOrd, (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17)); 649 (read3X4(CRTCModuleTest) & 0xDF) | ((base & 0x10000) >> 11));
650 write3X4(CRTHiOrd,
651 (read3X4(CRTHiOrd) & 0xF8) | ((base & 0xE0000) >> 17));
607} 652}
608 653
609/* Use 20.12 fixed-point for NTSC value and frequency calculation */ 654/* Use 20.12 fixed-point for NTSC value and frequency calculation */
610#define calc_freq(n,m,k) ( ((unsigned long)0xE517 * (n+8) / ((m+2)*(1<<k))) >> 12 ) 655#define calc_freq(n, m, k) ( ((unsigned long)0xE517 * (n + 8) / ((m + 2) * (1 << k))) >> 12 )
611 656
612/* Set dotclock frequency */ 657/* Set dotclock frequency */
613static void set_vclk(int freq) 658static void set_vclk(int freq)
614{ 659{
615 int m,n,k; 660 int m, n, k;
616 int f,fi,d,di; 661 int f, fi, d, di;
617 unsigned char lo=0,hi=0; 662 unsigned char lo = 0, hi = 0;
618 663
619 d = 20; 664 d = 20;
620 for(k = 2;k>=0;k--) 665 for (k = 2; k >= 0; k--)
621 for(m = 0;m<63;m++) 666 for (m = 0; m < 63; m++)
622 for(n = 0;n<128;n++) { 667 for (n = 0; n < 128; n++) {
623 fi = calc_freq(n,m,k); 668 fi = calc_freq(n, m, k);
624 if ((di = abs(fi - freq)) < d) { 669 if ((di = abs(fi - freq)) < d) {
625 d = di; 670 d = di;
626 f = fi; 671 f = fi;
627 lo = n; 672 lo = n;
628 hi = (k<<6) | m; 673 hi = (k << 6) | m;
629 } 674 }
630 } 675 }
631 if (chip3D) { 676 if (chip3D) {
632 write3C4(ClockHigh,hi); 677 write3C4(ClockHigh, hi);
633 write3C4(ClockLow,lo); 678 write3C4(ClockLow, lo);
634 } else { 679 } else {
635 outb(lo,0x43C8); 680 outb(lo, 0x43C8);
636 outb(hi,0x43C9); 681 outb(hi, 0x43C9);
637 } 682 }
638 debug("VCLK = %X %X\n",hi,lo); 683 debug("VCLK = %X %X\n", hi, lo);
639} 684}
640 685
641/* Set number of lines for flat panels*/ 686/* Set number of lines for flat panels*/
@@ -663,7 +708,7 @@ static unsigned int __devinit get_displaytype(void)
663 return DISPLAY_FP; 708 return DISPLAY_FP;
664 if (crt || !chipcyber) 709 if (crt || !chipcyber)
665 return DISPLAY_CRT; 710 return DISPLAY_CRT;
666 return (read3CE(FPConfig) & 0x10)?DISPLAY_FP:DISPLAY_CRT; 711 return (read3CE(FPConfig) & 0x10) ? DISPLAY_FP : DISPLAY_CRT;
667} 712}
668 713
669/* Try detecting the video memory size */ 714/* Try detecting the video memory size */
@@ -676,100 +721,136 @@ static unsigned int __devinit get_memsize(void)
676 if (memsize) 721 if (memsize)
677 k = memsize * Kb; 722 k = memsize * Kb;
678 else 723 else
679 switch (chip_id) { 724 switch (chip_id) {
680 case CYBER9525DVD: k = 2560 * Kb; break; 725 case CYBER9525DVD:
726 k = 2560 * Kb;
727 break;
681 default: 728 default:
682 tmp = read3X4(SPR) & 0x0F; 729 tmp = read3X4(SPR) & 0x0F;
683 switch (tmp) { 730 switch (tmp) {
684 731
685 case 0x01: k = 512; break; 732 case 0x01:
686 case 0x02: k = 6 * Mb; break; /* XP */ 733 k = 512;
687 case 0x03: k = 1 * Mb; break; 734 break;
688 case 0x04: k = 8 * Mb; break; 735 case 0x02:
689 case 0x06: k = 10 * Mb; break; /* XP */ 736 k = 6 * Mb; /* XP */
690 case 0x07: k = 2 * Mb; break; 737 break;
691 case 0x08: k = 12 * Mb; break; /* XP */ 738 case 0x03:
692 case 0x0A: k = 14 * Mb; break; /* XP */ 739 k = 1 * Mb;
693 case 0x0C: k = 16 * Mb; break; /* XP */ 740 break;
694 case 0x0E: /* XP */ 741 case 0x04:
695 742 k = 8 * Mb;
696 tmp2 = read3C4(0xC1); 743 break;
697 switch (tmp2) { 744 case 0x06:
698 case 0x00: k = 20 * Mb; break; 745 k = 10 * Mb; /* XP */
699 case 0x01: k = 24 * Mb; break; 746 break;
700 case 0x10: k = 28 * Mb; break; 747 case 0x07:
701 case 0x11: k = 32 * Mb; break; 748 k = 2 * Mb;
702 default: k = 1 * Mb; break; 749 break;
703 } 750 case 0x08:
751 k = 12 * Mb; /* XP */
752 break;
753 case 0x0A:
754 k = 14 * Mb; /* XP */
755 break;
756 case 0x0C:
757 k = 16 * Mb; /* XP */
758 break;
759 case 0x0E: /* XP */
760
761 tmp2 = read3C4(0xC1);
762 switch (tmp2) {
763 case 0x00:
764 k = 20 * Mb;
765 break;
766 case 0x01:
767 k = 24 * Mb;
768 break;
769 case 0x10:
770 k = 28 * Mb;
771 break;
772 case 0x11:
773 k = 32 * Mb;
774 break;
775 default:
776 k = 1 * Mb;
777 break;
778 }
779 break;
780
781 case 0x0F:
782 k = 4 * Mb;
783 break;
784 default:
785 k = 1 * Mb;
704 break; 786 break;
705
706 case 0x0F: k = 4 * Mb; break;
707 default: k = 1 * Mb;
708 } 787 }
709 } 788 }
710 789
711 k -= memdiff * Kb; 790 k -= memdiff * Kb;
712 output("framebuffer size = %d Kb\n", k/Kb); 791 output("framebuffer size = %d Kb\n", k / Kb);
713 return k; 792 return k;
714} 793}
715 794
716/* See if we can handle the video mode described in var */ 795/* See if we can handle the video mode described in var */
717static int tridentfb_check_var(struct fb_var_screeninfo *var, struct fb_info *info) 796static int tridentfb_check_var(struct fb_var_screeninfo *var,
797 struct fb_info *info)
718{ 798{
719 int bpp = var->bits_per_pixel; 799 int bpp = var->bits_per_pixel;
720 debug("enter\n"); 800 debug("enter\n");
721 801
722 /* check color depth */ 802 /* check color depth */
723 if (bpp == 24 ) 803 if (bpp == 24)
724 bpp = var->bits_per_pixel = 32; 804 bpp = var->bits_per_pixel = 32;
725 /* check whether resolution fits on panel and in memory*/ 805 /* check whether resolution fits on panel and in memory */
726 if (flatpanel && nativex && var->xres > nativex) 806 if (flatpanel && nativex && var->xres > nativex)
727 return -EINVAL; 807 return -EINVAL;
728 if (var->xres * var->yres_virtual * bpp/8 > info->fix.smem_len) 808 if (var->xres * var->yres_virtual * bpp / 8 > info->fix.smem_len)
729 return -EINVAL; 809 return -EINVAL;
730 810
731 switch (bpp) { 811 switch (bpp) {
732 case 8: 812 case 8:
733 var->red.offset = 0; 813 var->red.offset = 0;
734 var->green.offset = 0; 814 var->green.offset = 0;
735 var->blue.offset = 0; 815 var->blue.offset = 0;
736 var->red.length = 6; 816 var->red.length = 6;
737 var->green.length = 6; 817 var->green.length = 6;
738 var->blue.length = 6; 818 var->blue.length = 6;
739 break; 819 break;
740 case 16: 820 case 16:
741 var->red.offset = 11; 821 var->red.offset = 11;
742 var->green.offset = 5; 822 var->green.offset = 5;
743 var->blue.offset = 0; 823 var->blue.offset = 0;
744 var->red.length = 5; 824 var->red.length = 5;
745 var->green.length = 6; 825 var->green.length = 6;
746 var->blue.length = 5; 826 var->blue.length = 5;
747 break; 827 break;
748 case 32: 828 case 32:
749 var->red.offset = 16; 829 var->red.offset = 16;
750 var->green.offset = 8; 830 var->green.offset = 8;
751 var->blue.offset = 0; 831 var->blue.offset = 0;
752 var->red.length = 8; 832 var->red.length = 8;
753 var->green.length = 8; 833 var->green.length = 8;
754 var->blue.length = 8; 834 var->blue.length = 8;
755 break; 835 break;
756 default: 836 default:
757 return -EINVAL; 837 return -EINVAL;
758 } 838 }
759 debug("exit\n"); 839 debug("exit\n");
760 840
761 return 0; 841 return 0;
762 842
763} 843}
844
764/* Pan the display */ 845/* Pan the display */
765static int tridentfb_pan_display(struct fb_var_screeninfo *var, 846static int tridentfb_pan_display(struct fb_var_screeninfo *var,
766 struct fb_info *info) 847 struct fb_info *info)
767{ 848{
768 unsigned int offset; 849 unsigned int offset;
769 850
770 debug("enter\n"); 851 debug("enter\n");
771 offset = (var->xoffset + (var->yoffset * var->xres)) 852 offset = (var->xoffset + (var->yoffset * var->xres))
772 * var->bits_per_pixel/32; 853 * var->bits_per_pixel / 32;
773 info->var.xoffset = var->xoffset; 854 info->var.xoffset = var->xoffset;
774 info->var.yoffset = var->yoffset; 855 info->var.yoffset = var->yoffset;
775 set_screen_start(offset); 856 set_screen_start(offset);
@@ -777,36 +858,38 @@ static int tridentfb_pan_display(struct fb_var_screeninfo *var,
777 return 0; 858 return 0;
778} 859}
779 860
780#define shadowmode_on() write3CE(CyberControl,read3CE(CyberControl) | 0x81) 861#define shadowmode_on() write3CE(CyberControl, read3CE(CyberControl) | 0x81)
781#define shadowmode_off() write3CE(CyberControl,read3CE(CyberControl) & 0x7E) 862#define shadowmode_off() write3CE(CyberControl, read3CE(CyberControl) & 0x7E)
782 863
783/* Set the hardware to the requested video mode */ 864/* Set the hardware to the requested video mode */
784static int tridentfb_set_par(struct fb_info *info) 865static int tridentfb_set_par(struct fb_info *info)
785{ 866{
786 struct tridentfb_par * par = (struct tridentfb_par *)(info->par); 867 struct tridentfb_par *par = (struct tridentfb_par *)(info->par);
787 u32 htotal,hdispend,hsyncstart,hsyncend,hblankstart,hblankend, 868 u32 htotal, hdispend, hsyncstart, hsyncend, hblankstart, hblankend;
788 vtotal,vdispend,vsyncstart,vsyncend,vblankstart,vblankend; 869 u32 vtotal, vdispend, vsyncstart, vsyncend, vblankstart, vblankend;
789 struct fb_var_screeninfo *var = &info->var; 870 struct fb_var_screeninfo *var = &info->var;
790 int bpp = var->bits_per_pixel; 871 int bpp = var->bits_per_pixel;
791 unsigned char tmp; 872 unsigned char tmp;
792 debug("enter\n"); 873 debug("enter\n");
793 htotal = (var->xres + var->left_margin + var->right_margin + var->hsync_len)/8 - 10; 874 hdispend = var->xres / 8 - 1;
794 hdispend = var->xres/8 - 1; 875 hsyncstart = (var->xres + var->right_margin) / 8;
795 hsyncstart = (var->xres + var->right_margin)/8; 876 hsyncend = var->hsync_len / 8;
796 hsyncend = var->hsync_len/8; 877 htotal =
878 (var->xres + var->left_margin + var->right_margin +
879 var->hsync_len) / 8 - 10;
797 hblankstart = hdispend + 1; 880 hblankstart = hdispend + 1;
798 hblankend = htotal + 5; 881 hblankend = htotal + 5;
799 882
800 vtotal = var->yres + var->upper_margin + var->lower_margin + var->vsync_len - 2;
801 vdispend = var->yres - 1; 883 vdispend = var->yres - 1;
802 vsyncstart = var->yres + var->lower_margin; 884 vsyncstart = var->yres + var->lower_margin;
803 vsyncend = var->vsync_len; 885 vsyncend = var->vsync_len;
886 vtotal = var->upper_margin + vsyncstart + vsyncend - 2;
804 vblankstart = var->yres; 887 vblankstart = var->yres;
805 vblankend = vtotal + 2; 888 vblankend = vtotal + 2;
806 889
807 enable_mmio(); 890 enable_mmio();
808 crtc_unlock(); 891 crtc_unlock();
809 write3CE(CyberControl,8); 892 write3CE(CyberControl, 8);
810 893
811 if (flatpanel && var->xres < nativex) { 894 if (flatpanel && var->xres < nativex) {
812 /* 895 /*
@@ -814,18 +897,18 @@ static int tridentfb_set_par(struct fb_info *info)
814 * than requested resolution decide whether 897 * than requested resolution decide whether
815 * we stretch or center 898 * we stretch or center
816 */ 899 */
817 t_outb(0xEB,0x3C2); 900 t_outb(0xEB, 0x3C2);
818 901
819 shadowmode_on(); 902 shadowmode_on();
820 903
821 if (center) 904 if (center)
822 screen_center(); 905 screen_center();
823 else if (stretch) 906 else if (stretch)
824 screen_stretch(); 907 screen_stretch();
825 908
826 } else { 909 } else {
827 t_outb(0x2B,0x3C2); 910 t_outb(0x2B, 0x3C2);
828 write3CE(CyberControl,8); 911 write3CE(CyberControl, 8);
829 } 912 }
830 913
831 /* vertical timing values */ 914 /* vertical timing values */
@@ -834,15 +917,15 @@ static int tridentfb_set_par(struct fb_info *info)
834 write3X4(CRTVSyncStart, vsyncstart & 0xFF); 917 write3X4(CRTVSyncStart, vsyncstart & 0xFF);
835 write3X4(CRTVSyncEnd, (vsyncend & 0x0F)); 918 write3X4(CRTVSyncEnd, (vsyncend & 0x0F));
836 write3X4(CRTVBlankStart, vblankstart & 0xFF); 919 write3X4(CRTVBlankStart, vblankstart & 0xFF);
837 write3X4(CRTVBlankEnd, 0/*p->vblankend & 0xFF*/); 920 write3X4(CRTVBlankEnd, 0 /* p->vblankend & 0xFF */ );
838 921
839 /* horizontal timing values */ 922 /* horizontal timing values */
840 write3X4(CRTHTotal, htotal & 0xFF); 923 write3X4(CRTHTotal, htotal & 0xFF);
841 write3X4(CRTHDispEnd, hdispend & 0xFF); 924 write3X4(CRTHDispEnd, hdispend & 0xFF);
842 write3X4(CRTHSyncStart, hsyncstart & 0xFF); 925 write3X4(CRTHSyncStart, hsyncstart & 0xFF);
843 write3X4(CRTHSyncEnd, (hsyncend & 0x1F) | ((hblankend & 0x20)<<2)); 926 write3X4(CRTHSyncEnd, (hsyncend & 0x1F) | ((hblankend & 0x20) << 2));
844 write3X4(CRTHBlankStart, hblankstart & 0xFF); 927 write3X4(CRTHBlankStart, hblankstart & 0xFF);
845 write3X4(CRTHBlankEnd, 0/*(p->hblankend & 0x1F)*/); 928 write3X4(CRTHBlankEnd, 0 /* (p->hblankend & 0x1F) */ );
846 929
847 /* higher bits of vertical timing values */ 930 /* higher bits of vertical timing values */
848 tmp = 0x10; 931 tmp = 0x10;
@@ -856,7 +939,7 @@ static int tridentfb_set_par(struct fb_info *info)
856 if (vsyncstart & 0x200) tmp |= 0x80; 939 if (vsyncstart & 0x200) tmp |= 0x80;
857 write3X4(CRTOverflow, tmp); 940 write3X4(CRTOverflow, tmp);
858 941
859 tmp = read3X4(CRTHiOrd) | 0x08; //line compare bit 10 942 tmp = read3X4(CRTHiOrd) | 0x08; /* line compare bit 10 */
860 if (vtotal & 0x400) tmp |= 0x80; 943 if (vtotal & 0x400) tmp |= 0x80;
861 if (vblankstart & 0x400) tmp |= 0x40; 944 if (vblankstart & 0x400) tmp |= 0x40;
862 if (vsyncstart & 0x400) tmp |= 0x20; 945 if (vsyncstart & 0x400) tmp |= 0x20;
@@ -867,84 +950,100 @@ static int tridentfb_set_par(struct fb_info *info)
867 if (htotal & 0x800) tmp |= 0x800 >> 11; 950 if (htotal & 0x800) tmp |= 0x800 >> 11;
868 if (hblankstart & 0x800) tmp |= 0x800 >> 7; 951 if (hblankstart & 0x800) tmp |= 0x800 >> 7;
869 write3X4(HorizOverflow, tmp); 952 write3X4(HorizOverflow, tmp);
870 953
871 tmp = 0x40; 954 tmp = 0x40;
872 if (vblankstart & 0x200) tmp |= 0x20; 955 if (vblankstart & 0x200) tmp |= 0x20;
873//FIXME if (info->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; //double scan for 200 line modes 956//FIXME if (info->var.vmode & FB_VMODE_DOUBLE) tmp |= 0x80; /* double scan for 200 line modes */
874 write3X4(CRTMaxScanLine, tmp); 957 write3X4(CRTMaxScanLine, tmp);
875 958
876 write3X4(CRTLineCompare,0xFF); 959 write3X4(CRTLineCompare, 0xFF);
877 write3X4(CRTPRowScan,0); 960 write3X4(CRTPRowScan, 0);
878 write3X4(CRTModeControl,0xC3); 961 write3X4(CRTModeControl, 0xC3);
879 962
880 write3X4(LinearAddReg,0x20); //enable linear addressing 963 write3X4(LinearAddReg, 0x20); /* enable linear addressing */
881 964
882 tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84:0x80; 965 tmp = (info->var.vmode & FB_VMODE_INTERLACED) ? 0x84 : 0x80;
883 write3X4(CRTCModuleTest,tmp); //enable access extended memory 966 write3X4(CRTCModuleTest, tmp); /* enable access extended memory */
884 967
885 write3X4(GraphEngReg, 0x80); //enable GE for text acceleration 968 write3X4(GraphEngReg, 0x80); /* enable GE for text acceleration */
886 969
887#ifdef CONFIG_FB_TRIDENT_ACCEL 970#ifdef CONFIG_FB_TRIDENT_ACCEL
888 acc->init_accel(info->var.xres,bpp); 971 acc->init_accel(info->var.xres, bpp);
889#endif 972#endif
890 973
891 switch (bpp) { 974 switch (bpp) {
892 case 8: tmp = 0x00; break; 975 case 8:
893 case 16: tmp = 0x05; break; 976 tmp = 0x00;
894 case 24: tmp = 0x29; break; 977 break;
895 case 32: tmp = 0x09; 978 case 16:
979 tmp = 0x05;
980 break;
981 case 24:
982 tmp = 0x29;
983 break;
984 case 32:
985 tmp = 0x09;
986 break;
896 } 987 }
897 988
898 write3X4(PixelBusReg, tmp); 989 write3X4(PixelBusReg, tmp);
899 990
900 tmp = 0x10; 991 tmp = 0x10;
901 if (chipcyber) 992 if (chipcyber)
902 tmp |= 0x20; 993 tmp |= 0x20;
903 write3X4(DRAMControl, tmp); //both IO,linear enable 994 write3X4(DRAMControl, tmp); /* both IO, linear enable */
904 995
905 write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40); 996 write3X4(InterfaceSel, read3X4(InterfaceSel) | 0x40);
906 write3X4(Performance,0x92); 997 write3X4(Performance, 0x92);
907 write3X4(PCIReg,0x07); //MMIO & PCI read and write burst enable 998 write3X4(PCIReg, 0x07); /* MMIO & PCI read and write burst enable */
908 999
909 /* convert from picoseconds to MHz */ 1000 /* convert from picoseconds to MHz */
910 par->vclk = 1000000/info->var.pixclock; 1001 par->vclk = 1000000 / info->var.pixclock;
911 if (bpp == 32) 1002 if (bpp == 32)
912 par->vclk *=2; 1003 par->vclk *= 2;
913 set_vclk(par->vclk); 1004 set_vclk(par->vclk);
914 1005
915 write3C4(0,3); 1006 write3C4(0, 3);
916 write3C4(1,1); //set char clock 8 dots wide 1007 write3C4(1, 1); /* set char clock 8 dots wide */
917 write3C4(2,0x0F); //enable 4 maps because needed in chain4 mode 1008 write3C4(2, 0x0F); /* enable 4 maps because needed in chain4 mode */
918 write3C4(3,0); 1009 write3C4(3, 0);
919 write3C4(4,0x0E); //memory mode enable bitmaps ?? 1010 write3C4(4, 0x0E); /* memory mode enable bitmaps ?? */
920 1011
921 write3CE(MiscExtFunc,(bpp==32)?0x1A:0x12); //divide clock by 2 if 32bpp 1012 write3CE(MiscExtFunc, (bpp == 32) ? 0x1A : 0x12); /* divide clock by 2 if 32bpp */
922 //chain4 mode display and CPU path 1013 /* chain4 mode display and CPU path */
923 write3CE(0x5,0x40); //no CGA compat,allow 256 col 1014 write3CE(0x5, 0x40); /* no CGA compat, allow 256 col */
924 write3CE(0x6,0x05); //graphics mode 1015 write3CE(0x6, 0x05); /* graphics mode */
925 write3CE(0x7,0x0F); //planes? 1016 write3CE(0x7, 0x0F); /* planes? */
926 1017
927 if (chip_id == CYBERBLADEXPAi1) { 1018 if (chip_id == CYBERBLADEXPAi1) {
928 /* This fixes snow-effect in 32 bpp */ 1019 /* This fixes snow-effect in 32 bpp */
929 write3X4(CRTHSyncStart,0x84); 1020 write3X4(CRTHSyncStart, 0x84);
930 } 1021 }
931 1022
932 writeAttr(0x10,0x41); //graphics mode and support 256 color modes 1023 writeAttr(0x10, 0x41); /* graphics mode and support 256 color modes */
933 writeAttr(0x12,0x0F); //planes 1024 writeAttr(0x12, 0x0F); /* planes */
934 writeAttr(0x13,0); //horizontal pel panning 1025 writeAttr(0x13, 0); /* horizontal pel panning */
935 1026
936 //colors 1027 /* colors */
937 for(tmp = 0;tmp < 0x10;tmp++) 1028 for (tmp = 0; tmp < 0x10; tmp++)
938 writeAttr(tmp,tmp); 1029 writeAttr(tmp, tmp);
939 readb(par->io_virt + CRT + 0x0A); //flip-flop to index 1030 readb(par->io_virt + CRT + 0x0A); /* flip-flop to index */
940 t_outb(0x20, 0x3C0); //enable attr 1031 t_outb(0x20, 0x3C0); /* enable attr */
941 1032
942 switch (bpp) { 1033 switch (bpp) {
943 case 8: tmp = 0;break; //256 colors 1034 case 8:
944 case 15: tmp = 0x10;break; 1035 tmp = 0;
945 case 16: tmp = 0x30;break; //hicolor 1036 break;
946 case 24: //truecolor 1037 case 15:
947 case 32: tmp = 0xD0;break; 1038 tmp = 0x10;
1039 break;
1040 case 16:
1041 tmp = 0x30;
1042 break;
1043 case 24:
1044 case 32:
1045 tmp = 0xD0;
1046 break;
948 } 1047 }
949 1048
950 t_inb(0x3C8); 1049 t_inb(0x3C8);
@@ -952,37 +1051,36 @@ static int tridentfb_set_par(struct fb_info *info)
952 t_inb(0x3C6); 1051 t_inb(0x3C6);
953 t_inb(0x3C6); 1052 t_inb(0x3C6);
954 t_inb(0x3C6); 1053 t_inb(0x3C6);
955 t_outb(tmp,0x3C6); 1054 t_outb(tmp, 0x3C6);
956 t_inb(0x3C8); 1055 t_inb(0x3C8);
957 1056
958 if (flatpanel) 1057 if (flatpanel)
959 set_number_of_lines(info->var.yres); 1058 set_number_of_lines(info->var.yres);
960 set_lwidth(info->var.xres * bpp/(4*16)); 1059 set_lwidth(info->var.xres * bpp / (4 * 16));
961 info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR; 1060 info->fix.visual = (bpp == 8) ? FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
962 info->fix.line_length = info->var.xres * (bpp >> 3); 1061 info->fix.line_length = info->var.xres * (bpp >> 3);
963 info->cmap.len = (bpp == 8) ? 256: 16; 1062 info->cmap.len = (bpp == 8) ? 256 : 16;
964 debug("exit\n"); 1063 debug("exit\n");
965 return 0; 1064 return 0;
966} 1065}
967 1066
968/* Set one color register */ 1067/* Set one color register */
969static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green, 1068static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
970 unsigned blue, unsigned transp, 1069 unsigned blue, unsigned transp,
971 struct fb_info *info) 1070 struct fb_info *info)
972{ 1071{
973 int bpp = info->var.bits_per_pixel; 1072 int bpp = info->var.bits_per_pixel;
974 1073
975 if (regno >= info->cmap.len) 1074 if (regno >= info->cmap.len)
976 return 1; 1075 return 1;
977 1076
978
979 if (bpp == 8) { 1077 if (bpp == 8) {
980 t_outb(0xFF,0x3C6); 1078 t_outb(0xFF, 0x3C6);
981 t_outb(regno,0x3C8); 1079 t_outb(regno, 0x3C8);
982 1080
983 t_outb(red>>10,0x3C9); 1081 t_outb(red >> 10, 0x3C9);
984 t_outb(green>>10,0x3C9); 1082 t_outb(green >> 10, 0x3C9);
985 t_outb(blue>>10,0x3C9); 1083 t_outb(blue >> 10, 0x3C9);
986 1084
987 } else if (regno < 16) { 1085 } else if (regno < 16) {
988 if (bpp == 16) { /* RGB 565 */ 1086 if (bpp == 16) { /* RGB 565 */
@@ -994,29 +1092,28 @@ static int tridentfb_setcolreg(unsigned regno, unsigned red, unsigned green,
994 ((u32 *)(info->pseudo_palette))[regno] = col; 1092 ((u32 *)(info->pseudo_palette))[regno] = col;
995 } else if (bpp == 32) /* ARGB 8888 */ 1093 } else if (bpp == 32) /* ARGB 8888 */
996 ((u32*)info->pseudo_palette)[regno] = 1094 ((u32*)info->pseudo_palette)[regno] =
997 ((transp & 0xFF00) <<16) | 1095 ((transp & 0xFF00) << 16) |
998 ((red & 0xFF00) << 8) | 1096 ((red & 0xFF00) << 8) |
999 ((green & 0xFF00)) | 1097 ((green & 0xFF00)) |
1000 ((blue & 0xFF00)>>8); 1098 ((blue & 0xFF00) >> 8);
1001 } 1099 }
1002 1100
1003// debug("exit\n"); 1101/* debug("exit\n"); */
1004 return 0; 1102 return 0;
1005} 1103}
1006 1104
1007/* Try blanking the screen.For flat panels it does nothing */ 1105/* Try blanking the screen.For flat panels it does nothing */
1008static int tridentfb_blank(int blank_mode, struct fb_info *info) 1106static int tridentfb_blank(int blank_mode, struct fb_info *info)
1009{ 1107{
1010 unsigned char PMCont,DPMSCont; 1108 unsigned char PMCont, DPMSCont;
1011 1109
1012 debug("enter\n"); 1110 debug("enter\n");
1013 if (flatpanel) 1111 if (flatpanel)
1014 return 0; 1112 return 0;
1015 t_outb(0x04,0x83C8); /* Read DPMS Control */ 1113 t_outb(0x04, 0x83C8); /* Read DPMS Control */
1016 PMCont = t_inb(0x83C6) & 0xFC; 1114 PMCont = t_inb(0x83C6) & 0xFC;
1017 DPMSCont = read3CE(PowerStatus) & 0xFC; 1115 DPMSCont = read3CE(PowerStatus) & 0xFC;
1018 switch (blank_mode) 1116 switch (blank_mode) {
1019 {
1020 case FB_BLANK_UNBLANK: 1117 case FB_BLANK_UNBLANK:
1021 /* Screen: On, HSync: On, VSync: On */ 1118 /* Screen: On, HSync: On, VSync: On */
1022 case FB_BLANK_NORMAL: 1119 case FB_BLANK_NORMAL:
@@ -1039,11 +1136,11 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info)
1039 PMCont |= 0x00; 1136 PMCont |= 0x00;
1040 DPMSCont |= 0x03; 1137 DPMSCont |= 0x03;
1041 break; 1138 break;
1042 } 1139 }
1043 1140
1044 write3CE(PowerStatus,DPMSCont); 1141 write3CE(PowerStatus, DPMSCont);
1045 t_outb(4,0x83C8); 1142 t_outb(4, 0x83C8);
1046 t_outb(PMCont,0x83C6); 1143 t_outb(PMCont, 0x83C6);
1047 1144
1048 debug("exit\n"); 1145 debug("exit\n");
1049 1146
@@ -1051,7 +1148,20 @@ static int tridentfb_blank(int blank_mode, struct fb_info *info)
1051 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0; 1148 return (blank_mode == FB_BLANK_NORMAL) ? 1 : 0;
1052} 1149}
1053 1150
1054static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_device_id * id) 1151static struct fb_ops tridentfb_ops = {
1152 .owner = THIS_MODULE,
1153 .fb_setcolreg = tridentfb_setcolreg,
1154 .fb_pan_display = tridentfb_pan_display,
1155 .fb_blank = tridentfb_blank,
1156 .fb_check_var = tridentfb_check_var,
1157 .fb_set_par = tridentfb_set_par,
1158 .fb_fillrect = tridentfb_fillrect,
1159 .fb_copyarea = tridentfb_copyarea,
1160 .fb_imageblit = cfb_imageblit,
1161};
1162
1163static int __devinit trident_pci_probe(struct pci_dev * dev,
1164 const struct pci_device_id * id)
1055{ 1165{
1056 int err; 1166 int err;
1057 unsigned char revision; 1167 unsigned char revision;
@@ -1062,31 +1172,42 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1062 1172
1063 chip_id = id->device; 1173 chip_id = id->device;
1064 1174
1065 if(chip_id == CYBERBLADEi1) 1175 if (chip_id == CYBERBLADEi1)
1066 output("*** Please do use cyblafb, Cyberblade/i1 support " 1176 output("*** Please do use cyblafb, Cyberblade/i1 support "
1067 "will soon be removed from tridentfb!\n"); 1177 "will soon be removed from tridentfb!\n");
1068 1178
1069 1179
1070 /* If PCI id is 0x9660 then further detect chip type */ 1180 /* If PCI id is 0x9660 then further detect chip type */
1071 1181
1072 if (chip_id == TGUI9660) { 1182 if (chip_id == TGUI9660) {
1073 outb(RevisionID,0x3C4); 1183 outb(RevisionID, 0x3C4);
1074 revision = inb(0x3C5); 1184 revision = inb(0x3C5);
1075 1185
1076 switch (revision) { 1186 switch (revision) {
1077 case 0x22: 1187 case 0x22:
1078 case 0x23: chip_id = CYBER9397;break; 1188 case 0x23:
1079 case 0x2A: chip_id = CYBER9397DVD;break; 1189 chip_id = CYBER9397;
1080 case 0x30: 1190 break;
1081 case 0x33: 1191 case 0x2A:
1082 case 0x34: 1192 chip_id = CYBER9397DVD;
1083 case 0x35: 1193 break;
1084 case 0x38: 1194 case 0x30:
1085 case 0x3A: 1195 case 0x33:
1086 case 0xB3: chip_id = CYBER9385;break; 1196 case 0x34:
1087 case 0x40 ... 0x43: chip_id = CYBER9382;break; 1197 case 0x35:
1088 case 0x4A: chip_id = CYBER9388;break; 1198 case 0x38:
1089 default:break; 1199 case 0x3A:
1200 case 0xB3:
1201 chip_id = CYBER9385;
1202 break;
1203 case 0x40 ... 0x43:
1204 chip_id = CYBER9382;
1205 break;
1206 case 0x4A:
1207 chip_id = CYBER9388;
1208 break;
1209 default:
1210 break;
1090 } 1211 }
1091 } 1212 }
1092 1213
@@ -1095,8 +1216,7 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1095 1216
1096 if (is_xp(chip_id)) { 1217 if (is_xp(chip_id)) {
1097 acc = &accel_xp; 1218 acc = &accel_xp;
1098 } else 1219 } else if (is_blade(chip_id)) {
1099 if (is_blade(chip_id)) {
1100 acc = &accel_blade; 1220 acc = &accel_blade;
1101 } else { 1221 } else {
1102 acc = &accel_image; 1222 acc = &accel_image;
@@ -1108,8 +1228,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1108 fb_info.par = &default_par; 1228 fb_info.par = &default_par;
1109 1229
1110 /* setup MMIO region */ 1230 /* setup MMIO region */
1111 tridentfb_fix.mmio_start = pci_resource_start(dev,1); 1231 tridentfb_fix.mmio_start = pci_resource_start(dev, 1);
1112 tridentfb_fix.mmio_len = chip3D ? 0x20000:0x10000; 1232 tridentfb_fix.mmio_len = chip3D ? 0x20000 : 0x10000;
1113 1233
1114 if (!request_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len, "tridentfb")) { 1234 if (!request_mem_region(tridentfb_fix.mmio_start, tridentfb_fix.mmio_len, "tridentfb")) {
1115 debug("request_region failed!\n"); 1235 debug("request_region failed!\n");
@@ -1125,11 +1245,11 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1125 } 1245 }
1126 1246
1127 enable_mmio(); 1247 enable_mmio();
1128 1248
1129 /* setup framebuffer memory */ 1249 /* setup framebuffer memory */
1130 tridentfb_fix.smem_start = pci_resource_start(dev,0); 1250 tridentfb_fix.smem_start = pci_resource_start(dev, 0);
1131 tridentfb_fix.smem_len = get_memsize(); 1251 tridentfb_fix.smem_len = get_memsize();
1132 1252
1133 if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) { 1253 if (!request_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len, "tridentfb")) {
1134 debug("request_mem_region failed!\n"); 1254 debug("request_mem_region failed!\n");
1135 err = -1; 1255 err = -1;
@@ -1137,7 +1257,7 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1137 } 1257 }
1138 1258
1139 fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start, 1259 fb_info.screen_base = ioremap_nocache(tridentfb_fix.smem_start,
1140 tridentfb_fix.smem_len); 1260 tridentfb_fix.smem_len);
1141 1261
1142 if (!fb_info.screen_base) { 1262 if (!fb_info.screen_base) {
1143 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len); 1263 release_mem_region(tridentfb_fix.smem_start, tridentfb_fix.smem_len);
@@ -1147,13 +1267,13 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1147 } 1267 }
1148 1268
1149 output("%s board found\n", pci_name(dev)); 1269 output("%s board found\n", pci_name(dev));
1150#if 0 1270#if 0
1151 output("Trident board found : mem = %X,io = %X, mem_v = %X, io_v = %X\n", 1271 output("Trident board found : mem = %X, io = %X, mem_v = %X, io_v = %X\n",
1152 tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt); 1272 tridentfb_fix.smem_start, tridentfb_fix.mmio_start, fb_info.screen_base, default_par.io_virt);
1153#endif 1273#endif
1154 displaytype = get_displaytype(); 1274 displaytype = get_displaytype();
1155 1275
1156 if(flatpanel) 1276 if (flatpanel)
1157 nativex = get_nativex(); 1277 nativex = get_nativex();
1158 1278
1159 fb_info.fix = tridentfb_fix; 1279 fb_info.fix = tridentfb_fix;
@@ -1166,11 +1286,11 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1166#endif 1286#endif
1167 fb_info.pseudo_palette = pseudo_pal; 1287 fb_info.pseudo_palette = pseudo_pal;
1168 1288
1169 if (!fb_find_mode(&default_var,&fb_info,mode,NULL,0,NULL,bpp)) { 1289 if (!fb_find_mode(&default_var, &fb_info, mode, NULL, 0, NULL, bpp)) {
1170 err = -EINVAL; 1290 err = -EINVAL;
1171 goto out_unmap; 1291 goto out_unmap;
1172 } 1292 }
1173 fb_alloc_cmap(&fb_info.cmap,256,0); 1293 fb_alloc_cmap(&fb_info.cmap, 256, 0);
1174 if (defaultaccel && acc) 1294 if (defaultaccel && acc)
1175 default_var.accel_flags |= FB_ACCELF_TEXT; 1295 default_var.accel_flags |= FB_ACCELF_TEXT;
1176 else 1296 else
@@ -1184,8 +1304,8 @@ static int __devinit trident_pci_probe(struct pci_dev * dev, const struct pci_de
1184 goto out_unmap; 1304 goto out_unmap;
1185 } 1305 }
1186 output("fb%d: %s frame buffer device %dx%d-%dbpp\n", 1306 output("fb%d: %s frame buffer device %dx%d-%dbpp\n",
1187 fb_info.node, fb_info.fix.id,default_var.xres, 1307 fb_info.node, fb_info.fix.id, default_var.xres,
1188 default_var.yres,default_var.bits_per_pixel); 1308 default_var.yres, default_var.bits_per_pixel);
1189 return 0; 1309 return 0;
1190 1310
1191out_unmap: 1311out_unmap:
@@ -1196,7 +1316,7 @@ out_unmap:
1196 return err; 1316 return err;
1197} 1317}
1198 1318
1199static void __devexit trident_pci_remove(struct pci_dev * dev) 1319static void __devexit trident_pci_remove(struct pci_dev *dev)
1200{ 1320{
1201 struct tridentfb_par *par = (struct tridentfb_par*)fb_info.par; 1321 struct tridentfb_par *par = (struct tridentfb_par*)fb_info.par;
1202 unregister_framebuffer(&fb_info); 1322 unregister_framebuffer(&fb_info);
@@ -1208,69 +1328,70 @@ static void __devexit trident_pci_remove(struct pci_dev * dev)
1208 1328
1209/* List of boards that we are trying to support */ 1329/* List of boards that we are trying to support */
1210static struct pci_device_id trident_devices[] = { 1330static struct pci_device_id trident_devices[] = {
1211 {PCI_VENDOR_ID_TRIDENT, BLADE3D, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1331 {PCI_VENDOR_ID_TRIDENT, BLADE3D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1212 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1332 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1213 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7D, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1333 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi7D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1214 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1334 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1215 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1335 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEi1D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1216 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1336 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1217 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1D, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1337 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEAi1D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1218 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEE4, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1338 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEE4, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1219 {PCI_VENDOR_ID_TRIDENT, TGUI9660, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1339 {PCI_VENDOR_ID_TRIDENT, TGUI9660, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1220 {PCI_VENDOR_ID_TRIDENT, IMAGE975, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1340 {PCI_VENDOR_ID_TRIDENT, IMAGE975, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1221 {PCI_VENDOR_ID_TRIDENT, IMAGE985, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1341 {PCI_VENDOR_ID_TRIDENT, IMAGE985, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1222 {PCI_VENDOR_ID_TRIDENT, CYBER9320, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1342 {PCI_VENDOR_ID_TRIDENT, CYBER9320, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1223 {PCI_VENDOR_ID_TRIDENT, CYBER9388, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1343 {PCI_VENDOR_ID_TRIDENT, CYBER9388, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1224 {PCI_VENDOR_ID_TRIDENT, CYBER9520, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1344 {PCI_VENDOR_ID_TRIDENT, CYBER9520, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1225 {PCI_VENDOR_ID_TRIDENT, CYBER9525DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1345 {PCI_VENDOR_ID_TRIDENT, CYBER9525DVD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1226 {PCI_VENDOR_ID_TRIDENT, CYBER9397, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1346 {PCI_VENDOR_ID_TRIDENT, CYBER9397, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1227 {PCI_VENDOR_ID_TRIDENT, CYBER9397DVD, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1347 {PCI_VENDOR_ID_TRIDENT, CYBER9397DVD, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1228 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPAi1, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1348 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPAi1, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1229 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm8, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1349 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm8, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1230 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm16, PCI_ANY_ID,PCI_ANY_ID,0,0,0}, 1350 {PCI_VENDOR_ID_TRIDENT, CYBERBLADEXPm16, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0},
1231 {0,} 1351 {0,}
1232}; 1352};
1233 1353
1234MODULE_DEVICE_TABLE(pci,trident_devices); 1354MODULE_DEVICE_TABLE(pci, trident_devices);
1235 1355
1236static struct pci_driver tridentfb_pci_driver = { 1356static struct pci_driver tridentfb_pci_driver = {
1237 .name = "tridentfb", 1357 .name = "tridentfb",
1238 .id_table = trident_devices, 1358 .id_table = trident_devices,
1239 .probe = trident_pci_probe, 1359 .probe = trident_pci_probe,
1240 .remove = __devexit_p(trident_pci_remove) 1360 .remove = __devexit_p(trident_pci_remove)
1241}; 1361};
1242 1362
1243/* 1363/*
1244 * Parse user specified options (`video=trident:') 1364 * Parse user specified options (`video=trident:')
1245 * example: 1365 * example:
1246 * video=trident:800x600,bpp=16,noaccel 1366 * video=trident:800x600,bpp=16,noaccel
1247 */ 1367 */
1248#ifndef MODULE 1368#ifndef MODULE
1249static int tridentfb_setup(char *options) 1369static int tridentfb_setup(char *options)
1250{ 1370{
1251 char * opt; 1371 char *opt;
1252 if (!options || !*options) 1372 if (!options || !*options)
1253 return 0; 1373 return 0;
1254 while((opt = strsep(&options,",")) != NULL ) { 1374 while ((opt = strsep(&options, ",")) != NULL) {
1255 if (!*opt) continue; 1375 if (!*opt)
1256 if (!strncmp(opt,"noaccel",7)) 1376 continue;
1377 if (!strncmp(opt, "noaccel", 7))
1257 noaccel = 1; 1378 noaccel = 1;
1258 else if (!strncmp(opt,"fp",2)) 1379 else if (!strncmp(opt, "fp", 2))
1259 displaytype = DISPLAY_FP; 1380 displaytype = DISPLAY_FP;
1260 else if (!strncmp(opt,"crt",3)) 1381 else if (!strncmp(opt, "crt", 3))
1261 displaytype = DISPLAY_CRT; 1382 displaytype = DISPLAY_CRT;
1262 else if (!strncmp(opt,"bpp=",4)) 1383 else if (!strncmp(opt, "bpp=", 4))
1263 bpp = simple_strtoul(opt+4,NULL,0); 1384 bpp = simple_strtoul(opt + 4, NULL, 0);
1264 else if (!strncmp(opt,"center",6)) 1385 else if (!strncmp(opt, "center", 6))
1265 center = 1; 1386 center = 1;
1266 else if (!strncmp(opt,"stretch",7)) 1387 else if (!strncmp(opt, "stretch", 7))
1267 stretch = 1; 1388 stretch = 1;
1268 else if (!strncmp(opt,"memsize=",8)) 1389 else if (!strncmp(opt, "memsize=", 8))
1269 memsize = simple_strtoul(opt+8,NULL,0); 1390 memsize = simple_strtoul(opt + 8, NULL, 0);
1270 else if (!strncmp(opt,"memdiff=",8)) 1391 else if (!strncmp(opt, "memdiff=", 8))
1271 memdiff = simple_strtoul(opt+8,NULL,0); 1392 memdiff = simple_strtoul(opt + 8, NULL, 0);
1272 else if (!strncmp(opt,"nativex=",8)) 1393 else if (!strncmp(opt, "nativex=", 8))
1273 nativex = simple_strtoul(opt+8,NULL,0); 1394 nativex = simple_strtoul(opt + 8, NULL, 0);
1274 else 1395 else
1275 mode = opt; 1396 mode = opt;
1276 } 1397 }
@@ -1296,18 +1417,6 @@ static void __exit tridentfb_exit(void)
1296 pci_unregister_driver(&tridentfb_pci_driver); 1417 pci_unregister_driver(&tridentfb_pci_driver);
1297} 1418}
1298 1419
1299static struct fb_ops tridentfb_ops = {
1300 .owner = THIS_MODULE,
1301 .fb_setcolreg = tridentfb_setcolreg,
1302 .fb_pan_display = tridentfb_pan_display,
1303 .fb_blank = tridentfb_blank,
1304 .fb_check_var = tridentfb_check_var,
1305 .fb_set_par = tridentfb_set_par,
1306 .fb_fillrect = tridentfb_fillrect,
1307 .fb_copyarea= tridentfb_copyarea,
1308 .fb_imageblit = cfb_imageblit,
1309};
1310
1311module_init(tridentfb_init); 1420module_init(tridentfb_init);
1312module_exit(tridentfb_exit); 1421module_exit(tridentfb_exit);
1313 1422
diff --git a/drivers/video/uvesafb.c b/drivers/video/uvesafb.c
new file mode 100644
index 000000000000..b983d262ab78
--- /dev/null
+++ b/drivers/video/uvesafb.c
@@ -0,0 +1,2066 @@
1/*
2 * A framebuffer driver for VBE 2.0+ compliant video cards
3 *
4 * (c) 2007 Michal Januszewski <spock@gentoo.org>
5 * Loosely based upon the vesafb driver.
6 *
7 */
8#include <linux/init.h>
9#include <linux/module.h>
10#include <linux/moduleparam.h>
11#include <linux/skbuff.h>
12#include <linux/timer.h>
13#include <linux/completion.h>
14#include <linux/connector.h>
15#include <linux/random.h>
16#include <linux/platform_device.h>
17#include <linux/limits.h>
18#include <linux/fb.h>
19#include <linux/io.h>
20#include <linux/mutex.h>
21#include <video/edid.h>
22#include <video/uvesafb.h>
23#ifdef CONFIG_X86
24#include <video/vga.h>
25#endif
26#ifdef CONFIG_MTRR
27#include <asm/mtrr.h>
28#endif
29#include "edid.h"
30
31static struct cb_id uvesafb_cn_id = {
32 .idx = CN_IDX_V86D,
33 .val = CN_VAL_V86D_UVESAFB
34};
35static char v86d_path[PATH_MAX] = "/sbin/v86d";
36static char v86d_started; /* has v86d been started by uvesafb? */
37
38static struct fb_fix_screeninfo uvesafb_fix __devinitdata = {
39 .id = "VESA VGA",
40 .type = FB_TYPE_PACKED_PIXELS,
41 .accel = FB_ACCEL_NONE,
42 .visual = FB_VISUAL_TRUECOLOR,
43};
44
45static int mtrr __devinitdata = 3; /* enable mtrr by default */
46static int blank __devinitdata = 1; /* enable blanking by default */
47static int ypan __devinitdata = 1; /* 0: scroll, 1: ypan, 2: ywrap */
48static int pmi_setpal __devinitdata = 1; /* use PMI for palette changes */
49static int nocrtc __devinitdata; /* ignore CRTC settings */
50static int noedid __devinitdata; /* don't try DDC transfers */
51static int vram_remap __devinitdata; /* set amt. of memory to be used */
52static int vram_total __devinitdata; /* set total amount of memory */
53static u16 maxclk __devinitdata; /* maximum pixel clock */
54static u16 maxvf __devinitdata; /* maximum vertical frequency */
55static u16 maxhf __devinitdata; /* maximum horizontal frequency */
56static u16 vbemode __devinitdata; /* force use of a specific VBE mode */
57static char *mode_option __devinitdata;
58
59static struct uvesafb_ktask *uvfb_tasks[UVESAFB_TASKS_MAX];
60static DEFINE_MUTEX(uvfb_lock);
61
62/*
63 * A handler for replies from userspace.
64 *
65 * Make sure each message passes consistency checks and if it does,
66 * find the kernel part of the task struct, copy the registers and
67 * the buffer contents and then complete the task.
68 */
69static void uvesafb_cn_callback(void *data)
70{
71 struct cn_msg *msg = data;
72 struct uvesafb_task *utask;
73 struct uvesafb_ktask *task;
74
75 if (msg->seq >= UVESAFB_TASKS_MAX)
76 return;
77
78 mutex_lock(&uvfb_lock);
79 task = uvfb_tasks[msg->seq];
80
81 if (!task || msg->ack != task->ack) {
82 mutex_unlock(&uvfb_lock);
83 return;
84 }
85
86 utask = (struct uvesafb_task *)msg->data;
87
88 /* Sanity checks for the buffer length. */
89 if (task->t.buf_len < utask->buf_len ||
90 utask->buf_len > msg->len - sizeof(*utask)) {
91 mutex_unlock(&uvfb_lock);
92 return;
93 }
94
95 uvfb_tasks[msg->seq] = NULL;
96 mutex_unlock(&uvfb_lock);
97
98 memcpy(&task->t, utask, sizeof(*utask));
99
100 if (task->t.buf_len && task->buf)
101 memcpy(task->buf, utask + 1, task->t.buf_len);
102
103 complete(task->done);
104 return;
105}
106
107static int uvesafb_helper_start(void)
108{
109 char *envp[] = {
110 "HOME=/",
111 "PATH=/sbin:/bin",
112 NULL,
113 };
114
115 char *argv[] = {
116 v86d_path,
117 NULL,
118 };
119
120 return call_usermodehelper(v86d_path, argv, envp, 1);
121}
122
123/*
124 * Execute a uvesafb task.
125 *
126 * Returns 0 if the task is executed successfully.
127 *
128 * A message sent to the userspace consists of the uvesafb_task
129 * struct and (optionally) a buffer. The uvesafb_task struct is
130 * a simplified version of uvesafb_ktask (its kernel counterpart)
131 * containing only the register values, flags and the length of
132 * the buffer.
133 *
134 * Each message is assigned a sequence number (increased linearly)
135 * and a random ack number. The sequence number is used as a key
136 * for the uvfb_tasks array which holds pointers to uvesafb_ktask
137 * structs for all requests.
138 */
139static int uvesafb_exec(struct uvesafb_ktask *task)
140{
141 static int seq;
142 struct cn_msg *m;
143 int err;
144 int len = sizeof(task->t) + task->t.buf_len;
145
146 /*
147 * Check whether the message isn't longer than the maximum
148 * allowed by connector.
149 */
150 if (sizeof(*m) + len > CONNECTOR_MAX_MSG_SIZE) {
151 printk(KERN_WARNING "uvesafb: message too long (%d), "
152 "can't execute task\n", (int)(sizeof(*m) + len));
153 return -E2BIG;
154 }
155
156 m = kzalloc(sizeof(*m) + len, GFP_KERNEL);
157 if (!m)
158 return -ENOMEM;
159
160 init_completion(task->done);
161
162 memcpy(&m->id, &uvesafb_cn_id, sizeof(m->id));
163 m->seq = seq;
164 m->len = len;
165 m->ack = random32();
166
167 /* uvesafb_task structure */
168 memcpy(m + 1, &task->t, sizeof(task->t));
169
170 /* Buffer */
171 memcpy((u8 *)(m + 1) + sizeof(task->t), task->buf, task->t.buf_len);
172
173 /*
174 * Save the message ack number so that we can find the kernel
175 * part of this task when a reply is received from userspace.
176 */
177 task->ack = m->ack;
178
179 mutex_lock(&uvfb_lock);
180
181 /* If all slots are taken -- bail out. */
182 if (uvfb_tasks[seq]) {
183 mutex_unlock(&uvfb_lock);
184 return -EBUSY;
185 }
186
187 /* Save a pointer to the kernel part of the task struct. */
188 uvfb_tasks[seq] = task;
189 mutex_unlock(&uvfb_lock);
190
191 err = cn_netlink_send(m, 0, gfp_any());
192 if (err == -ESRCH) {
193 /*
194 * Try to start the userspace helper if sending
195 * the request failed the first time.
196 */
197 err = uvesafb_helper_start();
198 if (err) {
199 printk(KERN_ERR "uvesafb: failed to execute %s\n",
200 v86d_path);
201 printk(KERN_ERR "uvesafb: make sure that the v86d "
202 "helper is installed and executable\n");
203 } else {
204 v86d_started = 1;
205 err = cn_netlink_send(m, 0, gfp_any());
206 }
207 }
208 kfree(m);
209
210 if (!err && !(task->t.flags & TF_EXIT))
211 err = !wait_for_completion_timeout(task->done,
212 msecs_to_jiffies(UVESAFB_TIMEOUT));
213
214 mutex_lock(&uvfb_lock);
215 uvfb_tasks[seq] = NULL;
216 mutex_unlock(&uvfb_lock);
217
218 seq++;
219 if (seq >= UVESAFB_TASKS_MAX)
220 seq = 0;
221
222 return err;
223}
224
225/*
226 * Free a uvesafb_ktask struct.
227 */
228static void uvesafb_free(struct uvesafb_ktask *task)
229{
230 if (task) {
231 if (task->done)
232 kfree(task->done);
233 kfree(task);
234 }
235}
236
237/*
238 * Prepare a uvesafb_ktask struct to be used again.
239 */
240static void uvesafb_reset(struct uvesafb_ktask *task)
241{
242 struct completion *cpl = task->done;
243
244 memset(task, 0, sizeof(*task));
245 task->done = cpl;
246}
247
248/*
249 * Allocate and prepare a uvesafb_ktask struct.
250 */
251static struct uvesafb_ktask *uvesafb_prep(void)
252{
253 struct uvesafb_ktask *task;
254
255 task = kzalloc(sizeof(*task), GFP_KERNEL);
256 if (task) {
257 task->done = kzalloc(sizeof(*task->done), GFP_KERNEL);
258 if (!task->done) {
259 kfree(task);
260 task = NULL;
261 }
262 }
263 return task;
264}
265
266static void uvesafb_setup_var(struct fb_var_screeninfo *var,
267 struct fb_info *info, struct vbe_mode_ib *mode)
268{
269 struct uvesafb_par *par = info->par;
270
271 var->vmode = FB_VMODE_NONINTERLACED;
272 var->sync = FB_SYNC_VERT_HIGH_ACT;
273
274 var->xres = mode->x_res;
275 var->yres = mode->y_res;
276 var->xres_virtual = mode->x_res;
277 var->yres_virtual = (par->ypan) ?
278 info->fix.smem_len / mode->bytes_per_scan_line :
279 mode->y_res;
280 var->xoffset = 0;
281 var->yoffset = 0;
282 var->bits_per_pixel = mode->bits_per_pixel;
283
284 if (var->bits_per_pixel == 15)
285 var->bits_per_pixel = 16;
286
287 if (var->bits_per_pixel > 8) {
288 var->red.offset = mode->red_off;
289 var->red.length = mode->red_len;
290 var->green.offset = mode->green_off;
291 var->green.length = mode->green_len;
292 var->blue.offset = mode->blue_off;
293 var->blue.length = mode->blue_len;
294 var->transp.offset = mode->rsvd_off;
295 var->transp.length = mode->rsvd_len;
296 } else {
297 var->red.offset = 0;
298 var->green.offset = 0;
299 var->blue.offset = 0;
300 var->transp.offset = 0;
301
302 /*
303 * We're assuming that we can switch the DAC to 8 bits. If
304 * this proves to be incorrect, we'll update the fields
305 * later in set_par().
306 */
307 if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC) {
308 var->red.length = 8;
309 var->green.length = 8;
310 var->blue.length = 8;
311 var->transp.length = 0;
312 } else {
313 var->red.length = 6;
314 var->green.length = 6;
315 var->blue.length = 6;
316 var->transp.length = 0;
317 }
318 }
319}
320
321static int uvesafb_vbe_find_mode(struct uvesafb_par *par,
322 int xres, int yres, int depth, unsigned char flags)
323{
324 int i, match = -1, h = 0, d = 0x7fffffff;
325
326 for (i = 0; i < par->vbe_modes_cnt; i++) {
327 h = abs(par->vbe_modes[i].x_res - xres) +
328 abs(par->vbe_modes[i].y_res - yres) +
329 abs(depth - par->vbe_modes[i].depth);
330
331 /*
332 * We have an exact match in terms of resolution
333 * and depth.
334 */
335 if (h == 0)
336 return i;
337
338 if (h < d || (h == d && par->vbe_modes[i].depth > depth)) {
339 d = h;
340 match = i;
341 }
342 }
343 i = 1;
344
345 if (flags & UVESAFB_EXACT_DEPTH &&
346 par->vbe_modes[match].depth != depth)
347 i = 0;
348
349 if (flags & UVESAFB_EXACT_RES && d > 24)
350 i = 0;
351
352 if (i != 0)
353 return match;
354 else
355 return -1;
356}
357
358static u8 *uvesafb_vbe_state_save(struct uvesafb_par *par)
359{
360 struct uvesafb_ktask *task;
361 u8 *state;
362 int err;
363
364 if (!par->vbe_state_size)
365 return NULL;
366
367 state = kmalloc(par->vbe_state_size, GFP_KERNEL);
368 if (!state)
369 return NULL;
370
371 task = uvesafb_prep();
372 if (!task) {
373 kfree(state);
374 return NULL;
375 }
376
377 task->t.regs.eax = 0x4f04;
378 task->t.regs.ecx = 0x000f;
379 task->t.regs.edx = 0x0001;
380 task->t.flags = TF_BUF_RET | TF_BUF_ESBX;
381 task->t.buf_len = par->vbe_state_size;
382 task->buf = state;
383 err = uvesafb_exec(task);
384
385 if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
386 printk(KERN_WARNING "uvesafb: VBE get state call "
387 "failed (eax=0x%x, err=%d)\n",
388 task->t.regs.eax, err);
389 kfree(state);
390 state = NULL;
391 }
392
393 uvesafb_free(task);
394 return state;
395}
396
397static void uvesafb_vbe_state_restore(struct uvesafb_par *par, u8 *state_buf)
398{
399 struct uvesafb_ktask *task;
400 int err;
401
402 if (!state_buf)
403 return;
404
405 task = uvesafb_prep();
406 if (!task)
407 return;
408
409 task->t.regs.eax = 0x4f04;
410 task->t.regs.ecx = 0x000f;
411 task->t.regs.edx = 0x0002;
412 task->t.buf_len = par->vbe_state_size;
413 task->t.flags = TF_BUF_ESBX;
414 task->buf = state_buf;
415
416 err = uvesafb_exec(task);
417 if (err || (task->t.regs.eax & 0xffff) != 0x004f)
418 printk(KERN_WARNING "uvesafb: VBE state restore call "
419 "failed (eax=0x%x, err=%d)\n",
420 task->t.regs.eax, err);
421
422 uvesafb_free(task);
423}
424
425static int __devinit uvesafb_vbe_getinfo(struct uvesafb_ktask *task,
426 struct uvesafb_par *par)
427{
428 int err;
429
430 task->t.regs.eax = 0x4f00;
431 task->t.flags = TF_VBEIB;
432 task->t.buf_len = sizeof(struct vbe_ib);
433 task->buf = &par->vbe_ib;
434 strncpy(par->vbe_ib.vbe_signature, "VBE2", 4);
435
436 err = uvesafb_exec(task);
437 if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
438 printk(KERN_ERR "uvesafb: Getting VBE info block failed "
439 "(eax=0x%x, err=%d)\n", (u32)task->t.regs.eax,
440 err);
441 return -EINVAL;
442 }
443
444 if (par->vbe_ib.vbe_version < 0x0200) {
445 printk(KERN_ERR "uvesafb: Sorry, pre-VBE 2.0 cards are "
446 "not supported.\n");
447 return -EINVAL;
448 }
449
450 if (!par->vbe_ib.mode_list_ptr) {
451 printk(KERN_ERR "uvesafb: Missing mode list!\n");
452 return -EINVAL;
453 }
454
455 printk(KERN_INFO "uvesafb: ");
456
457 /*
458 * Convert string pointers and the mode list pointer into
459 * usable addresses. Print informational messages about the
460 * video adapter and its vendor.
461 */
462 if (par->vbe_ib.oem_vendor_name_ptr)
463 printk("%s, ",
464 ((char *)task->buf) + par->vbe_ib.oem_vendor_name_ptr);
465
466 if (par->vbe_ib.oem_product_name_ptr)
467 printk("%s, ",
468 ((char *)task->buf) + par->vbe_ib.oem_product_name_ptr);
469
470 if (par->vbe_ib.oem_product_rev_ptr)
471 printk("%s, ",
472 ((char *)task->buf) + par->vbe_ib.oem_product_rev_ptr);
473
474 if (par->vbe_ib.oem_string_ptr)
475 printk("OEM: %s, ",
476 ((char *)task->buf) + par->vbe_ib.oem_string_ptr);
477
478 printk("VBE v%d.%d\n", ((par->vbe_ib.vbe_version & 0xff00) >> 8),
479 par->vbe_ib.vbe_version & 0xff);
480
481 return 0;
482}
483
484static int __devinit uvesafb_vbe_getmodes(struct uvesafb_ktask *task,
485 struct uvesafb_par *par)
486{
487 int off = 0, err;
488 u16 *mode;
489
490 par->vbe_modes_cnt = 0;
491
492 /* Count available modes. */
493 mode = (u16 *) (((u8 *)&par->vbe_ib) + par->vbe_ib.mode_list_ptr);
494 while (*mode != 0xffff) {
495 par->vbe_modes_cnt++;
496 mode++;
497 }
498
499 par->vbe_modes = kzalloc(sizeof(struct vbe_mode_ib) *
500 par->vbe_modes_cnt, GFP_KERNEL);
501 if (!par->vbe_modes)
502 return -ENOMEM;
503
504 /* Get info about all available modes. */
505 mode = (u16 *) (((u8 *)&par->vbe_ib) + par->vbe_ib.mode_list_ptr);
506 while (*mode != 0xffff) {
507 struct vbe_mode_ib *mib;
508
509 uvesafb_reset(task);
510 task->t.regs.eax = 0x4f01;
511 task->t.regs.ecx = (u32) *mode;
512 task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
513 task->t.buf_len = sizeof(struct vbe_mode_ib);
514 task->buf = par->vbe_modes + off;
515
516 err = uvesafb_exec(task);
517 if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
518 printk(KERN_ERR "uvesafb: Getting mode info block "
519 "for mode 0x%x failed (eax=0x%x, err=%d)\n",
520 *mode, (u32)task->t.regs.eax, err);
521 return -EINVAL;
522 }
523
524 mib = task->buf;
525 mib->mode_id = *mode;
526
527 /*
528 * We only want modes that are supported with the current
529 * hardware configuration, color, graphics and that have
530 * support for the LFB.
531 */
532 if ((mib->mode_attr & VBE_MODE_MASK) == VBE_MODE_MASK &&
533 mib->bits_per_pixel >= 8)
534 off++;
535 else
536 par->vbe_modes_cnt--;
537
538 mode++;
539 mib->depth = mib->red_len + mib->green_len + mib->blue_len;
540
541 /*
542 * Handle 8bpp modes and modes with broken color component
543 * lengths.
544 */
545 if (mib->depth == 0 || (mib->depth == 24 &&
546 mib->bits_per_pixel == 32))
547 mib->depth = mib->bits_per_pixel;
548 }
549
550 return 0;
551}
552
553/*
554 * The Protected Mode Interface is 32-bit x86 code, so we only run it on
555 * x86 and not x86_64.
556 */
557#ifdef CONFIG_X86_32
558static int __devinit uvesafb_vbe_getpmi(struct uvesafb_ktask *task,
559 struct uvesafb_par *par)
560{
561 int i, err;
562
563 uvesafb_reset(task);
564 task->t.regs.eax = 0x4f0a;
565 task->t.regs.ebx = 0x0;
566 err = uvesafb_exec(task);
567
568 if ((task->t.regs.eax & 0xffff) != 0x4f || task->t.regs.es < 0xc000) {
569 par->pmi_setpal = par->ypan = 0;
570 } else {
571 par->pmi_base = (u16 *)phys_to_virt(((u32)task->t.regs.es << 4)
572 + task->t.regs.edi);
573 par->pmi_start = (u8 *)par->pmi_base + par->pmi_base[1];
574 par->pmi_pal = (u8 *)par->pmi_base + par->pmi_base[2];
575 printk(KERN_INFO "uvesafb: protected mode interface info at "
576 "%04x:%04x\n",
577 (u16)task->t.regs.es, (u16)task->t.regs.edi);
578 printk(KERN_INFO "uvesafb: pmi: set display start = %p, "
579 "set palette = %p\n", par->pmi_start,
580 par->pmi_pal);
581
582 if (par->pmi_base[3]) {
583 printk(KERN_INFO "uvesafb: pmi: ports = ");
584 for (i = par->pmi_base[3]/2;
585 par->pmi_base[i] != 0xffff; i++)
586 printk("%x ", par->pmi_base[i]);
587 printk("\n");
588
589 if (par->pmi_base[i] != 0xffff) {
590 printk(KERN_INFO "uvesafb: can't handle memory"
591 " requests, pmi disabled\n");
592 par->ypan = par->pmi_setpal = 0;
593 }
594 }
595 }
596 return 0;
597}
598#endif /* CONFIG_X86_32 */
599
600/*
601 * Check whether a video mode is supported by the Video BIOS and is
602 * compatible with the monitor limits.
603 */
604static int __devinit uvesafb_is_valid_mode(struct fb_videomode *mode,
605 struct fb_info *info)
606{
607 if (info->monspecs.gtf) {
608 fb_videomode_to_var(&info->var, mode);
609 if (fb_validate_mode(&info->var, info))
610 return 0;
611 }
612
613 if (uvesafb_vbe_find_mode(info->par, mode->xres, mode->yres, 8,
614 UVESAFB_EXACT_RES) == -1)
615 return 0;
616
617 return 1;
618}
619
620static int __devinit uvesafb_vbe_getedid(struct uvesafb_ktask *task,
621 struct fb_info *info)
622{
623 struct uvesafb_par *par = info->par;
624 int err = 0;
625
626 if (noedid || par->vbe_ib.vbe_version < 0x0300)
627 return -EINVAL;
628
629 task->t.regs.eax = 0x4f15;
630 task->t.regs.ebx = 0;
631 task->t.regs.ecx = 0;
632 task->t.buf_len = 0;
633 task->t.flags = 0;
634
635 err = uvesafb_exec(task);
636
637 if ((task->t.regs.eax & 0xffff) != 0x004f || err)
638 return -EINVAL;
639
640 if ((task->t.regs.ebx & 0x3) == 3) {
641 printk(KERN_INFO "uvesafb: VBIOS/hardware supports both "
642 "DDC1 and DDC2 transfers\n");
643 } else if ((task->t.regs.ebx & 0x3) == 2) {
644 printk(KERN_INFO "uvesafb: VBIOS/hardware supports DDC2 "
645 "transfers\n");
646 } else if ((task->t.regs.ebx & 0x3) == 1) {
647 printk(KERN_INFO "uvesafb: VBIOS/hardware supports DDC1 "
648 "transfers\n");
649 } else {
650 printk(KERN_INFO "uvesafb: VBIOS/hardware doesn't support "
651 "DDC transfers\n");
652 return -EINVAL;
653 }
654
655 task->t.regs.eax = 0x4f15;
656 task->t.regs.ebx = 1;
657 task->t.regs.ecx = task->t.regs.edx = 0;
658 task->t.flags = TF_BUF_RET | TF_BUF_ESDI;
659 task->t.buf_len = EDID_LENGTH;
660 task->buf = kzalloc(EDID_LENGTH, GFP_KERNEL);
661
662 err = uvesafb_exec(task);
663
664 if ((task->t.regs.eax & 0xffff) == 0x004f && !err) {
665 fb_edid_to_monspecs(task->buf, &info->monspecs);
666
667 if (info->monspecs.vfmax && info->monspecs.hfmax) {
668 /*
669 * If the maximum pixel clock wasn't specified in
670 * the EDID block, set it to 300 MHz.
671 */
672 if (info->monspecs.dclkmax == 0)
673 info->monspecs.dclkmax = 300 * 1000000;
674 info->monspecs.gtf = 1;
675 }
676 } else {
677 err = -EINVAL;
678 }
679
680 kfree(task->buf);
681 return err;
682}
683
684static void __devinit uvesafb_vbe_getmonspecs(struct uvesafb_ktask *task,
685 struct fb_info *info)
686{
687 struct uvesafb_par *par = info->par;
688 int i;
689
690 memset(&info->monspecs, 0, sizeof(info->monspecs));
691
692 /*
693 * If we don't get all necessary data from the EDID block,
694 * mark it as incompatible with the GTF and set nocrtc so
695 * that we always use the default BIOS refresh rate.
696 */
697 if (uvesafb_vbe_getedid(task, info)) {
698 info->monspecs.gtf = 0;
699 par->nocrtc = 1;
700 }
701
702 /* Kernel command line overrides. */
703 if (maxclk)
704 info->monspecs.dclkmax = maxclk * 1000000;
705 if (maxvf)
706 info->monspecs.vfmax = maxvf;
707 if (maxhf)
708 info->monspecs.hfmax = maxhf * 1000;
709
710 /*
711 * In case DDC transfers are not supported, the user can provide
712 * monitor limits manually. Lower limits are set to "safe" values.
713 */
714 if (info->monspecs.gtf == 0 && maxclk && maxvf && maxhf) {
715 info->monspecs.dclkmin = 0;
716 info->monspecs.vfmin = 60;
717 info->monspecs.hfmin = 29000;
718 info->monspecs.gtf = 1;
719 par->nocrtc = 0;
720 }
721
722 if (info->monspecs.gtf)
723 printk(KERN_INFO
724 "uvesafb: monitor limits: vf = %d Hz, hf = %d kHz, "
725 "clk = %d MHz\n", info->monspecs.vfmax,
726 (int)(info->monspecs.hfmax / 1000),
727 (int)(info->monspecs.dclkmax / 1000000));
728 else
729 printk(KERN_INFO "uvesafb: no monitor limits have been set, "
730 "default refresh rate will be used\n");
731
732 /* Add VBE modes to the modelist. */
733 for (i = 0; i < par->vbe_modes_cnt; i++) {
734 struct fb_var_screeninfo var;
735 struct vbe_mode_ib *mode;
736 struct fb_videomode vmode;
737
738 mode = &par->vbe_modes[i];
739 memset(&var, 0, sizeof(var));
740
741 var.xres = mode->x_res;
742 var.yres = mode->y_res;
743
744 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, &var, info);
745 fb_var_to_videomode(&vmode, &var);
746 fb_add_videomode(&vmode, &info->modelist);
747 }
748
749 /* Add valid VESA modes to our modelist. */
750 for (i = 0; i < VESA_MODEDB_SIZE; i++) {
751 if (uvesafb_is_valid_mode((struct fb_videomode *)
752 &vesa_modes[i], info))
753 fb_add_videomode(&vesa_modes[i], &info->modelist);
754 }
755
756 for (i = 0; i < info->monspecs.modedb_len; i++) {
757 if (uvesafb_is_valid_mode(&info->monspecs.modedb[i], info))
758 fb_add_videomode(&info->monspecs.modedb[i],
759 &info->modelist);
760 }
761
762 return;
763}
764
765static void __devinit uvesafb_vbe_getstatesize(struct uvesafb_ktask *task,
766 struct uvesafb_par *par)
767{
768 int err;
769
770 uvesafb_reset(task);
771
772 /*
773 * Get the VBE state buffer size. We want all available
774 * hardware state data (CL = 0x0f).
775 */
776 task->t.regs.eax = 0x4f04;
777 task->t.regs.ecx = 0x000f;
778 task->t.regs.edx = 0x0000;
779 task->t.flags = 0;
780
781 err = uvesafb_exec(task);
782
783 if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
784 printk(KERN_WARNING "uvesafb: VBE state buffer size "
785 "cannot be determined (eax=0x%x, err=%d)\n",
786 task->t.regs.eax, err);
787 par->vbe_state_size = 0;
788 return;
789 }
790
791 par->vbe_state_size = 64 * (task->t.regs.ebx & 0xffff);
792}
793
794static int __devinit uvesafb_vbe_init(struct fb_info *info)
795{
796 struct uvesafb_ktask *task = NULL;
797 struct uvesafb_par *par = info->par;
798 int err;
799
800 task = uvesafb_prep();
801 if (!task)
802 return -ENOMEM;
803
804 err = uvesafb_vbe_getinfo(task, par);
805 if (err)
806 goto out;
807
808 err = uvesafb_vbe_getmodes(task, par);
809 if (err)
810 goto out;
811
812 par->nocrtc = nocrtc;
813#ifdef CONFIG_X86_32
814 par->pmi_setpal = pmi_setpal;
815 par->ypan = ypan;
816
817 if (par->pmi_setpal || par->ypan)
818 uvesafb_vbe_getpmi(task, par);
819#else
820 /* The protected mode interface is not available on non-x86. */
821 par->pmi_setpal = par->ypan = 0;
822#endif
823
824 INIT_LIST_HEAD(&info->modelist);
825 uvesafb_vbe_getmonspecs(task, info);
826 uvesafb_vbe_getstatesize(task, par);
827
828out: uvesafb_free(task);
829 return err;
830}
831
832static int __devinit uvesafb_vbe_init_mode(struct fb_info *info)
833{
834 struct list_head *pos;
835 struct fb_modelist *modelist;
836 struct fb_videomode *mode;
837 struct uvesafb_par *par = info->par;
838 int i, modeid;
839
840 /* Has the user requested a specific VESA mode? */
841 if (vbemode) {
842 for (i = 0; i < par->vbe_modes_cnt; i++) {
843 if (par->vbe_modes[i].mode_id == vbemode) {
844 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
845 &info->var, info);
846 /*
847 * With pixclock set to 0, the default BIOS
848 * timings will be used in set_par().
849 */
850 info->var.pixclock = 0;
851 modeid = i;
852 goto gotmode;
853 }
854 }
855 printk(KERN_INFO "uvesafb: requested VBE mode 0x%x is "
856 "unavailable\n", vbemode);
857 vbemode = 0;
858 }
859
860 /* Count the modes in the modelist */
861 i = 0;
862 list_for_each(pos, &info->modelist)
863 i++;
864
865 /*
866 * Convert the modelist into a modedb so that we can use it with
867 * fb_find_mode().
868 */
869 mode = kzalloc(i * sizeof(*mode), GFP_KERNEL);
870 if (mode) {
871 i = 0;
872 list_for_each(pos, &info->modelist) {
873 modelist = list_entry(pos, struct fb_modelist, list);
874 mode[i] = modelist->mode;
875 i++;
876 }
877
878 if (!mode_option)
879 mode_option = UVESAFB_DEFAULT_MODE;
880
881 i = fb_find_mode(&info->var, info, mode_option, mode, i,
882 NULL, 8);
883
884 kfree(mode);
885 }
886
887 /* fb_find_mode() failed */
888 if (i == 0 || i >= 3) {
889 info->var.xres = 640;
890 info->var.yres = 480;
891 mode = (struct fb_videomode *)
892 fb_find_best_mode(&info->var, &info->modelist);
893
894 if (mode) {
895 fb_videomode_to_var(&info->var, mode);
896 } else {
897 modeid = par->vbe_modes[0].mode_id;
898 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
899 &info->var, info);
900 goto gotmode;
901 }
902 }
903
904 /* Look for a matching VBE mode. */
905 modeid = uvesafb_vbe_find_mode(par, info->var.xres, info->var.yres,
906 info->var.bits_per_pixel, UVESAFB_EXACT_RES);
907
908 if (modeid == -1)
909 return -EINVAL;
910
911gotmode:
912 uvesafb_setup_var(&info->var, info, &par->vbe_modes[modeid]);
913
914 /*
915 * If we are not VBE3.0+ compliant, we're done -- the BIOS will
916 * ignore our timings anyway.
917 */
918 if (par->vbe_ib.vbe_version < 0x0300 || par->nocrtc)
919 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60,
920 &info->var, info);
921
922 return modeid;
923}
924
925static int uvesafb_setpalette(struct uvesafb_pal_entry *entries, int count,
926 int start, struct fb_info *info)
927{
928 struct uvesafb_ktask *task;
929 struct uvesafb_par *par = info->par;
930 int i = par->mode_idx;
931 int err = 0;
932
933 /*
934 * We support palette modifications for 8 bpp modes only, so
935 * there can never be more than 256 entries.
936 */
937 if (start + count > 256)
938 return -EINVAL;
939
940#ifdef CONFIG_X86
941 /* Use VGA registers if mode is VGA-compatible. */
942 if (i >= 0 && i < par->vbe_modes_cnt &&
943 par->vbe_modes[i].mode_attr & VBE_MODE_VGACOMPAT) {
944 for (i = 0; i < count; i++) {
945 outb_p(start + i, dac_reg);
946 outb_p(entries[i].red, dac_val);
947 outb_p(entries[i].green, dac_val);
948 outb_p(entries[i].blue, dac_val);
949 }
950 }
951#ifdef CONFIG_X86_32
952 else if (par->pmi_setpal) {
953 __asm__ __volatile__(
954 "call *(%%esi)"
955 : /* no return value */
956 : "a" (0x4f09), /* EAX */
957 "b" (0), /* EBX */
958 "c" (count), /* ECX */
959 "d" (start), /* EDX */
960 "D" (entries), /* EDI */
961 "S" (&par->pmi_pal)); /* ESI */
962 }
963#endif /* CONFIG_X86_32 */
964 else
965#endif /* CONFIG_X86 */
966 {
967 task = uvesafb_prep();
968 if (!task)
969 return -ENOMEM;
970
971 task->t.regs.eax = 0x4f09;
972 task->t.regs.ebx = 0x0;
973 task->t.regs.ecx = count;
974 task->t.regs.edx = start;
975 task->t.flags = TF_BUF_ESDI;
976 task->t.buf_len = sizeof(struct uvesafb_pal_entry) * count;
977 task->buf = entries;
978
979 err = uvesafb_exec(task);
980 if ((task->t.regs.eax & 0xffff) != 0x004f)
981 err = 1;
982
983 uvesafb_free(task);
984 }
985 return err;
986}
987
988static int uvesafb_setcolreg(unsigned regno, unsigned red, unsigned green,
989 unsigned blue, unsigned transp,
990 struct fb_info *info)
991{
992 struct uvesafb_pal_entry entry;
993 int shift = 16 - info->var.green.length;
994 int err = 0;
995
996 if (regno >= info->cmap.len)
997 return -EINVAL;
998
999 if (info->var.bits_per_pixel == 8) {
1000 entry.red = red >> shift;
1001 entry.green = green >> shift;
1002 entry.blue = blue >> shift;
1003 entry.pad = 0;
1004
1005 err = uvesafb_setpalette(&entry, 1, regno, info);
1006 } else if (regno < 16) {
1007 switch (info->var.bits_per_pixel) {
1008 case 16:
1009 if (info->var.red.offset == 10) {
1010 /* 1:5:5:5 */
1011 ((u32 *) (info->pseudo_palette))[regno] =
1012 ((red & 0xf800) >> 1) |
1013 ((green & 0xf800) >> 6) |
1014 ((blue & 0xf800) >> 11);
1015 } else {
1016 /* 0:5:6:5 */
1017 ((u32 *) (info->pseudo_palette))[regno] =
1018 ((red & 0xf800) ) |
1019 ((green & 0xfc00) >> 5) |
1020 ((blue & 0xf800) >> 11);
1021 }
1022 break;
1023
1024 case 24:
1025 case 32:
1026 red >>= 8;
1027 green >>= 8;
1028 blue >>= 8;
1029 ((u32 *)(info->pseudo_palette))[regno] =
1030 (red << info->var.red.offset) |
1031 (green << info->var.green.offset) |
1032 (blue << info->var.blue.offset);
1033 break;
1034 }
1035 }
1036 return err;
1037}
1038
1039static int uvesafb_setcmap(struct fb_cmap *cmap, struct fb_info *info)
1040{
1041 struct uvesafb_pal_entry *entries;
1042 int shift = 16 - info->var.green.length;
1043 int i, err = 0;
1044
1045 if (info->var.bits_per_pixel == 8) {
1046 if (cmap->start + cmap->len > info->cmap.start +
1047 info->cmap.len || cmap->start < info->cmap.start)
1048 return -EINVAL;
1049
1050 entries = kmalloc(sizeof(*entries) * cmap->len, GFP_KERNEL);
1051 if (!entries)
1052 return -ENOMEM;
1053
1054 for (i = 0; i < cmap->len; i++) {
1055 entries[i].red = cmap->red[i] >> shift;
1056 entries[i].green = cmap->green[i] >> shift;
1057 entries[i].blue = cmap->blue[i] >> shift;
1058 entries[i].pad = 0;
1059 }
1060 err = uvesafb_setpalette(entries, cmap->len, cmap->start, info);
1061 kfree(entries);
1062 } else {
1063 /*
1064 * For modes with bpp > 8, we only set the pseudo palette in
1065 * the fb_info struct. We rely on uvesafb_setcolreg to do all
1066 * sanity checking.
1067 */
1068 for (i = 0; i < cmap->len; i++) {
1069 err |= uvesafb_setcolreg(cmap->start + i, cmap->red[i],
1070 cmap->green[i], cmap->blue[i],
1071 0, info);
1072 }
1073 }
1074 return err;
1075}
1076
1077static int uvesafb_pan_display(struct fb_var_screeninfo *var,
1078 struct fb_info *info)
1079{
1080#ifdef CONFIG_X86_32
1081 int offset;
1082 struct uvesafb_par *par = info->par;
1083
1084 offset = (var->yoffset * info->fix.line_length + var->xoffset) / 4;
1085
1086 /*
1087 * It turns out it's not the best idea to do panning via vm86,
1088 * so we only allow it if we have a PMI.
1089 */
1090 if (par->pmi_start) {
1091 __asm__ __volatile__(
1092 "call *(%%edi)"
1093 : /* no return value */
1094 : "a" (0x4f07), /* EAX */
1095 "b" (0), /* EBX */
1096 "c" (offset), /* ECX */
1097 "d" (offset >> 16), /* EDX */
1098 "D" (&par->pmi_start)); /* EDI */
1099 }
1100#endif
1101 return 0;
1102}
1103
1104static int uvesafb_blank(int blank, struct fb_info *info)
1105{
1106 struct uvesafb_par *par = info->par;
1107 struct uvesafb_ktask *task;
1108 int err = 1;
1109
1110#ifdef CONFIG_X86
1111 if (par->vbe_ib.capabilities & VBE_CAP_VGACOMPAT) {
1112 int loop = 10000;
1113 u8 seq = 0, crtc17 = 0;
1114
1115 if (blank == FB_BLANK_POWERDOWN) {
1116 seq = 0x20;
1117 crtc17 = 0x00;
1118 err = 0;
1119 } else {
1120 seq = 0x00;
1121 crtc17 = 0x80;
1122 err = (blank == FB_BLANK_UNBLANK) ? 0 : -EINVAL;
1123 }
1124
1125 vga_wseq(NULL, 0x00, 0x01);
1126 seq |= vga_rseq(NULL, 0x01) & ~0x20;
1127 vga_wseq(NULL, 0x00, seq);
1128
1129 crtc17 |= vga_rcrt(NULL, 0x17) & ~0x80;
1130 while (loop--);
1131 vga_wcrt(NULL, 0x17, crtc17);
1132 vga_wseq(NULL, 0x00, 0x03);
1133 } else
1134#endif /* CONFIG_X86 */
1135 {
1136 task = uvesafb_prep();
1137 if (!task)
1138 return -ENOMEM;
1139
1140 task->t.regs.eax = 0x4f10;
1141 switch (blank) {
1142 case FB_BLANK_UNBLANK:
1143 task->t.regs.ebx = 0x0001;
1144 break;
1145 case FB_BLANK_NORMAL:
1146 task->t.regs.ebx = 0x0101; /* standby */
1147 break;
1148 case FB_BLANK_POWERDOWN:
1149 task->t.regs.ebx = 0x0401; /* powerdown */
1150 break;
1151 default:
1152 goto out;
1153 }
1154
1155 err = uvesafb_exec(task);
1156 if (err || (task->t.regs.eax & 0xffff) != 0x004f)
1157 err = 1;
1158out: uvesafb_free(task);
1159 }
1160 return err;
1161}
1162
1163static int uvesafb_open(struct fb_info *info, int user)
1164{
1165 struct uvesafb_par *par = info->par;
1166 int cnt = atomic_read(&par->ref_count);
1167
1168 if (!cnt && par->vbe_state_size)
1169 par->vbe_state_orig = uvesafb_vbe_state_save(par);
1170
1171 atomic_inc(&par->ref_count);
1172 return 0;
1173}
1174
1175static int uvesafb_release(struct fb_info *info, int user)
1176{
1177 struct uvesafb_ktask *task = NULL;
1178 struct uvesafb_par *par = info->par;
1179 int cnt = atomic_read(&par->ref_count);
1180
1181 if (!cnt)
1182 return -EINVAL;
1183
1184 if (cnt != 1)
1185 goto out;
1186
1187 task = uvesafb_prep();
1188 if (!task)
1189 goto out;
1190
1191 /* First, try to set the standard 80x25 text mode. */
1192 task->t.regs.eax = 0x0003;
1193 uvesafb_exec(task);
1194
1195 /*
1196 * Now try to restore whatever hardware state we might have
1197 * saved when the fb device was first opened.
1198 */
1199 uvesafb_vbe_state_restore(par, par->vbe_state_orig);
1200out:
1201 atomic_dec(&par->ref_count);
1202 if (task)
1203 uvesafb_free(task);
1204 return 0;
1205}
1206
1207static int uvesafb_set_par(struct fb_info *info)
1208{
1209 struct uvesafb_par *par = info->par;
1210 struct uvesafb_ktask *task = NULL;
1211 struct vbe_crtc_ib *crtc = NULL;
1212 struct vbe_mode_ib *mode = NULL;
1213 int i, err = 0, depth = info->var.bits_per_pixel;
1214
1215 if (depth > 8 && depth != 32)
1216 depth = info->var.red.length + info->var.green.length +
1217 info->var.blue.length;
1218
1219 i = uvesafb_vbe_find_mode(par, info->var.xres, info->var.yres, depth,
1220 UVESAFB_EXACT_RES | UVESAFB_EXACT_DEPTH);
1221 if (i >= 0)
1222 mode = &par->vbe_modes[i];
1223 else
1224 return -EINVAL;
1225
1226 task = uvesafb_prep();
1227 if (!task)
1228 return -ENOMEM;
1229setmode:
1230 task->t.regs.eax = 0x4f02;
1231 task->t.regs.ebx = mode->mode_id | 0x4000; /* use LFB */
1232
1233 if (par->vbe_ib.vbe_version >= 0x0300 && !par->nocrtc &&
1234 info->var.pixclock != 0) {
1235 task->t.regs.ebx |= 0x0800; /* use CRTC data */
1236 task->t.flags = TF_BUF_ESDI;
1237 crtc = kzalloc(sizeof(struct vbe_crtc_ib), GFP_KERNEL);
1238 if (!crtc) {
1239 err = -ENOMEM;
1240 goto out;
1241 }
1242 crtc->horiz_start = info->var.xres + info->var.right_margin;
1243 crtc->horiz_end = crtc->horiz_start + info->var.hsync_len;
1244 crtc->horiz_total = crtc->horiz_end + info->var.left_margin;
1245
1246 crtc->vert_start = info->var.yres + info->var.lower_margin;
1247 crtc->vert_end = crtc->vert_start + info->var.vsync_len;
1248 crtc->vert_total = crtc->vert_end + info->var.upper_margin;
1249
1250 crtc->pixel_clock = PICOS2KHZ(info->var.pixclock) * 1000;
1251 crtc->refresh_rate = (u16)(100 * (crtc->pixel_clock /
1252 (crtc->vert_total * crtc->horiz_total)));
1253
1254 if (info->var.vmode & FB_VMODE_DOUBLE)
1255 crtc->flags |= 0x1;
1256 if (info->var.vmode & FB_VMODE_INTERLACED)
1257 crtc->flags |= 0x2;
1258 if (!(info->var.sync & FB_SYNC_HOR_HIGH_ACT))
1259 crtc->flags |= 0x4;
1260 if (!(info->var.sync & FB_SYNC_VERT_HIGH_ACT))
1261 crtc->flags |= 0x8;
1262 memcpy(&par->crtc, crtc, sizeof(*crtc));
1263 } else {
1264 memset(&par->crtc, 0, sizeof(*crtc));
1265 }
1266
1267 task->t.buf_len = sizeof(struct vbe_crtc_ib);
1268 task->buf = &par->crtc;
1269
1270 err = uvesafb_exec(task);
1271 if (err || (task->t.regs.eax & 0xffff) != 0x004f) {
1272 /*
1273 * The mode switch might have failed because we tried to
1274 * use our own timings. Try again with the default timings.
1275 */
1276 if (crtc != NULL) {
1277 printk(KERN_WARNING "uvesafb: mode switch failed "
1278 "(eax=0x%x, err=%d). Trying again with "
1279 "default timings.\n", task->t.regs.eax, err);
1280 uvesafb_reset(task);
1281 kfree(crtc);
1282 crtc = NULL;
1283 info->var.pixclock = 0;
1284 goto setmode;
1285 } else {
1286 printk(KERN_ERR "uvesafb: mode switch failed (eax="
1287 "0x%x, err=%d)\n", task->t.regs.eax, err);
1288 err = -EINVAL;
1289 goto out;
1290 }
1291 }
1292 par->mode_idx = i;
1293
1294 /* For 8bpp modes, always try to set the DAC to 8 bits. */
1295 if (par->vbe_ib.capabilities & VBE_CAP_CAN_SWITCH_DAC &&
1296 mode->bits_per_pixel <= 8) {
1297 uvesafb_reset(task);
1298 task->t.regs.eax = 0x4f08;
1299 task->t.regs.ebx = 0x0800;
1300
1301 err = uvesafb_exec(task);
1302 if (err || (task->t.regs.eax & 0xffff) != 0x004f ||
1303 ((task->t.regs.ebx & 0xff00) >> 8) != 8) {
1304 /*
1305 * We've failed to set the DAC palette format -
1306 * time to correct var.
1307 */
1308 info->var.red.length = 6;
1309 info->var.green.length = 6;
1310 info->var.blue.length = 6;
1311 }
1312 }
1313
1314 info->fix.visual = (info->var.bits_per_pixel == 8) ?
1315 FB_VISUAL_PSEUDOCOLOR : FB_VISUAL_TRUECOLOR;
1316 info->fix.line_length = mode->bytes_per_scan_line;
1317
1318out: if (crtc != NULL)
1319 kfree(crtc);
1320 uvesafb_free(task);
1321
1322 return err;
1323}
1324
1325static void uvesafb_check_limits(struct fb_var_screeninfo *var,
1326 struct fb_info *info)
1327{
1328 const struct fb_videomode *mode;
1329 struct uvesafb_par *par = info->par;
1330
1331 /*
1332 * If pixclock is set to 0, then we're using default BIOS timings
1333 * and thus don't have to perform any checks here.
1334 */
1335 if (!var->pixclock)
1336 return;
1337
1338 if (par->vbe_ib.vbe_version < 0x0300) {
1339 fb_get_mode(FB_VSYNCTIMINGS | FB_IGNOREMON, 60, var, info);
1340 return;
1341 }
1342
1343 if (!fb_validate_mode(var, info))
1344 return;
1345
1346 mode = fb_find_best_mode(var, &info->modelist);
1347 if (mode) {
1348 if (mode->xres == var->xres && mode->yres == var->yres &&
1349 !(mode->vmode & (FB_VMODE_INTERLACED | FB_VMODE_DOUBLE))) {
1350 fb_videomode_to_var(var, mode);
1351 return;
1352 }
1353 }
1354
1355 if (info->monspecs.gtf && !fb_get_mode(FB_MAXTIMINGS, 0, var, info))
1356 return;
1357 /* Use default refresh rate */
1358 var->pixclock = 0;
1359}
1360
1361static int uvesafb_check_var(struct fb_var_screeninfo *var,
1362 struct fb_info *info)
1363{
1364 struct uvesafb_par *par = info->par;
1365 struct vbe_mode_ib *mode = NULL;
1366 int match = -1;
1367 int depth = var->red.length + var->green.length + var->blue.length;
1368
1369 /*
1370 * Various apps will use bits_per_pixel to set the color depth,
1371 * which is theoretically incorrect, but which we'll try to handle
1372 * here.
1373 */
1374 if (depth == 0 || abs(depth - var->bits_per_pixel) >= 8)
1375 depth = var->bits_per_pixel;
1376
1377 match = uvesafb_vbe_find_mode(par, var->xres, var->yres, depth,
1378 UVESAFB_EXACT_RES);
1379 if (match == -1)
1380 return -EINVAL;
1381
1382 mode = &par->vbe_modes[match];
1383 uvesafb_setup_var(var, info, mode);
1384
1385 /*
1386 * Check whether we have remapped enough memory for this mode.
1387 * We might be called at an early stage, when we haven't remapped
1388 * any memory yet, in which case we simply skip the check.
1389 */
1390 if (var->yres * mode->bytes_per_scan_line > info->fix.smem_len
1391 && info->fix.smem_len)
1392 return -EINVAL;
1393
1394 if ((var->vmode & FB_VMODE_DOUBLE) &&
1395 !(par->vbe_modes[match].mode_attr & 0x100))
1396 var->vmode &= ~FB_VMODE_DOUBLE;
1397
1398 if ((var->vmode & FB_VMODE_INTERLACED) &&
1399 !(par->vbe_modes[match].mode_attr & 0x200))
1400 var->vmode &= ~FB_VMODE_INTERLACED;
1401
1402 uvesafb_check_limits(var, info);
1403
1404 var->xres_virtual = var->xres;
1405 var->yres_virtual = (par->ypan) ?
1406 info->fix.smem_len / mode->bytes_per_scan_line :
1407 var->yres;
1408 return 0;
1409}
1410
1411static void uvesafb_save_state(struct fb_info *info)
1412{
1413 struct uvesafb_par *par = info->par;
1414
1415 if (par->vbe_state_saved)
1416 kfree(par->vbe_state_saved);
1417
1418 par->vbe_state_saved = uvesafb_vbe_state_save(par);
1419}
1420
1421static void uvesafb_restore_state(struct fb_info *info)
1422{
1423 struct uvesafb_par *par = info->par;
1424
1425 uvesafb_vbe_state_restore(par, par->vbe_state_saved);
1426}
1427
1428static struct fb_ops uvesafb_ops = {
1429 .owner = THIS_MODULE,
1430 .fb_open = uvesafb_open,
1431 .fb_release = uvesafb_release,
1432 .fb_setcolreg = uvesafb_setcolreg,
1433 .fb_setcmap = uvesafb_setcmap,
1434 .fb_pan_display = uvesafb_pan_display,
1435 .fb_blank = uvesafb_blank,
1436 .fb_fillrect = cfb_fillrect,
1437 .fb_copyarea = cfb_copyarea,
1438 .fb_imageblit = cfb_imageblit,
1439 .fb_check_var = uvesafb_check_var,
1440 .fb_set_par = uvesafb_set_par,
1441 .fb_save_state = uvesafb_save_state,
1442 .fb_restore_state = uvesafb_restore_state,
1443};
1444
1445static void __devinit uvesafb_init_info(struct fb_info *info,
1446 struct vbe_mode_ib *mode)
1447{
1448 unsigned int size_vmode;
1449 unsigned int size_remap;
1450 unsigned int size_total;
1451 struct uvesafb_par *par = info->par;
1452 int i, h;
1453
1454 info->pseudo_palette = ((u8 *)info->par + sizeof(struct uvesafb_par));
1455 info->fix = uvesafb_fix;
1456 info->fix.ypanstep = par->ypan ? 1 : 0;
1457 info->fix.ywrapstep = (par->ypan > 1) ? 1 : 0;
1458
1459 /*
1460 * If we were unable to get the state buffer size, disable
1461 * functions for saving and restoring the hardware state.
1462 */
1463 if (par->vbe_state_size == 0) {
1464 info->fbops->fb_save_state = NULL;
1465 info->fbops->fb_restore_state = NULL;
1466 }
1467
1468 /* Disable blanking if the user requested so. */
1469 if (!blank)
1470 info->fbops->fb_blank = NULL;
1471
1472 /*
1473 * Find out how much IO memory is required for the mode with
1474 * the highest resolution.
1475 */
1476 size_remap = 0;
1477 for (i = 0; i < par->vbe_modes_cnt; i++) {
1478 h = par->vbe_modes[i].bytes_per_scan_line *
1479 par->vbe_modes[i].y_res;
1480 if (h > size_remap)
1481 size_remap = h;
1482 }
1483 size_remap *= 2;
1484
1485 /*
1486 * size_vmode -- that is the amount of memory needed for the
1487 * used video mode, i.e. the minimum amount of
1488 * memory we need.
1489 */
1490 if (mode != NULL) {
1491 size_vmode = info->var.yres * mode->bytes_per_scan_line;
1492 } else {
1493 size_vmode = info->var.yres * info->var.xres *
1494 ((info->var.bits_per_pixel + 7) >> 3);
1495 }
1496
1497 /*
1498 * size_total -- all video memory we have. Used for mtrr
1499 * entries, resource allocation and bounds
1500 * checking.
1501 */
1502 size_total = par->vbe_ib.total_memory * 65536;
1503 if (vram_total)
1504 size_total = vram_total * 1024 * 1024;
1505 if (size_total < size_vmode)
1506 size_total = size_vmode;
1507
1508 /*
1509 * size_remap -- the amount of video memory we are going to
1510 * use for vesafb. With modern cards it is no
1511 * option to simply use size_total as th
1512 * wastes plenty of kernel address space.
1513 */
1514 if (vram_remap)
1515 size_remap = vram_remap * 1024 * 1024;
1516 if (size_remap < size_vmode)
1517 size_remap = size_vmode;
1518 if (size_remap > size_total)
1519 size_remap = size_total;
1520
1521 info->fix.smem_len = size_remap;
1522 info->fix.smem_start = mode->phys_base_ptr;
1523
1524 /*
1525 * We have to set yres_virtual here because when setup_var() was
1526 * called, smem_len wasn't defined yet.
1527 */
1528 info->var.yres_virtual = info->fix.smem_len /
1529 mode->bytes_per_scan_line;
1530
1531 if (par->ypan && info->var.yres_virtual > info->var.yres) {
1532 printk(KERN_INFO "uvesafb: scrolling: %s "
1533 "using protected mode interface, "
1534 "yres_virtual=%d\n",
1535 (par->ypan > 1) ? "ywrap" : "ypan",
1536 info->var.yres_virtual);
1537 } else {
1538 printk(KERN_INFO "uvesafb: scrolling: redraw\n");
1539 info->var.yres_virtual = info->var.yres;
1540 par->ypan = 0;
1541 }
1542
1543 info->flags = FBINFO_FLAG_DEFAULT |
1544 (par->ypan) ? FBINFO_HWACCEL_YPAN : 0;
1545
1546 if (!par->ypan)
1547 info->fbops->fb_pan_display = NULL;
1548}
1549
1550static void uvesafb_init_mtrr(struct fb_info *info)
1551{
1552#ifdef CONFIG_MTRR
1553 if (mtrr && !(info->fix.smem_start & (PAGE_SIZE - 1))) {
1554 int temp_size = info->fix.smem_len;
1555 unsigned int type = 0;
1556
1557 switch (mtrr) {
1558 case 1:
1559 type = MTRR_TYPE_UNCACHABLE;
1560 break;
1561 case 2:
1562 type = MTRR_TYPE_WRBACK;
1563 break;
1564 case 3:
1565 type = MTRR_TYPE_WRCOMB;
1566 break;
1567 case 4:
1568 type = MTRR_TYPE_WRTHROUGH;
1569 break;
1570 default:
1571 type = 0;
1572 break;
1573 }
1574
1575 if (type) {
1576 int rc;
1577
1578 /* Find the largest power-of-two */
1579 while (temp_size & (temp_size - 1))
1580 temp_size &= (temp_size - 1);
1581
1582 /* Try and find a power of two to add */
1583 do {
1584 rc = mtrr_add(info->fix.smem_start,
1585 temp_size, type, 1);
1586 temp_size >>= 1;
1587 } while (temp_size >= PAGE_SIZE && rc == -EINVAL);
1588 }
1589 }
1590#endif /* CONFIG_MTRR */
1591}
1592
1593
1594static ssize_t uvesafb_show_vbe_ver(struct device *dev,
1595 struct device_attribute *attr, char *buf)
1596{
1597 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1598 struct uvesafb_par *par = info->par;
1599
1600 return snprintf(buf, PAGE_SIZE, "%.4x\n", par->vbe_ib.vbe_version);
1601}
1602
1603static DEVICE_ATTR(vbe_version, S_IRUGO, uvesafb_show_vbe_ver, NULL);
1604
1605static ssize_t uvesafb_show_vbe_modes(struct device *dev,
1606 struct device_attribute *attr, char *buf)
1607{
1608 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1609 struct uvesafb_par *par = info->par;
1610 int ret = 0, i;
1611
1612 for (i = 0; i < par->vbe_modes_cnt && ret < PAGE_SIZE; i++) {
1613 ret += snprintf(buf + ret, PAGE_SIZE - ret,
1614 "%dx%d-%d, 0x%.4x\n",
1615 par->vbe_modes[i].x_res, par->vbe_modes[i].y_res,
1616 par->vbe_modes[i].depth, par->vbe_modes[i].mode_id);
1617 }
1618
1619 return ret;
1620}
1621
1622static DEVICE_ATTR(vbe_modes, S_IRUGO, uvesafb_show_vbe_modes, NULL);
1623
1624static ssize_t uvesafb_show_vendor(struct device *dev,
1625 struct device_attribute *attr, char *buf)
1626{
1627 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1628 struct uvesafb_par *par = info->par;
1629
1630 if (par->vbe_ib.oem_vendor_name_ptr)
1631 return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1632 (&par->vbe_ib) + par->vbe_ib.oem_vendor_name_ptr);
1633 else
1634 return 0;
1635}
1636
1637static DEVICE_ATTR(oem_vendor, S_IRUGO, uvesafb_show_vendor, NULL);
1638
1639static ssize_t uvesafb_show_product_name(struct device *dev,
1640 struct device_attribute *attr, char *buf)
1641{
1642 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1643 struct uvesafb_par *par = info->par;
1644
1645 if (par->vbe_ib.oem_product_name_ptr)
1646 return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1647 (&par->vbe_ib) + par->vbe_ib.oem_product_name_ptr);
1648 else
1649 return 0;
1650}
1651
1652static DEVICE_ATTR(oem_product_name, S_IRUGO, uvesafb_show_product_name, NULL);
1653
1654static ssize_t uvesafb_show_product_rev(struct device *dev,
1655 struct device_attribute *attr, char *buf)
1656{
1657 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1658 struct uvesafb_par *par = info->par;
1659
1660 if (par->vbe_ib.oem_product_rev_ptr)
1661 return snprintf(buf, PAGE_SIZE, "%s\n", (char *)
1662 (&par->vbe_ib) + par->vbe_ib.oem_product_rev_ptr);
1663 else
1664 return 0;
1665}
1666
1667static DEVICE_ATTR(oem_product_rev, S_IRUGO, uvesafb_show_product_rev, NULL);
1668
1669static ssize_t uvesafb_show_oem_string(struct device *dev,
1670 struct device_attribute *attr, char *buf)
1671{
1672 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1673 struct uvesafb_par *par = info->par;
1674
1675 if (par->vbe_ib.oem_string_ptr)
1676 return snprintf(buf, PAGE_SIZE, "%s\n",
1677 (char *)(&par->vbe_ib) + par->vbe_ib.oem_string_ptr);
1678 else
1679 return 0;
1680}
1681
1682static DEVICE_ATTR(oem_string, S_IRUGO, uvesafb_show_oem_string, NULL);
1683
1684static ssize_t uvesafb_show_nocrtc(struct device *dev,
1685 struct device_attribute *attr, char *buf)
1686{
1687 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1688 struct uvesafb_par *par = info->par;
1689
1690 return snprintf(buf, PAGE_SIZE, "%d\n", par->nocrtc);
1691}
1692
1693static ssize_t uvesafb_store_nocrtc(struct device *dev,
1694 struct device_attribute *attr, const char *buf, size_t count)
1695{
1696 struct fb_info *info = platform_get_drvdata(to_platform_device(dev));
1697 struct uvesafb_par *par = info->par;
1698
1699 if (count > 0) {
1700 if (buf[0] == '0')
1701 par->nocrtc = 0;
1702 else
1703 par->nocrtc = 1;
1704 }
1705 return count;
1706}
1707
1708static DEVICE_ATTR(nocrtc, S_IRUGO | S_IWUSR, uvesafb_show_nocrtc,
1709 uvesafb_store_nocrtc);
1710
1711static struct attribute *uvesafb_dev_attrs[] = {
1712 &dev_attr_vbe_version.attr,
1713 &dev_attr_vbe_modes.attr,
1714 &dev_attr_oem_vendor.attr,
1715 &dev_attr_oem_product_name.attr,
1716 &dev_attr_oem_product_rev.attr,
1717 &dev_attr_oem_string.attr,
1718 &dev_attr_nocrtc.attr,
1719 NULL,
1720};
1721
1722static struct attribute_group uvesafb_dev_attgrp = {
1723 .name = NULL,
1724 .attrs = uvesafb_dev_attrs,
1725};
1726
1727static int __devinit uvesafb_probe(struct platform_device *dev)
1728{
1729 struct fb_info *info;
1730 struct vbe_mode_ib *mode = NULL;
1731 struct uvesafb_par *par;
1732 int err = 0, i;
1733
1734 info = framebuffer_alloc(sizeof(*par) + sizeof(u32) * 256, &dev->dev);
1735 if (!info)
1736 return -ENOMEM;
1737
1738 par = info->par;
1739
1740 err = uvesafb_vbe_init(info);
1741 if (err) {
1742 printk(KERN_ERR "uvesafb: vbe_init() failed with %d\n", err);
1743 goto out;
1744 }
1745
1746 info->fbops = &uvesafb_ops;
1747
1748 i = uvesafb_vbe_init_mode(info);
1749 if (i < 0) {
1750 err = -EINVAL;
1751 goto out;
1752 } else {
1753 mode = &par->vbe_modes[i];
1754 }
1755
1756 if (fb_alloc_cmap(&info->cmap, 256, 0) < 0) {
1757 err = -ENXIO;
1758 goto out;
1759 }
1760
1761 uvesafb_init_info(info, mode);
1762
1763 if (!request_mem_region(info->fix.smem_start, info->fix.smem_len,
1764 "uvesafb")) {
1765 printk(KERN_ERR "uvesafb: cannot reserve video memory at "
1766 "0x%lx\n", info->fix.smem_start);
1767 err = -EIO;
1768 goto out_mode;
1769 }
1770
1771 info->screen_base = ioremap(info->fix.smem_start, info->fix.smem_len);
1772
1773 if (!info->screen_base) {
1774 printk(KERN_ERR
1775 "uvesafb: abort, cannot ioremap 0x%x bytes of video "
1776 "memory at 0x%lx\n",
1777 info->fix.smem_len, info->fix.smem_start);
1778 err = -EIO;
1779 goto out_mem;
1780 }
1781
1782 if (!request_region(0x3c0, 32, "uvesafb")) {
1783 printk(KERN_ERR "uvesafb: request region 0x3c0-0x3e0 failed\n");
1784 err = -EIO;
1785 goto out_unmap;
1786 }
1787
1788 uvesafb_init_mtrr(info);
1789 platform_set_drvdata(dev, info);
1790
1791 if (register_framebuffer(info) < 0) {
1792 printk(KERN_ERR
1793 "uvesafb: failed to register framebuffer device\n");
1794 err = -EINVAL;
1795 goto out_reg;
1796 }
1797
1798 printk(KERN_INFO "uvesafb: framebuffer at 0x%lx, mapped to 0x%p, "
1799 "using %dk, total %dk\n", info->fix.smem_start,
1800 info->screen_base, info->fix.smem_len/1024,
1801 par->vbe_ib.total_memory * 64);
1802 printk(KERN_INFO "fb%d: %s frame buffer device\n", info->node,
1803 info->fix.id);
1804
1805 err = sysfs_create_group(&dev->dev.kobj, &uvesafb_dev_attgrp);
1806 if (err != 0)
1807 printk(KERN_WARNING "fb%d: failed to register attributes\n",
1808 info->node);
1809
1810 return 0;
1811
1812out_reg:
1813 release_region(0x3c0, 32);
1814out_unmap:
1815 iounmap(info->screen_base);
1816out_mem:
1817 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1818out_mode:
1819 if (!list_empty(&info->modelist))
1820 fb_destroy_modelist(&info->modelist);
1821 fb_destroy_modedb(info->monspecs.modedb);
1822 fb_dealloc_cmap(&info->cmap);
1823out:
1824 if (par->vbe_modes)
1825 kfree(par->vbe_modes);
1826
1827 framebuffer_release(info);
1828 return err;
1829}
1830
1831static int uvesafb_remove(struct platform_device *dev)
1832{
1833 struct fb_info *info = platform_get_drvdata(dev);
1834
1835 if (info) {
1836 struct uvesafb_par *par = info->par;
1837
1838 sysfs_remove_group(&dev->dev.kobj, &uvesafb_dev_attgrp);
1839 unregister_framebuffer(info);
1840 release_region(0x3c0, 32);
1841 iounmap(info->screen_base);
1842 release_mem_region(info->fix.smem_start, info->fix.smem_len);
1843 fb_destroy_modedb(info->monspecs.modedb);
1844 fb_dealloc_cmap(&info->cmap);
1845
1846 if (par) {
1847 if (par->vbe_modes)
1848 kfree(par->vbe_modes);
1849 if (par->vbe_state_orig)
1850 kfree(par->vbe_state_orig);
1851 if (par->vbe_state_saved)
1852 kfree(par->vbe_state_saved);
1853 }
1854
1855 framebuffer_release(info);
1856 }
1857 return 0;
1858}
1859
1860static struct platform_driver uvesafb_driver = {
1861 .probe = uvesafb_probe,
1862 .remove = uvesafb_remove,
1863 .driver = {
1864 .name = "uvesafb",
1865 },
1866};
1867
1868static struct platform_device *uvesafb_device;
1869
1870#ifndef MODULE
1871static int __devinit uvesafb_setup(char *options)
1872{
1873 char *this_opt;
1874
1875 if (!options || !*options)
1876 return 0;
1877
1878 while ((this_opt = strsep(&options, ",")) != NULL) {
1879 if (!*this_opt) continue;
1880
1881 if (!strcmp(this_opt, "redraw"))
1882 ypan = 0;
1883 else if (!strcmp(this_opt, "ypan"))
1884 ypan = 1;
1885 else if (!strcmp(this_opt, "ywrap"))
1886 ypan = 2;
1887 else if (!strcmp(this_opt, "vgapal"))
1888 pmi_setpal = 0;
1889 else if (!strcmp(this_opt, "pmipal"))
1890 pmi_setpal = 1;
1891 else if (!strncmp(this_opt, "mtrr:", 5))
1892 mtrr = simple_strtoul(this_opt+5, NULL, 0);
1893 else if (!strcmp(this_opt, "nomtrr"))
1894 mtrr = 0;
1895 else if (!strcmp(this_opt, "nocrtc"))
1896 nocrtc = 1;
1897 else if (!strcmp(this_opt, "noedid"))
1898 noedid = 1;
1899 else if (!strcmp(this_opt, "noblank"))
1900 blank = 0;
1901 else if (!strncmp(this_opt, "vtotal:", 7))
1902 vram_total = simple_strtoul(this_opt + 7, NULL, 0);
1903 else if (!strncmp(this_opt, "vremap:", 7))
1904 vram_remap = simple_strtoul(this_opt + 7, NULL, 0);
1905 else if (!strncmp(this_opt, "maxhf:", 6))
1906 maxhf = simple_strtoul(this_opt + 6, NULL, 0);
1907 else if (!strncmp(this_opt, "maxvf:", 6))
1908 maxvf = simple_strtoul(this_opt + 6, NULL, 0);
1909 else if (!strncmp(this_opt, "maxclk:", 7))
1910 maxclk = simple_strtoul(this_opt + 7, NULL, 0);
1911 else if (!strncmp(this_opt, "vbemode:", 8))
1912 vbemode = simple_strtoul(this_opt + 8, NULL, 0);
1913 else if (this_opt[0] >= '0' && this_opt[0] <= '9') {
1914 mode_option = this_opt;
1915 } else {
1916 printk(KERN_WARNING
1917 "uvesafb: unrecognized option %s\n", this_opt);
1918 }
1919 }
1920
1921 return 0;
1922}
1923#endif /* !MODULE */
1924
1925static ssize_t show_v86d(struct device_driver *dev, char *buf)
1926{
1927 return snprintf(buf, PAGE_SIZE, "%s\n", v86d_path);
1928}
1929
1930static ssize_t store_v86d(struct device_driver *dev, const char *buf,
1931 size_t count)
1932{
1933 strncpy(v86d_path, buf, PATH_MAX);
1934 return count;
1935}
1936
1937static DRIVER_ATTR(v86d, S_IRUGO | S_IWUSR, show_v86d, store_v86d);
1938
1939static int __devinit uvesafb_init(void)
1940{
1941 int err;
1942
1943#ifndef MODULE
1944 char *option = NULL;
1945
1946 if (fb_get_options("uvesafb", &option))
1947 return -ENODEV;
1948 uvesafb_setup(option);
1949#endif
1950 err = cn_add_callback(&uvesafb_cn_id, "uvesafb", uvesafb_cn_callback);
1951 if (err)
1952 return err;
1953
1954 err = platform_driver_register(&uvesafb_driver);
1955
1956 if (!err) {
1957 uvesafb_device = platform_device_alloc("uvesafb", 0);
1958 if (uvesafb_device)
1959 err = platform_device_add(uvesafb_device);
1960 else
1961 err = -ENOMEM;
1962
1963 if (err) {
1964 platform_device_put(uvesafb_device);
1965 platform_driver_unregister(&uvesafb_driver);
1966 cn_del_callback(&uvesafb_cn_id);
1967 return err;
1968 }
1969
1970 err = driver_create_file(&uvesafb_driver.driver,
1971 &driver_attr_v86d);
1972 if (err) {
1973 printk(KERN_WARNING "uvesafb: failed to register "
1974 "attributes\n");
1975 err = 0;
1976 }
1977 }
1978 return err;
1979}
1980
1981module_init(uvesafb_init);
1982
1983static void __devexit uvesafb_exit(void)
1984{
1985 struct uvesafb_ktask *task;
1986
1987 if (v86d_started) {
1988 task = uvesafb_prep();
1989 if (task) {
1990 task->t.flags = TF_EXIT;
1991 uvesafb_exec(task);
1992 uvesafb_free(task);
1993 }
1994 }
1995
1996 cn_del_callback(&uvesafb_cn_id);
1997 driver_remove_file(&uvesafb_driver.driver, &driver_attr_v86d);
1998 platform_device_unregister(uvesafb_device);
1999 platform_driver_unregister(&uvesafb_driver);
2000}
2001
2002module_exit(uvesafb_exit);
2003
2004static inline int param_get_scroll(char *buffer, struct kernel_param *kp)
2005{
2006 return 0;
2007}
2008
2009static inline int param_set_scroll(const char *val, struct kernel_param *kp)
2010{
2011 ypan = 0;
2012
2013 if (!strcmp(val, "redraw"))
2014 ypan = 0;
2015 else if (!strcmp(val, "ypan"))
2016 ypan = 1;
2017 else if (!strcmp(val, "ywrap"))
2018 ypan = 2;
2019
2020 return 0;
2021}
2022
2023#define param_check_scroll(name, p) __param_check(name, p, void);
2024
2025module_param_named(scroll, ypan, scroll, 0);
2026MODULE_PARM_DESC(scroll,
2027 "Scrolling mode, set to 'redraw', ''ypan' or 'ywrap'");
2028module_param_named(vgapal, pmi_setpal, invbool, 0);
2029MODULE_PARM_DESC(vgapal, "Set palette using VGA registers");
2030module_param_named(pmipal, pmi_setpal, bool, 0);
2031MODULE_PARM_DESC(pmipal, "Set palette using PMI calls");
2032module_param(mtrr, uint, 0);
2033MODULE_PARM_DESC(mtrr,
2034 "Memory Type Range Registers setting. Use 0 to disable.");
2035module_param(blank, bool, 0);
2036MODULE_PARM_DESC(blank, "Enable hardware blanking");
2037module_param(nocrtc, bool, 0);
2038MODULE_PARM_DESC(nocrtc, "Ignore CRTC timings when setting modes");
2039module_param(noedid, bool, 0);
2040MODULE_PARM_DESC(noedid,
2041 "Ignore EDID-provided monitor limits when setting modes");
2042module_param(vram_remap, uint, 0);
2043MODULE_PARM_DESC(vram_remap, "Set amount of video memory to be used [MiB]");
2044module_param(vram_total, uint, 0);
2045MODULE_PARM_DESC(vram_total, "Set total amount of video memoery [MiB]");
2046module_param(maxclk, ushort, 0);
2047MODULE_PARM_DESC(maxclk, "Maximum pixelclock [MHz], overrides EDID data");
2048module_param(maxhf, ushort, 0);
2049MODULE_PARM_DESC(maxhf,
2050 "Maximum horizontal frequency [kHz], overrides EDID data");
2051module_param(maxvf, ushort, 0);
2052MODULE_PARM_DESC(maxvf,
2053 "Maximum vertical frequency [Hz], overrides EDID data");
2054module_param_named(mode, mode_option, charp, 0);
2055MODULE_PARM_DESC(mode,
2056 "Specify initial video mode as \"<xres>x<yres>[-<bpp>][@<refresh>]\"");
2057module_param(vbemode, ushort, 0);
2058MODULE_PARM_DESC(vbemode,
2059 "VBE mode number to set, overrides the 'mode' option");
2060module_param_string(v86d, v86d_path, PATH_MAX, 0660);
2061MODULE_PARM_DESC(v86d, "Path to the v86d userspace helper.");
2062
2063MODULE_LICENSE("GPL");
2064MODULE_AUTHOR("Michal Januszewski <spock@gentoo.org>");
2065MODULE_DESCRIPTION("Framebuffer driver for VBE2.0+ compliant graphics boards");
2066
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/vermilion/vermilion.c
index de531c907718..ff9e805c43bc 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/vermilion/vermilion.c
@@ -39,7 +39,6 @@
39#include <asm/cacheflush.h> 39#include <asm/cacheflush.h>
40#include <asm/tlbflush.h> 40#include <asm/tlbflush.h>
41#include <linux/mmzone.h> 41#include <linux/mmzone.h>
42#include <asm/uaccess.h>
43 42
44/* #define VERMILION_DEBUG */ 43/* #define VERMILION_DEBUG */
45 44
diff --git a/drivers/video/vfb.c b/drivers/video/vfb.c
index 64ee78c3c12b..072638a9528a 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/vfb.c
@@ -21,7 +21,6 @@
21#include <linux/interrupt.h> 21#include <linux/interrupt.h>
22#include <linux/platform_device.h> 22#include <linux/platform_device.h>
23 23
24#include <asm/uaccess.h>
25#include <linux/fb.h> 24#include <linux/fb.h>
26#include <linux/init.h> 25#include <linux/init.h>
27 26
@@ -38,6 +37,48 @@ static void *videomemory;
38static u_long videomemorysize = VIDEOMEMSIZE; 37static u_long videomemorysize = VIDEOMEMSIZE;
39module_param(videomemorysize, ulong, 0); 38module_param(videomemorysize, ulong, 0);
40 39
40/**********************************************************************
41 *
42 * Memory management
43 *
44 **********************************************************************/
45static void *rvmalloc(unsigned long size)
46{
47 void *mem;
48 unsigned long adr;
49
50 size = PAGE_ALIGN(size);
51 mem = vmalloc_32(size);
52 if (!mem)
53 return NULL;
54
55 memset(mem, 0, size); /* Clear the ram out, no junk to the user */
56 adr = (unsigned long) mem;
57 while (size > 0) {
58 SetPageReserved(vmalloc_to_page((void *)adr));
59 adr += PAGE_SIZE;
60 size -= PAGE_SIZE;
61 }
62
63 return mem;
64}
65
66static void rvfree(void *mem, unsigned long size)
67{
68 unsigned long adr;
69
70 if (!mem)
71 return;
72
73 adr = (unsigned long) mem;
74 while ((long) size > 0) {
75 ClearPageReserved(vmalloc_to_page((void *)adr));
76 adr += PAGE_SIZE;
77 size -= PAGE_SIZE;
78 }
79 vfree(mem);
80}
81
41static struct fb_var_screeninfo vfb_default __initdata = { 82static struct fb_var_screeninfo vfb_default __initdata = {
42 .xres = 640, 83 .xres = 640,
43 .yres = 480, 84 .yres = 480,
@@ -372,7 +413,33 @@ static int vfb_pan_display(struct fb_var_screeninfo *var,
372static int vfb_mmap(struct fb_info *info, 413static int vfb_mmap(struct fb_info *info,
373 struct vm_area_struct *vma) 414 struct vm_area_struct *vma)
374{ 415{
375 return -EINVAL; 416 unsigned long start = vma->vm_start;
417 unsigned long size = vma->vm_end - vma->vm_start;
418 unsigned long offset = vma->vm_pgoff << PAGE_SHIFT;
419 unsigned long page, pos;
420
421 if (offset + size > info->fix.smem_len) {
422 return -EINVAL;
423 }
424
425 pos = (unsigned long)info->fix.smem_start + offset;
426
427 while (size > 0) {
428 page = vmalloc_to_pfn((void *)pos);
429 if (remap_pfn_range(vma, start, page, PAGE_SIZE, PAGE_SHARED)) {
430 return -EAGAIN;
431 }
432 start += PAGE_SIZE;
433 pos += PAGE_SIZE;
434 if (size > PAGE_SIZE)
435 size -= PAGE_SIZE;
436 else
437 size = 0;
438 }
439
440 vma->vm_flags |= VM_RESERVED; /* avoid to swap out this VMA */
441 return 0;
442
376} 443}
377 444
378#ifndef MODULE 445#ifndef MODULE
@@ -407,7 +474,7 @@ static int __init vfb_probe(struct platform_device *dev)
407 /* 474 /*
408 * For real video cards we use ioremap. 475 * For real video cards we use ioremap.
409 */ 476 */
410 if (!(videomemory = vmalloc(videomemorysize))) 477 if (!(videomemory = rvmalloc(videomemorysize)))
411 return retval; 478 return retval;
412 479
413 /* 480 /*
@@ -430,6 +497,8 @@ static int __init vfb_probe(struct platform_device *dev)
430 497
431 if (!retval || (retval == 4)) 498 if (!retval || (retval == 4))
432 info->var = vfb_default; 499 info->var = vfb_default;
500 vfb_fix.smem_start = (unsigned long) videomemory;
501 vfb_fix.smem_len = videomemorysize;
433 info->fix = vfb_fix; 502 info->fix = vfb_fix;
434 info->pseudo_palette = info->par; 503 info->pseudo_palette = info->par;
435 info->par = NULL; 504 info->par = NULL;
@@ -453,7 +522,7 @@ err2:
453err1: 522err1:
454 framebuffer_release(info); 523 framebuffer_release(info);
455err: 524err:
456 vfree(videomemory); 525 rvfree(videomemory, videomemorysize);
457 return retval; 526 return retval;
458} 527}
459 528
@@ -463,7 +532,7 @@ static int vfb_remove(struct platform_device *dev)
463 532
464 if (info) { 533 if (info) {
465 unregister_framebuffer(info); 534 unregister_framebuffer(info);
466 vfree(videomemory); 535 rvfree(videomemory, videomemorysize);
467 framebuffer_release(info); 536 framebuffer_release(info);
468 } 537 }
469 return 0; 538 return 0;
diff --git a/fs/adfs/inode.c b/fs/adfs/inode.c
index 7e7a04be1278..e647200262a2 100644
--- a/fs/adfs/inode.c
+++ b/fs/adfs/inode.c
@@ -61,10 +61,14 @@ static int adfs_readpage(struct file *file, struct page *page)
61 return block_read_full_page(page, adfs_get_block); 61 return block_read_full_page(page, adfs_get_block);
62} 62}
63 63
64static int adfs_prepare_write(struct file *file, struct page *page, unsigned int from, unsigned int to) 64static int adfs_write_begin(struct file *file, struct address_space *mapping,
65 loff_t pos, unsigned len, unsigned flags,
66 struct page **pagep, void **fsdata)
65{ 67{
66 return cont_prepare_write(page, from, to, adfs_get_block, 68 *pagep = NULL;
67 &ADFS_I(page->mapping->host)->mmu_private); 69 return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
70 adfs_get_block,
71 &ADFS_I(mapping->host)->mmu_private);
68} 72}
69 73
70static sector_t _adfs_bmap(struct address_space *mapping, sector_t block) 74static sector_t _adfs_bmap(struct address_space *mapping, sector_t block)
@@ -76,8 +80,8 @@ static const struct address_space_operations adfs_aops = {
76 .readpage = adfs_readpage, 80 .readpage = adfs_readpage,
77 .writepage = adfs_writepage, 81 .writepage = adfs_writepage,
78 .sync_page = block_sync_page, 82 .sync_page = block_sync_page,
79 .prepare_write = adfs_prepare_write, 83 .write_begin = adfs_write_begin,
80 .commit_write = generic_commit_write, 84 .write_end = generic_write_end,
81 .bmap = _adfs_bmap 85 .bmap = _adfs_bmap
82}; 86};
83 87
diff --git a/fs/affs/file.c b/fs/affs/file.c
index c314a35f0918..6e0c9399200e 100644
--- a/fs/affs/file.c
+++ b/fs/affs/file.c
@@ -395,25 +395,33 @@ static int affs_writepage(struct page *page, struct writeback_control *wbc)
395{ 395{
396 return block_write_full_page(page, affs_get_block, wbc); 396 return block_write_full_page(page, affs_get_block, wbc);
397} 397}
398
398static int affs_readpage(struct file *file, struct page *page) 399static int affs_readpage(struct file *file, struct page *page)
399{ 400{
400 return block_read_full_page(page, affs_get_block); 401 return block_read_full_page(page, affs_get_block);
401} 402}
402static int affs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) 403
404static int affs_write_begin(struct file *file, struct address_space *mapping,
405 loff_t pos, unsigned len, unsigned flags,
406 struct page **pagep, void **fsdata)
403{ 407{
404 return cont_prepare_write(page, from, to, affs_get_block, 408 *pagep = NULL;
405 &AFFS_I(page->mapping->host)->mmu_private); 409 return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
410 affs_get_block,
411 &AFFS_I(mapping->host)->mmu_private);
406} 412}
413
407static sector_t _affs_bmap(struct address_space *mapping, sector_t block) 414static sector_t _affs_bmap(struct address_space *mapping, sector_t block)
408{ 415{
409 return generic_block_bmap(mapping,block,affs_get_block); 416 return generic_block_bmap(mapping,block,affs_get_block);
410} 417}
418
411const struct address_space_operations affs_aops = { 419const struct address_space_operations affs_aops = {
412 .readpage = affs_readpage, 420 .readpage = affs_readpage,
413 .writepage = affs_writepage, 421 .writepage = affs_writepage,
414 .sync_page = block_sync_page, 422 .sync_page = block_sync_page,
415 .prepare_write = affs_prepare_write, 423 .write_begin = affs_write_begin,
416 .commit_write = generic_commit_write, 424 .write_end = generic_write_end,
417 .bmap = _affs_bmap 425 .bmap = _affs_bmap
418}; 426};
419 427
@@ -603,54 +611,65 @@ affs_readpage_ofs(struct file *file, struct page *page)
603 return err; 611 return err;
604} 612}
605 613
606static int affs_prepare_write_ofs(struct file *file, struct page *page, unsigned from, unsigned to) 614static int affs_write_begin_ofs(struct file *file, struct address_space *mapping,
615 loff_t pos, unsigned len, unsigned flags,
616 struct page **pagep, void **fsdata)
607{ 617{
608 struct inode *inode = page->mapping->host; 618 struct inode *inode = mapping->host;
609 u32 size, offset; 619 struct page *page;
610 u32 tmp; 620 pgoff_t index;
611 int err = 0; 621 int err = 0;
612 622
613 pr_debug("AFFS: prepare_write(%u, %ld, %d, %d)\n", (u32)inode->i_ino, page->index, from, to); 623 pr_debug("AFFS: write_begin(%u, %llu, %llu)\n", (u32)inode->i_ino, (unsigned long long)pos, (unsigned long long)pos + len);
614 offset = page->index << PAGE_CACHE_SHIFT; 624 if (pos > AFFS_I(inode)->mmu_private) {
615 if (offset + from > AFFS_I(inode)->mmu_private) { 625 /* XXX: this probably leaves a too-big i_size in case of
616 err = affs_extent_file_ofs(inode, offset + from); 626 * failure. Should really be updating i_size at write_end time
627 */
628 err = affs_extent_file_ofs(inode, pos);
617 if (err) 629 if (err)
618 return err; 630 return err;
619 } 631 }
620 size = inode->i_size; 632
633 index = pos >> PAGE_CACHE_SHIFT;
634 page = __grab_cache_page(mapping, index);
635 if (!page)
636 return -ENOMEM;
637 *pagep = page;
621 638
622 if (PageUptodate(page)) 639 if (PageUptodate(page))
623 return 0; 640 return 0;
624 641
625 if (from) { 642 /* XXX: inefficient but safe in the face of short writes */
626 err = affs_do_readpage_ofs(file, page, 0, from); 643 err = affs_do_readpage_ofs(file, page, 0, PAGE_CACHE_SIZE);
627 if (err) 644 if (err) {
628 return err; 645 unlock_page(page);
629 } 646 page_cache_release(page);
630 if (to < PAGE_CACHE_SIZE) {
631 zero_user_page(page, to, PAGE_CACHE_SIZE - to, KM_USER0);
632 if (size > offset + to) {
633 if (size < offset + PAGE_CACHE_SIZE)
634 tmp = size & ~PAGE_CACHE_MASK;
635 else
636 tmp = PAGE_CACHE_SIZE;
637 err = affs_do_readpage_ofs(file, page, to, tmp);
638 }
639 } 647 }
640 return err; 648 return err;
641} 649}
642 650
643static int affs_commit_write_ofs(struct file *file, struct page *page, unsigned from, unsigned to) 651static int affs_write_end_ofs(struct file *file, struct address_space *mapping,
652 loff_t pos, unsigned len, unsigned copied,
653 struct page *page, void *fsdata)
644{ 654{
645 struct inode *inode = page->mapping->host; 655 struct inode *inode = mapping->host;
646 struct super_block *sb = inode->i_sb; 656 struct super_block *sb = inode->i_sb;
647 struct buffer_head *bh, *prev_bh; 657 struct buffer_head *bh, *prev_bh;
648 char *data; 658 char *data;
649 u32 bidx, boff, bsize; 659 u32 bidx, boff, bsize;
660 unsigned from, to;
650 u32 tmp; 661 u32 tmp;
651 int written; 662 int written;
652 663
653 pr_debug("AFFS: commit_write(%u, %ld, %d, %d)\n", (u32)inode->i_ino, page->index, from, to); 664 from = pos & (PAGE_CACHE_SIZE - 1);
665 to = pos + len;
666 /*
667 * XXX: not sure if this can handle short copies (len < copied), but
668 * we don't have to, because the page should always be uptodate here,
669 * due to write_begin.
670 */
671
672 pr_debug("AFFS: write_begin(%u, %llu, %llu)\n", (u32)inode->i_ino, (unsigned long long)pos, (unsigned long long)pos + len);
654 bsize = AFFS_SB(sb)->s_data_blksize; 673 bsize = AFFS_SB(sb)->s_data_blksize;
655 data = page_address(page); 674 data = page_address(page);
656 675
@@ -748,6 +767,9 @@ done:
748 if (tmp > inode->i_size) 767 if (tmp > inode->i_size)
749 inode->i_size = AFFS_I(inode)->mmu_private = tmp; 768 inode->i_size = AFFS_I(inode)->mmu_private = tmp;
750 769
770 unlock_page(page);
771 page_cache_release(page);
772
751 return written; 773 return written;
752 774
753out: 775out:
@@ -761,8 +783,8 @@ const struct address_space_operations affs_aops_ofs = {
761 .readpage = affs_readpage_ofs, 783 .readpage = affs_readpage_ofs,
762 //.writepage = affs_writepage_ofs, 784 //.writepage = affs_writepage_ofs,
763 //.sync_page = affs_sync_page_ofs, 785 //.sync_page = affs_sync_page_ofs,
764 .prepare_write = affs_prepare_write_ofs, 786 .write_begin = affs_write_begin_ofs,
765 .commit_write = affs_commit_write_ofs 787 .write_end = affs_write_end_ofs
766}; 788};
767 789
768/* Free any preallocated blocks. */ 790/* Free any preallocated blocks. */
@@ -805,18 +827,13 @@ affs_truncate(struct inode *inode)
805 if (inode->i_size > AFFS_I(inode)->mmu_private) { 827 if (inode->i_size > AFFS_I(inode)->mmu_private) {
806 struct address_space *mapping = inode->i_mapping; 828 struct address_space *mapping = inode->i_mapping;
807 struct page *page; 829 struct page *page;
808 u32 size = inode->i_size - 1; 830 void *fsdata;
831 u32 size = inode->i_size;
809 int res; 832 int res;
810 833
811 page = grab_cache_page(mapping, size >> PAGE_CACHE_SHIFT); 834 res = mapping->a_ops->write_begin(NULL, mapping, size, 0, 0, &page, &fsdata);
812 if (!page)
813 return;
814 size = (size & (PAGE_CACHE_SIZE - 1)) + 1;
815 res = mapping->a_ops->prepare_write(NULL, page, size, size);
816 if (!res) 835 if (!res)
817 res = mapping->a_ops->commit_write(NULL, page, size, size); 836 res = mapping->a_ops->write_end(NULL, mapping, size, 0, 0, page, fsdata);
818 unlock_page(page);
819 page_cache_release(page);
820 mark_inode_dirty(inode); 837 mark_inode_dirty(inode);
821 return; 838 return;
822 } else if (inode->i_size == AFFS_I(inode)->mmu_private) 839 } else if (inode->i_size == AFFS_I(inode)->mmu_private)
diff --git a/fs/bfs/file.c b/fs/bfs/file.c
index 24310e9ee05a..911b4ccf470f 100644
--- a/fs/bfs/file.c
+++ b/fs/bfs/file.c
@@ -145,9 +145,13 @@ static int bfs_readpage(struct file *file, struct page *page)
145 return block_read_full_page(page, bfs_get_block); 145 return block_read_full_page(page, bfs_get_block);
146} 146}
147 147
148static int bfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) 148static int bfs_write_begin(struct file *file, struct address_space *mapping,
149 loff_t pos, unsigned len, unsigned flags,
150 struct page **pagep, void **fsdata)
149{ 151{
150 return block_prepare_write(page, from, to, bfs_get_block); 152 *pagep = NULL;
153 return block_write_begin(file, mapping, pos, len, flags,
154 pagep, fsdata, bfs_get_block);
151} 155}
152 156
153static sector_t bfs_bmap(struct address_space *mapping, sector_t block) 157static sector_t bfs_bmap(struct address_space *mapping, sector_t block)
@@ -159,8 +163,8 @@ const struct address_space_operations bfs_aops = {
159 .readpage = bfs_readpage, 163 .readpage = bfs_readpage,
160 .writepage = bfs_writepage, 164 .writepage = bfs_writepage,
161 .sync_page = block_sync_page, 165 .sync_page = block_sync_page,
162 .prepare_write = bfs_prepare_write, 166 .write_begin = bfs_write_begin,
163 .commit_write = generic_commit_write, 167 .write_end = generic_write_end,
164 .bmap = bfs_bmap, 168 .bmap = bfs_bmap,
165}; 169};
166 170
diff --git a/fs/binfmt_elf.c b/fs/binfmt_elf.c
index b1013f34085d..f3037c645ca9 100644
--- a/fs/binfmt_elf.c
+++ b/fs/binfmt_elf.c
@@ -1725,7 +1725,7 @@ static int elf_core_dump(long signr, struct pt_regs *regs, struct file *file)
1725 &page, &vma) <= 0) { 1725 &page, &vma) <= 0) {
1726 DUMP_SEEK(PAGE_SIZE); 1726 DUMP_SEEK(PAGE_SIZE);
1727 } else { 1727 } else {
1728 if (page == ZERO_PAGE(addr)) { 1728 if (page == ZERO_PAGE(0)) {
1729 if (!dump_seek(file, PAGE_SIZE)) { 1729 if (!dump_seek(file, PAGE_SIZE)) {
1730 page_cache_release(page); 1730 page_cache_release(page);
1731 goto end_coredump; 1731 goto end_coredump;
diff --git a/fs/binfmt_elf_fdpic.c b/fs/binfmt_elf_fdpic.c
index 2f5d8dbe676d..c5ca2f0aca7f 100644
--- a/fs/binfmt_elf_fdpic.c
+++ b/fs/binfmt_elf_fdpic.c
@@ -1488,7 +1488,7 @@ static int elf_fdpic_dump_segments(struct file *file, size_t *size,
1488 &page, &vma) <= 0) { 1488 &page, &vma) <= 0) {
1489 DUMP_SEEK(file->f_pos + PAGE_SIZE); 1489 DUMP_SEEK(file->f_pos + PAGE_SIZE);
1490 } 1490 }
1491 else if (page == ZERO_PAGE(addr)) { 1491 else if (page == ZERO_PAGE(0)) {
1492 page_cache_release(page); 1492 page_cache_release(page);
1493 DUMP_SEEK(file->f_pos + PAGE_SIZE); 1493 DUMP_SEEK(file->f_pos + PAGE_SIZE);
1494 } 1494 }
diff --git a/fs/bio.c b/fs/bio.c
index 5f604f269dfa..d59ddbf79626 100644
--- a/fs/bio.c
+++ b/fs/bio.c
@@ -109,11 +109,14 @@ static inline struct bio_vec *bvec_alloc_bs(gfp_t gfp_mask, int nr, unsigned lon
109 109
110void bio_free(struct bio *bio, struct bio_set *bio_set) 110void bio_free(struct bio *bio, struct bio_set *bio_set)
111{ 111{
112 const int pool_idx = BIO_POOL_IDX(bio); 112 if (bio->bi_io_vec) {
113 const int pool_idx = BIO_POOL_IDX(bio);
113 114
114 BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS); 115 BIO_BUG_ON(pool_idx >= BIOVEC_NR_POOLS);
116
117 mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]);
118 }
115 119
116 mempool_free(bio->bi_io_vec, bio_set->bvec_pools[pool_idx]);
117 mempool_free(bio, bio_set->bio_pool); 120 mempool_free(bio, bio_set->bio_pool);
118} 121}
119 122
@@ -127,21 +130,9 @@ static void bio_fs_destructor(struct bio *bio)
127 130
128void bio_init(struct bio *bio) 131void bio_init(struct bio *bio)
129{ 132{
130 bio->bi_next = NULL; 133 memset(bio, 0, sizeof(*bio));
131 bio->bi_bdev = NULL;
132 bio->bi_flags = 1 << BIO_UPTODATE; 134 bio->bi_flags = 1 << BIO_UPTODATE;
133 bio->bi_rw = 0;
134 bio->bi_vcnt = 0;
135 bio->bi_idx = 0;
136 bio->bi_phys_segments = 0;
137 bio->bi_hw_segments = 0;
138 bio->bi_hw_front_size = 0;
139 bio->bi_hw_back_size = 0;
140 bio->bi_size = 0;
141 bio->bi_max_vecs = 0;
142 bio->bi_end_io = NULL;
143 atomic_set(&bio->bi_cnt, 1); 135 atomic_set(&bio->bi_cnt, 1);
144 bio->bi_private = NULL;
145} 136}
146 137
147/** 138/**
diff --git a/fs/block_dev.c b/fs/block_dev.c
index 6339a30879b7..379a446e243e 100644
--- a/fs/block_dev.c
+++ b/fs/block_dev.c
@@ -378,14 +378,26 @@ static int blkdev_readpage(struct file * file, struct page * page)
378 return block_read_full_page(page, blkdev_get_block); 378 return block_read_full_page(page, blkdev_get_block);
379} 379}
380 380
381static int blkdev_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) 381static int blkdev_write_begin(struct file *file, struct address_space *mapping,
382 loff_t pos, unsigned len, unsigned flags,
383 struct page **pagep, void **fsdata)
382{ 384{
383 return block_prepare_write(page, from, to, blkdev_get_block); 385 *pagep = NULL;
386 return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
387 blkdev_get_block);
384} 388}
385 389
386static int blkdev_commit_write(struct file *file, struct page *page, unsigned from, unsigned to) 390static int blkdev_write_end(struct file *file, struct address_space *mapping,
391 loff_t pos, unsigned len, unsigned copied,
392 struct page *page, void *fsdata)
387{ 393{
388 return block_commit_write(page, from, to); 394 int ret;
395 ret = block_write_end(file, mapping, pos, len, copied, page, fsdata);
396
397 unlock_page(page);
398 page_cache_release(page);
399
400 return ret;
389} 401}
390 402
391/* 403/*
@@ -1327,8 +1339,8 @@ const struct address_space_operations def_blk_aops = {
1327 .readpage = blkdev_readpage, 1339 .readpage = blkdev_readpage,
1328 .writepage = blkdev_writepage, 1340 .writepage = blkdev_writepage,
1329 .sync_page = block_sync_page, 1341 .sync_page = block_sync_page,
1330 .prepare_write = blkdev_prepare_write, 1342 .write_begin = blkdev_write_begin,
1331 .commit_write = blkdev_commit_write, 1343 .write_end = blkdev_write_end,
1332 .writepages = generic_writepages, 1344 .writepages = generic_writepages,
1333 .direct_IO = blkdev_direct_IO, 1345 .direct_IO = blkdev_direct_IO,
1334}; 1346};
diff --git a/fs/buffer.c b/fs/buffer.c
index 75b51dfa5e03..faceb5eecca9 100644
--- a/fs/buffer.c
+++ b/fs/buffer.c
@@ -110,10 +110,14 @@ static void buffer_io_error(struct buffer_head *bh)
110} 110}
111 111
112/* 112/*
113 * Default synchronous end-of-IO handler.. Just mark it up-to-date and 113 * End-of-IO handler helper function which does not touch the bh after
114 * unlock the buffer. This is what ll_rw_block uses too. 114 * unlocking it.
115 * Note: unlock_buffer() sort-of does touch the bh after unlocking it, but
116 * a race there is benign: unlock_buffer() only use the bh's address for
117 * hashing after unlocking the buffer, so it doesn't actually touch the bh
118 * itself.
115 */ 119 */
116void end_buffer_read_sync(struct buffer_head *bh, int uptodate) 120static void __end_buffer_read_notouch(struct buffer_head *bh, int uptodate)
117{ 121{
118 if (uptodate) { 122 if (uptodate) {
119 set_buffer_uptodate(bh); 123 set_buffer_uptodate(bh);
@@ -122,6 +126,15 @@ void end_buffer_read_sync(struct buffer_head *bh, int uptodate)
122 clear_buffer_uptodate(bh); 126 clear_buffer_uptodate(bh);
123 } 127 }
124 unlock_buffer(bh); 128 unlock_buffer(bh);
129}
130
131/*
132 * Default synchronous end-of-IO handler.. Just mark it up-to-date and
133 * unlock the buffer. This is what ll_rw_block uses too.
134 */
135void end_buffer_read_sync(struct buffer_head *bh, int uptodate)
136{
137 __end_buffer_read_notouch(bh, uptodate);
125 put_bh(bh); 138 put_bh(bh);
126} 139}
127 140
@@ -1757,6 +1770,48 @@ recover:
1757 goto done; 1770 goto done;
1758} 1771}
1759 1772
1773/*
1774 * If a page has any new buffers, zero them out here, and mark them uptodate
1775 * and dirty so they'll be written out (in order to prevent uninitialised
1776 * block data from leaking). And clear the new bit.
1777 */
1778void page_zero_new_buffers(struct page *page, unsigned from, unsigned to)
1779{
1780 unsigned int block_start, block_end;
1781 struct buffer_head *head, *bh;
1782
1783 BUG_ON(!PageLocked(page));
1784 if (!page_has_buffers(page))
1785 return;
1786
1787 bh = head = page_buffers(page);
1788 block_start = 0;
1789 do {
1790 block_end = block_start + bh->b_size;
1791
1792 if (buffer_new(bh)) {
1793 if (block_end > from && block_start < to) {
1794 if (!PageUptodate(page)) {
1795 unsigned start, size;
1796
1797 start = max(from, block_start);
1798 size = min(to, block_end) - start;
1799
1800 zero_user_page(page, start, size, KM_USER0);
1801 set_buffer_uptodate(bh);
1802 }
1803
1804 clear_buffer_new(bh);
1805 mark_buffer_dirty(bh);
1806 }
1807 }
1808
1809 block_start = block_end;
1810 bh = bh->b_this_page;
1811 } while (bh != head);
1812}
1813EXPORT_SYMBOL(page_zero_new_buffers);
1814
1760static int __block_prepare_write(struct inode *inode, struct page *page, 1815static int __block_prepare_write(struct inode *inode, struct page *page,
1761 unsigned from, unsigned to, get_block_t *get_block) 1816 unsigned from, unsigned to, get_block_t *get_block)
1762{ 1817{
@@ -1800,7 +1855,9 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
1800 unmap_underlying_metadata(bh->b_bdev, 1855 unmap_underlying_metadata(bh->b_bdev,
1801 bh->b_blocknr); 1856 bh->b_blocknr);
1802 if (PageUptodate(page)) { 1857 if (PageUptodate(page)) {
1858 clear_buffer_new(bh);
1803 set_buffer_uptodate(bh); 1859 set_buffer_uptodate(bh);
1860 mark_buffer_dirty(bh);
1804 continue; 1861 continue;
1805 } 1862 }
1806 if (block_end > to || block_start < from) { 1863 if (block_end > to || block_start < from) {
@@ -1839,38 +1896,8 @@ static int __block_prepare_write(struct inode *inode, struct page *page,
1839 if (!buffer_uptodate(*wait_bh)) 1896 if (!buffer_uptodate(*wait_bh))
1840 err = -EIO; 1897 err = -EIO;
1841 } 1898 }
1842 if (!err) { 1899 if (unlikely(err))
1843 bh = head; 1900 page_zero_new_buffers(page, from, to);
1844 do {
1845 if (buffer_new(bh))
1846 clear_buffer_new(bh);
1847 } while ((bh = bh->b_this_page) != head);
1848 return 0;
1849 }
1850 /* Error case: */
1851 /*
1852 * Zero out any newly allocated blocks to avoid exposing stale
1853 * data. If BH_New is set, we know that the block was newly
1854 * allocated in the above loop.
1855 */
1856 bh = head;
1857 block_start = 0;
1858 do {
1859 block_end = block_start+blocksize;
1860 if (block_end <= from)
1861 goto next_bh;
1862 if (block_start >= to)
1863 break;
1864 if (buffer_new(bh)) {
1865 clear_buffer_new(bh);
1866 zero_user_page(page, block_start, bh->b_size, KM_USER0);
1867 set_buffer_uptodate(bh);
1868 mark_buffer_dirty(bh);
1869 }
1870next_bh:
1871 block_start = block_end;
1872 bh = bh->b_this_page;
1873 } while (bh != head);
1874 return err; 1901 return err;
1875} 1902}
1876 1903
@@ -1895,6 +1922,7 @@ static int __block_commit_write(struct inode *inode, struct page *page,
1895 set_buffer_uptodate(bh); 1922 set_buffer_uptodate(bh);
1896 mark_buffer_dirty(bh); 1923 mark_buffer_dirty(bh);
1897 } 1924 }
1925 clear_buffer_new(bh);
1898 } 1926 }
1899 1927
1900 /* 1928 /*
@@ -1909,6 +1937,130 @@ static int __block_commit_write(struct inode *inode, struct page *page,
1909} 1937}
1910 1938
1911/* 1939/*
1940 * block_write_begin takes care of the basic task of block allocation and
1941 * bringing partial write blocks uptodate first.
1942 *
1943 * If *pagep is not NULL, then block_write_begin uses the locked page
1944 * at *pagep rather than allocating its own. In this case, the page will
1945 * not be unlocked or deallocated on failure.
1946 */
1947int block_write_begin(struct file *file, struct address_space *mapping,
1948 loff_t pos, unsigned len, unsigned flags,
1949 struct page **pagep, void **fsdata,
1950 get_block_t *get_block)
1951{
1952 struct inode *inode = mapping->host;
1953 int status = 0;
1954 struct page *page;
1955 pgoff_t index;
1956 unsigned start, end;
1957 int ownpage = 0;
1958
1959 index = pos >> PAGE_CACHE_SHIFT;
1960 start = pos & (PAGE_CACHE_SIZE - 1);
1961 end = start + len;
1962
1963 page = *pagep;
1964 if (page == NULL) {
1965 ownpage = 1;
1966 page = __grab_cache_page(mapping, index);
1967 if (!page) {
1968 status = -ENOMEM;
1969 goto out;
1970 }
1971 *pagep = page;
1972 } else
1973 BUG_ON(!PageLocked(page));
1974
1975 status = __block_prepare_write(inode, page, start, end, get_block);
1976 if (unlikely(status)) {
1977 ClearPageUptodate(page);
1978
1979 if (ownpage) {
1980 unlock_page(page);
1981 page_cache_release(page);
1982 *pagep = NULL;
1983
1984 /*
1985 * prepare_write() may have instantiated a few blocks
1986 * outside i_size. Trim these off again. Don't need
1987 * i_size_read because we hold i_mutex.
1988 */
1989 if (pos + len > inode->i_size)
1990 vmtruncate(inode, inode->i_size);
1991 }
1992 goto out;
1993 }
1994
1995out:
1996 return status;
1997}
1998EXPORT_SYMBOL(block_write_begin);
1999
2000int block_write_end(struct file *file, struct address_space *mapping,
2001 loff_t pos, unsigned len, unsigned copied,
2002 struct page *page, void *fsdata)
2003{
2004 struct inode *inode = mapping->host;
2005 unsigned start;
2006
2007 start = pos & (PAGE_CACHE_SIZE - 1);
2008
2009 if (unlikely(copied < len)) {
2010 /*
2011 * The buffers that were written will now be uptodate, so we
2012 * don't have to worry about a readpage reading them and
2013 * overwriting a partial write. However if we have encountered
2014 * a short write and only partially written into a buffer, it
2015 * will not be marked uptodate, so a readpage might come in and
2016 * destroy our partial write.
2017 *
2018 * Do the simplest thing, and just treat any short write to a
2019 * non uptodate page as a zero-length write, and force the
2020 * caller to redo the whole thing.
2021 */
2022 if (!PageUptodate(page))
2023 copied = 0;
2024
2025 page_zero_new_buffers(page, start+copied, start+len);
2026 }
2027 flush_dcache_page(page);
2028
2029 /* This could be a short (even 0-length) commit */
2030 __block_commit_write(inode, page, start, start+copied);
2031
2032 return copied;
2033}
2034EXPORT_SYMBOL(block_write_end);
2035
2036int generic_write_end(struct file *file, struct address_space *mapping,
2037 loff_t pos, unsigned len, unsigned copied,
2038 struct page *page, void *fsdata)
2039{
2040 struct inode *inode = mapping->host;
2041
2042 copied = block_write_end(file, mapping, pos, len, copied, page, fsdata);
2043
2044 /*
2045 * No need to use i_size_read() here, the i_size
2046 * cannot change under us because we hold i_mutex.
2047 *
2048 * But it's important to update i_size while still holding page lock:
2049 * page writeout could otherwise come in and zero beyond i_size.
2050 */
2051 if (pos+copied > inode->i_size) {
2052 i_size_write(inode, pos+copied);
2053 mark_inode_dirty(inode);
2054 }
2055
2056 unlock_page(page);
2057 page_cache_release(page);
2058
2059 return copied;
2060}
2061EXPORT_SYMBOL(generic_write_end);
2062
2063/*
1912 * Generic "read page" function for block devices that have the normal 2064 * Generic "read page" function for block devices that have the normal
1913 * get_block functionality. This is most of the block device filesystems. 2065 * get_block functionality. This is most of the block device filesystems.
1914 * Reads the page asynchronously --- the unlock_buffer() and 2066 * Reads the page asynchronously --- the unlock_buffer() and
@@ -2004,14 +2156,14 @@ int block_read_full_page(struct page *page, get_block_t *get_block)
2004} 2156}
2005 2157
2006/* utility function for filesystems that need to do work on expanding 2158/* utility function for filesystems that need to do work on expanding
2007 * truncates. Uses prepare/commit_write to allow the filesystem to 2159 * truncates. Uses filesystem pagecache writes to allow the filesystem to
2008 * deal with the hole. 2160 * deal with the hole.
2009 */ 2161 */
2010static int __generic_cont_expand(struct inode *inode, loff_t size, 2162int generic_cont_expand_simple(struct inode *inode, loff_t size)
2011 pgoff_t index, unsigned int offset)
2012{ 2163{
2013 struct address_space *mapping = inode->i_mapping; 2164 struct address_space *mapping = inode->i_mapping;
2014 struct page *page; 2165 struct page *page;
2166 void *fsdata;
2015 unsigned long limit; 2167 unsigned long limit;
2016 int err; 2168 int err;
2017 2169
@@ -2024,140 +2176,115 @@ static int __generic_cont_expand(struct inode *inode, loff_t size,
2024 if (size > inode->i_sb->s_maxbytes) 2176 if (size > inode->i_sb->s_maxbytes)
2025 goto out; 2177 goto out;
2026 2178
2027 err = -ENOMEM; 2179 err = pagecache_write_begin(NULL, mapping, size, 0,
2028 page = grab_cache_page(mapping, index); 2180 AOP_FLAG_UNINTERRUPTIBLE|AOP_FLAG_CONT_EXPAND,
2029 if (!page) 2181 &page, &fsdata);
2030 goto out; 2182 if (err)
2031 err = mapping->a_ops->prepare_write(NULL, page, offset, offset);
2032 if (err) {
2033 /*
2034 * ->prepare_write() may have instantiated a few blocks
2035 * outside i_size. Trim these off again.
2036 */
2037 unlock_page(page);
2038 page_cache_release(page);
2039 vmtruncate(inode, inode->i_size);
2040 goto out; 2183 goto out;
2041 }
2042 2184
2043 err = mapping->a_ops->commit_write(NULL, page, offset, offset); 2185 err = pagecache_write_end(NULL, mapping, size, 0, 0, page, fsdata);
2186 BUG_ON(err > 0);
2044 2187
2045 unlock_page(page);
2046 page_cache_release(page);
2047 if (err > 0)
2048 err = 0;
2049out: 2188out:
2050 return err; 2189 return err;
2051} 2190}
2052 2191
2053int generic_cont_expand(struct inode *inode, loff_t size) 2192int cont_expand_zero(struct file *file, struct address_space *mapping,
2193 loff_t pos, loff_t *bytes)
2054{ 2194{
2055 pgoff_t index; 2195 struct inode *inode = mapping->host;
2056 unsigned int offset; 2196 unsigned blocksize = 1 << inode->i_blkbits;
2197 struct page *page;
2198 void *fsdata;
2199 pgoff_t index, curidx;
2200 loff_t curpos;
2201 unsigned zerofrom, offset, len;
2202 int err = 0;
2057 2203
2058 offset = (size & (PAGE_CACHE_SIZE - 1)); /* Within page */ 2204 index = pos >> PAGE_CACHE_SHIFT;
2205 offset = pos & ~PAGE_CACHE_MASK;
2059 2206
2060 /* ugh. in prepare/commit_write, if from==to==start of block, we 2207 while (index > (curidx = (curpos = *bytes)>>PAGE_CACHE_SHIFT)) {
2061 ** skip the prepare. make sure we never send an offset for the start 2208 zerofrom = curpos & ~PAGE_CACHE_MASK;
2062 ** of a block 2209 if (zerofrom & (blocksize-1)) {
2063 */ 2210 *bytes |= (blocksize-1);
2064 if ((offset & (inode->i_sb->s_blocksize - 1)) == 0) { 2211 (*bytes)++;
2065 /* caller must handle this extra byte. */ 2212 }
2066 offset++; 2213 len = PAGE_CACHE_SIZE - zerofrom;
2067 }
2068 index = size >> PAGE_CACHE_SHIFT;
2069 2214
2070 return __generic_cont_expand(inode, size, index, offset); 2215 err = pagecache_write_begin(file, mapping, curpos, len,
2071} 2216 AOP_FLAG_UNINTERRUPTIBLE,
2217 &page, &fsdata);
2218 if (err)
2219 goto out;
2220 zero_user_page(page, zerofrom, len, KM_USER0);
2221 err = pagecache_write_end(file, mapping, curpos, len, len,
2222 page, fsdata);
2223 if (err < 0)
2224 goto out;
2225 BUG_ON(err != len);
2226 err = 0;
2227 }
2072 2228
2073int generic_cont_expand_simple(struct inode *inode, loff_t size) 2229 /* page covers the boundary, find the boundary offset */
2074{ 2230 if (index == curidx) {
2075 loff_t pos = size - 1; 2231 zerofrom = curpos & ~PAGE_CACHE_MASK;
2076 pgoff_t index = pos >> PAGE_CACHE_SHIFT; 2232 /* if we will expand the thing last block will be filled */
2077 unsigned int offset = (pos & (PAGE_CACHE_SIZE - 1)) + 1; 2233 if (offset <= zerofrom) {
2234 goto out;
2235 }
2236 if (zerofrom & (blocksize-1)) {
2237 *bytes |= (blocksize-1);
2238 (*bytes)++;
2239 }
2240 len = offset - zerofrom;
2078 2241
2079 /* prepare/commit_write can handle even if from==to==start of block. */ 2242 err = pagecache_write_begin(file, mapping, curpos, len,
2080 return __generic_cont_expand(inode, size, index, offset); 2243 AOP_FLAG_UNINTERRUPTIBLE,
2244 &page, &fsdata);
2245 if (err)
2246 goto out;
2247 zero_user_page(page, zerofrom, len, KM_USER0);
2248 err = pagecache_write_end(file, mapping, curpos, len, len,
2249 page, fsdata);
2250 if (err < 0)
2251 goto out;
2252 BUG_ON(err != len);
2253 err = 0;
2254 }
2255out:
2256 return err;
2081} 2257}
2082 2258
2083/* 2259/*
2084 * For moronic filesystems that do not allow holes in file. 2260 * For moronic filesystems that do not allow holes in file.
2085 * We may have to extend the file. 2261 * We may have to extend the file.
2086 */ 2262 */
2087 2263int cont_write_begin(struct file *file, struct address_space *mapping,
2088int cont_prepare_write(struct page *page, unsigned offset, 2264 loff_t pos, unsigned len, unsigned flags,
2089 unsigned to, get_block_t *get_block, loff_t *bytes) 2265 struct page **pagep, void **fsdata,
2266 get_block_t *get_block, loff_t *bytes)
2090{ 2267{
2091 struct address_space *mapping = page->mapping;
2092 struct inode *inode = mapping->host; 2268 struct inode *inode = mapping->host;
2093 struct page *new_page;
2094 pgoff_t pgpos;
2095 long status;
2096 unsigned zerofrom;
2097 unsigned blocksize = 1 << inode->i_blkbits; 2269 unsigned blocksize = 1 << inode->i_blkbits;
2270 unsigned zerofrom;
2271 int err;
2098 2272
2099 while(page->index > (pgpos = *bytes>>PAGE_CACHE_SHIFT)) { 2273 err = cont_expand_zero(file, mapping, pos, bytes);
2100 status = -ENOMEM; 2274 if (err)
2101 new_page = grab_cache_page(mapping, pgpos); 2275 goto out;
2102 if (!new_page)
2103 goto out;
2104 /* we might sleep */
2105 if (*bytes>>PAGE_CACHE_SHIFT != pgpos) {
2106 unlock_page(new_page);
2107 page_cache_release(new_page);
2108 continue;
2109 }
2110 zerofrom = *bytes & ~PAGE_CACHE_MASK;
2111 if (zerofrom & (blocksize-1)) {
2112 *bytes |= (blocksize-1);
2113 (*bytes)++;
2114 }
2115 status = __block_prepare_write(inode, new_page, zerofrom,
2116 PAGE_CACHE_SIZE, get_block);
2117 if (status)
2118 goto out_unmap;
2119 zero_user_page(new_page, zerofrom, PAGE_CACHE_SIZE - zerofrom,
2120 KM_USER0);
2121 generic_commit_write(NULL, new_page, zerofrom, PAGE_CACHE_SIZE);
2122 unlock_page(new_page);
2123 page_cache_release(new_page);
2124 }
2125
2126 if (page->index < pgpos) {
2127 /* completely inside the area */
2128 zerofrom = offset;
2129 } else {
2130 /* page covers the boundary, find the boundary offset */
2131 zerofrom = *bytes & ~PAGE_CACHE_MASK;
2132
2133 /* if we will expand the thing last block will be filled */
2134 if (to > zerofrom && (zerofrom & (blocksize-1))) {
2135 *bytes |= (blocksize-1);
2136 (*bytes)++;
2137 }
2138 2276
2139 /* starting below the boundary? Nothing to zero out */ 2277 zerofrom = *bytes & ~PAGE_CACHE_MASK;
2140 if (offset <= zerofrom) 2278 if (pos+len > *bytes && zerofrom & (blocksize-1)) {
2141 zerofrom = offset; 2279 *bytes |= (blocksize-1);
2142 } 2280 (*bytes)++;
2143 status = __block_prepare_write(inode, page, zerofrom, to, get_block);
2144 if (status)
2145 goto out1;
2146 if (zerofrom < offset) {
2147 zero_user_page(page, zerofrom, offset - zerofrom, KM_USER0);
2148 __block_commit_write(inode, page, zerofrom, offset);
2149 } 2281 }
2150 return 0;
2151out1:
2152 ClearPageUptodate(page);
2153 return status;
2154 2282
2155out_unmap: 2283 *pagep = NULL;
2156 ClearPageUptodate(new_page); 2284 err = block_write_begin(file, mapping, pos, len,
2157 unlock_page(new_page); 2285 flags, pagep, fsdata, get_block);
2158 page_cache_release(new_page);
2159out: 2286out:
2160 return status; 2287 return err;
2161} 2288}
2162 2289
2163int block_prepare_write(struct page *page, unsigned from, unsigned to, 2290int block_prepare_write(struct page *page, unsigned from, unsigned to,
@@ -2242,81 +2369,129 @@ out_unlock:
2242} 2369}
2243 2370
2244/* 2371/*
2245 * nobh_prepare_write()'s prereads are special: the buffer_heads are freed 2372 * nobh_write_begin()'s prereads are special: the buffer_heads are freed
2246 * immediately, while under the page lock. So it needs a special end_io 2373 * immediately, while under the page lock. So it needs a special end_io
2247 * handler which does not touch the bh after unlocking it. 2374 * handler which does not touch the bh after unlocking it.
2248 *
2249 * Note: unlock_buffer() sort-of does touch the bh after unlocking it, but
2250 * a race there is benign: unlock_buffer() only use the bh's address for
2251 * hashing after unlocking the buffer, so it doesn't actually touch the bh
2252 * itself.
2253 */ 2375 */
2254static void end_buffer_read_nobh(struct buffer_head *bh, int uptodate) 2376static void end_buffer_read_nobh(struct buffer_head *bh, int uptodate)
2255{ 2377{
2256 if (uptodate) { 2378 __end_buffer_read_notouch(bh, uptodate);
2257 set_buffer_uptodate(bh); 2379}
2258 } else { 2380
2259 /* This happens, due to failed READA attempts. */ 2381/*
2260 clear_buffer_uptodate(bh); 2382 * Attach the singly-linked list of buffers created by nobh_write_begin, to
2261 } 2383 * the page (converting it to circular linked list and taking care of page
2262 unlock_buffer(bh); 2384 * dirty races).
2385 */
2386static void attach_nobh_buffers(struct page *page, struct buffer_head *head)
2387{
2388 struct buffer_head *bh;
2389
2390 BUG_ON(!PageLocked(page));
2391
2392 spin_lock(&page->mapping->private_lock);
2393 bh = head;
2394 do {
2395 if (PageDirty(page))
2396 set_buffer_dirty(bh);
2397 if (!bh->b_this_page)
2398 bh->b_this_page = head;
2399 bh = bh->b_this_page;
2400 } while (bh != head);
2401 attach_page_buffers(page, head);
2402 spin_unlock(&page->mapping->private_lock);
2263} 2403}
2264 2404
2265/* 2405/*
2266 * On entry, the page is fully not uptodate. 2406 * On entry, the page is fully not uptodate.
2267 * On exit the page is fully uptodate in the areas outside (from,to) 2407 * On exit the page is fully uptodate in the areas outside (from,to)
2268 */ 2408 */
2269int nobh_prepare_write(struct page *page, unsigned from, unsigned to, 2409int nobh_write_begin(struct file *file, struct address_space *mapping,
2410 loff_t pos, unsigned len, unsigned flags,
2411 struct page **pagep, void **fsdata,
2270 get_block_t *get_block) 2412 get_block_t *get_block)
2271{ 2413{
2272 struct inode *inode = page->mapping->host; 2414 struct inode *inode = mapping->host;
2273 const unsigned blkbits = inode->i_blkbits; 2415 const unsigned blkbits = inode->i_blkbits;
2274 const unsigned blocksize = 1 << blkbits; 2416 const unsigned blocksize = 1 << blkbits;
2275 struct buffer_head map_bh; 2417 struct buffer_head *head, *bh;
2276 struct buffer_head *read_bh[MAX_BUF_PER_PAGE]; 2418 struct page *page;
2419 pgoff_t index;
2420 unsigned from, to;
2277 unsigned block_in_page; 2421 unsigned block_in_page;
2278 unsigned block_start; 2422 unsigned block_start, block_end;
2279 sector_t block_in_file; 2423 sector_t block_in_file;
2280 char *kaddr; 2424 char *kaddr;
2281 int nr_reads = 0; 2425 int nr_reads = 0;
2282 int i;
2283 int ret = 0; 2426 int ret = 0;
2284 int is_mapped_to_disk = 1; 2427 int is_mapped_to_disk = 1;
2285 2428
2429 index = pos >> PAGE_CACHE_SHIFT;
2430 from = pos & (PAGE_CACHE_SIZE - 1);
2431 to = from + len;
2432
2433 page = __grab_cache_page(mapping, index);
2434 if (!page)
2435 return -ENOMEM;
2436 *pagep = page;
2437 *fsdata = NULL;
2438
2439 if (page_has_buffers(page)) {
2440 unlock_page(page);
2441 page_cache_release(page);
2442 *pagep = NULL;
2443 return block_write_begin(file, mapping, pos, len, flags, pagep,
2444 fsdata, get_block);
2445 }
2446
2286 if (PageMappedToDisk(page)) 2447 if (PageMappedToDisk(page))
2287 return 0; 2448 return 0;
2288 2449
2450 /*
2451 * Allocate buffers so that we can keep track of state, and potentially
2452 * attach them to the page if an error occurs. In the common case of
2453 * no error, they will just be freed again without ever being attached
2454 * to the page (which is all OK, because we're under the page lock).
2455 *
2456 * Be careful: the buffer linked list is a NULL terminated one, rather
2457 * than the circular one we're used to.
2458 */
2459 head = alloc_page_buffers(page, blocksize, 0);
2460 if (!head) {
2461 ret = -ENOMEM;
2462 goto out_release;
2463 }
2464
2289 block_in_file = (sector_t)page->index << (PAGE_CACHE_SHIFT - blkbits); 2465 block_in_file = (sector_t)page->index << (PAGE_CACHE_SHIFT - blkbits);
2290 map_bh.b_page = page;
2291 2466
2292 /* 2467 /*
2293 * We loop across all blocks in the page, whether or not they are 2468 * We loop across all blocks in the page, whether or not they are
2294 * part of the affected region. This is so we can discover if the 2469 * part of the affected region. This is so we can discover if the
2295 * page is fully mapped-to-disk. 2470 * page is fully mapped-to-disk.
2296 */ 2471 */
2297 for (block_start = 0, block_in_page = 0; 2472 for (block_start = 0, block_in_page = 0, bh = head;
2298 block_start < PAGE_CACHE_SIZE; 2473 block_start < PAGE_CACHE_SIZE;
2299 block_in_page++, block_start += blocksize) { 2474 block_in_page++, block_start += blocksize, bh = bh->b_this_page) {
2300 unsigned block_end = block_start + blocksize;
2301 int create; 2475 int create;
2302 2476
2303 map_bh.b_state = 0; 2477 block_end = block_start + blocksize;
2478 bh->b_state = 0;
2304 create = 1; 2479 create = 1;
2305 if (block_start >= to) 2480 if (block_start >= to)
2306 create = 0; 2481 create = 0;
2307 map_bh.b_size = blocksize;
2308 ret = get_block(inode, block_in_file + block_in_page, 2482 ret = get_block(inode, block_in_file + block_in_page,
2309 &map_bh, create); 2483 bh, create);
2310 if (ret) 2484 if (ret)
2311 goto failed; 2485 goto failed;
2312 if (!buffer_mapped(&map_bh)) 2486 if (!buffer_mapped(bh))
2313 is_mapped_to_disk = 0; 2487 is_mapped_to_disk = 0;
2314 if (buffer_new(&map_bh)) 2488 if (buffer_new(bh))
2315 unmap_underlying_metadata(map_bh.b_bdev, 2489 unmap_underlying_metadata(bh->b_bdev, bh->b_blocknr);
2316 map_bh.b_blocknr); 2490 if (PageUptodate(page)) {
2317 if (PageUptodate(page)) 2491 set_buffer_uptodate(bh);
2318 continue; 2492 continue;
2319 if (buffer_new(&map_bh) || !buffer_mapped(&map_bh)) { 2493 }
2494 if (buffer_new(bh) || !buffer_mapped(bh)) {
2320 kaddr = kmap_atomic(page, KM_USER0); 2495 kaddr = kmap_atomic(page, KM_USER0);
2321 if (block_start < from) 2496 if (block_start < from)
2322 memset(kaddr+block_start, 0, from-block_start); 2497 memset(kaddr+block_start, 0, from-block_start);
@@ -2326,49 +2501,26 @@ int nobh_prepare_write(struct page *page, unsigned from, unsigned to,
2326 kunmap_atomic(kaddr, KM_USER0); 2501 kunmap_atomic(kaddr, KM_USER0);
2327 continue; 2502 continue;
2328 } 2503 }
2329 if (buffer_uptodate(&map_bh)) 2504 if (buffer_uptodate(bh))
2330 continue; /* reiserfs does this */ 2505 continue; /* reiserfs does this */
2331 if (block_start < from || block_end > to) { 2506 if (block_start < from || block_end > to) {
2332 struct buffer_head *bh = alloc_buffer_head(GFP_NOFS); 2507 lock_buffer(bh);
2333 2508 bh->b_end_io = end_buffer_read_nobh;
2334 if (!bh) { 2509 submit_bh(READ, bh);
2335 ret = -ENOMEM; 2510 nr_reads++;
2336 goto failed;
2337 }
2338 bh->b_state = map_bh.b_state;
2339 atomic_set(&bh->b_count, 0);
2340 bh->b_this_page = NULL;
2341 bh->b_page = page;
2342 bh->b_blocknr = map_bh.b_blocknr;
2343 bh->b_size = blocksize;
2344 bh->b_data = (char *)(long)block_start;
2345 bh->b_bdev = map_bh.b_bdev;
2346 bh->b_private = NULL;
2347 read_bh[nr_reads++] = bh;
2348 } 2511 }
2349 } 2512 }
2350 2513
2351 if (nr_reads) { 2514 if (nr_reads) {
2352 struct buffer_head *bh;
2353
2354 /* 2515 /*
2355 * The page is locked, so these buffers are protected from 2516 * The page is locked, so these buffers are protected from
2356 * any VM or truncate activity. Hence we don't need to care 2517 * any VM or truncate activity. Hence we don't need to care
2357 * for the buffer_head refcounts. 2518 * for the buffer_head refcounts.
2358 */ 2519 */
2359 for (i = 0; i < nr_reads; i++) { 2520 for (bh = head; bh; bh = bh->b_this_page) {
2360 bh = read_bh[i];
2361 lock_buffer(bh);
2362 bh->b_end_io = end_buffer_read_nobh;
2363 submit_bh(READ, bh);
2364 }
2365 for (i = 0; i < nr_reads; i++) {
2366 bh = read_bh[i];
2367 wait_on_buffer(bh); 2521 wait_on_buffer(bh);
2368 if (!buffer_uptodate(bh)) 2522 if (!buffer_uptodate(bh))
2369 ret = -EIO; 2523 ret = -EIO;
2370 free_buffer_head(bh);
2371 read_bh[i] = NULL;
2372 } 2524 }
2373 if (ret) 2525 if (ret)
2374 goto failed; 2526 goto failed;
@@ -2377,44 +2529,70 @@ int nobh_prepare_write(struct page *page, unsigned from, unsigned to,
2377 if (is_mapped_to_disk) 2529 if (is_mapped_to_disk)
2378 SetPageMappedToDisk(page); 2530 SetPageMappedToDisk(page);
2379 2531
2532 *fsdata = head; /* to be released by nobh_write_end */
2533
2380 return 0; 2534 return 0;
2381 2535
2382failed: 2536failed:
2383 for (i = 0; i < nr_reads; i++) { 2537 BUG_ON(!ret);
2384 if (read_bh[i])
2385 free_buffer_head(read_bh[i]);
2386 }
2387
2388 /* 2538 /*
2389 * Error recovery is pretty slack. Clear the page and mark it dirty 2539 * Error recovery is a bit difficult. We need to zero out blocks that
2390 * so we'll later zero out any blocks which _were_ allocated. 2540 * were newly allocated, and dirty them to ensure they get written out.
2541 * Buffers need to be attached to the page at this point, otherwise
2542 * the handling of potential IO errors during writeout would be hard
2543 * (could try doing synchronous writeout, but what if that fails too?)
2391 */ 2544 */
2392 zero_user_page(page, 0, PAGE_CACHE_SIZE, KM_USER0); 2545 attach_nobh_buffers(page, head);
2393 SetPageUptodate(page); 2546 page_zero_new_buffers(page, from, to);
2394 set_page_dirty(page); 2547
2548out_release:
2549 unlock_page(page);
2550 page_cache_release(page);
2551 *pagep = NULL;
2552
2553 if (pos + len > inode->i_size)
2554 vmtruncate(inode, inode->i_size);
2555
2395 return ret; 2556 return ret;
2396} 2557}
2397EXPORT_SYMBOL(nobh_prepare_write); 2558EXPORT_SYMBOL(nobh_write_begin);
2398 2559
2399/* 2560int nobh_write_end(struct file *file, struct address_space *mapping,
2400 * Make sure any changes to nobh_commit_write() are reflected in 2561 loff_t pos, unsigned len, unsigned copied,
2401 * nobh_truncate_page(), since it doesn't call commit_write(). 2562 struct page *page, void *fsdata)
2402 */
2403int nobh_commit_write(struct file *file, struct page *page,
2404 unsigned from, unsigned to)
2405{ 2563{
2406 struct inode *inode = page->mapping->host; 2564 struct inode *inode = page->mapping->host;
2407 loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; 2565 struct buffer_head *head = NULL;
2566 struct buffer_head *bh;
2567
2568 if (!PageMappedToDisk(page)) {
2569 if (unlikely(copied < len) && !page_has_buffers(page))
2570 attach_nobh_buffers(page, head);
2571 if (page_has_buffers(page))
2572 return generic_write_end(file, mapping, pos, len,
2573 copied, page, fsdata);
2574 }
2408 2575
2409 SetPageUptodate(page); 2576 SetPageUptodate(page);
2410 set_page_dirty(page); 2577 set_page_dirty(page);
2411 if (pos > inode->i_size) { 2578 if (pos+copied > inode->i_size) {
2412 i_size_write(inode, pos); 2579 i_size_write(inode, pos+copied);
2413 mark_inode_dirty(inode); 2580 mark_inode_dirty(inode);
2414 } 2581 }
2415 return 0; 2582
2583 unlock_page(page);
2584 page_cache_release(page);
2585
2586 head = fsdata;
2587 while (head) {
2588 bh = head;
2589 head = head->b_this_page;
2590 free_buffer_head(bh);
2591 }
2592
2593 return copied;
2416} 2594}
2417EXPORT_SYMBOL(nobh_commit_write); 2595EXPORT_SYMBOL(nobh_write_end);
2418 2596
2419/* 2597/*
2420 * nobh_writepage() - based on block_full_write_page() except 2598 * nobh_writepage() - based on block_full_write_page() except
@@ -2467,44 +2645,79 @@ out:
2467} 2645}
2468EXPORT_SYMBOL(nobh_writepage); 2646EXPORT_SYMBOL(nobh_writepage);
2469 2647
2470/* 2648int nobh_truncate_page(struct address_space *mapping,
2471 * This function assumes that ->prepare_write() uses nobh_prepare_write(). 2649 loff_t from, get_block_t *get_block)
2472 */
2473int nobh_truncate_page(struct address_space *mapping, loff_t from)
2474{ 2650{
2475 struct inode *inode = mapping->host;
2476 unsigned blocksize = 1 << inode->i_blkbits;
2477 pgoff_t index = from >> PAGE_CACHE_SHIFT; 2651 pgoff_t index = from >> PAGE_CACHE_SHIFT;
2478 unsigned offset = from & (PAGE_CACHE_SIZE-1); 2652 unsigned offset = from & (PAGE_CACHE_SIZE-1);
2479 unsigned to; 2653 unsigned blocksize;
2654 sector_t iblock;
2655 unsigned length, pos;
2656 struct inode *inode = mapping->host;
2480 struct page *page; 2657 struct page *page;
2481 const struct address_space_operations *a_ops = mapping->a_ops; 2658 struct buffer_head map_bh;
2482 int ret = 0; 2659 int err;
2483 2660
2484 if ((offset & (blocksize - 1)) == 0) 2661 blocksize = 1 << inode->i_blkbits;
2485 goto out; 2662 length = offset & (blocksize - 1);
2663
2664 /* Block boundary? Nothing to do */
2665 if (!length)
2666 return 0;
2667
2668 length = blocksize - length;
2669 iblock = (sector_t)index << (PAGE_CACHE_SHIFT - inode->i_blkbits);
2486 2670
2487 ret = -ENOMEM;
2488 page = grab_cache_page(mapping, index); 2671 page = grab_cache_page(mapping, index);
2672 err = -ENOMEM;
2489 if (!page) 2673 if (!page)
2490 goto out; 2674 goto out;
2491 2675
2492 to = (offset + blocksize) & ~(blocksize - 1); 2676 if (page_has_buffers(page)) {
2493 ret = a_ops->prepare_write(NULL, page, offset, to); 2677has_buffers:
2494 if (ret == 0) { 2678 unlock_page(page);
2495 zero_user_page(page, offset, PAGE_CACHE_SIZE - offset, 2679 page_cache_release(page);
2496 KM_USER0); 2680 return block_truncate_page(mapping, from, get_block);
2497 /*
2498 * It would be more correct to call aops->commit_write()
2499 * here, but this is more efficient.
2500 */
2501 SetPageUptodate(page);
2502 set_page_dirty(page);
2503 } 2681 }
2682
2683 /* Find the buffer that contains "offset" */
2684 pos = blocksize;
2685 while (offset >= pos) {
2686 iblock++;
2687 pos += blocksize;
2688 }
2689
2690 err = get_block(inode, iblock, &map_bh, 0);
2691 if (err)
2692 goto unlock;
2693 /* unmapped? It's a hole - nothing to do */
2694 if (!buffer_mapped(&map_bh))
2695 goto unlock;
2696
2697 /* Ok, it's mapped. Make sure it's up-to-date */
2698 if (!PageUptodate(page)) {
2699 err = mapping->a_ops->readpage(NULL, page);
2700 if (err) {
2701 page_cache_release(page);
2702 goto out;
2703 }
2704 lock_page(page);
2705 if (!PageUptodate(page)) {
2706 err = -EIO;
2707 goto unlock;
2708 }
2709 if (page_has_buffers(page))
2710 goto has_buffers;
2711 }
2712 zero_user_page(page, offset, length, KM_USER0);
2713 set_page_dirty(page);
2714 err = 0;
2715
2716unlock:
2504 unlock_page(page); 2717 unlock_page(page);
2505 page_cache_release(page); 2718 page_cache_release(page);
2506out: 2719out:
2507 return ret; 2720 return err;
2508} 2721}
2509EXPORT_SYMBOL(nobh_truncate_page); 2722EXPORT_SYMBOL(nobh_truncate_page);
2510 2723
@@ -2956,7 +3169,8 @@ static void recalc_bh_state(void)
2956 3169
2957struct buffer_head *alloc_buffer_head(gfp_t gfp_flags) 3170struct buffer_head *alloc_buffer_head(gfp_t gfp_flags)
2958{ 3171{
2959 struct buffer_head *ret = kmem_cache_zalloc(bh_cachep, gfp_flags); 3172 struct buffer_head *ret = kmem_cache_zalloc(bh_cachep,
3173 set_migrateflags(gfp_flags, __GFP_RECLAIMABLE));
2960 if (ret) { 3174 if (ret) {
2961 INIT_LIST_HEAD(&ret->b_assoc_buffers); 3175 INIT_LIST_HEAD(&ret->b_assoc_buffers);
2962 get_cpu_var(bh_accounting).nr++; 3176 get_cpu_var(bh_accounting).nr++;
@@ -3024,14 +3238,13 @@ EXPORT_SYMBOL(block_read_full_page);
3024EXPORT_SYMBOL(block_sync_page); 3238EXPORT_SYMBOL(block_sync_page);
3025EXPORT_SYMBOL(block_truncate_page); 3239EXPORT_SYMBOL(block_truncate_page);
3026EXPORT_SYMBOL(block_write_full_page); 3240EXPORT_SYMBOL(block_write_full_page);
3027EXPORT_SYMBOL(cont_prepare_write); 3241EXPORT_SYMBOL(cont_write_begin);
3028EXPORT_SYMBOL(end_buffer_read_sync); 3242EXPORT_SYMBOL(end_buffer_read_sync);
3029EXPORT_SYMBOL(end_buffer_write_sync); 3243EXPORT_SYMBOL(end_buffer_write_sync);
3030EXPORT_SYMBOL(file_fsync); 3244EXPORT_SYMBOL(file_fsync);
3031EXPORT_SYMBOL(fsync_bdev); 3245EXPORT_SYMBOL(fsync_bdev);
3032EXPORT_SYMBOL(generic_block_bmap); 3246EXPORT_SYMBOL(generic_block_bmap);
3033EXPORT_SYMBOL(generic_commit_write); 3247EXPORT_SYMBOL(generic_commit_write);
3034EXPORT_SYMBOL(generic_cont_expand);
3035EXPORT_SYMBOL(generic_cont_expand_simple); 3248EXPORT_SYMBOL(generic_cont_expand_simple);
3036EXPORT_SYMBOL(init_buffer); 3249EXPORT_SYMBOL(init_buffer);
3037EXPORT_SYMBOL(invalidate_bdev); 3250EXPORT_SYMBOL(invalidate_bdev);
diff --git a/fs/configfs/inode.c b/fs/configfs/inode.c
index ddc003a9d214..dbd257d956c4 100644
--- a/fs/configfs/inode.c
+++ b/fs/configfs/inode.c
@@ -41,8 +41,8 @@ extern struct super_block * configfs_sb;
41 41
42static const struct address_space_operations configfs_aops = { 42static const struct address_space_operations configfs_aops = {
43 .readpage = simple_readpage, 43 .readpage = simple_readpage,
44 .prepare_write = simple_prepare_write, 44 .write_begin = simple_write_begin,
45 .commit_write = simple_commit_write 45 .write_end = simple_write_end,
46}; 46};
47 47
48static struct backing_dev_info configfs_backing_dev_info = { 48static struct backing_dev_info configfs_backing_dev_info = {
diff --git a/fs/dcache.c b/fs/dcache.c
index 678d39deb607..7da0cf50873e 100644
--- a/fs/dcache.c
+++ b/fs/dcache.c
@@ -903,7 +903,7 @@ struct dentry *d_alloc(struct dentry * parent, const struct qstr *name)
903 struct dentry *dentry; 903 struct dentry *dentry;
904 char *dname; 904 char *dname;
905 905
906 dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL); 906 dentry = kmem_cache_alloc(dentry_cache, GFP_KERNEL);
907 if (!dentry) 907 if (!dentry)
908 return NULL; 908 return NULL;
909 909
diff --git a/fs/debugfs/file.c b/fs/debugfs/file.c
index a9b99c0dc2e7..fa6b7f7ff914 100644
--- a/fs/debugfs/file.c
+++ b/fs/debugfs/file.c
@@ -227,15 +227,24 @@ DEFINE_SIMPLE_ATTRIBUTE(fops_x16, debugfs_u16_get, debugfs_u16_set, "0x%04llx\n"
227 227
228DEFINE_SIMPLE_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set, "0x%08llx\n"); 228DEFINE_SIMPLE_ATTRIBUTE(fops_x32, debugfs_u32_get, debugfs_u32_set, "0x%08llx\n");
229 229
230/** 230/*
231 * debugfs_create_x8 - create a debugfs file that is used to read and write an unsigned 8-bit value 231 * debugfs_create_x{8,16,32} - create a debugfs file that is used to read and write an unsigned {8,16,32}-bit value
232 * debugfs_create_x16 - create a debugfs file that is used to read and write an unsigned 16-bit value
233 * debugfs_create_x32 - create a debugfs file that is used to read and write an unsigned 32-bit value
234 * 232 *
235 * These functions are exactly the same as the above functions, (but use a hex 233 * These functions are exactly the same as the above functions (but use a hex
236 * output for the decimal challenged) for details look at the above unsigned 234 * output for the decimal challenged). For details look at the above unsigned
237 * decimal functions. 235 * decimal functions.
238 */ 236 */
237
238/**
239 * debugfs_create_x8 - create a debugfs file that is used to read and write an unsigned 8-bit value
240 * @name: a pointer to a string containing the name of the file to create.
241 * @mode: the permission that the file should have
242 * @parent: a pointer to the parent dentry for this file. This should be a
243 * directory dentry if set. If this parameter is %NULL, then the
244 * file will be created in the root of the debugfs filesystem.
245 * @value: a pointer to the variable that the file should read to and write
246 * from.
247 */
239struct dentry *debugfs_create_x8(const char *name, mode_t mode, 248struct dentry *debugfs_create_x8(const char *name, mode_t mode,
240 struct dentry *parent, u8 *value) 249 struct dentry *parent, u8 *value)
241{ 250{
@@ -243,6 +252,16 @@ struct dentry *debugfs_create_x8(const char *name, mode_t mode,
243} 252}
244EXPORT_SYMBOL_GPL(debugfs_create_x8); 253EXPORT_SYMBOL_GPL(debugfs_create_x8);
245 254
255/**
256 * debugfs_create_x16 - create a debugfs file that is used to read and write an unsigned 16-bit value
257 * @name: a pointer to a string containing the name of the file to create.
258 * @mode: the permission that the file should have
259 * @parent: a pointer to the parent dentry for this file. This should be a
260 * directory dentry if set. If this parameter is %NULL, then the
261 * file will be created in the root of the debugfs filesystem.
262 * @value: a pointer to the variable that the file should read to and write
263 * from.
264 */
246struct dentry *debugfs_create_x16(const char *name, mode_t mode, 265struct dentry *debugfs_create_x16(const char *name, mode_t mode,
247 struct dentry *parent, u16 *value) 266 struct dentry *parent, u16 *value)
248{ 267{
@@ -250,6 +269,16 @@ struct dentry *debugfs_create_x16(const char *name, mode_t mode,
250} 269}
251EXPORT_SYMBOL_GPL(debugfs_create_x16); 270EXPORT_SYMBOL_GPL(debugfs_create_x16);
252 271
272/**
273 * debugfs_create_x32 - create a debugfs file that is used to read and write an unsigned 32-bit value
274 * @name: a pointer to a string containing the name of the file to create.
275 * @mode: the permission that the file should have
276 * @parent: a pointer to the parent dentry for this file. This should be a
277 * directory dentry if set. If this parameter is %NULL, then the
278 * file will be created in the root of the debugfs filesystem.
279 * @value: a pointer to the variable that the file should read to and write
280 * from.
281 */
253struct dentry *debugfs_create_x32(const char *name, mode_t mode, 282struct dentry *debugfs_create_x32(const char *name, mode_t mode,
254 struct dentry *parent, u32 *value) 283 struct dentry *parent, u32 *value)
255{ 284{
diff --git a/fs/direct-io.c b/fs/direct-io.c
index b5928a7b6a5a..acf0da1bd257 100644
--- a/fs/direct-io.c
+++ b/fs/direct-io.c
@@ -163,7 +163,7 @@ static int dio_refill_pages(struct dio *dio)
163 up_read(&current->mm->mmap_sem); 163 up_read(&current->mm->mmap_sem);
164 164
165 if (ret < 0 && dio->blocks_available && (dio->rw & WRITE)) { 165 if (ret < 0 && dio->blocks_available && (dio->rw & WRITE)) {
166 struct page *page = ZERO_PAGE(dio->curr_user_address); 166 struct page *page = ZERO_PAGE(0);
167 /* 167 /*
168 * A memory fault, but the filesystem has some outstanding 168 * A memory fault, but the filesystem has some outstanding
169 * mapped blocks. We need to use those blocks up to avoid 169 * mapped blocks. We need to use those blocks up to avoid
@@ -763,7 +763,7 @@ static void dio_zero_block(struct dio *dio, int end)
763 763
764 this_chunk_bytes = this_chunk_blocks << dio->blkbits; 764 this_chunk_bytes = this_chunk_blocks << dio->blkbits;
765 765
766 page = ZERO_PAGE(dio->curr_user_address); 766 page = ZERO_PAGE(0);
767 if (submit_page_section(dio, page, 0, this_chunk_bytes, 767 if (submit_page_section(dio, page, 0, this_chunk_bytes,
768 dio->next_block_for_io)) 768 dio->next_block_for_io))
769 return; 769 return;
diff --git a/fs/ecryptfs/Makefile b/fs/ecryptfs/Makefile
index 1f1107237eab..768857015516 100644
--- a/fs/ecryptfs/Makefile
+++ b/fs/ecryptfs/Makefile
@@ -4,4 +4,4 @@
4 4
5obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o 5obj-$(CONFIG_ECRYPT_FS) += ecryptfs.o
6 6
7ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o crypto.o keystore.o messaging.o netlink.o debug.o 7ecryptfs-objs := dentry.o file.o inode.o main.o super.o mmap.o read_write.o crypto.o keystore.o messaging.o netlink.o debug.o
diff --git a/fs/ecryptfs/crypto.c b/fs/ecryptfs/crypto.c
index 6ac630625b70..1ae90ef2c74d 100644
--- a/fs/ecryptfs/crypto.c
+++ b/fs/ecryptfs/crypto.c
@@ -123,9 +123,9 @@ out:
123 return rc; 123 return rc;
124} 124}
125 125
126int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, 126static int ecryptfs_crypto_api_algify_cipher_name(char **algified_name,
127 char *cipher_name, 127 char *cipher_name,
128 char *chaining_modifier) 128 char *chaining_modifier)
129{ 129{
130 int cipher_name_len = strlen(cipher_name); 130 int cipher_name_len = strlen(cipher_name);
131 int chaining_modifier_len = strlen(chaining_modifier); 131 int chaining_modifier_len = strlen(chaining_modifier);
@@ -149,7 +149,7 @@ out:
149 * ecryptfs_derive_iv 149 * ecryptfs_derive_iv
150 * @iv: destination for the derived iv vale 150 * @iv: destination for the derived iv vale
151 * @crypt_stat: Pointer to crypt_stat struct for the current inode 151 * @crypt_stat: Pointer to crypt_stat struct for the current inode
152 * @offset: Offset of the page whose's iv we are to derive 152 * @offset: Offset of the extent whose IV we are to derive
153 * 153 *
154 * Generate the initialization vector from the given root IV and page 154 * Generate the initialization vector from the given root IV and page
155 * offset. 155 * offset.
@@ -157,7 +157,7 @@ out:
157 * Returns zero on success; non-zero on error. 157 * Returns zero on success; non-zero on error.
158 */ 158 */
159static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat, 159static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
160 pgoff_t offset) 160 loff_t offset)
161{ 161{
162 int rc = 0; 162 int rc = 0;
163 char dst[MD5_DIGEST_SIZE]; 163 char dst[MD5_DIGEST_SIZE];
@@ -173,7 +173,7 @@ static int ecryptfs_derive_iv(char *iv, struct ecryptfs_crypt_stat *crypt_stat,
173 * hashing business. -Halcrow */ 173 * hashing business. -Halcrow */
174 memcpy(src, crypt_stat->root_iv, crypt_stat->iv_bytes); 174 memcpy(src, crypt_stat->root_iv, crypt_stat->iv_bytes);
175 memset((src + crypt_stat->iv_bytes), 0, 16); 175 memset((src + crypt_stat->iv_bytes), 0, 16);
176 snprintf((src + crypt_stat->iv_bytes), 16, "%ld", offset); 176 snprintf((src + crypt_stat->iv_bytes), 16, "%lld", offset);
177 if (unlikely(ecryptfs_verbosity > 0)) { 177 if (unlikely(ecryptfs_verbosity > 0)) {
178 ecryptfs_printk(KERN_DEBUG, "source:\n"); 178 ecryptfs_printk(KERN_DEBUG, "source:\n");
179 ecryptfs_dump_hex(src, (crypt_stat->iv_bytes + 16)); 179 ecryptfs_dump_hex(src, (crypt_stat->iv_bytes + 16));
@@ -204,6 +204,8 @@ void
204ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) 204ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
205{ 205{
206 memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); 206 memset((void *)crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
207 INIT_LIST_HEAD(&crypt_stat->keysig_list);
208 mutex_init(&crypt_stat->keysig_list_mutex);
207 mutex_init(&crypt_stat->cs_mutex); 209 mutex_init(&crypt_stat->cs_mutex);
208 mutex_init(&crypt_stat->cs_tfm_mutex); 210 mutex_init(&crypt_stat->cs_tfm_mutex);
209 mutex_init(&crypt_stat->cs_hash_tfm_mutex); 211 mutex_init(&crypt_stat->cs_hash_tfm_mutex);
@@ -211,27 +213,48 @@ ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
211} 213}
212 214
213/** 215/**
214 * ecryptfs_destruct_crypt_stat 216 * ecryptfs_destroy_crypt_stat
215 * @crypt_stat: Pointer to the crypt_stat struct to initialize. 217 * @crypt_stat: Pointer to the crypt_stat struct to initialize.
216 * 218 *
217 * Releases all memory associated with a crypt_stat struct. 219 * Releases all memory associated with a crypt_stat struct.
218 */ 220 */
219void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat) 221void ecryptfs_destroy_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat)
220{ 222{
223 struct ecryptfs_key_sig *key_sig, *key_sig_tmp;
224
221 if (crypt_stat->tfm) 225 if (crypt_stat->tfm)
222 crypto_free_blkcipher(crypt_stat->tfm); 226 crypto_free_blkcipher(crypt_stat->tfm);
223 if (crypt_stat->hash_tfm) 227 if (crypt_stat->hash_tfm)
224 crypto_free_hash(crypt_stat->hash_tfm); 228 crypto_free_hash(crypt_stat->hash_tfm);
229 mutex_lock(&crypt_stat->keysig_list_mutex);
230 list_for_each_entry_safe(key_sig, key_sig_tmp,
231 &crypt_stat->keysig_list, crypt_stat_list) {
232 list_del(&key_sig->crypt_stat_list);
233 kmem_cache_free(ecryptfs_key_sig_cache, key_sig);
234 }
235 mutex_unlock(&crypt_stat->keysig_list_mutex);
225 memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat)); 236 memset(crypt_stat, 0, sizeof(struct ecryptfs_crypt_stat));
226} 237}
227 238
228void ecryptfs_destruct_mount_crypt_stat( 239void ecryptfs_destroy_mount_crypt_stat(
229 struct ecryptfs_mount_crypt_stat *mount_crypt_stat) 240 struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
230{ 241{
231 if (mount_crypt_stat->global_auth_tok_key) 242 struct ecryptfs_global_auth_tok *auth_tok, *auth_tok_tmp;
232 key_put(mount_crypt_stat->global_auth_tok_key); 243
233 if (mount_crypt_stat->global_key_tfm) 244 if (!(mount_crypt_stat->flags & ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED))
234 crypto_free_blkcipher(mount_crypt_stat->global_key_tfm); 245 return;
246 mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
247 list_for_each_entry_safe(auth_tok, auth_tok_tmp,
248 &mount_crypt_stat->global_auth_tok_list,
249 mount_crypt_stat_list) {
250 list_del(&auth_tok->mount_crypt_stat_list);
251 mount_crypt_stat->num_global_auth_toks--;
252 if (auth_tok->global_auth_tok_key
253 && !(auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID))
254 key_put(auth_tok->global_auth_tok_key);
255 kmem_cache_free(ecryptfs_global_auth_tok_cache, auth_tok);
256 }
257 mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
235 memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat)); 258 memset(mount_crypt_stat, 0, sizeof(struct ecryptfs_mount_crypt_stat));
236} 259}
237 260
@@ -330,114 +353,82 @@ out:
330 return rc; 353 return rc;
331} 354}
332 355
333static void 356/**
334ecryptfs_extent_to_lwr_pg_idx_and_offset(unsigned long *lower_page_idx, 357 * ecryptfs_lower_offset_for_extent
335 int *byte_offset, 358 *
336 struct ecryptfs_crypt_stat *crypt_stat, 359 * Convert an eCryptfs page index into a lower byte offset
337 unsigned long extent_num) 360 */
361void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
362 struct ecryptfs_crypt_stat *crypt_stat)
338{ 363{
339 unsigned long lower_extent_num; 364 (*offset) = ((crypt_stat->extent_size
340 int extents_occupied_by_headers_at_front; 365 * crypt_stat->num_header_extents_at_front)
341 int bytes_occupied_by_headers_at_front; 366 + (crypt_stat->extent_size * extent_num));
342 int extent_offset;
343 int extents_per_page;
344
345 bytes_occupied_by_headers_at_front =
346 ( crypt_stat->header_extent_size
347 * crypt_stat->num_header_extents_at_front );
348 extents_occupied_by_headers_at_front =
349 ( bytes_occupied_by_headers_at_front
350 / crypt_stat->extent_size );
351 lower_extent_num = extents_occupied_by_headers_at_front + extent_num;
352 extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size;
353 (*lower_page_idx) = lower_extent_num / extents_per_page;
354 extent_offset = lower_extent_num % extents_per_page;
355 (*byte_offset) = extent_offset * crypt_stat->extent_size;
356 ecryptfs_printk(KERN_DEBUG, " * crypt_stat->header_extent_size = "
357 "[%d]\n", crypt_stat->header_extent_size);
358 ecryptfs_printk(KERN_DEBUG, " * crypt_stat->"
359 "num_header_extents_at_front = [%d]\n",
360 crypt_stat->num_header_extents_at_front);
361 ecryptfs_printk(KERN_DEBUG, " * extents_occupied_by_headers_at_"
362 "front = [%d]\n", extents_occupied_by_headers_at_front);
363 ecryptfs_printk(KERN_DEBUG, " * lower_extent_num = [0x%.16x]\n",
364 lower_extent_num);
365 ecryptfs_printk(KERN_DEBUG, " * extents_per_page = [%d]\n",
366 extents_per_page);
367 ecryptfs_printk(KERN_DEBUG, " * (*lower_page_idx) = [0x%.16x]\n",
368 (*lower_page_idx));
369 ecryptfs_printk(KERN_DEBUG, " * extent_offset = [%d]\n",
370 extent_offset);
371 ecryptfs_printk(KERN_DEBUG, " * (*byte_offset) = [%d]\n",
372 (*byte_offset));
373} 367}
374 368
375static int ecryptfs_write_out_page(struct ecryptfs_page_crypt_context *ctx, 369/**
376 struct page *lower_page, 370 * ecryptfs_encrypt_extent
377 struct inode *lower_inode, 371 * @enc_extent_page: Allocated page into which to encrypt the data in
378 int byte_offset_in_page, int bytes_to_write) 372 * @page
373 * @crypt_stat: crypt_stat containing cryptographic context for the
374 * encryption operation
375 * @page: Page containing plaintext data extent to encrypt
376 * @extent_offset: Page extent offset for use in generating IV
377 *
378 * Encrypts one extent of data.
379 *
380 * Return zero on success; non-zero otherwise
381 */
382static int ecryptfs_encrypt_extent(struct page *enc_extent_page,
383 struct ecryptfs_crypt_stat *crypt_stat,
384 struct page *page,
385 unsigned long extent_offset)
379{ 386{
380 int rc = 0; 387 loff_t extent_base;
388 char extent_iv[ECRYPTFS_MAX_IV_BYTES];
389 int rc;
381 390
382 if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) { 391 extent_base = (((loff_t)page->index)
383 rc = ecryptfs_commit_lower_page(lower_page, lower_inode, 392 * (PAGE_CACHE_SIZE / crypt_stat->extent_size));
384 ctx->param.lower_file, 393 rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
385 byte_offset_in_page, 394 (extent_base + extent_offset));
386 bytes_to_write); 395 if (rc) {
387 if (rc) { 396 ecryptfs_printk(KERN_ERR, "Error attempting to "
388 ecryptfs_printk(KERN_ERR, "Error calling lower " 397 "derive IV for extent [0x%.16x]; "
389 "commit; rc = [%d]\n", rc); 398 "rc = [%d]\n", (extent_base + extent_offset),
390 goto out; 399 rc);
391 } 400 goto out;
392 } else {
393 rc = ecryptfs_writepage_and_release_lower_page(lower_page,
394 lower_inode,
395 ctx->param.wbc);
396 if (rc) {
397 ecryptfs_printk(KERN_ERR, "Error calling lower "
398 "writepage(); rc = [%d]\n", rc);
399 goto out;
400 }
401 } 401 }
402out: 402 if (unlikely(ecryptfs_verbosity > 0)) {
403 return rc; 403 ecryptfs_printk(KERN_DEBUG, "Encrypting extent "
404} 404 "with iv:\n");
405 405 ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
406static int ecryptfs_read_in_page(struct ecryptfs_page_crypt_context *ctx, 406 ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
407 struct page **lower_page, 407 "encryption:\n");
408 struct inode *lower_inode, 408 ecryptfs_dump_hex((char *)
409 unsigned long lower_page_idx, 409 (page_address(page)
410 int byte_offset_in_page) 410 + (extent_offset * crypt_stat->extent_size)),
411{ 411 8);
412 int rc = 0; 412 }
413 413 rc = ecryptfs_encrypt_page_offset(crypt_stat, enc_extent_page, 0,
414 if (ctx->mode == ECRYPTFS_PREPARE_COMMIT_MODE) { 414 page, (extent_offset
415 /* TODO: Limit this to only the data extents that are 415 * crypt_stat->extent_size),
416 * needed */ 416 crypt_stat->extent_size, extent_iv);
417 rc = ecryptfs_get_lower_page(lower_page, lower_inode, 417 if (rc < 0) {
418 ctx->param.lower_file, 418 printk(KERN_ERR "%s: Error attempting to encrypt page with "
419 lower_page_idx, 419 "page->index = [%ld], extent_offset = [%ld]; "
420 byte_offset_in_page, 420 "rc = [%d]\n", __FUNCTION__, page->index, extent_offset,
421 (PAGE_CACHE_SIZE 421 rc);
422 - byte_offset_in_page)); 422 goto out;
423 if (rc) { 423 }
424 ecryptfs_printk( 424 rc = 0;
425 KERN_ERR, "Error attempting to grab, map, " 425 if (unlikely(ecryptfs_verbosity > 0)) {
426 "and prepare_write lower page with index " 426 ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; "
427 "[0x%.16x]; rc = [%d]\n", lower_page_idx, rc); 427 "rc = [%d]\n", (extent_base + extent_offset),
428 goto out; 428 rc);
429 } 429 ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
430 } else { 430 "encryption:\n");
431 *lower_page = grab_cache_page(lower_inode->i_mapping, 431 ecryptfs_dump_hex((char *)(page_address(enc_extent_page)), 8);
432 lower_page_idx);
433 if (!(*lower_page)) {
434 rc = -EINVAL;
435 ecryptfs_printk(
436 KERN_ERR, "Error attempting to grab and map "
437 "lower page with index [0x%.16x]; rc = [%d]\n",
438 lower_page_idx, rc);
439 goto out;
440 }
441 } 432 }
442out: 433out:
443 return rc; 434 return rc;
@@ -445,7 +436,9 @@ out:
445 436
446/** 437/**
447 * ecryptfs_encrypt_page 438 * ecryptfs_encrypt_page
448 * @ctx: The context of the page 439 * @page: Page mapped from the eCryptfs inode for the file; contains
440 * decrypted content that needs to be encrypted (to a temporary
441 * page; not in place) and written out to the lower file
449 * 442 *
450 * Encrypt an eCryptfs page. This is done on a per-extent basis. Note 443 * Encrypt an eCryptfs page. This is done on a per-extent basis. Note
451 * that eCryptfs pages may straddle the lower pages -- for instance, 444 * that eCryptfs pages may straddle the lower pages -- for instance,
@@ -455,128 +448,122 @@ out:
455 * file, 24K of page 0 of the lower file will be read and decrypted, 448 * file, 24K of page 0 of the lower file will be read and decrypted,
456 * and then 8K of page 1 of the lower file will be read and decrypted. 449 * and then 8K of page 1 of the lower file will be read and decrypted.
457 * 450 *
458 * The actual operations performed on each page depends on the
459 * contents of the ecryptfs_page_crypt_context struct.
460 *
461 * Returns zero on success; negative on error 451 * Returns zero on success; negative on error
462 */ 452 */
463int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx) 453int ecryptfs_encrypt_page(struct page *page)
464{ 454{
465 char extent_iv[ECRYPTFS_MAX_IV_BYTES]; 455 struct inode *ecryptfs_inode;
466 unsigned long base_extent;
467 unsigned long extent_offset = 0;
468 unsigned long lower_page_idx = 0;
469 unsigned long prior_lower_page_idx = 0;
470 struct page *lower_page;
471 struct inode *lower_inode;
472 struct ecryptfs_inode_info *inode_info;
473 struct ecryptfs_crypt_stat *crypt_stat; 456 struct ecryptfs_crypt_stat *crypt_stat;
457 char *enc_extent_virt = NULL;
458 struct page *enc_extent_page;
459 loff_t extent_offset;
474 int rc = 0; 460 int rc = 0;
475 int lower_byte_offset = 0; 461
476 int orig_byte_offset = 0; 462 ecryptfs_inode = page->mapping->host;
477 int num_extents_per_page; 463 crypt_stat =
478#define ECRYPTFS_PAGE_STATE_UNREAD 0 464 &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
479#define ECRYPTFS_PAGE_STATE_READ 1
480#define ECRYPTFS_PAGE_STATE_MODIFIED 2
481#define ECRYPTFS_PAGE_STATE_WRITTEN 3
482 int page_state;
483
484 lower_inode = ecryptfs_inode_to_lower(ctx->page->mapping->host);
485 inode_info = ecryptfs_inode_to_private(ctx->page->mapping->host);
486 crypt_stat = &inode_info->crypt_stat;
487 if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { 465 if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
488 rc = ecryptfs_copy_page_to_lower(ctx->page, lower_inode, 466 rc = ecryptfs_write_lower_page_segment(ecryptfs_inode, page,
489 ctx->param.lower_file); 467 0, PAGE_CACHE_SIZE);
490 if (rc) 468 if (rc)
491 ecryptfs_printk(KERN_ERR, "Error attempting to copy " 469 printk(KERN_ERR "%s: Error attempting to copy "
492 "page at index [0x%.16x]\n", 470 "page at index [%ld]\n", __FUNCTION__,
493 ctx->page->index); 471 page->index);
494 goto out; 472 goto out;
495 } 473 }
496 num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size; 474 enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER);
497 base_extent = (ctx->page->index * num_extents_per_page); 475 if (!enc_extent_virt) {
498 page_state = ECRYPTFS_PAGE_STATE_UNREAD; 476 rc = -ENOMEM;
499 while (extent_offset < num_extents_per_page) { 477 ecryptfs_printk(KERN_ERR, "Error allocating memory for "
500 ecryptfs_extent_to_lwr_pg_idx_and_offset( 478 "encrypted extent\n");
501 &lower_page_idx, &lower_byte_offset, crypt_stat, 479 goto out;
502 (base_extent + extent_offset)); 480 }
503 if (prior_lower_page_idx != lower_page_idx 481 enc_extent_page = virt_to_page(enc_extent_virt);
504 && page_state == ECRYPTFS_PAGE_STATE_MODIFIED) { 482 for (extent_offset = 0;
505 rc = ecryptfs_write_out_page(ctx, lower_page, 483 extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size);
506 lower_inode, 484 extent_offset++) {
507 orig_byte_offset, 485 loff_t offset;
508 (PAGE_CACHE_SIZE 486
509 - orig_byte_offset)); 487 rc = ecryptfs_encrypt_extent(enc_extent_page, crypt_stat, page,
510 if (rc) { 488 extent_offset);
511 ecryptfs_printk(KERN_ERR, "Error attempting "
512 "to write out page; rc = [%d]"
513 "\n", rc);
514 goto out;
515 }
516 page_state = ECRYPTFS_PAGE_STATE_WRITTEN;
517 }
518 if (page_state == ECRYPTFS_PAGE_STATE_UNREAD
519 || page_state == ECRYPTFS_PAGE_STATE_WRITTEN) {
520 rc = ecryptfs_read_in_page(ctx, &lower_page,
521 lower_inode, lower_page_idx,
522 lower_byte_offset);
523 if (rc) {
524 ecryptfs_printk(KERN_ERR, "Error attempting "
525 "to read in lower page with "
526 "index [0x%.16x]; rc = [%d]\n",
527 lower_page_idx, rc);
528 goto out;
529 }
530 orig_byte_offset = lower_byte_offset;
531 prior_lower_page_idx = lower_page_idx;
532 page_state = ECRYPTFS_PAGE_STATE_READ;
533 }
534 BUG_ON(!(page_state == ECRYPTFS_PAGE_STATE_MODIFIED
535 || page_state == ECRYPTFS_PAGE_STATE_READ));
536 rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
537 (base_extent + extent_offset));
538 if (rc) { 489 if (rc) {
539 ecryptfs_printk(KERN_ERR, "Error attempting to " 490 printk(KERN_ERR "%s: Error encrypting extent; "
540 "derive IV for extent [0x%.16x]; " 491 "rc = [%d]\n", __FUNCTION__, rc);
541 "rc = [%d]\n",
542 (base_extent + extent_offset), rc);
543 goto out; 492 goto out;
544 } 493 }
545 if (unlikely(ecryptfs_verbosity > 0)) { 494 ecryptfs_lower_offset_for_extent(
546 ecryptfs_printk(KERN_DEBUG, "Encrypting extent " 495 &offset, ((((loff_t)page->index)
547 "with iv:\n"); 496 * (PAGE_CACHE_SIZE
548 ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); 497 / crypt_stat->extent_size))
549 ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " 498 + extent_offset), crypt_stat);
550 "encryption:\n"); 499 rc = ecryptfs_write_lower(ecryptfs_inode, enc_extent_virt,
551 ecryptfs_dump_hex((char *) 500 offset, crypt_stat->extent_size);
552 (page_address(ctx->page) 501 if (rc) {
553 + (extent_offset 502 ecryptfs_printk(KERN_ERR, "Error attempting "
554 * crypt_stat->extent_size)), 8); 503 "to write lower page; rc = [%d]"
555 } 504 "\n", rc);
556 rc = ecryptfs_encrypt_page_offset( 505 goto out;
557 crypt_stat, lower_page, lower_byte_offset, ctx->page,
558 (extent_offset * crypt_stat->extent_size),
559 crypt_stat->extent_size, extent_iv);
560 ecryptfs_printk(KERN_DEBUG, "Encrypt extent [0x%.16x]; "
561 "rc = [%d]\n",
562 (base_extent + extent_offset), rc);
563 if (unlikely(ecryptfs_verbosity > 0)) {
564 ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
565 "encryption:\n");
566 ecryptfs_dump_hex((char *)(page_address(lower_page)
567 + lower_byte_offset), 8);
568 } 506 }
569 page_state = ECRYPTFS_PAGE_STATE_MODIFIED;
570 extent_offset++; 507 extent_offset++;
571 } 508 }
572 BUG_ON(orig_byte_offset != 0); 509out:
573 rc = ecryptfs_write_out_page(ctx, lower_page, lower_inode, 0, 510 kfree(enc_extent_virt);
574 (lower_byte_offset 511 return rc;
575 + crypt_stat->extent_size)); 512}
513
514static int ecryptfs_decrypt_extent(struct page *page,
515 struct ecryptfs_crypt_stat *crypt_stat,
516 struct page *enc_extent_page,
517 unsigned long extent_offset)
518{
519 loff_t extent_base;
520 char extent_iv[ECRYPTFS_MAX_IV_BYTES];
521 int rc;
522
523 extent_base = (((loff_t)page->index)
524 * (PAGE_CACHE_SIZE / crypt_stat->extent_size));
525 rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
526 (extent_base + extent_offset));
576 if (rc) { 527 if (rc) {
577 ecryptfs_printk(KERN_ERR, "Error attempting to write out " 528 ecryptfs_printk(KERN_ERR, "Error attempting to "
578 "page; rc = [%d]\n", rc); 529 "derive IV for extent [0x%.16x]; "
579 goto out; 530 "rc = [%d]\n", (extent_base + extent_offset),
531 rc);
532 goto out;
533 }
534 if (unlikely(ecryptfs_verbosity > 0)) {
535 ecryptfs_printk(KERN_DEBUG, "Decrypting extent "
536 "with iv:\n");
537 ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes);
538 ecryptfs_printk(KERN_DEBUG, "First 8 bytes before "
539 "decryption:\n");
540 ecryptfs_dump_hex((char *)
541 (page_address(enc_extent_page)
542 + (extent_offset * crypt_stat->extent_size)),
543 8);
544 }
545 rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
546 (extent_offset
547 * crypt_stat->extent_size),
548 enc_extent_page, 0,
549 crypt_stat->extent_size, extent_iv);
550 if (rc < 0) {
551 printk(KERN_ERR "%s: Error attempting to decrypt to page with "
552 "page->index = [%ld], extent_offset = [%ld]; "
553 "rc = [%d]\n", __FUNCTION__, page->index, extent_offset,
554 rc);
555 goto out;
556 }
557 rc = 0;
558 if (unlikely(ecryptfs_verbosity > 0)) {
559 ecryptfs_printk(KERN_DEBUG, "Decrypt extent [0x%.16x]; "
560 "rc = [%d]\n", (extent_base + extent_offset),
561 rc);
562 ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
563 "decryption:\n");
564 ecryptfs_dump_hex((char *)(page_address(page)
565 + (extent_offset
566 * crypt_stat->extent_size)), 8);
580 } 567 }
581out: 568out:
582 return rc; 569 return rc;
@@ -584,8 +571,9 @@ out:
584 571
585/** 572/**
586 * ecryptfs_decrypt_page 573 * ecryptfs_decrypt_page
587 * @file: The ecryptfs file 574 * @page: Page mapped from the eCryptfs inode for the file; data read
588 * @page: The page in ecryptfs to decrypt 575 * and decrypted from the lower file will be written into this
576 * page
589 * 577 *
590 * Decrypt an eCryptfs page. This is done on a per-extent basis. Note 578 * Decrypt an eCryptfs page. This is done on a per-extent basis. Note
591 * that eCryptfs pages may straddle the lower pages -- for instance, 579 * that eCryptfs pages may straddle the lower pages -- for instance,
@@ -597,108 +585,75 @@ out:
597 * 585 *
598 * Returns zero on success; negative on error 586 * Returns zero on success; negative on error
599 */ 587 */
600int ecryptfs_decrypt_page(struct file *file, struct page *page) 588int ecryptfs_decrypt_page(struct page *page)
601{ 589{
602 char extent_iv[ECRYPTFS_MAX_IV_BYTES]; 590 struct inode *ecryptfs_inode;
603 unsigned long base_extent;
604 unsigned long extent_offset = 0;
605 unsigned long lower_page_idx = 0;
606 unsigned long prior_lower_page_idx = 0;
607 struct page *lower_page;
608 char *lower_page_virt = NULL;
609 struct inode *lower_inode;
610 struct ecryptfs_crypt_stat *crypt_stat; 591 struct ecryptfs_crypt_stat *crypt_stat;
592 char *enc_extent_virt = NULL;
593 struct page *enc_extent_page;
594 unsigned long extent_offset;
611 int rc = 0; 595 int rc = 0;
612 int byte_offset;
613 int num_extents_per_page;
614 int page_state;
615 596
616 crypt_stat = &(ecryptfs_inode_to_private( 597 ecryptfs_inode = page->mapping->host;
617 page->mapping->host)->crypt_stat); 598 crypt_stat =
618 lower_inode = ecryptfs_inode_to_lower(page->mapping->host); 599 &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
619 if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { 600 if (!(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
620 rc = ecryptfs_do_readpage(file, page, page->index); 601 rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
602 PAGE_CACHE_SIZE,
603 ecryptfs_inode);
621 if (rc) 604 if (rc)
622 ecryptfs_printk(KERN_ERR, "Error attempting to copy " 605 printk(KERN_ERR "%s: Error attempting to copy "
623 "page at index [0x%.16x]\n", 606 "page at index [%ld]\n", __FUNCTION__,
624 page->index); 607 page->index);
625 goto out; 608 goto out;
626 } 609 }
627 num_extents_per_page = PAGE_CACHE_SIZE / crypt_stat->extent_size; 610 enc_extent_virt = kmalloc(PAGE_CACHE_SIZE, GFP_USER);
628 base_extent = (page->index * num_extents_per_page); 611 if (!enc_extent_virt) {
629 lower_page_virt = kmem_cache_alloc(ecryptfs_lower_page_cache,
630 GFP_KERNEL);
631 if (!lower_page_virt) {
632 rc = -ENOMEM; 612 rc = -ENOMEM;
633 ecryptfs_printk(KERN_ERR, "Error getting page for encrypted " 613 ecryptfs_printk(KERN_ERR, "Error allocating memory for "
634 "lower page(s)\n"); 614 "encrypted extent\n");
635 goto out; 615 goto out;
636 } 616 }
637 lower_page = virt_to_page(lower_page_virt); 617 enc_extent_page = virt_to_page(enc_extent_virt);
638 page_state = ECRYPTFS_PAGE_STATE_UNREAD; 618 for (extent_offset = 0;
639 while (extent_offset < num_extents_per_page) { 619 extent_offset < (PAGE_CACHE_SIZE / crypt_stat->extent_size);
640 ecryptfs_extent_to_lwr_pg_idx_and_offset( 620 extent_offset++) {
641 &lower_page_idx, &byte_offset, crypt_stat, 621 loff_t offset;
642 (base_extent + extent_offset)); 622
643 if (prior_lower_page_idx != lower_page_idx 623 ecryptfs_lower_offset_for_extent(
644 || page_state == ECRYPTFS_PAGE_STATE_UNREAD) { 624 &offset, ((page->index * (PAGE_CACHE_SIZE
645 rc = ecryptfs_do_readpage(file, lower_page, 625 / crypt_stat->extent_size))
646 lower_page_idx); 626 + extent_offset), crypt_stat);
647 if (rc) { 627 rc = ecryptfs_read_lower(enc_extent_virt, offset,
648 ecryptfs_printk(KERN_ERR, "Error reading " 628 crypt_stat->extent_size,
649 "lower encrypted page; rc = " 629 ecryptfs_inode);
650 "[%d]\n", rc);
651 goto out;
652 }
653 prior_lower_page_idx = lower_page_idx;
654 page_state = ECRYPTFS_PAGE_STATE_READ;
655 }
656 rc = ecryptfs_derive_iv(extent_iv, crypt_stat,
657 (base_extent + extent_offset));
658 if (rc) { 630 if (rc) {
659 ecryptfs_printk(KERN_ERR, "Error attempting to " 631 ecryptfs_printk(KERN_ERR, "Error attempting "
660 "derive IV for extent [0x%.16x]; rc = " 632 "to read lower page; rc = [%d]"
661 "[%d]\n", 633 "\n", rc);
662 (base_extent + extent_offset), rc);
663 goto out; 634 goto out;
664 } 635 }
665 if (unlikely(ecryptfs_verbosity > 0)) { 636 rc = ecryptfs_decrypt_extent(page, crypt_stat, enc_extent_page,
666 ecryptfs_printk(KERN_DEBUG, "Decrypting extent " 637 extent_offset);
667 "with iv:\n"); 638 if (rc) {
668 ecryptfs_dump_hex(extent_iv, crypt_stat->iv_bytes); 639 printk(KERN_ERR "%s: Error encrypting extent; "
669 ecryptfs_printk(KERN_DEBUG, "First 8 bytes before " 640 "rc = [%d]\n", __FUNCTION__, rc);
670 "decryption:\n");
671 ecryptfs_dump_hex((lower_page_virt + byte_offset), 8);
672 }
673 rc = ecryptfs_decrypt_page_offset(crypt_stat, page,
674 (extent_offset
675 * crypt_stat->extent_size),
676 lower_page, byte_offset,
677 crypt_stat->extent_size,
678 extent_iv);
679 if (rc != crypt_stat->extent_size) {
680 ecryptfs_printk(KERN_ERR, "Error attempting to "
681 "decrypt extent [0x%.16x]\n",
682 (base_extent + extent_offset));
683 goto out; 641 goto out;
684 } 642 }
685 rc = 0;
686 if (unlikely(ecryptfs_verbosity > 0)) {
687 ecryptfs_printk(KERN_DEBUG, "First 8 bytes after "
688 "decryption:\n");
689 ecryptfs_dump_hex((char *)(page_address(page)
690 + byte_offset), 8);
691 }
692 extent_offset++; 643 extent_offset++;
693 } 644 }
694out: 645out:
695 if (lower_page_virt) 646 kfree(enc_extent_virt);
696 kmem_cache_free(ecryptfs_lower_page_cache, lower_page_virt);
697 return rc; 647 return rc;
698} 648}
699 649
700/** 650/**
701 * decrypt_scatterlist 651 * decrypt_scatterlist
652 * @crypt_stat: Cryptographic context
653 * @dest_sg: The destination scatterlist to decrypt into
654 * @src_sg: The source scatterlist to decrypt from
655 * @size: The number of bytes to decrypt
656 * @iv: The initialization vector to use for the decryption
702 * 657 *
703 * Returns the number of bytes decrypted; negative value on error 658 * Returns the number of bytes decrypted; negative value on error
704 */ 659 */
@@ -740,6 +695,13 @@ out:
740 695
741/** 696/**
742 * ecryptfs_encrypt_page_offset 697 * ecryptfs_encrypt_page_offset
698 * @crypt_stat: The cryptographic context
699 * @dst_page: The page to encrypt into
700 * @dst_offset: The offset in the page to encrypt into
701 * @src_page: The page to encrypt from
702 * @src_offset: The offset in the page to encrypt from
703 * @size: The number of bytes to encrypt
704 * @iv: The initialization vector to use for the encryption
743 * 705 *
744 * Returns the number of bytes encrypted 706 * Returns the number of bytes encrypted
745 */ 707 */
@@ -762,6 +724,13 @@ ecryptfs_encrypt_page_offset(struct ecryptfs_crypt_stat *crypt_stat,
762 724
763/** 725/**
764 * ecryptfs_decrypt_page_offset 726 * ecryptfs_decrypt_page_offset
727 * @crypt_stat: The cryptographic context
728 * @dst_page: The page to decrypt into
729 * @dst_offset: The offset in the page to decrypt into
730 * @src_page: The page to decrypt from
731 * @src_offset: The offset in the page to decrypt from
732 * @size: The number of bytes to decrypt
733 * @iv: The initialization vector to use for the decryption
765 * 734 *
766 * Returns the number of bytes decrypted 735 * Returns the number of bytes decrypted
767 */ 736 */
@@ -857,15 +826,17 @@ void ecryptfs_set_default_sizes(struct ecryptfs_crypt_stat *crypt_stat)
857 crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE; 826 crypt_stat->extent_size = ECRYPTFS_DEFAULT_EXTENT_SIZE;
858 set_extent_mask_and_shift(crypt_stat); 827 set_extent_mask_and_shift(crypt_stat);
859 crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES; 828 crypt_stat->iv_bytes = ECRYPTFS_DEFAULT_IV_BYTES;
860 if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE) {
861 crypt_stat->header_extent_size =
862 ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE;
863 } else
864 crypt_stat->header_extent_size = PAGE_CACHE_SIZE;
865 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) 829 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
866 crypt_stat->num_header_extents_at_front = 0; 830 crypt_stat->num_header_extents_at_front = 0;
867 else 831 else {
868 crypt_stat->num_header_extents_at_front = 1; 832 if (PAGE_CACHE_SIZE <= ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)
833 crypt_stat->num_header_extents_at_front =
834 (ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE
835 / crypt_stat->extent_size);
836 else
837 crypt_stat->num_header_extents_at_front =
838 (PAGE_CACHE_SIZE / crypt_stat->extent_size);
839 }
869} 840}
870 841
871/** 842/**
@@ -917,6 +888,8 @@ static void ecryptfs_generate_new_key(struct ecryptfs_crypt_stat *crypt_stat)
917 888
918/** 889/**
919 * ecryptfs_copy_mount_wide_flags_to_inode_flags 890 * ecryptfs_copy_mount_wide_flags_to_inode_flags
891 * @crypt_stat: The inode's cryptographic context
892 * @mount_crypt_stat: The mount point's cryptographic context
920 * 893 *
921 * This function propagates the mount-wide flags to individual inode 894 * This function propagates the mount-wide flags to individual inode
922 * flags. 895 * flags.
@@ -931,9 +904,34 @@ static void ecryptfs_copy_mount_wide_flags_to_inode_flags(
931 crypt_stat->flags |= ECRYPTFS_VIEW_AS_ENCRYPTED; 904 crypt_stat->flags |= ECRYPTFS_VIEW_AS_ENCRYPTED;
932} 905}
933 906
907static int ecryptfs_copy_mount_wide_sigs_to_inode_sigs(
908 struct ecryptfs_crypt_stat *crypt_stat,
909 struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
910{
911 struct ecryptfs_global_auth_tok *global_auth_tok;
912 int rc = 0;
913
914 mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
915 list_for_each_entry(global_auth_tok,
916 &mount_crypt_stat->global_auth_tok_list,
917 mount_crypt_stat_list) {
918 rc = ecryptfs_add_keysig(crypt_stat, global_auth_tok->sig);
919 if (rc) {
920 printk(KERN_ERR "Error adding keysig; rc = [%d]\n", rc);
921 mutex_unlock(
922 &mount_crypt_stat->global_auth_tok_list_mutex);
923 goto out;
924 }
925 }
926 mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
927out:
928 return rc;
929}
930
934/** 931/**
935 * ecryptfs_set_default_crypt_stat_vals 932 * ecryptfs_set_default_crypt_stat_vals
936 * @crypt_stat 933 * @crypt_stat: The inode's cryptographic context
934 * @mount_crypt_stat: The mount point's cryptographic context
937 * 935 *
938 * Default values in the event that policy does not override them. 936 * Default values in the event that policy does not override them.
939 */ 937 */
@@ -953,7 +951,7 @@ static void ecryptfs_set_default_crypt_stat_vals(
953 951
954/** 952/**
955 * ecryptfs_new_file_context 953 * ecryptfs_new_file_context
956 * @ecryptfs_dentry 954 * @ecryptfs_dentry: The eCryptfs dentry
957 * 955 *
958 * If the crypto context for the file has not yet been established, 956 * If the crypto context for the file has not yet been established,
959 * this is where we do that. Establishing a new crypto context 957 * this is where we do that. Establishing a new crypto context
@@ -970,49 +968,42 @@ static void ecryptfs_set_default_crypt_stat_vals(
970 * 968 *
971 * Returns zero on success; non-zero otherwise 969 * Returns zero on success; non-zero otherwise
972 */ 970 */
973/* Associate an authentication token(s) with the file */
974int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry) 971int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry)
975{ 972{
976 int rc = 0;
977 struct ecryptfs_crypt_stat *crypt_stat = 973 struct ecryptfs_crypt_stat *crypt_stat =
978 &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; 974 &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
979 struct ecryptfs_mount_crypt_stat *mount_crypt_stat = 975 struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
980 &ecryptfs_superblock_to_private( 976 &ecryptfs_superblock_to_private(
981 ecryptfs_dentry->d_sb)->mount_crypt_stat; 977 ecryptfs_dentry->d_sb)->mount_crypt_stat;
982 int cipher_name_len; 978 int cipher_name_len;
979 int rc = 0;
983 980
984 ecryptfs_set_default_crypt_stat_vals(crypt_stat, mount_crypt_stat); 981 ecryptfs_set_default_crypt_stat_vals(crypt_stat, mount_crypt_stat);
985 /* See if there are mount crypt options */ 982 crypt_stat->flags |= (ECRYPTFS_ENCRYPTED | ECRYPTFS_KEY_VALID);
986 if (mount_crypt_stat->global_auth_tok) { 983 ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat,
987 ecryptfs_printk(KERN_DEBUG, "Initializing context for new " 984 mount_crypt_stat);
988 "file using mount_crypt_stat\n"); 985 rc = ecryptfs_copy_mount_wide_sigs_to_inode_sigs(crypt_stat,
989 crypt_stat->flags |= ECRYPTFS_ENCRYPTED; 986 mount_crypt_stat);
990 crypt_stat->flags |= ECRYPTFS_KEY_VALID; 987 if (rc) {
991 ecryptfs_copy_mount_wide_flags_to_inode_flags(crypt_stat, 988 printk(KERN_ERR "Error attempting to copy mount-wide key sigs "
992 mount_crypt_stat); 989 "to the inode key sigs; rc = [%d]\n", rc);
993 memcpy(crypt_stat->keysigs[crypt_stat->num_keysigs++], 990 goto out;
994 mount_crypt_stat->global_auth_tok_sig, 991 }
995 ECRYPTFS_SIG_SIZE_HEX); 992 cipher_name_len =
996 cipher_name_len = 993 strlen(mount_crypt_stat->global_default_cipher_name);
997 strlen(mount_crypt_stat->global_default_cipher_name); 994 memcpy(crypt_stat->cipher,
998 memcpy(crypt_stat->cipher, 995 mount_crypt_stat->global_default_cipher_name,
999 mount_crypt_stat->global_default_cipher_name, 996 cipher_name_len);
1000 cipher_name_len); 997 crypt_stat->cipher[cipher_name_len] = '\0';
1001 crypt_stat->cipher[cipher_name_len] = '\0'; 998 crypt_stat->key_size =
1002 crypt_stat->key_size = 999 mount_crypt_stat->global_default_cipher_key_size;
1003 mount_crypt_stat->global_default_cipher_key_size; 1000 ecryptfs_generate_new_key(crypt_stat);
1004 ecryptfs_generate_new_key(crypt_stat);
1005 } else
1006 /* We should not encounter this scenario since we
1007 * should detect lack of global_auth_tok at mount time
1008 * TODO: Applies to 0.1 release only; remove in future
1009 * release */
1010 BUG();
1011 rc = ecryptfs_init_crypt_ctx(crypt_stat); 1001 rc = ecryptfs_init_crypt_ctx(crypt_stat);
1012 if (rc) 1002 if (rc)
1013 ecryptfs_printk(KERN_ERR, "Error initializing cryptographic " 1003 ecryptfs_printk(KERN_ERR, "Error initializing cryptographic "
1014 "context for cipher [%s]: rc = [%d]\n", 1004 "context for cipher [%s]: rc = [%d]\n",
1015 crypt_stat->cipher, rc); 1005 crypt_stat->cipher, rc);
1006out:
1016 return rc; 1007 return rc;
1017} 1008}
1018 1009
@@ -1054,7 +1045,7 @@ static struct ecryptfs_flag_map_elem ecryptfs_flag_map[] = {
1054 1045
1055/** 1046/**
1056 * ecryptfs_process_flags 1047 * ecryptfs_process_flags
1057 * @crypt_stat 1048 * @crypt_stat: The cryptographic context
1058 * @page_virt: Source data to be parsed 1049 * @page_virt: Source data to be parsed
1059 * @bytes_read: Updated with the number of bytes read 1050 * @bytes_read: Updated with the number of bytes read
1060 * 1051 *
@@ -1142,7 +1133,7 @@ ecryptfs_cipher_code_str_map[] = {
1142 1133
1143/** 1134/**
1144 * ecryptfs_code_for_cipher_string 1135 * ecryptfs_code_for_cipher_string
1145 * @str: The string representing the cipher name 1136 * @crypt_stat: The cryptographic context
1146 * 1137 *
1147 * Returns zero on no match, or the cipher code on match 1138 * Returns zero on no match, or the cipher code on match
1148 */ 1139 */
@@ -1198,59 +1189,28 @@ int ecryptfs_cipher_code_to_string(char *str, u16 cipher_code)
1198 return rc; 1189 return rc;
1199} 1190}
1200 1191
1201/** 1192int ecryptfs_read_and_validate_header_region(char *data,
1202 * ecryptfs_read_header_region 1193 struct inode *ecryptfs_inode)
1203 * @data
1204 * @dentry
1205 * @nd
1206 *
1207 * Returns zero on success; non-zero otherwise
1208 */
1209static int ecryptfs_read_header_region(char *data, struct dentry *dentry,
1210 struct vfsmount *mnt)
1211{ 1194{
1212 struct file *lower_file; 1195 struct ecryptfs_crypt_stat *crypt_stat =
1213 mm_segment_t oldfs; 1196 &(ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat);
1214 int rc; 1197 int rc;
1215 1198
1216 if ((rc = ecryptfs_open_lower_file(&lower_file, dentry, mnt, 1199 rc = ecryptfs_read_lower(data, 0, crypt_stat->extent_size,
1217 O_RDONLY))) { 1200 ecryptfs_inode);
1218 printk(KERN_ERR 1201 if (rc) {
1219 "Error opening lower_file to read header region\n"); 1202 printk(KERN_ERR "%s: Error reading header region; rc = [%d]\n",
1220 goto out; 1203 __FUNCTION__, rc);
1221 }
1222 lower_file->f_pos = 0;
1223 oldfs = get_fs();
1224 set_fs(get_ds());
1225 /* For releases 0.1 and 0.2, all of the header information
1226 * fits in the first data extent-sized region. */
1227 rc = lower_file->f_op->read(lower_file, (char __user *)data,
1228 ECRYPTFS_DEFAULT_EXTENT_SIZE, &lower_file->f_pos);
1229 set_fs(oldfs);
1230 if ((rc = ecryptfs_close_lower_file(lower_file))) {
1231 printk(KERN_ERR "Error closing lower_file\n");
1232 goto out; 1204 goto out;
1233 } 1205 }
1234 rc = 0; 1206 if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES)) {
1235out:
1236 return rc;
1237}
1238
1239int ecryptfs_read_and_validate_header_region(char *data, struct dentry *dentry,
1240 struct vfsmount *mnt)
1241{
1242 int rc;
1243
1244 rc = ecryptfs_read_header_region(data, dentry, mnt);
1245 if (rc)
1246 goto out;
1247 if (!contains_ecryptfs_marker(data + ECRYPTFS_FILE_SIZE_BYTES))
1248 rc = -EINVAL; 1207 rc = -EINVAL;
1208 ecryptfs_printk(KERN_DEBUG, "Valid marker not found\n");
1209 }
1249out: 1210out:
1250 return rc; 1211 return rc;
1251} 1212}
1252 1213
1253
1254void 1214void
1255ecryptfs_write_header_metadata(char *virt, 1215ecryptfs_write_header_metadata(char *virt,
1256 struct ecryptfs_crypt_stat *crypt_stat, 1216 struct ecryptfs_crypt_stat *crypt_stat,
@@ -1259,7 +1219,7 @@ ecryptfs_write_header_metadata(char *virt,
1259 u32 header_extent_size; 1219 u32 header_extent_size;
1260 u16 num_header_extents_at_front; 1220 u16 num_header_extents_at_front;
1261 1221
1262 header_extent_size = (u32)crypt_stat->header_extent_size; 1222 header_extent_size = (u32)crypt_stat->extent_size;
1263 num_header_extents_at_front = 1223 num_header_extents_at_front =
1264 (u16)crypt_stat->num_header_extents_at_front; 1224 (u16)crypt_stat->num_header_extents_at_front;
1265 header_extent_size = cpu_to_be32(header_extent_size); 1225 header_extent_size = cpu_to_be32(header_extent_size);
@@ -1276,9 +1236,10 @@ struct kmem_cache *ecryptfs_header_cache_2;
1276 1236
1277/** 1237/**
1278 * ecryptfs_write_headers_virt 1238 * ecryptfs_write_headers_virt
1279 * @page_virt 1239 * @page_virt: The virtual address to write the headers to
1280 * @crypt_stat 1240 * @size: Set to the number of bytes written by this function
1281 * @ecryptfs_dentry 1241 * @crypt_stat: The cryptographic context
1242 * @ecryptfs_dentry: The eCryptfs dentry
1282 * 1243 *
1283 * Format version: 1 1244 * Format version: 1
1284 * 1245 *
@@ -1332,53 +1293,50 @@ static int ecryptfs_write_headers_virt(char *page_virt, size_t *size,
1332 return rc; 1293 return rc;
1333} 1294}
1334 1295
1335static int ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat, 1296static int
1336 struct file *lower_file, 1297ecryptfs_write_metadata_to_contents(struct ecryptfs_crypt_stat *crypt_stat,
1337 char *page_virt) 1298 struct dentry *ecryptfs_dentry,
1299 char *page_virt)
1338{ 1300{
1339 mm_segment_t oldfs;
1340 int current_header_page; 1301 int current_header_page;
1341 int header_pages; 1302 int header_pages;
1342 ssize_t size; 1303 int rc;
1343 int rc = 0;
1344 1304
1345 lower_file->f_pos = 0; 1305 rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode, page_virt,
1346 oldfs = get_fs(); 1306 0, PAGE_CACHE_SIZE);
1347 set_fs(get_ds()); 1307 if (rc) {
1348 size = vfs_write(lower_file, (char __user *)page_virt, PAGE_CACHE_SIZE, 1308 printk(KERN_ERR "%s: Error attempting to write header "
1349 &lower_file->f_pos); 1309 "information to lower file; rc = [%d]\n", __FUNCTION__,
1350 if (size < 0) { 1310 rc);
1351 rc = (int)size;
1352 printk(KERN_ERR "Error attempting to write lower page; "
1353 "rc = [%d]\n", rc);
1354 set_fs(oldfs);
1355 goto out; 1311 goto out;
1356 } 1312 }
1357 header_pages = ((crypt_stat->header_extent_size 1313 header_pages = ((crypt_stat->extent_size
1358 * crypt_stat->num_header_extents_at_front) 1314 * crypt_stat->num_header_extents_at_front)
1359 / PAGE_CACHE_SIZE); 1315 / PAGE_CACHE_SIZE);
1360 memset(page_virt, 0, PAGE_CACHE_SIZE); 1316 memset(page_virt, 0, PAGE_CACHE_SIZE);
1361 current_header_page = 1; 1317 current_header_page = 1;
1362 while (current_header_page < header_pages) { 1318 while (current_header_page < header_pages) {
1363 size = vfs_write(lower_file, (char __user *)page_virt, 1319 loff_t offset;
1364 PAGE_CACHE_SIZE, &lower_file->f_pos); 1320
1365 if (size < 0) { 1321 offset = (((loff_t)current_header_page) << PAGE_CACHE_SHIFT);
1366 rc = (int)size; 1322 if ((rc = ecryptfs_write_lower(ecryptfs_dentry->d_inode,
1367 printk(KERN_ERR "Error attempting to write lower page; " 1323 page_virt, offset,
1368 "rc = [%d]\n", rc); 1324 PAGE_CACHE_SIZE))) {
1369 set_fs(oldfs); 1325 printk(KERN_ERR "%s: Error attempting to write header "
1326 "information to lower file; rc = [%d]\n",
1327 __FUNCTION__, rc);
1370 goto out; 1328 goto out;
1371 } 1329 }
1372 current_header_page++; 1330 current_header_page++;
1373 } 1331 }
1374 set_fs(oldfs);
1375out: 1332out:
1376 return rc; 1333 return rc;
1377} 1334}
1378 1335
1379static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry, 1336static int
1380 struct ecryptfs_crypt_stat *crypt_stat, 1337ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
1381 char *page_virt, size_t size) 1338 struct ecryptfs_crypt_stat *crypt_stat,
1339 char *page_virt, size_t size)
1382{ 1340{
1383 int rc; 1341 int rc;
1384 1342
@@ -1389,7 +1347,7 @@ static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
1389 1347
1390/** 1348/**
1391 * ecryptfs_write_metadata 1349 * ecryptfs_write_metadata
1392 * @lower_file: The lower file struct, which was returned from dentry_open 1350 * @ecryptfs_dentry: The eCryptfs dentry
1393 * 1351 *
1394 * Write the file headers out. This will likely involve a userspace 1352 * Write the file headers out. This will likely involve a userspace
1395 * callout, in which the session key is encrypted with one or more 1353 * callout, in which the session key is encrypted with one or more
@@ -1397,22 +1355,21 @@ static int ecryptfs_write_metadata_to_xattr(struct dentry *ecryptfs_dentry,
1397 * retrieved via a prompt. Exactly what happens at this point should 1355 * retrieved via a prompt. Exactly what happens at this point should
1398 * be policy-dependent. 1356 * be policy-dependent.
1399 * 1357 *
1358 * TODO: Support header information spanning multiple pages
1359 *
1400 * Returns zero on success; non-zero on error 1360 * Returns zero on success; non-zero on error
1401 */ 1361 */
1402int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry, 1362int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry)
1403 struct file *lower_file)
1404{ 1363{
1405 struct ecryptfs_crypt_stat *crypt_stat; 1364 struct ecryptfs_crypt_stat *crypt_stat =
1365 &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
1406 char *page_virt; 1366 char *page_virt;
1407 size_t size; 1367 size_t size = 0;
1408 int rc = 0; 1368 int rc = 0;
1409 1369
1410 crypt_stat = &ecryptfs_inode_to_private(
1411 ecryptfs_dentry->d_inode)->crypt_stat;
1412 if (likely(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) { 1370 if (likely(crypt_stat->flags & ECRYPTFS_ENCRYPTED)) {
1413 if (!(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { 1371 if (!(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
1414 ecryptfs_printk(KERN_DEBUG, "Key is " 1372 printk(KERN_ERR "Key is invalid; bailing out\n");
1415 "invalid; bailing out\n");
1416 rc = -EINVAL; 1373 rc = -EINVAL;
1417 goto out; 1374 goto out;
1418 } 1375 }
@@ -1441,7 +1398,8 @@ int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
1441 crypt_stat, page_virt, 1398 crypt_stat, page_virt,
1442 size); 1399 size);
1443 else 1400 else
1444 rc = ecryptfs_write_metadata_to_contents(crypt_stat, lower_file, 1401 rc = ecryptfs_write_metadata_to_contents(crypt_stat,
1402 ecryptfs_dentry,
1445 page_virt); 1403 page_virt);
1446 if (rc) { 1404 if (rc) {
1447 printk(KERN_ERR "Error writing metadata out to lower file; " 1405 printk(KERN_ERR "Error writing metadata out to lower file; "
@@ -1464,28 +1422,28 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
1464 u32 header_extent_size; 1422 u32 header_extent_size;
1465 u16 num_header_extents_at_front; 1423 u16 num_header_extents_at_front;
1466 1424
1467 memcpy(&header_extent_size, virt, 4); 1425 memcpy(&header_extent_size, virt, sizeof(u32));
1468 header_extent_size = be32_to_cpu(header_extent_size); 1426 header_extent_size = be32_to_cpu(header_extent_size);
1469 virt += 4; 1427 virt += sizeof(u32);
1470 memcpy(&num_header_extents_at_front, virt, 2); 1428 memcpy(&num_header_extents_at_front, virt, sizeof(u16));
1471 num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front); 1429 num_header_extents_at_front = be16_to_cpu(num_header_extents_at_front);
1472 crypt_stat->header_extent_size = (int)header_extent_size;
1473 crypt_stat->num_header_extents_at_front = 1430 crypt_stat->num_header_extents_at_front =
1474 (int)num_header_extents_at_front; 1431 (int)num_header_extents_at_front;
1475 (*bytes_read) = 6; 1432 (*bytes_read) = (sizeof(u32) + sizeof(u16));
1476 if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE) 1433 if ((validate_header_size == ECRYPTFS_VALIDATE_HEADER_SIZE)
1477 && ((crypt_stat->header_extent_size 1434 && ((crypt_stat->extent_size
1478 * crypt_stat->num_header_extents_at_front) 1435 * crypt_stat->num_header_extents_at_front)
1479 < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) { 1436 < ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE)) {
1480 rc = -EINVAL; 1437 rc = -EINVAL;
1481 ecryptfs_printk(KERN_WARNING, "Invalid header extent size: " 1438 printk(KERN_WARNING "Invalid number of header extents: [%zd]\n",
1482 "[%d]\n", crypt_stat->header_extent_size); 1439 crypt_stat->num_header_extents_at_front);
1483 } 1440 }
1484 return rc; 1441 return rc;
1485} 1442}
1486 1443
1487/** 1444/**
1488 * set_default_header_data 1445 * set_default_header_data
1446 * @crypt_stat: The cryptographic context
1489 * 1447 *
1490 * For version 0 file format; this function is only for backwards 1448 * For version 0 file format; this function is only for backwards
1491 * compatibility for files created with the prior versions of 1449 * compatibility for files created with the prior versions of
@@ -1493,12 +1451,15 @@ static int parse_header_metadata(struct ecryptfs_crypt_stat *crypt_stat,
1493 */ 1451 */
1494static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat) 1452static void set_default_header_data(struct ecryptfs_crypt_stat *crypt_stat)
1495{ 1453{
1496 crypt_stat->header_extent_size = 4096; 1454 crypt_stat->num_header_extents_at_front = 2;
1497 crypt_stat->num_header_extents_at_front = 1;
1498} 1455}
1499 1456
1500/** 1457/**
1501 * ecryptfs_read_headers_virt 1458 * ecryptfs_read_headers_virt
1459 * @page_virt: The virtual address into which to read the headers
1460 * @crypt_stat: The cryptographic context
1461 * @ecryptfs_dentry: The eCryptfs dentry
1462 * @validate_header_size: Whether to validate the header size while reading
1502 * 1463 *
1503 * Read/parse the header data. The header format is detailed in the 1464 * Read/parse the header data. The header format is detailed in the
1504 * comment block for the ecryptfs_write_headers_virt() function. 1465 * comment block for the ecryptfs_write_headers_virt() function.
@@ -1558,19 +1519,25 @@ out:
1558 1519
1559/** 1520/**
1560 * ecryptfs_read_xattr_region 1521 * ecryptfs_read_xattr_region
1522 * @page_virt: The vitual address into which to read the xattr data
1523 * @ecryptfs_inode: The eCryptfs inode
1561 * 1524 *
1562 * Attempts to read the crypto metadata from the extended attribute 1525 * Attempts to read the crypto metadata from the extended attribute
1563 * region of the lower file. 1526 * region of the lower file.
1527 *
1528 * Returns zero on success; non-zero on error
1564 */ 1529 */
1565int ecryptfs_read_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry) 1530int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode)
1566{ 1531{
1532 struct dentry *lower_dentry =
1533 ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry;
1567 ssize_t size; 1534 ssize_t size;
1568 int rc = 0; 1535 int rc = 0;
1569 1536
1570 size = ecryptfs_getxattr(ecryptfs_dentry, ECRYPTFS_XATTR_NAME, 1537 size = ecryptfs_getxattr_lower(lower_dentry, ECRYPTFS_XATTR_NAME,
1571 page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE); 1538 page_virt, ECRYPTFS_DEFAULT_EXTENT_SIZE);
1572 if (size < 0) { 1539 if (size < 0) {
1573 printk(KERN_DEBUG "Error attempting to read the [%s] " 1540 printk(KERN_ERR "Error attempting to read the [%s] "
1574 "xattr from the lower file; return value = [%zd]\n", 1541 "xattr from the lower file; return value = [%zd]\n",
1575 ECRYPTFS_XATTR_NAME, size); 1542 ECRYPTFS_XATTR_NAME, size);
1576 rc = -EINVAL; 1543 rc = -EINVAL;
@@ -1585,7 +1552,7 @@ int ecryptfs_read_and_validate_xattr_region(char *page_virt,
1585{ 1552{
1586 int rc; 1553 int rc;
1587 1554
1588 rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_dentry); 1555 rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_dentry->d_inode);
1589 if (rc) 1556 if (rc)
1590 goto out; 1557 goto out;
1591 if (!contains_ecryptfs_marker(page_virt + ECRYPTFS_FILE_SIZE_BYTES)) { 1558 if (!contains_ecryptfs_marker(page_virt + ECRYPTFS_FILE_SIZE_BYTES)) {
@@ -1609,15 +1576,13 @@ out:
1609 * 1576 *
1610 * Returns zero if valid headers found and parsed; non-zero otherwise 1577 * Returns zero if valid headers found and parsed; non-zero otherwise
1611 */ 1578 */
1612int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry, 1579int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry)
1613 struct file *lower_file)
1614{ 1580{
1615 int rc = 0; 1581 int rc = 0;
1616 char *page_virt = NULL; 1582 char *page_virt = NULL;
1617 mm_segment_t oldfs; 1583 struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode;
1618 ssize_t bytes_read;
1619 struct ecryptfs_crypt_stat *crypt_stat = 1584 struct ecryptfs_crypt_stat *crypt_stat =
1620 &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat; 1585 &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
1621 struct ecryptfs_mount_crypt_stat *mount_crypt_stat = 1586 struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
1622 &ecryptfs_superblock_to_private( 1587 &ecryptfs_superblock_to_private(
1623 ecryptfs_dentry->d_sb)->mount_crypt_stat; 1588 ecryptfs_dentry->d_sb)->mount_crypt_stat;
@@ -1628,27 +1593,18 @@ int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry,
1628 page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER); 1593 page_virt = kmem_cache_alloc(ecryptfs_header_cache_1, GFP_USER);
1629 if (!page_virt) { 1594 if (!page_virt) {
1630 rc = -ENOMEM; 1595 rc = -ENOMEM;
1631 ecryptfs_printk(KERN_ERR, "Unable to allocate page_virt\n"); 1596 printk(KERN_ERR "%s: Unable to allocate page_virt\n",
1597 __FUNCTION__);
1632 goto out; 1598 goto out;
1633 } 1599 }
1634 lower_file->f_pos = 0; 1600 rc = ecryptfs_read_lower(page_virt, 0, crypt_stat->extent_size,
1635 oldfs = get_fs(); 1601 ecryptfs_inode);
1636 set_fs(get_ds()); 1602 if (!rc)
1637 bytes_read = lower_file->f_op->read(lower_file, 1603 rc = ecryptfs_read_headers_virt(page_virt, crypt_stat,
1638 (char __user *)page_virt, 1604 ecryptfs_dentry,
1639 ECRYPTFS_DEFAULT_EXTENT_SIZE, 1605 ECRYPTFS_VALIDATE_HEADER_SIZE);
1640 &lower_file->f_pos);
1641 set_fs(oldfs);
1642 if (bytes_read != ECRYPTFS_DEFAULT_EXTENT_SIZE) {
1643 rc = -EINVAL;
1644 goto out;
1645 }
1646 rc = ecryptfs_read_headers_virt(page_virt, crypt_stat,
1647 ecryptfs_dentry,
1648 ECRYPTFS_VALIDATE_HEADER_SIZE);
1649 if (rc) { 1606 if (rc) {
1650 rc = ecryptfs_read_xattr_region(page_virt, 1607 rc = ecryptfs_read_xattr_region(page_virt, ecryptfs_inode);
1651 ecryptfs_dentry);
1652 if (rc) { 1608 if (rc) {
1653 printk(KERN_DEBUG "Valid eCryptfs headers not found in " 1609 printk(KERN_DEBUG "Valid eCryptfs headers not found in "
1654 "file header region or xattr region\n"); 1610 "file header region or xattr region\n");
@@ -1776,7 +1732,7 @@ out:
1776} 1732}
1777 1733
1778/** 1734/**
1779 * ecryptfs_process_cipher - Perform cipher initialization. 1735 * ecryptfs_process_key_cipher - Perform key cipher initialization.
1780 * @key_tfm: Crypto context for key material, set by this function 1736 * @key_tfm: Crypto context for key material, set by this function
1781 * @cipher_name: Name of the cipher 1737 * @cipher_name: Name of the cipher
1782 * @key_size: Size of the key in bytes 1738 * @key_size: Size of the key in bytes
@@ -1785,9 +1741,9 @@ out:
1785 * should be released by other functions, such as on a superblock put 1741 * should be released by other functions, such as on a superblock put
1786 * event, regardless of whether this function succeeds for fails. 1742 * event, regardless of whether this function succeeds for fails.
1787 */ 1743 */
1788int 1744static int
1789ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name, 1745ecryptfs_process_key_cipher(struct crypto_blkcipher **key_tfm,
1790 size_t *key_size) 1746 char *cipher_name, size_t *key_size)
1791{ 1747{
1792 char dummy_key[ECRYPTFS_MAX_KEY_BYTES]; 1748 char dummy_key[ECRYPTFS_MAX_KEY_BYTES];
1793 char *full_alg_name; 1749 char *full_alg_name;
@@ -1829,3 +1785,100 @@ ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
1829out: 1785out:
1830 return rc; 1786 return rc;
1831} 1787}
1788
1789struct kmem_cache *ecryptfs_key_tfm_cache;
1790struct list_head key_tfm_list;
1791struct mutex key_tfm_list_mutex;
1792
1793int ecryptfs_init_crypto(void)
1794{
1795 mutex_init(&key_tfm_list_mutex);
1796 INIT_LIST_HEAD(&key_tfm_list);
1797 return 0;
1798}
1799
1800int ecryptfs_destroy_crypto(void)
1801{
1802 struct ecryptfs_key_tfm *key_tfm, *key_tfm_tmp;
1803
1804 mutex_lock(&key_tfm_list_mutex);
1805 list_for_each_entry_safe(key_tfm, key_tfm_tmp, &key_tfm_list,
1806 key_tfm_list) {
1807 list_del(&key_tfm->key_tfm_list);
1808 if (key_tfm->key_tfm)
1809 crypto_free_blkcipher(key_tfm->key_tfm);
1810 kmem_cache_free(ecryptfs_key_tfm_cache, key_tfm);
1811 }
1812 mutex_unlock(&key_tfm_list_mutex);
1813 return 0;
1814}
1815
1816int
1817ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name,
1818 size_t key_size)
1819{
1820 struct ecryptfs_key_tfm *tmp_tfm;
1821 int rc = 0;
1822
1823 tmp_tfm = kmem_cache_alloc(ecryptfs_key_tfm_cache, GFP_KERNEL);
1824 if (key_tfm != NULL)
1825 (*key_tfm) = tmp_tfm;
1826 if (!tmp_tfm) {
1827 rc = -ENOMEM;
1828 printk(KERN_ERR "Error attempting to allocate from "
1829 "ecryptfs_key_tfm_cache\n");
1830 goto out;
1831 }
1832 mutex_init(&tmp_tfm->key_tfm_mutex);
1833 strncpy(tmp_tfm->cipher_name, cipher_name,
1834 ECRYPTFS_MAX_CIPHER_NAME_SIZE);
1835 tmp_tfm->key_size = key_size;
1836 rc = ecryptfs_process_key_cipher(&tmp_tfm->key_tfm,
1837 tmp_tfm->cipher_name,
1838 &tmp_tfm->key_size);
1839 if (rc) {
1840 printk(KERN_ERR "Error attempting to initialize key TFM "
1841 "cipher with name = [%s]; rc = [%d]\n",
1842 tmp_tfm->cipher_name, rc);
1843 kmem_cache_free(ecryptfs_key_tfm_cache, tmp_tfm);
1844 if (key_tfm != NULL)
1845 (*key_tfm) = NULL;
1846 goto out;
1847 }
1848 mutex_lock(&key_tfm_list_mutex);
1849 list_add(&tmp_tfm->key_tfm_list, &key_tfm_list);
1850 mutex_unlock(&key_tfm_list_mutex);
1851out:
1852 return rc;
1853}
1854
1855int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm,
1856 struct mutex **tfm_mutex,
1857 char *cipher_name)
1858{
1859 struct ecryptfs_key_tfm *key_tfm;
1860 int rc = 0;
1861
1862 (*tfm) = NULL;
1863 (*tfm_mutex) = NULL;
1864 mutex_lock(&key_tfm_list_mutex);
1865 list_for_each_entry(key_tfm, &key_tfm_list, key_tfm_list) {
1866 if (strcmp(key_tfm->cipher_name, cipher_name) == 0) {
1867 (*tfm) = key_tfm->key_tfm;
1868 (*tfm_mutex) = &key_tfm->key_tfm_mutex;
1869 mutex_unlock(&key_tfm_list_mutex);
1870 goto out;
1871 }
1872 }
1873 mutex_unlock(&key_tfm_list_mutex);
1874 rc = ecryptfs_add_new_key_tfm(&key_tfm, cipher_name, 0);
1875 if (rc) {
1876 printk(KERN_ERR "Error adding new key_tfm to list; rc = [%d]\n",
1877 rc);
1878 goto out;
1879 }
1880 (*tfm) = key_tfm->key_tfm;
1881 (*tfm_mutex) = &key_tfm->key_tfm_mutex;
1882out:
1883 return rc;
1884}
diff --git a/fs/ecryptfs/debug.c b/fs/ecryptfs/debug.c
index 434c7efd80f8..3d2bdf546ec6 100644
--- a/fs/ecryptfs/debug.c
+++ b/fs/ecryptfs/debug.c
@@ -38,8 +38,6 @@ void ecryptfs_dump_auth_tok(struct ecryptfs_auth_tok *auth_tok)
38 auth_tok); 38 auth_tok);
39 if (auth_tok->flags & ECRYPTFS_PRIVATE_KEY) { 39 if (auth_tok->flags & ECRYPTFS_PRIVATE_KEY) {
40 ecryptfs_printk(KERN_DEBUG, " * private key type\n"); 40 ecryptfs_printk(KERN_DEBUG, " * private key type\n");
41 ecryptfs_printk(KERN_DEBUG, " * (NO PRIVATE KEY SUPPORT "
42 "IN ECRYPTFS VERSION 0.1)\n");
43 } else { 41 } else {
44 ecryptfs_printk(KERN_DEBUG, " * passphrase type\n"); 42 ecryptfs_printk(KERN_DEBUG, " * passphrase type\n");
45 ecryptfs_to_hex(salt, auth_tok->token.password.salt, 43 ecryptfs_to_hex(salt, auth_tok->token.password.salt,
diff --git a/fs/ecryptfs/ecryptfs_kernel.h b/fs/ecryptfs/ecryptfs_kernel.h
index 1b9dd9a96f19..ce7a5d4aec36 100644
--- a/fs/ecryptfs/ecryptfs_kernel.h
+++ b/fs/ecryptfs/ecryptfs_kernel.h
@@ -38,7 +38,7 @@
38/* Version verification for shared data structures w/ userspace */ 38/* Version verification for shared data structures w/ userspace */
39#define ECRYPTFS_VERSION_MAJOR 0x00 39#define ECRYPTFS_VERSION_MAJOR 0x00
40#define ECRYPTFS_VERSION_MINOR 0x04 40#define ECRYPTFS_VERSION_MINOR 0x04
41#define ECRYPTFS_SUPPORTED_FILE_VERSION 0x02 41#define ECRYPTFS_SUPPORTED_FILE_VERSION 0x03
42/* These flags indicate which features are supported by the kernel 42/* These flags indicate which features are supported by the kernel
43 * module; userspace tools such as the mount helper read 43 * module; userspace tools such as the mount helper read
44 * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine 44 * ECRYPTFS_VERSIONING_MASK from a sysfs handle in order to determine
@@ -48,10 +48,12 @@
48#define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004 48#define ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH 0x00000004
49#define ECRYPTFS_VERSIONING_POLICY 0x00000008 49#define ECRYPTFS_VERSIONING_POLICY 0x00000008
50#define ECRYPTFS_VERSIONING_XATTR 0x00000010 50#define ECRYPTFS_VERSIONING_XATTR 0x00000010
51#define ECRYPTFS_VERSIONING_MULTKEY 0x00000020
51#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \ 52#define ECRYPTFS_VERSIONING_MASK (ECRYPTFS_VERSIONING_PASSPHRASE \
52 | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \ 53 | ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH \
53 | ECRYPTFS_VERSIONING_PUBKEY \ 54 | ECRYPTFS_VERSIONING_PUBKEY \
54 | ECRYPTFS_VERSIONING_XATTR) 55 | ECRYPTFS_VERSIONING_XATTR \
56 | ECRYPTFS_VERSIONING_MULTKEY)
55#define ECRYPTFS_MAX_PASSWORD_LENGTH 64 57#define ECRYPTFS_MAX_PASSWORD_LENGTH 64
56#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH 58#define ECRYPTFS_MAX_PASSPHRASE_BYTES ECRYPTFS_MAX_PASSWORD_LENGTH
57#define ECRYPTFS_SALT_SIZE 8 59#define ECRYPTFS_SALT_SIZE 8
@@ -65,8 +67,7 @@
65#define ECRYPTFS_MAX_KEY_BYTES 64 67#define ECRYPTFS_MAX_KEY_BYTES 64
66#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512 68#define ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 512
67#define ECRYPTFS_DEFAULT_IV_BYTES 16 69#define ECRYPTFS_DEFAULT_IV_BYTES 16
68#define ECRYPTFS_FILE_VERSION 0x02 70#define ECRYPTFS_FILE_VERSION 0x03
69#define ECRYPTFS_DEFAULT_HEADER_EXTENT_SIZE 8192
70#define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096 71#define ECRYPTFS_DEFAULT_EXTENT_SIZE 4096
71#define ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 8192 72#define ECRYPTFS_MINIMUM_HEADER_EXTENT_SIZE 8192
72#define ECRYPTFS_DEFAULT_MSG_CTX_ELEMS 32 73#define ECRYPTFS_DEFAULT_MSG_CTX_ELEMS 32
@@ -144,6 +145,7 @@ struct ecryptfs_private_key {
144struct ecryptfs_auth_tok { 145struct ecryptfs_auth_tok {
145 u16 version; /* 8-bit major and 8-bit minor */ 146 u16 version; /* 8-bit major and 8-bit minor */
146 u16 token_type; 147 u16 token_type;
148#define ECRYPTFS_ENCRYPT_ONLY 0x00000001
147 u32 flags; 149 u32 flags;
148 struct ecryptfs_session_key session_key; 150 struct ecryptfs_session_key session_key;
149 u8 reserved[32]; 151 u8 reserved[32];
@@ -194,12 +196,11 @@ ecryptfs_get_key_payload_data(struct key *key)
194#define ECRYPTFS_MAX_KEYSET_SIZE 1024 196#define ECRYPTFS_MAX_KEYSET_SIZE 1024
195#define ECRYPTFS_MAX_CIPHER_NAME_SIZE 32 197#define ECRYPTFS_MAX_CIPHER_NAME_SIZE 32
196#define ECRYPTFS_MAX_NUM_ENC_KEYS 64 198#define ECRYPTFS_MAX_NUM_ENC_KEYS 64
197#define ECRYPTFS_MAX_NUM_KEYSIGS 2 /* TODO: Make this a linked list */
198#define ECRYPTFS_MAX_IV_BYTES 16 /* 128 bits */ 199#define ECRYPTFS_MAX_IV_BYTES 16 /* 128 bits */
199#define ECRYPTFS_SALT_BYTES 2 200#define ECRYPTFS_SALT_BYTES 2
200#define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5 201#define MAGIC_ECRYPTFS_MARKER 0x3c81b7f5
201#define MAGIC_ECRYPTFS_MARKER_SIZE_BYTES 8 /* 4*2 */ 202#define MAGIC_ECRYPTFS_MARKER_SIZE_BYTES 8 /* 4*2 */
202#define ECRYPTFS_FILE_SIZE_BYTES 8 203#define ECRYPTFS_FILE_SIZE_BYTES (sizeof(u64))
203#define ECRYPTFS_DEFAULT_CIPHER "aes" 204#define ECRYPTFS_DEFAULT_CIPHER "aes"
204#define ECRYPTFS_DEFAULT_KEY_BYTES 16 205#define ECRYPTFS_DEFAULT_KEY_BYTES 16
205#define ECRYPTFS_DEFAULT_HASH "md5" 206#define ECRYPTFS_DEFAULT_HASH "md5"
@@ -212,6 +213,11 @@ ecryptfs_get_key_payload_data(struct key *key)
212#define ECRYPTFS_TAG_67_PACKET_TYPE 0x43 213#define ECRYPTFS_TAG_67_PACKET_TYPE 0x43
213#define MD5_DIGEST_SIZE 16 214#define MD5_DIGEST_SIZE 16
214 215
216struct ecryptfs_key_sig {
217 struct list_head crypt_stat_list;
218 char keysig[ECRYPTFS_SIG_SIZE_HEX];
219};
220
215/** 221/**
216 * This is the primary struct associated with each encrypted file. 222 * This is the primary struct associated with each encrypted file.
217 * 223 *
@@ -231,8 +237,6 @@ struct ecryptfs_crypt_stat {
231 u32 flags; 237 u32 flags;
232 unsigned int file_version; 238 unsigned int file_version;
233 size_t iv_bytes; 239 size_t iv_bytes;
234 size_t num_keysigs;
235 size_t header_extent_size;
236 size_t num_header_extents_at_front; 240 size_t num_header_extents_at_front;
237 size_t extent_size; /* Data extent size; default is 4096 */ 241 size_t extent_size; /* Data extent size; default is 4096 */
238 size_t key_size; 242 size_t key_size;
@@ -245,7 +249,8 @@ struct ecryptfs_crypt_stat {
245 unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE]; 249 unsigned char cipher[ECRYPTFS_MAX_CIPHER_NAME_SIZE];
246 unsigned char key[ECRYPTFS_MAX_KEY_BYTES]; 250 unsigned char key[ECRYPTFS_MAX_KEY_BYTES];
247 unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES]; 251 unsigned char root_iv[ECRYPTFS_MAX_IV_BYTES];
248 unsigned char keysigs[ECRYPTFS_MAX_NUM_KEYSIGS][ECRYPTFS_SIG_SIZE_HEX]; 252 struct list_head keysig_list;
253 struct mutex keysig_list_mutex;
249 struct mutex cs_tfm_mutex; 254 struct mutex cs_tfm_mutex;
250 struct mutex cs_hash_tfm_mutex; 255 struct mutex cs_hash_tfm_mutex;
251 struct mutex cs_mutex; 256 struct mutex cs_mutex;
@@ -255,6 +260,8 @@ struct ecryptfs_crypt_stat {
255struct ecryptfs_inode_info { 260struct ecryptfs_inode_info {
256 struct inode vfs_inode; 261 struct inode vfs_inode;
257 struct inode *wii_inode; 262 struct inode *wii_inode;
263 struct file *lower_file;
264 struct mutex lower_file_mutex;
258 struct ecryptfs_crypt_stat crypt_stat; 265 struct ecryptfs_crypt_stat crypt_stat;
259}; 266};
260 267
@@ -266,6 +273,59 @@ struct ecryptfs_dentry_info {
266}; 273};
267 274
268/** 275/**
276 * ecryptfs_global_auth_tok - A key used to encrypt all new files under the mountpoint
277 * @flags: Status flags
278 * @mount_crypt_stat_list: These auth_toks hang off the mount-wide
279 * cryptographic context. Every time a new
280 * inode comes into existence, eCryptfs copies
281 * the auth_toks on that list to the set of
282 * auth_toks on the inode's crypt_stat
283 * @global_auth_tok_key: The key from the user's keyring for the sig
284 * @global_auth_tok: The key contents
285 * @sig: The key identifier
286 *
287 * ecryptfs_global_auth_tok structs refer to authentication token keys
288 * in the user keyring that apply to newly created files. A list of
289 * these objects hangs off of the mount_crypt_stat struct for any
290 * given eCryptfs mount. This struct maintains a reference to both the
291 * key contents and the key itself so that the key can be put on
292 * unmount.
293 */
294struct ecryptfs_global_auth_tok {
295#define ECRYPTFS_AUTH_TOK_INVALID 0x00000001
296 u32 flags;
297 struct list_head mount_crypt_stat_list;
298 struct key *global_auth_tok_key;
299 struct ecryptfs_auth_tok *global_auth_tok;
300 unsigned char sig[ECRYPTFS_SIG_SIZE_HEX + 1];
301};
302
303/**
304 * ecryptfs_key_tfm - Persistent key tfm
305 * @key_tfm: crypto API handle to the key
306 * @key_size: Key size in bytes
307 * @key_tfm_mutex: Mutex to ensure only one operation in eCryptfs is
308 * using the persistent TFM at any point in time
309 * @key_tfm_list: Handle to hang this off the module-wide TFM list
310 * @cipher_name: String name for the cipher for this TFM
311 *
312 * Typically, eCryptfs will use the same ciphers repeatedly throughout
313 * the course of its operations. In order to avoid unnecessarily
314 * destroying and initializing the same cipher repeatedly, eCryptfs
315 * keeps a list of crypto API contexts around to use when needed.
316 */
317struct ecryptfs_key_tfm {
318 struct crypto_blkcipher *key_tfm;
319 size_t key_size;
320 struct mutex key_tfm_mutex;
321 struct list_head key_tfm_list;
322 unsigned char cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE + 1];
323};
324
325extern struct list_head key_tfm_list;
326extern struct mutex key_tfm_list_mutex;
327
328/**
269 * This struct is to enable a mount-wide passphrase/salt combo. This 329 * This struct is to enable a mount-wide passphrase/salt combo. This
270 * is more or less a stopgap to provide similar functionality to other 330 * is more or less a stopgap to provide similar functionality to other
271 * crypto filesystems like EncFS or CFS until full policy support is 331 * crypto filesystems like EncFS or CFS until full policy support is
@@ -276,15 +336,14 @@ struct ecryptfs_mount_crypt_stat {
276#define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001 336#define ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED 0x00000001
277#define ECRYPTFS_XATTR_METADATA_ENABLED 0x00000002 337#define ECRYPTFS_XATTR_METADATA_ENABLED 0x00000002
278#define ECRYPTFS_ENCRYPTED_VIEW_ENABLED 0x00000004 338#define ECRYPTFS_ENCRYPTED_VIEW_ENABLED 0x00000004
339#define ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED 0x00000008
279 u32 flags; 340 u32 flags;
280 struct ecryptfs_auth_tok *global_auth_tok; 341 struct list_head global_auth_tok_list;
281 struct key *global_auth_tok_key; 342 struct mutex global_auth_tok_list_mutex;
343 size_t num_global_auth_toks;
282 size_t global_default_cipher_key_size; 344 size_t global_default_cipher_key_size;
283 struct crypto_blkcipher *global_key_tfm;
284 struct mutex global_key_tfm_mutex;
285 unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE 345 unsigned char global_default_cipher_name[ECRYPTFS_MAX_CIPHER_NAME_SIZE
286 + 1]; 346 + 1];
287 unsigned char global_auth_tok_sig[ECRYPTFS_SIG_SIZE_HEX + 1];
288}; 347};
289 348
290/* superblock private data. */ 349/* superblock private data. */
@@ -468,6 +527,9 @@ extern struct kmem_cache *ecryptfs_header_cache_2;
468extern struct kmem_cache *ecryptfs_xattr_cache; 527extern struct kmem_cache *ecryptfs_xattr_cache;
469extern struct kmem_cache *ecryptfs_lower_page_cache; 528extern struct kmem_cache *ecryptfs_lower_page_cache;
470extern struct kmem_cache *ecryptfs_key_record_cache; 529extern struct kmem_cache *ecryptfs_key_record_cache;
530extern struct kmem_cache *ecryptfs_key_sig_cache;
531extern struct kmem_cache *ecryptfs_global_auth_tok_cache;
532extern struct kmem_cache *ecryptfs_key_tfm_cache;
471 533
472int ecryptfs_interpose(struct dentry *hidden_dentry, 534int ecryptfs_interpose(struct dentry *hidden_dentry,
473 struct dentry *this_dentry, struct super_block *sb, 535 struct dentry *this_dentry, struct super_block *sb,
@@ -486,44 +548,18 @@ int virt_to_scatterlist(const void *addr, int size, struct scatterlist *sg,
486int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat); 548int ecryptfs_compute_root_iv(struct ecryptfs_crypt_stat *crypt_stat);
487void ecryptfs_rotate_iv(unsigned char *iv); 549void ecryptfs_rotate_iv(unsigned char *iv);
488void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat); 550void ecryptfs_init_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
489void ecryptfs_destruct_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat); 551void ecryptfs_destroy_crypt_stat(struct ecryptfs_crypt_stat *crypt_stat);
490void ecryptfs_destruct_mount_crypt_stat( 552void ecryptfs_destroy_mount_crypt_stat(
491 struct ecryptfs_mount_crypt_stat *mount_crypt_stat); 553 struct ecryptfs_mount_crypt_stat *mount_crypt_stat);
492int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat); 554int ecryptfs_init_crypt_ctx(struct ecryptfs_crypt_stat *crypt_stat);
493int ecryptfs_crypto_api_algify_cipher_name(char **algified_name, 555int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode);
494 char *cipher_name, 556int ecryptfs_encrypt_page(struct page *page);
495 char *chaining_modifier); 557int ecryptfs_decrypt_page(struct page *page);
496#define ECRYPTFS_LOWER_I_MUTEX_NOT_HELD 0 558int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry);
497#define ECRYPTFS_LOWER_I_MUTEX_HELD 1 559int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry);
498int ecryptfs_write_inode_size_to_metadata(struct file *lower_file,
499 struct inode *lower_inode,
500 struct inode *inode,
501 struct dentry *ecryptfs_dentry,
502 int lower_i_mutex_held);
503int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
504 struct file *lower_file,
505 unsigned long lower_page_index, int byte_offset,
506 int region_bytes);
507int
508ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
509 struct file *lower_file, int byte_offset,
510 int region_size);
511int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode,
512 struct file *lower_file);
513int ecryptfs_do_readpage(struct file *file, struct page *page,
514 pgoff_t lower_page_index);
515int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
516 struct inode *lower_inode,
517 struct writeback_control *wbc);
518int ecryptfs_encrypt_page(struct ecryptfs_page_crypt_context *ctx);
519int ecryptfs_decrypt_page(struct file *file, struct page *page);
520int ecryptfs_write_metadata(struct dentry *ecryptfs_dentry,
521 struct file *lower_file);
522int ecryptfs_read_metadata(struct dentry *ecryptfs_dentry,
523 struct file *lower_file);
524int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry); 560int ecryptfs_new_file_context(struct dentry *ecryptfs_dentry);
525int ecryptfs_read_and_validate_header_region(char *data, struct dentry *dentry, 561int ecryptfs_read_and_validate_header_region(char *data,
526 struct vfsmount *mnt); 562 struct inode *ecryptfs_inode);
527int ecryptfs_read_and_validate_xattr_region(char *page_virt, 563int ecryptfs_read_and_validate_xattr_region(char *page_virt,
528 struct dentry *ecryptfs_dentry); 564 struct dentry *ecryptfs_dentry);
529u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat); 565u16 ecryptfs_code_for_cipher_string(struct ecryptfs_crypt_stat *crypt_stat);
@@ -533,27 +569,22 @@ int ecryptfs_generate_key_packet_set(char *dest_base,
533 struct ecryptfs_crypt_stat *crypt_stat, 569 struct ecryptfs_crypt_stat *crypt_stat,
534 struct dentry *ecryptfs_dentry, 570 struct dentry *ecryptfs_dentry,
535 size_t *len, size_t max); 571 size_t *len, size_t max);
536int process_request_key_err(long err_code);
537int 572int
538ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat, 573ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
539 unsigned char *src, struct dentry *ecryptfs_dentry); 574 unsigned char *src, struct dentry *ecryptfs_dentry);
540int ecryptfs_truncate(struct dentry *dentry, loff_t new_length); 575int ecryptfs_truncate(struct dentry *dentry, loff_t new_length);
541int
542ecryptfs_process_cipher(struct crypto_blkcipher **key_tfm, char *cipher_name,
543 size_t *key_size);
544int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode); 576int ecryptfs_inode_test(struct inode *inode, void *candidate_lower_inode);
545int ecryptfs_inode_set(struct inode *inode, void *lower_inode); 577int ecryptfs_inode_set(struct inode *inode, void *lower_inode);
546void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode); 578void ecryptfs_init_inode(struct inode *inode, struct inode *lower_inode);
547int ecryptfs_open_lower_file(struct file **lower_file,
548 struct dentry *lower_dentry,
549 struct vfsmount *lower_mnt, int flags);
550int ecryptfs_close_lower_file(struct file *lower_file);
551ssize_t ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, 579ssize_t ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
552 size_t size); 580 size_t size);
581ssize_t
582ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
583 void *value, size_t size);
553int 584int
554ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value, 585ecryptfs_setxattr(struct dentry *dentry, const char *name, const void *value,
555 size_t size, int flags); 586 size_t size, int flags);
556int ecryptfs_read_xattr_region(char *page_virt, struct dentry *ecryptfs_dentry); 587int ecryptfs_read_xattr_region(char *page_virt, struct inode *ecryptfs_inode);
557int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid); 588int ecryptfs_process_helo(unsigned int transport, uid_t uid, pid_t pid);
558int ecryptfs_process_quit(uid_t uid, pid_t pid); 589int ecryptfs_process_quit(uid_t uid, pid_t pid);
559int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid, 590int ecryptfs_process_response(struct ecryptfs_message *msg, uid_t uid,
@@ -580,7 +611,43 @@ void
580ecryptfs_write_header_metadata(char *virt, 611ecryptfs_write_header_metadata(char *virt,
581 struct ecryptfs_crypt_stat *crypt_stat, 612 struct ecryptfs_crypt_stat *crypt_stat,
582 size_t *written); 613 size_t *written);
614int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig);
615int
616ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
617 char *sig);
618int ecryptfs_get_global_auth_tok_for_sig(
619 struct ecryptfs_global_auth_tok **global_auth_tok,
620 struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig);
621int
622ecryptfs_add_new_key_tfm(struct ecryptfs_key_tfm **key_tfm, char *cipher_name,
623 size_t key_size);
624int ecryptfs_init_crypto(void);
625int ecryptfs_destroy_crypto(void);
626int ecryptfs_get_tfm_and_mutex_for_cipher_name(struct crypto_blkcipher **tfm,
627 struct mutex **tfm_mutex,
628 char *cipher_name);
629int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
630 struct ecryptfs_auth_tok **auth_tok,
631 char *sig);
583int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, 632int ecryptfs_write_zeros(struct file *file, pgoff_t index, int start,
584 int num_zeros); 633 int num_zeros);
634void ecryptfs_lower_offset_for_extent(loff_t *offset, loff_t extent_num,
635 struct ecryptfs_crypt_stat *crypt_stat);
636int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
637 loff_t offset, size_t size);
638int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
639 struct page *page_for_lower,
640 size_t offset_in_page, size_t size);
641int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
642 size_t size);
643int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
644 struct inode *ecryptfs_inode);
645int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
646 pgoff_t page_index,
647 size_t offset_in_page, size_t size,
648 struct inode *ecryptfs_inode);
649int ecryptfs_read(char *data, loff_t offset, size_t size,
650 struct file *ecryptfs_file);
651struct page *ecryptfs_get_locked_page(struct file *file, loff_t index);
585 652
586#endif /* #ifndef ECRYPTFS_KERNEL_H */ 653#endif /* #ifndef ECRYPTFS_KERNEL_H */
diff --git a/fs/ecryptfs/file.c b/fs/ecryptfs/file.c
index 94f456fe4d9b..c98c4690a771 100644
--- a/fs/ecryptfs/file.c
+++ b/fs/ecryptfs/file.c
@@ -141,34 +141,6 @@ retry:
141 141
142struct kmem_cache *ecryptfs_file_info_cache; 142struct kmem_cache *ecryptfs_file_info_cache;
143 143
144int ecryptfs_open_lower_file(struct file **lower_file,
145 struct dentry *lower_dentry,
146 struct vfsmount *lower_mnt, int flags)
147{
148 int rc = 0;
149
150 flags |= O_LARGEFILE;
151 dget(lower_dentry);
152 mntget(lower_mnt);
153 *lower_file = dentry_open(lower_dentry, lower_mnt, flags);
154 if (IS_ERR(*lower_file)) {
155 printk(KERN_ERR "Error opening lower file for lower_dentry "
156 "[0x%p], lower_mnt [0x%p], and flags [0x%x]\n",
157 lower_dentry, lower_mnt, flags);
158 rc = PTR_ERR(*lower_file);
159 *lower_file = NULL;
160 goto out;
161 }
162out:
163 return rc;
164}
165
166int ecryptfs_close_lower_file(struct file *lower_file)
167{
168 fput(lower_file);
169 return 0;
170}
171
172/** 144/**
173 * ecryptfs_open 145 * ecryptfs_open
174 * @inode: inode speciying file to open 146 * @inode: inode speciying file to open
@@ -187,11 +159,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
187 /* Private value of ecryptfs_dentry allocated in 159 /* Private value of ecryptfs_dentry allocated in
188 * ecryptfs_lookup() */ 160 * ecryptfs_lookup() */
189 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); 161 struct dentry *lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
190 struct inode *lower_inode = NULL;
191 struct file *lower_file = NULL;
192 struct vfsmount *lower_mnt;
193 struct ecryptfs_file_info *file_info; 162 struct ecryptfs_file_info *file_info;
194 int lower_flags;
195 163
196 mount_crypt_stat = &ecryptfs_superblock_to_private( 164 mount_crypt_stat = &ecryptfs_superblock_to_private(
197 ecryptfs_dentry->d_sb)->mount_crypt_stat; 165 ecryptfs_dentry->d_sb)->mount_crypt_stat;
@@ -219,25 +187,12 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
219 if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) { 187 if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) {
220 ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n"); 188 ecryptfs_printk(KERN_DEBUG, "Setting flags for stat...\n");
221 /* Policy code enabled in future release */ 189 /* Policy code enabled in future release */
222 crypt_stat->flags |= ECRYPTFS_POLICY_APPLIED; 190 crypt_stat->flags |= (ECRYPTFS_POLICY_APPLIED
223 crypt_stat->flags |= ECRYPTFS_ENCRYPTED; 191 | ECRYPTFS_ENCRYPTED);
224 } 192 }
225 mutex_unlock(&crypt_stat->cs_mutex); 193 mutex_unlock(&crypt_stat->cs_mutex);
226 lower_flags = file->f_flags; 194 ecryptfs_set_file_lower(
227 if ((lower_flags & O_ACCMODE) == O_WRONLY) 195 file, ecryptfs_inode_to_private(inode)->lower_file);
228 lower_flags = (lower_flags & O_ACCMODE) | O_RDWR;
229 if (file->f_flags & O_APPEND)
230 lower_flags &= ~O_APPEND;
231 lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
232 /* Corresponding fput() in ecryptfs_release() */
233 if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
234 lower_flags))) {
235 ecryptfs_printk(KERN_ERR, "Error opening lower file\n");
236 goto out_puts;
237 }
238 ecryptfs_set_file_lower(file, lower_file);
239 /* Isn't this check the same as the one in lookup? */
240 lower_inode = lower_dentry->d_inode;
241 if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { 196 if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
242 ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); 197 ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
243 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); 198 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
@@ -247,7 +202,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
247 mutex_lock(&crypt_stat->cs_mutex); 202 mutex_lock(&crypt_stat->cs_mutex);
248 if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) 203 if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
249 || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) { 204 || !(crypt_stat->flags & ECRYPTFS_KEY_VALID)) {
250 rc = ecryptfs_read_metadata(ecryptfs_dentry, lower_file); 205 rc = ecryptfs_read_metadata(ecryptfs_dentry);
251 if (rc) { 206 if (rc) {
252 ecryptfs_printk(KERN_DEBUG, 207 ecryptfs_printk(KERN_DEBUG,
253 "Valid headers not found\n"); 208 "Valid headers not found\n");
@@ -259,7 +214,7 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
259 "and plaintext passthrough mode is not " 214 "and plaintext passthrough mode is not "
260 "enabled; returning -EIO\n"); 215 "enabled; returning -EIO\n");
261 mutex_unlock(&crypt_stat->cs_mutex); 216 mutex_unlock(&crypt_stat->cs_mutex);
262 goto out_puts; 217 goto out_free;
263 } 218 }
264 rc = 0; 219 rc = 0;
265 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); 220 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
@@ -271,11 +226,8 @@ static int ecryptfs_open(struct inode *inode, struct file *file)
271 ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = [0x%.16x] " 226 ecryptfs_printk(KERN_DEBUG, "inode w/ addr = [0x%p], i_ino = [0x%.16x] "
272 "size: [0x%.16x]\n", inode, inode->i_ino, 227 "size: [0x%.16x]\n", inode, inode->i_ino,
273 i_size_read(inode)); 228 i_size_read(inode));
274 ecryptfs_set_file_lower(file, lower_file);
275 goto out; 229 goto out;
276out_puts: 230out_free:
277 mntput(lower_mnt);
278 dput(lower_dentry);
279 kmem_cache_free(ecryptfs_file_info_cache, 231 kmem_cache_free(ecryptfs_file_info_cache,
280 ecryptfs_file_to_private(file)); 232 ecryptfs_file_to_private(file));
281out: 233out:
@@ -295,19 +247,9 @@ static int ecryptfs_flush(struct file *file, fl_owner_t td)
295 247
296static int ecryptfs_release(struct inode *inode, struct file *file) 248static int ecryptfs_release(struct inode *inode, struct file *file)
297{ 249{
298 struct file *lower_file = ecryptfs_file_to_lower(file); 250 kmem_cache_free(ecryptfs_file_info_cache,
299 struct ecryptfs_file_info *file_info = ecryptfs_file_to_private(file); 251 ecryptfs_file_to_private(file));
300 struct inode *lower_inode = ecryptfs_inode_to_lower(inode); 252 return 0;
301 int rc;
302
303 if ((rc = ecryptfs_close_lower_file(lower_file))) {
304 printk(KERN_ERR "Error closing lower_file\n");
305 goto out;
306 }
307 inode->i_blocks = lower_inode->i_blocks;
308 kmem_cache_free(ecryptfs_file_info_cache, file_info);
309out:
310 return rc;
311} 253}
312 254
313static int 255static int
@@ -338,21 +280,6 @@ static int ecryptfs_fasync(int fd, struct file *file, int flag)
338 return rc; 280 return rc;
339} 281}
340 282
341static ssize_t ecryptfs_splice_read(struct file *file, loff_t * ppos,
342 struct pipe_inode_info *pipe, size_t count,
343 unsigned int flags)
344{
345 struct file *lower_file = NULL;
346 int rc = -EINVAL;
347
348 lower_file = ecryptfs_file_to_lower(file);
349 if (lower_file->f_op && lower_file->f_op->splice_read)
350 rc = lower_file->f_op->splice_read(lower_file, ppos, pipe,
351 count, flags);
352
353 return rc;
354}
355
356static int ecryptfs_ioctl(struct inode *inode, struct file *file, 283static int ecryptfs_ioctl(struct inode *inode, struct file *file,
357 unsigned int cmd, unsigned long arg); 284 unsigned int cmd, unsigned long arg);
358 285
@@ -365,7 +292,7 @@ const struct file_operations ecryptfs_dir_fops = {
365 .release = ecryptfs_release, 292 .release = ecryptfs_release,
366 .fsync = ecryptfs_fsync, 293 .fsync = ecryptfs_fsync,
367 .fasync = ecryptfs_fasync, 294 .fasync = ecryptfs_fasync,
368 .splice_read = ecryptfs_splice_read, 295 .splice_read = generic_file_splice_read,
369}; 296};
370 297
371const struct file_operations ecryptfs_main_fops = { 298const struct file_operations ecryptfs_main_fops = {
@@ -382,7 +309,7 @@ const struct file_operations ecryptfs_main_fops = {
382 .release = ecryptfs_release, 309 .release = ecryptfs_release,
383 .fsync = ecryptfs_fsync, 310 .fsync = ecryptfs_fsync,
384 .fasync = ecryptfs_fasync, 311 .fasync = ecryptfs_fasync,
385 .splice_read = ecryptfs_splice_read, 312 .splice_read = generic_file_splice_read,
386}; 313};
387 314
388static int 315static int
diff --git a/fs/ecryptfs/inode.c b/fs/ecryptfs/inode.c
index 131954b3fb98..5701f816faf4 100644
--- a/fs/ecryptfs/inode.c
+++ b/fs/ecryptfs/inode.c
@@ -119,10 +119,23 @@ ecryptfs_do_create(struct inode *directory_inode,
119 } 119 }
120 rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode, 120 rc = ecryptfs_create_underlying_file(lower_dir_dentry->d_inode,
121 ecryptfs_dentry, mode, nd); 121 ecryptfs_dentry, mode, nd);
122 if (unlikely(rc)) { 122 if (rc) {
123 ecryptfs_printk(KERN_ERR, 123 struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode;
124 "Failure to create underlying file\n"); 124 struct ecryptfs_inode_info *inode_info =
125 goto out_lock; 125 ecryptfs_inode_to_private(ecryptfs_inode);
126
127 printk(KERN_WARNING "%s: Error creating underlying file; "
128 "rc = [%d]; checking for existing\n", __FUNCTION__, rc);
129 if (inode_info) {
130 mutex_lock(&inode_info->lower_file_mutex);
131 if (!inode_info->lower_file) {
132 mutex_unlock(&inode_info->lower_file_mutex);
133 printk(KERN_ERR "%s: Failure to set underlying "
134 "file; rc = [%d]\n", __FUNCTION__, rc);
135 goto out_lock;
136 }
137 mutex_unlock(&inode_info->lower_file_mutex);
138 }
126 } 139 }
127 rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry, 140 rc = ecryptfs_interpose(lower_dentry, ecryptfs_dentry,
128 directory_inode->i_sb, 0); 141 directory_inode->i_sb, 0);
@@ -140,39 +153,30 @@ out:
140 153
141/** 154/**
142 * grow_file 155 * grow_file
143 * @ecryptfs_dentry: the ecryptfs dentry 156 * @ecryptfs_dentry: the eCryptfs dentry
144 * @lower_file: The lower file
145 * @inode: The ecryptfs inode
146 * @lower_inode: The lower inode
147 * 157 *
148 * This is the code which will grow the file to its correct size. 158 * This is the code which will grow the file to its correct size.
149 */ 159 */
150static int grow_file(struct dentry *ecryptfs_dentry, struct file *lower_file, 160static int grow_file(struct dentry *ecryptfs_dentry)
151 struct inode *inode, struct inode *lower_inode)
152{ 161{
153 int rc = 0; 162 struct inode *ecryptfs_inode = ecryptfs_dentry->d_inode;
154 struct file fake_file; 163 struct file fake_file;
155 struct ecryptfs_file_info tmp_file_info; 164 struct ecryptfs_file_info tmp_file_info;
165 char zero_virt[] = { 0x00 };
166 int rc = 0;
156 167
157 memset(&fake_file, 0, sizeof(fake_file)); 168 memset(&fake_file, 0, sizeof(fake_file));
158 fake_file.f_path.dentry = ecryptfs_dentry; 169 fake_file.f_path.dentry = ecryptfs_dentry;
159 memset(&tmp_file_info, 0, sizeof(tmp_file_info)); 170 memset(&tmp_file_info, 0, sizeof(tmp_file_info));
160 ecryptfs_set_file_private(&fake_file, &tmp_file_info); 171 ecryptfs_set_file_private(&fake_file, &tmp_file_info);
161 ecryptfs_set_file_lower(&fake_file, lower_file); 172 ecryptfs_set_file_lower(
162 rc = ecryptfs_fill_zeros(&fake_file, 1); 173 &fake_file,
163 if (rc) { 174 ecryptfs_inode_to_private(ecryptfs_inode)->lower_file);
164 ecryptfs_inode_to_private(inode)->crypt_stat.flags |= 175 rc = ecryptfs_write(&fake_file, zero_virt, 0, 1);
165 ECRYPTFS_SECURITY_WARNING; 176 i_size_write(ecryptfs_inode, 0);
166 ecryptfs_printk(KERN_WARNING, "Error attempting to fill zeros " 177 rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
167 "in file; rc = [%d]\n", rc); 178 ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat.flags |=
168 goto out; 179 ECRYPTFS_NEW_FILE;
169 }
170 i_size_write(inode, 0);
171 rc = ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode,
172 inode, ecryptfs_dentry,
173 ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
174 ecryptfs_inode_to_private(inode)->crypt_stat.flags |= ECRYPTFS_NEW_FILE;
175out:
176 return rc; 180 return rc;
177} 181}
178 182
@@ -186,51 +190,31 @@ out:
186 */ 190 */
187static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry) 191static int ecryptfs_initialize_file(struct dentry *ecryptfs_dentry)
188{ 192{
193 struct ecryptfs_crypt_stat *crypt_stat =
194 &ecryptfs_inode_to_private(ecryptfs_dentry->d_inode)->crypt_stat;
189 int rc = 0; 195 int rc = 0;
190 int lower_flags;
191 struct ecryptfs_crypt_stat *crypt_stat;
192 struct dentry *lower_dentry;
193 struct file *lower_file;
194 struct inode *inode, *lower_inode;
195 struct vfsmount *lower_mnt;
196 196
197 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
198 ecryptfs_printk(KERN_DEBUG, "lower_dentry->d_name.name = [%s]\n",
199 lower_dentry->d_name.name);
200 inode = ecryptfs_dentry->d_inode;
201 crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat;
202 lower_flags = ((O_CREAT | O_TRUNC) & O_ACCMODE) | O_RDWR;
203 lower_mnt = ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
204 /* Corresponding fput() at end of this function */
205 if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt,
206 lower_flags))) {
207 ecryptfs_printk(KERN_ERR,
208 "Error opening dentry; rc = [%i]\n", rc);
209 goto out;
210 }
211 lower_inode = lower_dentry->d_inode;
212 if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) { 197 if (S_ISDIR(ecryptfs_dentry->d_inode->i_mode)) {
213 ecryptfs_printk(KERN_DEBUG, "This is a directory\n"); 198 ecryptfs_printk(KERN_DEBUG, "This is a directory\n");
214 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); 199 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
215 goto out_fput; 200 goto out;
216 } 201 }
217 crypt_stat->flags |= ECRYPTFS_NEW_FILE; 202 crypt_stat->flags |= ECRYPTFS_NEW_FILE;
218 ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n"); 203 ecryptfs_printk(KERN_DEBUG, "Initializing crypto context\n");
219 rc = ecryptfs_new_file_context(ecryptfs_dentry); 204 rc = ecryptfs_new_file_context(ecryptfs_dentry);
220 if (rc) { 205 if (rc) {
221 ecryptfs_printk(KERN_DEBUG, "Error creating new file " 206 ecryptfs_printk(KERN_ERR, "Error creating new file "
222 "context\n"); 207 "context; rc = [%d]\n", rc);
223 goto out_fput; 208 goto out;
224 } 209 }
225 rc = ecryptfs_write_metadata(ecryptfs_dentry, lower_file); 210 rc = ecryptfs_write_metadata(ecryptfs_dentry);
226 if (rc) { 211 if (rc) {
227 ecryptfs_printk(KERN_DEBUG, "Error writing headers\n"); 212 printk(KERN_ERR "Error writing headers; rc = [%d]\n", rc);
228 goto out_fput; 213 goto out;
229 } 214 }
230 rc = grow_file(ecryptfs_dentry, lower_file, inode, lower_inode); 215 rc = grow_file(ecryptfs_dentry);
231out_fput: 216 if (rc)
232 if ((rc = ecryptfs_close_lower_file(lower_file))) 217 printk(KERN_ERR "Error growing file; rc = [%d]\n", rc);
233 printk(KERN_ERR "Error closing lower_file\n");
234out: 218out:
235 return rc; 219 return rc;
236} 220}
@@ -252,6 +236,8 @@ ecryptfs_create(struct inode *directory_inode, struct dentry *ecryptfs_dentry,
252{ 236{
253 int rc; 237 int rc;
254 238
239 /* ecryptfs_do_create() calls ecryptfs_interpose(), which opens
240 * the crypt_stat->lower_file (persistent file) */
255 rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, nd); 241 rc = ecryptfs_do_create(directory_inode, ecryptfs_dentry, mode, nd);
256 if (unlikely(rc)) { 242 if (unlikely(rc)) {
257 ecryptfs_printk(KERN_WARNING, "Failed to create file in" 243 ecryptfs_printk(KERN_WARNING, "Failed to create file in"
@@ -374,8 +360,8 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
374 crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat; 360 crypt_stat = &ecryptfs_inode_to_private(dentry->d_inode)->crypt_stat;
375 if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)) 361 if (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED))
376 ecryptfs_set_default_sizes(crypt_stat); 362 ecryptfs_set_default_sizes(crypt_stat);
377 rc = ecryptfs_read_and_validate_header_region(page_virt, lower_dentry, 363 rc = ecryptfs_read_and_validate_header_region(page_virt,
378 nd->mnt); 364 dentry->d_inode);
379 if (rc) { 365 if (rc) {
380 rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry); 366 rc = ecryptfs_read_and_validate_xattr_region(page_virt, dentry);
381 if (rc) { 367 if (rc) {
@@ -392,7 +378,8 @@ static struct dentry *ecryptfs_lookup(struct inode *dir, struct dentry *dentry,
392 dentry->d_sb)->mount_crypt_stat; 378 dentry->d_sb)->mount_crypt_stat;
393 if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) { 379 if (mount_crypt_stat->flags & ECRYPTFS_ENCRYPTED_VIEW_ENABLED) {
394 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) 380 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
395 file_size = (crypt_stat->header_extent_size 381 file_size = ((crypt_stat->extent_size
382 * crypt_stat->num_header_extents_at_front)
396 + i_size_read(lower_dentry->d_inode)); 383 + i_size_read(lower_dentry->d_inode));
397 else 384 else
398 file_size = i_size_read(lower_dentry->d_inode); 385 file_size = i_size_read(lower_dentry->d_inode);
@@ -722,8 +709,8 @@ upper_size_to_lower_size(struct ecryptfs_crypt_stat *crypt_stat,
722{ 709{
723 loff_t lower_size; 710 loff_t lower_size;
724 711
725 lower_size = ( crypt_stat->header_extent_size 712 lower_size = (crypt_stat->extent_size
726 * crypt_stat->num_header_extents_at_front ); 713 * crypt_stat->num_header_extents_at_front);
727 if (upper_size != 0) { 714 if (upper_size != 0) {
728 loff_t num_extents; 715 loff_t num_extents;
729 716
@@ -752,8 +739,7 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
752 int rc = 0; 739 int rc = 0;
753 struct inode *inode = dentry->d_inode; 740 struct inode *inode = dentry->d_inode;
754 struct dentry *lower_dentry; 741 struct dentry *lower_dentry;
755 struct vfsmount *lower_mnt; 742 struct file fake_ecryptfs_file;
756 struct file fake_ecryptfs_file, *lower_file = NULL;
757 struct ecryptfs_crypt_stat *crypt_stat; 743 struct ecryptfs_crypt_stat *crypt_stat;
758 loff_t i_size = i_size_read(inode); 744 loff_t i_size = i_size_read(inode);
759 loff_t lower_size_before_truncate; 745 loff_t lower_size_before_truncate;
@@ -776,62 +762,52 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
776 goto out; 762 goto out;
777 } 763 }
778 lower_dentry = ecryptfs_dentry_to_lower(dentry); 764 lower_dentry = ecryptfs_dentry_to_lower(dentry);
779 /* This dget & mntget is released through fput at out_fput: */ 765 ecryptfs_set_file_lower(
780 lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry); 766 &fake_ecryptfs_file,
781 if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry, lower_mnt, 767 ecryptfs_inode_to_private(dentry->d_inode)->lower_file);
782 O_RDWR))) {
783 ecryptfs_printk(KERN_ERR,
784 "Error opening dentry; rc = [%i]\n", rc);
785 goto out_free;
786 }
787 ecryptfs_set_file_lower(&fake_ecryptfs_file, lower_file);
788 /* Switch on growing or shrinking file */ 768 /* Switch on growing or shrinking file */
789 if (new_length > i_size) { 769 if (new_length > i_size) {
790 rc = ecryptfs_fill_zeros(&fake_ecryptfs_file, new_length); 770 char zero[] = { 0x00 };
791 if (rc) { 771
792 ecryptfs_printk(KERN_ERR, 772 /* Write a single 0 at the last position of the file;
793 "Problem with fill_zeros\n"); 773 * this triggers code that will fill in 0's throughout
794 goto out_fput; 774 * the intermediate portion of the previous end of the
795 } 775 * file and the new and of the file */
796 i_size_write(inode, new_length); 776 rc = ecryptfs_write(&fake_ecryptfs_file, zero,
797 rc = ecryptfs_write_inode_size_to_metadata( 777 (new_length - 1), 1);
798 lower_file, lower_dentry->d_inode, inode, dentry,
799 ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
800 if (rc) {
801 printk(KERN_ERR "Problem with "
802 "ecryptfs_write_inode_size_to_metadata; "
803 "rc = [%d]\n", rc);
804 goto out_fput;
805 }
806 } else { /* new_length < i_size_read(inode) */ 778 } else { /* new_length < i_size_read(inode) */
807 pgoff_t index = 0; 779 /* We're chopping off all the pages down do the page
808 int end_pos_in_page = -1; 780 * in which new_length is located. Fill in the end of
781 * that page from (new_length & ~PAGE_CACHE_MASK) to
782 * PAGE_CACHE_SIZE with zeros. */
783 size_t num_zeros = (PAGE_CACHE_SIZE
784 - (new_length & ~PAGE_CACHE_MASK));
809 785
810 if (new_length != 0) { 786 if (num_zeros) {
811 index = ((new_length - 1) >> PAGE_CACHE_SHIFT); 787 char *zeros_virt;
812 end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK); 788
813 } 789 zeros_virt = kzalloc(num_zeros, GFP_KERNEL);
814 if (end_pos_in_page != (PAGE_CACHE_SIZE - 1)) { 790 if (!zeros_virt) {
815 if ((rc = ecryptfs_write_zeros(&fake_ecryptfs_file, 791 rc = -ENOMEM;
816 index, 792 goto out_free;
817 (end_pos_in_page + 1), 793 }
818 ((PAGE_CACHE_SIZE - 1) 794 rc = ecryptfs_write(&fake_ecryptfs_file, zeros_virt,
819 - end_pos_in_page)))) { 795 new_length, num_zeros);
796 kfree(zeros_virt);
797 if (rc) {
820 printk(KERN_ERR "Error attempting to zero out " 798 printk(KERN_ERR "Error attempting to zero out "
821 "the remainder of the end page on " 799 "the remainder of the end page on "
822 "reducing truncate; rc = [%d]\n", rc); 800 "reducing truncate; rc = [%d]\n", rc);
823 goto out_fput; 801 goto out_free;
824 } 802 }
825 } 803 }
826 vmtruncate(inode, new_length); 804 vmtruncate(inode, new_length);
827 rc = ecryptfs_write_inode_size_to_metadata( 805 rc = ecryptfs_write_inode_size_to_metadata(inode);
828 lower_file, lower_dentry->d_inode, inode, dentry,
829 ECRYPTFS_LOWER_I_MUTEX_NOT_HELD);
830 if (rc) { 806 if (rc) {
831 printk(KERN_ERR "Problem with " 807 printk(KERN_ERR "Problem with "
832 "ecryptfs_write_inode_size_to_metadata; " 808 "ecryptfs_write_inode_size_to_metadata; "
833 "rc = [%d]\n", rc); 809 "rc = [%d]\n", rc);
834 goto out_fput; 810 goto out_free;
835 } 811 }
836 /* We are reducing the size of the ecryptfs file, and need to 812 /* We are reducing the size of the ecryptfs file, and need to
837 * know if we need to reduce the size of the lower file. */ 813 * know if we need to reduce the size of the lower file. */
@@ -843,13 +819,6 @@ int ecryptfs_truncate(struct dentry *dentry, loff_t new_length)
843 vmtruncate(lower_dentry->d_inode, 819 vmtruncate(lower_dentry->d_inode,
844 lower_size_after_truncate); 820 lower_size_after_truncate);
845 } 821 }
846 /* Update the access times */
847 lower_dentry->d_inode->i_mtime = lower_dentry->d_inode->i_ctime
848 = CURRENT_TIME;
849 mark_inode_dirty_sync(inode);
850out_fput:
851 if ((rc = ecryptfs_close_lower_file(lower_file)))
852 printk(KERN_ERR "Error closing lower_file\n");
853out_free: 822out_free:
854 if (ecryptfs_file_to_private(&fake_ecryptfs_file)) 823 if (ecryptfs_file_to_private(&fake_ecryptfs_file))
855 kmem_cache_free(ecryptfs_file_info_cache, 824 kmem_cache_free(ecryptfs_file_info_cache,
@@ -909,23 +878,12 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
909 else if (S_ISREG(dentry->d_inode->i_mode) 878 else if (S_ISREG(dentry->d_inode->i_mode)
910 && (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED) 879 && (!(crypt_stat->flags & ECRYPTFS_POLICY_APPLIED)
911 || !(crypt_stat->flags & ECRYPTFS_KEY_VALID))) { 880 || !(crypt_stat->flags & ECRYPTFS_KEY_VALID))) {
912 struct vfsmount *lower_mnt;
913 struct file *lower_file = NULL;
914 struct ecryptfs_mount_crypt_stat *mount_crypt_stat; 881 struct ecryptfs_mount_crypt_stat *mount_crypt_stat;
915 int lower_flags; 882
916
917 lower_mnt = ecryptfs_dentry_to_lower_mnt(dentry);
918 lower_flags = O_RDONLY;
919 if ((rc = ecryptfs_open_lower_file(&lower_file, lower_dentry,
920 lower_mnt, lower_flags))) {
921 printk(KERN_ERR
922 "Error opening lower file; rc = [%d]\n", rc);
923 mutex_unlock(&crypt_stat->cs_mutex);
924 goto out;
925 }
926 mount_crypt_stat = &ecryptfs_superblock_to_private( 883 mount_crypt_stat = &ecryptfs_superblock_to_private(
927 dentry->d_sb)->mount_crypt_stat; 884 dentry->d_sb)->mount_crypt_stat;
928 if ((rc = ecryptfs_read_metadata(dentry, lower_file))) { 885 rc = ecryptfs_read_metadata(dentry);
886 if (rc) {
929 if (!(mount_crypt_stat->flags 887 if (!(mount_crypt_stat->flags
930 & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) { 888 & ECRYPTFS_PLAINTEXT_PASSTHROUGH_ENABLED)) {
931 rc = -EIO; 889 rc = -EIO;
@@ -935,16 +893,13 @@ static int ecryptfs_setattr(struct dentry *dentry, struct iattr *ia)
935 "enabled; returning -EIO\n"); 893 "enabled; returning -EIO\n");
936 894
937 mutex_unlock(&crypt_stat->cs_mutex); 895 mutex_unlock(&crypt_stat->cs_mutex);
938 fput(lower_file);
939 goto out; 896 goto out;
940 } 897 }
941 rc = 0; 898 rc = 0;
942 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED); 899 crypt_stat->flags &= ~(ECRYPTFS_ENCRYPTED);
943 mutex_unlock(&crypt_stat->cs_mutex); 900 mutex_unlock(&crypt_stat->cs_mutex);
944 fput(lower_file);
945 goto out; 901 goto out;
946 } 902 }
947 fput(lower_file);
948 } 903 }
949 mutex_unlock(&crypt_stat->cs_mutex); 904 mutex_unlock(&crypt_stat->cs_mutex);
950 if (ia->ia_valid & ATTR_SIZE) { 905 if (ia->ia_valid & ATTR_SIZE) {
@@ -986,13 +941,11 @@ out:
986} 941}
987 942
988ssize_t 943ssize_t
989ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value, 944ecryptfs_getxattr_lower(struct dentry *lower_dentry, const char *name,
990 size_t size) 945 void *value, size_t size)
991{ 946{
992 int rc = 0; 947 int rc = 0;
993 struct dentry *lower_dentry;
994 948
995 lower_dentry = ecryptfs_dentry_to_lower(dentry);
996 if (!lower_dentry->d_inode->i_op->getxattr) { 949 if (!lower_dentry->d_inode->i_op->getxattr) {
997 rc = -ENOSYS; 950 rc = -ENOSYS;
998 goto out; 951 goto out;
@@ -1005,6 +958,14 @@ out:
1005 return rc; 958 return rc;
1006} 959}
1007 960
961ssize_t
962ecryptfs_getxattr(struct dentry *dentry, const char *name, void *value,
963 size_t size)
964{
965 return ecryptfs_getxattr_lower(ecryptfs_dentry_to_lower(dentry), name,
966 value, size);
967}
968
1008static ssize_t 969static ssize_t
1009ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size) 970ecryptfs_listxattr(struct dentry *dentry, char *list, size_t size)
1010{ 971{
diff --git a/fs/ecryptfs/keystore.c b/fs/ecryptfs/keystore.c
index b550dea8eee6..89d9710dd63d 100644
--- a/fs/ecryptfs/keystore.c
+++ b/fs/ecryptfs/keystore.c
@@ -39,7 +39,7 @@
39 * determine the type of error, make appropriate log entries, and 39 * determine the type of error, make appropriate log entries, and
40 * return an error code. 40 * return an error code.
41 */ 41 */
42int process_request_key_err(long err_code) 42static int process_request_key_err(long err_code)
43{ 43{
44 int rc = 0; 44 int rc = 0;
45 45
@@ -71,7 +71,7 @@ int process_request_key_err(long err_code)
71 * address; zero on error 71 * address; zero on error
72 * @length_size: The number of bytes occupied by the encoded length 72 * @length_size: The number of bytes occupied by the encoded length
73 * 73 *
74 * Returns Zero on success 74 * Returns zero on success; non-zero on error
75 */ 75 */
76static int parse_packet_length(unsigned char *data, size_t *size, 76static int parse_packet_length(unsigned char *data, size_t *size,
77 size_t *length_size) 77 size_t *length_size)
@@ -106,11 +106,11 @@ out:
106 106
107/** 107/**
108 * write_packet_length 108 * write_packet_length
109 * @dest: The byte array target into which to write the 109 * @dest: The byte array target into which to write the length. Must
110 * length. Must have at least 5 bytes allocated. 110 * have at least 5 bytes allocated.
111 * @size: The length to write. 111 * @size: The length to write.
112 * @packet_size_length: The number of bytes used to encode the 112 * @packet_size_length: The number of bytes used to encode the packet
113 * packet length is written to this address. 113 * length is written to this address.
114 * 114 *
115 * Returns zero on success; non-zero on error. 115 * Returns zero on success; non-zero on error.
116 */ 116 */
@@ -396,26 +396,53 @@ out:
396 return rc; 396 return rc;
397} 397}
398 398
399static int
400ecryptfs_get_auth_tok_sig(char **sig, struct ecryptfs_auth_tok *auth_tok)
401{
402 int rc = 0;
403
404 (*sig) = NULL;
405 switch (auth_tok->token_type) {
406 case ECRYPTFS_PASSWORD:
407 (*sig) = auth_tok->token.password.signature;
408 break;
409 case ECRYPTFS_PRIVATE_KEY:
410 (*sig) = auth_tok->token.private_key.signature;
411 break;
412 default:
413 printk(KERN_ERR "Cannot get sig for auth_tok of type [%d]\n",
414 auth_tok->token_type);
415 rc = -EINVAL;
416 }
417 return rc;
418}
419
399/** 420/**
400 * decrypt_pki_encrypted_session_key - Decrypt the session key with 421 * decrypt_pki_encrypted_session_key - Decrypt the session key with the given auth_tok.
401 * the given auth_tok. 422 * @auth_tok: The key authentication token used to decrypt the session key
423 * @crypt_stat: The cryptographic context
402 * 424 *
403 * Returns Zero on success; non-zero error otherwise. 425 * Returns zero on success; non-zero error otherwise.
404 */ 426 */
405static int decrypt_pki_encrypted_session_key( 427static int
406 struct ecryptfs_mount_crypt_stat *mount_crypt_stat, 428decrypt_pki_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
407 struct ecryptfs_auth_tok *auth_tok, 429 struct ecryptfs_crypt_stat *crypt_stat)
408 struct ecryptfs_crypt_stat *crypt_stat)
409{ 430{
410 u16 cipher_code = 0; 431 u16 cipher_code = 0;
411 struct ecryptfs_msg_ctx *msg_ctx; 432 struct ecryptfs_msg_ctx *msg_ctx;
412 struct ecryptfs_message *msg = NULL; 433 struct ecryptfs_message *msg = NULL;
434 char *auth_tok_sig;
413 char *netlink_message; 435 char *netlink_message;
414 size_t netlink_message_length; 436 size_t netlink_message_length;
415 int rc; 437 int rc;
416 438
417 rc = write_tag_64_packet(mount_crypt_stat->global_auth_tok_sig, 439 rc = ecryptfs_get_auth_tok_sig(&auth_tok_sig, auth_tok);
418 &(auth_tok->session_key), 440 if (rc) {
441 printk(KERN_ERR "Unrecognized auth tok type: [%d]\n",
442 auth_tok->token_type);
443 goto out;
444 }
445 rc = write_tag_64_packet(auth_tok_sig, &(auth_tok->session_key),
419 &netlink_message, &netlink_message_length); 446 &netlink_message, &netlink_message_length);
420 if (rc) { 447 if (rc) {
421 ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet"); 448 ecryptfs_printk(KERN_ERR, "Failed to write tag 64 packet");
@@ -465,40 +492,33 @@ out:
465 492
466static void wipe_auth_tok_list(struct list_head *auth_tok_list_head) 493static void wipe_auth_tok_list(struct list_head *auth_tok_list_head)
467{ 494{
468 struct list_head *walker;
469 struct ecryptfs_auth_tok_list_item *auth_tok_list_item; 495 struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
496 struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp;
470 497
471 walker = auth_tok_list_head->next; 498 list_for_each_entry_safe(auth_tok_list_item, auth_tok_list_item_tmp,
472 while (walker != auth_tok_list_head) { 499 auth_tok_list_head, list) {
473 auth_tok_list_item = 500 list_del(&auth_tok_list_item->list);
474 list_entry(walker, struct ecryptfs_auth_tok_list_item,
475 list);
476 walker = auth_tok_list_item->list.next;
477 memset(auth_tok_list_item, 0,
478 sizeof(struct ecryptfs_auth_tok_list_item));
479 kmem_cache_free(ecryptfs_auth_tok_list_item_cache, 501 kmem_cache_free(ecryptfs_auth_tok_list_item_cache,
480 auth_tok_list_item); 502 auth_tok_list_item);
481 } 503 }
482 auth_tok_list_head->next = NULL;
483} 504}
484 505
485struct kmem_cache *ecryptfs_auth_tok_list_item_cache; 506struct kmem_cache *ecryptfs_auth_tok_list_item_cache;
486 507
487
488/** 508/**
489 * parse_tag_1_packet 509 * parse_tag_1_packet
490 * @crypt_stat: The cryptographic context to modify based on packet 510 * @crypt_stat: The cryptographic context to modify based on packet contents
491 * contents.
492 * @data: The raw bytes of the packet. 511 * @data: The raw bytes of the packet.
493 * @auth_tok_list: eCryptfs parses packets into authentication tokens; 512 * @auth_tok_list: eCryptfs parses packets into authentication tokens;
494 * a new authentication token will be placed at the end 513 * a new authentication token will be placed at the
495 * of this list for this packet. 514 * end of this list for this packet.
496 * @new_auth_tok: Pointer to a pointer to memory that this function 515 * @new_auth_tok: Pointer to a pointer to memory that this function
497 * allocates; sets the memory address of the pointer to 516 * allocates; sets the memory address of the pointer to
498 * NULL on error. This object is added to the 517 * NULL on error. This object is added to the
499 * auth_tok_list. 518 * auth_tok_list.
500 * @packet_size: This function writes the size of the parsed packet 519 * @packet_size: This function writes the size of the parsed packet
501 * into this memory location; zero on error. 520 * into this memory location; zero on error.
521 * @max_packet_size: The maximum allowable packet size
502 * 522 *
503 * Returns zero on success; non-zero on error. 523 * Returns zero on success; non-zero on error.
504 */ 524 */
@@ -515,72 +535,65 @@ parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat,
515 535
516 (*packet_size) = 0; 536 (*packet_size) = 0;
517 (*new_auth_tok) = NULL; 537 (*new_auth_tok) = NULL;
518 538 /**
519 /* we check that: 539 * This format is inspired by OpenPGP; see RFC 2440
520 * one byte for the Tag 1 ID flag 540 * packet tag 1
521 * two bytes for the body size 541 *
522 * do not exceed the maximum_packet_size 542 * Tag 1 identifier (1 byte)
543 * Max Tag 1 packet size (max 3 bytes)
544 * Version (1 byte)
545 * Key identifier (8 bytes; ECRYPTFS_SIG_SIZE)
546 * Cipher identifier (1 byte)
547 * Encrypted key size (arbitrary)
548 *
549 * 12 bytes minimum packet size
523 */ 550 */
524 if (unlikely((*packet_size) + 3 > max_packet_size)) { 551 if (unlikely(max_packet_size < 12)) {
525 ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); 552 printk(KERN_ERR "Invalid max packet size; must be >=12\n");
526 rc = -EINVAL; 553 rc = -EINVAL;
527 goto out; 554 goto out;
528 } 555 }
529 /* check for Tag 1 identifier - one byte */
530 if (data[(*packet_size)++] != ECRYPTFS_TAG_1_PACKET_TYPE) { 556 if (data[(*packet_size)++] != ECRYPTFS_TAG_1_PACKET_TYPE) {
531 ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n", 557 printk(KERN_ERR "Enter w/ first byte != 0x%.2x\n",
532 ECRYPTFS_TAG_1_PACKET_TYPE); 558 ECRYPTFS_TAG_1_PACKET_TYPE);
533 rc = -EINVAL; 559 rc = -EINVAL;
534 goto out; 560 goto out;
535 } 561 }
536 /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or 562 /* Released: wipe_auth_tok_list called in ecryptfs_parse_packet_set or
537 * at end of function upon failure */ 563 * at end of function upon failure */
538 auth_tok_list_item = 564 auth_tok_list_item =
539 kmem_cache_alloc(ecryptfs_auth_tok_list_item_cache, 565 kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache,
540 GFP_KERNEL); 566 GFP_KERNEL);
541 if (!auth_tok_list_item) { 567 if (!auth_tok_list_item) {
542 ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); 568 printk(KERN_ERR "Unable to allocate memory\n");
543 rc = -ENOMEM; 569 rc = -ENOMEM;
544 goto out; 570 goto out;
545 } 571 }
546 memset(auth_tok_list_item, 0,
547 sizeof(struct ecryptfs_auth_tok_list_item));
548 (*new_auth_tok) = &auth_tok_list_item->auth_tok; 572 (*new_auth_tok) = &auth_tok_list_item->auth_tok;
549 /* check for body size - one to two bytes
550 *
551 * ***** TAG 1 Packet Format *****
552 * | version number | 1 byte |
553 * | key ID | 8 bytes |
554 * | public key algorithm | 1 byte |
555 * | encrypted session key | arbitrary |
556 */
557 rc = parse_packet_length(&data[(*packet_size)], &body_size, 573 rc = parse_packet_length(&data[(*packet_size)], &body_size,
558 &length_size); 574 &length_size);
559 if (rc) { 575 if (rc) {
560 ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " 576 printk(KERN_WARNING "Error parsing packet length; "
561 "rc = [%d]\n", rc); 577 "rc = [%d]\n", rc);
562 goto out_free; 578 goto out_free;
563 } 579 }
564 if (unlikely(body_size < (0x02 + ECRYPTFS_SIG_SIZE))) { 580 if (unlikely(body_size < (ECRYPTFS_SIG_SIZE + 2))) {
565 ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n", 581 printk(KERN_WARNING "Invalid body size ([%td])\n", body_size);
566 body_size);
567 rc = -EINVAL; 582 rc = -EINVAL;
568 goto out_free; 583 goto out_free;
569 } 584 }
570 (*packet_size) += length_size; 585 (*packet_size) += length_size;
571 if (unlikely((*packet_size) + body_size > max_packet_size)) { 586 if (unlikely((*packet_size) + body_size > max_packet_size)) {
572 ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); 587 printk(KERN_WARNING "Packet size exceeds max\n");
573 rc = -EINVAL; 588 rc = -EINVAL;
574 goto out_free; 589 goto out_free;
575 } 590 }
576 /* Version 3 (from RFC2440) - one byte */
577 if (unlikely(data[(*packet_size)++] != 0x03)) { 591 if (unlikely(data[(*packet_size)++] != 0x03)) {
578 ecryptfs_printk(KERN_DEBUG, "Unknown version number " 592 printk(KERN_WARNING "Unknown version number [%d]\n",
579 "[%d]\n", data[(*packet_size) - 1]); 593 data[(*packet_size) - 1]);
580 rc = -EINVAL; 594 rc = -EINVAL;
581 goto out_free; 595 goto out_free;
582 } 596 }
583 /* Read Signature */
584 ecryptfs_to_hex((*new_auth_tok)->token.private_key.signature, 597 ecryptfs_to_hex((*new_auth_tok)->token.private_key.signature,
585 &data[(*packet_size)], ECRYPTFS_SIG_SIZE); 598 &data[(*packet_size)], ECRYPTFS_SIG_SIZE);
586 *packet_size += ECRYPTFS_SIG_SIZE; 599 *packet_size += ECRYPTFS_SIG_SIZE;
@@ -588,27 +601,23 @@ parse_tag_1_packet(struct ecryptfs_crypt_stat *crypt_stat,
588 * know which public key encryption algorithm was used */ 601 * know which public key encryption algorithm was used */
589 (*packet_size)++; 602 (*packet_size)++;
590 (*new_auth_tok)->session_key.encrypted_key_size = 603 (*new_auth_tok)->session_key.encrypted_key_size =
591 body_size - (0x02 + ECRYPTFS_SIG_SIZE); 604 body_size - (ECRYPTFS_SIG_SIZE + 2);
592 if ((*new_auth_tok)->session_key.encrypted_key_size 605 if ((*new_auth_tok)->session_key.encrypted_key_size
593 > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) { 606 > ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES) {
594 ecryptfs_printk(KERN_ERR, "Tag 1 packet contains key larger " 607 printk(KERN_WARNING "Tag 1 packet contains key larger "
595 "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES"); 608 "than ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES");
596 rc = -EINVAL; 609 rc = -EINVAL;
597 goto out; 610 goto out;
598 } 611 }
599 ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n",
600 (*new_auth_tok)->session_key.encrypted_key_size);
601 memcpy((*new_auth_tok)->session_key.encrypted_key, 612 memcpy((*new_auth_tok)->session_key.encrypted_key,
602 &data[(*packet_size)], (body_size - 0x02 - ECRYPTFS_SIG_SIZE)); 613 &data[(*packet_size)], (body_size - (ECRYPTFS_SIG_SIZE + 2)));
603 (*packet_size) += (*new_auth_tok)->session_key.encrypted_key_size; 614 (*packet_size) += (*new_auth_tok)->session_key.encrypted_key_size;
604 (*new_auth_tok)->session_key.flags &= 615 (*new_auth_tok)->session_key.flags &=
605 ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; 616 ~ECRYPTFS_CONTAINS_DECRYPTED_KEY;
606 (*new_auth_tok)->session_key.flags |= 617 (*new_auth_tok)->session_key.flags |=
607 ECRYPTFS_CONTAINS_ENCRYPTED_KEY; 618 ECRYPTFS_CONTAINS_ENCRYPTED_KEY;
608 (*new_auth_tok)->token_type = ECRYPTFS_PRIVATE_KEY; 619 (*new_auth_tok)->token_type = ECRYPTFS_PRIVATE_KEY;
609 (*new_auth_tok)->flags |= ECRYPTFS_PRIVATE_KEY; 620 (*new_auth_tok)->flags = 0;
610 /* TODO: Why are we setting this flag here? Don't we want the
611 * userspace to decrypt the session key? */
612 (*new_auth_tok)->session_key.flags &= 621 (*new_auth_tok)->session_key.flags &=
613 ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT); 622 ~(ECRYPTFS_USERSPACE_SHOULD_TRY_TO_DECRYPT);
614 (*new_auth_tok)->session_key.flags &= 623 (*new_auth_tok)->session_key.flags &=
@@ -658,22 +667,30 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
658 667
659 (*packet_size) = 0; 668 (*packet_size) = 0;
660 (*new_auth_tok) = NULL; 669 (*new_auth_tok) = NULL;
661 670 /**
662 /* we check that: 671 *This format is inspired by OpenPGP; see RFC 2440
663 * one byte for the Tag 3 ID flag 672 * packet tag 3
664 * two bytes for the body size 673 *
665 * do not exceed the maximum_packet_size 674 * Tag 3 identifier (1 byte)
675 * Max Tag 3 packet size (max 3 bytes)
676 * Version (1 byte)
677 * Cipher code (1 byte)
678 * S2K specifier (1 byte)
679 * Hash identifier (1 byte)
680 * Salt (ECRYPTFS_SALT_SIZE)
681 * Hash iterations (1 byte)
682 * Encrypted key (arbitrary)
683 *
684 * (ECRYPTFS_SALT_SIZE + 7) minimum packet size
666 */ 685 */
667 if (unlikely((*packet_size) + 3 > max_packet_size)) { 686 if (max_packet_size < (ECRYPTFS_SALT_SIZE + 7)) {
668 ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); 687 printk(KERN_ERR "Max packet size too large\n");
669 rc = -EINVAL; 688 rc = -EINVAL;
670 goto out; 689 goto out;
671 } 690 }
672
673 /* check for Tag 3 identifyer - one byte */
674 if (data[(*packet_size)++] != ECRYPTFS_TAG_3_PACKET_TYPE) { 691 if (data[(*packet_size)++] != ECRYPTFS_TAG_3_PACKET_TYPE) {
675 ecryptfs_printk(KERN_ERR, "Enter w/ first byte != 0x%.2x\n", 692 printk(KERN_ERR "First byte != 0x%.2x; invalid packet\n",
676 ECRYPTFS_TAG_3_PACKET_TYPE); 693 ECRYPTFS_TAG_3_PACKET_TYPE);
677 rc = -EINVAL; 694 rc = -EINVAL;
678 goto out; 695 goto out;
679 } 696 }
@@ -682,56 +699,37 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
682 auth_tok_list_item = 699 auth_tok_list_item =
683 kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL); 700 kmem_cache_zalloc(ecryptfs_auth_tok_list_item_cache, GFP_KERNEL);
684 if (!auth_tok_list_item) { 701 if (!auth_tok_list_item) {
685 ecryptfs_printk(KERN_ERR, "Unable to allocate memory\n"); 702 printk(KERN_ERR "Unable to allocate memory\n");
686 rc = -ENOMEM; 703 rc = -ENOMEM;
687 goto out; 704 goto out;
688 } 705 }
689 (*new_auth_tok) = &auth_tok_list_item->auth_tok; 706 (*new_auth_tok) = &auth_tok_list_item->auth_tok;
690
691 /* check for body size - one to two bytes */
692 rc = parse_packet_length(&data[(*packet_size)], &body_size, 707 rc = parse_packet_length(&data[(*packet_size)], &body_size,
693 &length_size); 708 &length_size);
694 if (rc) { 709 if (rc) {
695 ecryptfs_printk(KERN_WARNING, "Error parsing packet length; " 710 printk(KERN_WARNING "Error parsing packet length; rc = [%d]\n",
696 "rc = [%d]\n", rc); 711 rc);
697 goto out_free; 712 goto out_free;
698 } 713 }
699 if (unlikely(body_size < (0x05 + ECRYPTFS_SALT_SIZE))) { 714 if (unlikely(body_size < (ECRYPTFS_SALT_SIZE + 5))) {
700 ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n", 715 printk(KERN_WARNING "Invalid body size ([%td])\n", body_size);
701 body_size);
702 rc = -EINVAL; 716 rc = -EINVAL;
703 goto out_free; 717 goto out_free;
704 } 718 }
705 (*packet_size) += length_size; 719 (*packet_size) += length_size;
706
707 /* now we know the length of the remainting Tag 3 packet size:
708 * 5 fix bytes for: version string, cipher, S2K ID, hash algo,
709 * number of hash iterations
710 * ECRYPTFS_SALT_SIZE bytes for salt
711 * body_size bytes minus the stuff above is the encrypted key size
712 */
713 if (unlikely((*packet_size) + body_size > max_packet_size)) { 720 if (unlikely((*packet_size) + body_size > max_packet_size)) {
714 ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); 721 printk(KERN_ERR "Packet size exceeds max\n");
715 rc = -EINVAL; 722 rc = -EINVAL;
716 goto out_free; 723 goto out_free;
717 } 724 }
718
719 /* There are 5 characters of additional information in the
720 * packet */
721 (*new_auth_tok)->session_key.encrypted_key_size = 725 (*new_auth_tok)->session_key.encrypted_key_size =
722 body_size - (0x05 + ECRYPTFS_SALT_SIZE); 726 (body_size - (ECRYPTFS_SALT_SIZE + 5));
723 ecryptfs_printk(KERN_DEBUG, "Encrypted key size = [%d]\n",
724 (*new_auth_tok)->session_key.encrypted_key_size);
725
726 /* Version 4 (from RFC2440) - one byte */
727 if (unlikely(data[(*packet_size)++] != 0x04)) { 727 if (unlikely(data[(*packet_size)++] != 0x04)) {
728 ecryptfs_printk(KERN_DEBUG, "Unknown version number " 728 printk(KERN_WARNING "Unknown version number [%d]\n",
729 "[%d]\n", data[(*packet_size) - 1]); 729 data[(*packet_size) - 1]);
730 rc = -EINVAL; 730 rc = -EINVAL;
731 goto out_free; 731 goto out_free;
732 } 732 }
733
734 /* cipher - one byte */
735 ecryptfs_cipher_code_to_string(crypt_stat->cipher, 733 ecryptfs_cipher_code_to_string(crypt_stat->cipher,
736 (u16)data[(*packet_size)]); 734 (u16)data[(*packet_size)]);
737 /* A little extra work to differentiate among the AES key 735 /* A little extra work to differentiate among the AES key
@@ -745,33 +743,26 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
745 (*new_auth_tok)->session_key.encrypted_key_size; 743 (*new_auth_tok)->session_key.encrypted_key_size;
746 } 744 }
747 ecryptfs_init_crypt_ctx(crypt_stat); 745 ecryptfs_init_crypt_ctx(crypt_stat);
748 /* S2K identifier 3 (from RFC2440) */
749 if (unlikely(data[(*packet_size)++] != 0x03)) { 746 if (unlikely(data[(*packet_size)++] != 0x03)) {
750 ecryptfs_printk(KERN_ERR, "Only S2K ID 3 is currently " 747 printk(KERN_WARNING "Only S2K ID 3 is currently supported\n");
751 "supported\n");
752 rc = -ENOSYS; 748 rc = -ENOSYS;
753 goto out_free; 749 goto out_free;
754 } 750 }
755
756 /* TODO: finish the hash mapping */ 751 /* TODO: finish the hash mapping */
757 /* hash algorithm - one byte */
758 switch (data[(*packet_size)++]) { 752 switch (data[(*packet_size)++]) {
759 case 0x01: /* See RFC2440 for these numbers and their mappings */ 753 case 0x01: /* See RFC2440 for these numbers and their mappings */
760 /* Choose MD5 */ 754 /* Choose MD5 */
761 /* salt - ECRYPTFS_SALT_SIZE bytes */
762 memcpy((*new_auth_tok)->token.password.salt, 755 memcpy((*new_auth_tok)->token.password.salt,
763 &data[(*packet_size)], ECRYPTFS_SALT_SIZE); 756 &data[(*packet_size)], ECRYPTFS_SALT_SIZE);
764 (*packet_size) += ECRYPTFS_SALT_SIZE; 757 (*packet_size) += ECRYPTFS_SALT_SIZE;
765
766 /* This conversion was taken straight from RFC2440 */ 758 /* This conversion was taken straight from RFC2440 */
767 /* number of hash iterations - one byte */
768 (*new_auth_tok)->token.password.hash_iterations = 759 (*new_auth_tok)->token.password.hash_iterations =
769 ((u32) 16 + (data[(*packet_size)] & 15)) 760 ((u32) 16 + (data[(*packet_size)] & 15))
770 << ((data[(*packet_size)] >> 4) + 6); 761 << ((data[(*packet_size)] >> 4) + 6);
771 (*packet_size)++; 762 (*packet_size)++;
772 763 /* Friendly reminder:
773 /* encrypted session key - 764 * (*new_auth_tok)->session_key.encrypted_key_size =
774 * (body_size-5-ECRYPTFS_SALT_SIZE) bytes */ 765 * (body_size - (ECRYPTFS_SALT_SIZE + 5)); */
775 memcpy((*new_auth_tok)->session_key.encrypted_key, 766 memcpy((*new_auth_tok)->session_key.encrypted_key,
776 &data[(*packet_size)], 767 &data[(*packet_size)],
777 (*new_auth_tok)->session_key.encrypted_key_size); 768 (*new_auth_tok)->session_key.encrypted_key_size);
@@ -781,7 +772,7 @@ parse_tag_3_packet(struct ecryptfs_crypt_stat *crypt_stat,
781 ~ECRYPTFS_CONTAINS_DECRYPTED_KEY; 772 ~ECRYPTFS_CONTAINS_DECRYPTED_KEY;
782 (*new_auth_tok)->session_key.flags |= 773 (*new_auth_tok)->session_key.flags |=
783 ECRYPTFS_CONTAINS_ENCRYPTED_KEY; 774 ECRYPTFS_CONTAINS_ENCRYPTED_KEY;
784 (*new_auth_tok)->token.password.hash_algo = 0x01; 775 (*new_auth_tok)->token.password.hash_algo = 0x01; /* MD5 */
785 break; 776 break;
786 default: 777 default:
787 ecryptfs_printk(KERN_ERR, "Unsupported hash algorithm: " 778 ecryptfs_printk(KERN_ERR, "Unsupported hash algorithm: "
@@ -837,82 +828,61 @@ parse_tag_11_packet(unsigned char *data, unsigned char *contents,
837 828
838 (*packet_size) = 0; 829 (*packet_size) = 0;
839 (*tag_11_contents_size) = 0; 830 (*tag_11_contents_size) = 0;
840 831 /* This format is inspired by OpenPGP; see RFC 2440
841 /* check that: 832 * packet tag 11
842 * one byte for the Tag 11 ID flag 833 *
843 * two bytes for the Tag 11 length 834 * Tag 11 identifier (1 byte)
844 * do not exceed the maximum_packet_size 835 * Max Tag 11 packet size (max 3 bytes)
836 * Binary format specifier (1 byte)
837 * Filename length (1 byte)
838 * Filename ("_CONSOLE") (8 bytes)
839 * Modification date (4 bytes)
840 * Literal data (arbitrary)
841 *
842 * We need at least 16 bytes of data for the packet to even be
843 * valid.
845 */ 844 */
846 if (unlikely((*packet_size) + 3 > max_packet_size)) { 845 if (max_packet_size < 16) {
847 ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); 846 printk(KERN_ERR "Maximum packet size too small\n");
848 rc = -EINVAL; 847 rc = -EINVAL;
849 goto out; 848 goto out;
850 } 849 }
851
852 /* check for Tag 11 identifyer - one byte */
853 if (data[(*packet_size)++] != ECRYPTFS_TAG_11_PACKET_TYPE) { 850 if (data[(*packet_size)++] != ECRYPTFS_TAG_11_PACKET_TYPE) {
854 ecryptfs_printk(KERN_WARNING, 851 printk(KERN_WARNING "Invalid tag 11 packet format\n");
855 "Invalid tag 11 packet format\n");
856 rc = -EINVAL; 852 rc = -EINVAL;
857 goto out; 853 goto out;
858 } 854 }
859
860 /* get Tag 11 content length - one or two bytes */
861 rc = parse_packet_length(&data[(*packet_size)], &body_size, 855 rc = parse_packet_length(&data[(*packet_size)], &body_size,
862 &length_size); 856 &length_size);
863 if (rc) { 857 if (rc) {
864 ecryptfs_printk(KERN_WARNING, 858 printk(KERN_WARNING "Invalid tag 11 packet format\n");
865 "Invalid tag 11 packet format\n");
866 goto out; 859 goto out;
867 } 860 }
868 (*packet_size) += length_size; 861 if (body_size < 14) {
869 862 printk(KERN_WARNING "Invalid body size ([%td])\n", body_size);
870 if (body_size < 13) {
871 ecryptfs_printk(KERN_WARNING, "Invalid body size ([%d])\n",
872 body_size);
873 rc = -EINVAL; 863 rc = -EINVAL;
874 goto out; 864 goto out;
875 } 865 }
876 /* We have 13 bytes of surrounding packet values */ 866 (*packet_size) += length_size;
877 (*tag_11_contents_size) = (body_size - 13); 867 (*tag_11_contents_size) = (body_size - 14);
878
879 /* now we know the length of the remainting Tag 11 packet size:
880 * 14 fix bytes for: special flag one, special flag two,
881 * 12 skipped bytes
882 * body_size bytes minus the stuff above is the Tag 11 content
883 */
884 /* FIXME why is the body size one byte smaller than the actual
885 * size of the body?
886 * this seems to be an error here as well as in
887 * write_tag_11_packet() */
888 if (unlikely((*packet_size) + body_size + 1 > max_packet_size)) { 868 if (unlikely((*packet_size) + body_size + 1 > max_packet_size)) {
889 ecryptfs_printk(KERN_ERR, "Packet size exceeds max\n"); 869 printk(KERN_ERR "Packet size exceeds max\n");
890 rc = -EINVAL; 870 rc = -EINVAL;
891 goto out; 871 goto out;
892 } 872 }
893
894 /* special flag one - one byte */
895 if (data[(*packet_size)++] != 0x62) { 873 if (data[(*packet_size)++] != 0x62) {
896 ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n"); 874 printk(KERN_WARNING "Unrecognizable packet\n");
897 rc = -EINVAL; 875 rc = -EINVAL;
898 goto out; 876 goto out;
899 } 877 }
900
901 /* special flag two - one byte */
902 if (data[(*packet_size)++] != 0x08) { 878 if (data[(*packet_size)++] != 0x08) {
903 ecryptfs_printk(KERN_WARNING, "Unrecognizable packet\n"); 879 printk(KERN_WARNING "Unrecognizable packet\n");
904 rc = -EINVAL; 880 rc = -EINVAL;
905 goto out; 881 goto out;
906 } 882 }
907 883 (*packet_size) += 12; /* Ignore filename and modification date */
908 /* skip the next 12 bytes */
909 (*packet_size) += 12; /* We don't care about the filename or
910 * the timestamp */
911
912 /* get the Tag 11 contents - tag_11_contents_size bytes */
913 memcpy(contents, &data[(*packet_size)], (*tag_11_contents_size)); 884 memcpy(contents, &data[(*packet_size)], (*tag_11_contents_size));
914 (*packet_size) += (*tag_11_contents_size); 885 (*packet_size) += (*tag_11_contents_size);
915
916out: 886out:
917 if (rc) { 887 if (rc) {
918 (*packet_size) = 0; 888 (*packet_size) = 0;
@@ -921,130 +891,229 @@ out:
921 return rc; 891 return rc;
922} 892}
923 893
894static int
895ecryptfs_find_global_auth_tok_for_sig(
896 struct ecryptfs_global_auth_tok **global_auth_tok,
897 struct ecryptfs_mount_crypt_stat *mount_crypt_stat, char *sig)
898{
899 struct ecryptfs_global_auth_tok *walker;
900 int rc = 0;
901
902 (*global_auth_tok) = NULL;
903 mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
904 list_for_each_entry(walker,
905 &mount_crypt_stat->global_auth_tok_list,
906 mount_crypt_stat_list) {
907 if (memcmp(walker->sig, sig, ECRYPTFS_SIG_SIZE_HEX) == 0) {
908 (*global_auth_tok) = walker;
909 goto out;
910 }
911 }
912 rc = -EINVAL;
913out:
914 mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
915 return rc;
916}
917
924/** 918/**
925 * decrypt_session_key - Decrypt the session key with the given auth_tok. 919 * ecryptfs_verify_version
920 * @version: The version number to confirm
926 * 921 *
927 * Returns Zero on success; non-zero error otherwise. 922 * Returns zero on good version; non-zero otherwise
928 */ 923 */
929static int decrypt_session_key(struct ecryptfs_auth_tok *auth_tok, 924static int ecryptfs_verify_version(u16 version)
930 struct ecryptfs_crypt_stat *crypt_stat)
931{ 925{
932 struct ecryptfs_password *password_s_ptr; 926 int rc = 0;
933 struct scatterlist src_sg[2], dst_sg[2]; 927 unsigned char major;
934 struct mutex *tfm_mutex = NULL; 928 unsigned char minor;
935 char *encrypted_session_key; 929
936 char *session_key; 930 major = ((version >> 8) & 0xFF);
931 minor = (version & 0xFF);
932 if (major != ECRYPTFS_VERSION_MAJOR) {
933 ecryptfs_printk(KERN_ERR, "Major version number mismatch. "
934 "Expected [%d]; got [%d]\n",
935 ECRYPTFS_VERSION_MAJOR, major);
936 rc = -EINVAL;
937 goto out;
938 }
939 if (minor != ECRYPTFS_VERSION_MINOR) {
940 ecryptfs_printk(KERN_ERR, "Minor version number mismatch. "
941 "Expected [%d]; got [%d]\n",
942 ECRYPTFS_VERSION_MINOR, minor);
943 rc = -EINVAL;
944 goto out;
945 }
946out:
947 return rc;
948}
949
950int ecryptfs_keyring_auth_tok_for_sig(struct key **auth_tok_key,
951 struct ecryptfs_auth_tok **auth_tok,
952 char *sig)
953{
954 int rc = 0;
955
956 (*auth_tok_key) = request_key(&key_type_user, sig, NULL);
957 if (!(*auth_tok_key) || IS_ERR(*auth_tok_key)) {
958 printk(KERN_ERR "Could not find key with description: [%s]\n",
959 sig);
960 process_request_key_err(PTR_ERR(*auth_tok_key));
961 rc = -EINVAL;
962 goto out;
963 }
964 (*auth_tok) = ecryptfs_get_key_payload_data(*auth_tok_key);
965 if (ecryptfs_verify_version((*auth_tok)->version)) {
966 printk(KERN_ERR
967 "Data structure version mismatch. "
968 "Userspace tools must match eCryptfs "
969 "kernel module with major version [%d] "
970 "and minor version [%d]\n",
971 ECRYPTFS_VERSION_MAJOR,
972 ECRYPTFS_VERSION_MINOR);
973 rc = -EINVAL;
974 goto out;
975 }
976 if ((*auth_tok)->token_type != ECRYPTFS_PASSWORD
977 && (*auth_tok)->token_type != ECRYPTFS_PRIVATE_KEY) {
978 printk(KERN_ERR "Invalid auth_tok structure "
979 "returned from key query\n");
980 rc = -EINVAL;
981 goto out;
982 }
983out:
984 return rc;
985}
986
987/**
988 * ecryptfs_find_auth_tok_for_sig
989 * @auth_tok: Set to the matching auth_tok; NULL if not found
990 * @crypt_stat: inode crypt_stat crypto context
991 * @sig: Sig of auth_tok to find
992 *
993 * For now, this function simply looks at the registered auth_tok's
994 * linked off the mount_crypt_stat, so all the auth_toks that can be
995 * used must be registered at mount time. This function could
996 * potentially try a lot harder to find auth_tok's (e.g., by calling
997 * out to ecryptfsd to dynamically retrieve an auth_tok object) so
998 * that static registration of auth_tok's will no longer be necessary.
999 *
1000 * Returns zero on no error; non-zero on error
1001 */
1002static int
1003ecryptfs_find_auth_tok_for_sig(
1004 struct ecryptfs_auth_tok **auth_tok,
1005 struct ecryptfs_crypt_stat *crypt_stat, char *sig)
1006{
1007 struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
1008 crypt_stat->mount_crypt_stat;
1009 struct ecryptfs_global_auth_tok *global_auth_tok;
1010 int rc = 0;
1011
1012 (*auth_tok) = NULL;
1013 if (ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok,
1014 mount_crypt_stat, sig)) {
1015 struct key *auth_tok_key;
1016
1017 rc = ecryptfs_keyring_auth_tok_for_sig(&auth_tok_key, auth_tok,
1018 sig);
1019 } else
1020 (*auth_tok) = global_auth_tok->global_auth_tok;
1021 return rc;
1022}
1023
1024/**
1025 * decrypt_passphrase_encrypted_session_key - Decrypt the session key with the given auth_tok.
1026 * @auth_tok: The passphrase authentication token to use to encrypt the FEK
1027 * @crypt_stat: The cryptographic context
1028 *
1029 * Returns zero on success; non-zero error otherwise
1030 */
1031static int
1032decrypt_passphrase_encrypted_session_key(struct ecryptfs_auth_tok *auth_tok,
1033 struct ecryptfs_crypt_stat *crypt_stat)
1034{
1035 struct scatterlist dst_sg;
1036 struct scatterlist src_sg;
1037 struct mutex *tfm_mutex;
937 struct blkcipher_desc desc = { 1038 struct blkcipher_desc desc = {
938 .flags = CRYPTO_TFM_REQ_MAY_SLEEP 1039 .flags = CRYPTO_TFM_REQ_MAY_SLEEP
939 }; 1040 };
940 int rc = 0; 1041 int rc = 0;
941 1042
942 password_s_ptr = &auth_tok->token.password; 1043 if (unlikely(ecryptfs_verbosity > 0)) {
943 if (password_s_ptr->flags & ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) 1044 ecryptfs_printk(
944 ecryptfs_printk(KERN_DEBUG, "Session key encryption key " 1045 KERN_DEBUG, "Session key encryption key (size [%d]):\n",
945 "set; skipping key generation\n"); 1046 auth_tok->token.password.session_key_encryption_key_bytes);
946 ecryptfs_printk(KERN_DEBUG, "Session key encryption key (size [%d])" 1047 ecryptfs_dump_hex(
947 ":\n", 1048 auth_tok->token.password.session_key_encryption_key,
948 password_s_ptr->session_key_encryption_key_bytes); 1049 auth_tok->token.password.session_key_encryption_key_bytes);
949 if (ecryptfs_verbosity > 0) 1050 }
950 ecryptfs_dump_hex(password_s_ptr->session_key_encryption_key, 1051 rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex,
951 password_s_ptr-> 1052 crypt_stat->cipher);
952 session_key_encryption_key_bytes); 1053 if (unlikely(rc)) {
953 if (!strcmp(crypt_stat->cipher, 1054 printk(KERN_ERR "Internal error whilst attempting to get "
954 crypt_stat->mount_crypt_stat->global_default_cipher_name) 1055 "tfm and mutex for cipher name [%s]; rc = [%d]\n",
955 && crypt_stat->mount_crypt_stat->global_key_tfm) { 1056 crypt_stat->cipher, rc);
956 desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm; 1057 goto out;
957 tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
958 } else {
959 char *full_alg_name;
960
961 rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
962 crypt_stat->cipher,
963 "ecb");
964 if (rc)
965 goto out;
966 desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0,
967 CRYPTO_ALG_ASYNC);
968 kfree(full_alg_name);
969 if (IS_ERR(desc.tfm)) {
970 rc = PTR_ERR(desc.tfm);
971 printk(KERN_ERR "Error allocating crypto context; "
972 "rc = [%d]\n", rc);
973 goto out;
974 }
975 crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY);
976 } 1058 }
977 if (tfm_mutex) 1059 rc = virt_to_scatterlist(auth_tok->session_key.encrypted_key,
978 mutex_lock(tfm_mutex); 1060 auth_tok->session_key.encrypted_key_size,
979 rc = crypto_blkcipher_setkey(desc.tfm, 1061 &src_sg, 1);
980 password_s_ptr->session_key_encryption_key, 1062 if (rc != 1) {
981 crypt_stat->key_size); 1063 printk(KERN_ERR "Internal error whilst attempting to convert "
982 if (rc < 0) { 1064 "auth_tok->session_key.encrypted_key to scatterlist; "
1065 "expected rc = 1; got rc = [%d]. "
1066 "auth_tok->session_key.encrypted_key_size = [%d]\n", rc,
1067 auth_tok->session_key.encrypted_key_size);
1068 goto out;
1069 }
1070 auth_tok->session_key.decrypted_key_size =
1071 auth_tok->session_key.encrypted_key_size;
1072 rc = virt_to_scatterlist(auth_tok->session_key.decrypted_key,
1073 auth_tok->session_key.decrypted_key_size,
1074 &dst_sg, 1);
1075 if (rc != 1) {
1076 printk(KERN_ERR "Internal error whilst attempting to convert "
1077 "auth_tok->session_key.decrypted_key to scatterlist; "
1078 "expected rc = 1; got rc = [%d]\n", rc);
1079 goto out;
1080 }
1081 mutex_lock(tfm_mutex);
1082 rc = crypto_blkcipher_setkey(
1083 desc.tfm, auth_tok->token.password.session_key_encryption_key,
1084 crypt_stat->key_size);
1085 if (unlikely(rc < 0)) {
1086 mutex_unlock(tfm_mutex);
983 printk(KERN_ERR "Error setting key for crypto context\n"); 1087 printk(KERN_ERR "Error setting key for crypto context\n");
984 rc = -EINVAL; 1088 rc = -EINVAL;
985 goto out_free_tfm; 1089 goto out;
986 }
987 /* TODO: virt_to_scatterlist */
988 encrypted_session_key = (char *)__get_free_page(GFP_KERNEL);
989 if (!encrypted_session_key) {
990 ecryptfs_printk(KERN_ERR, "Out of memory\n");
991 rc = -ENOMEM;
992 goto out_free_tfm;
993 } 1090 }
994 session_key = (char *)__get_free_page(GFP_KERNEL); 1091 rc = crypto_blkcipher_decrypt(&desc, &dst_sg, &src_sg,
995 if (!session_key) {
996 kfree(encrypted_session_key);
997 ecryptfs_printk(KERN_ERR, "Out of memory\n");
998 rc = -ENOMEM;
999 goto out_free_tfm;
1000 }
1001 memcpy(encrypted_session_key, auth_tok->session_key.encrypted_key,
1002 auth_tok->session_key.encrypted_key_size);
1003 src_sg[0].page = virt_to_page(encrypted_session_key);
1004 src_sg[0].offset = 0;
1005 BUG_ON(auth_tok->session_key.encrypted_key_size > PAGE_CACHE_SIZE);
1006 src_sg[0].length = auth_tok->session_key.encrypted_key_size;
1007 dst_sg[0].page = virt_to_page(session_key);
1008 dst_sg[0].offset = 0;
1009 auth_tok->session_key.decrypted_key_size =
1010 auth_tok->session_key.encrypted_key_size;
1011 dst_sg[0].length = auth_tok->session_key.encrypted_key_size;
1012 rc = crypto_blkcipher_decrypt(&desc, dst_sg, src_sg,
1013 auth_tok->session_key.encrypted_key_size); 1092 auth_tok->session_key.encrypted_key_size);
1014 if (rc) { 1093 mutex_unlock(tfm_mutex);
1094 if (unlikely(rc)) {
1015 printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc); 1095 printk(KERN_ERR "Error decrypting; rc = [%d]\n", rc);
1016 goto out_free_memory; 1096 goto out;
1017 } 1097 }
1018 auth_tok->session_key.decrypted_key_size =
1019 auth_tok->session_key.encrypted_key_size;
1020 memcpy(auth_tok->session_key.decrypted_key, session_key,
1021 auth_tok->session_key.decrypted_key_size);
1022 auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY; 1098 auth_tok->session_key.flags |= ECRYPTFS_CONTAINS_DECRYPTED_KEY;
1023 memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key, 1099 memcpy(crypt_stat->key, auth_tok->session_key.decrypted_key,
1024 auth_tok->session_key.decrypted_key_size); 1100 auth_tok->session_key.decrypted_key_size);
1025 crypt_stat->flags |= ECRYPTFS_KEY_VALID; 1101 crypt_stat->flags |= ECRYPTFS_KEY_VALID;
1026 ecryptfs_printk(KERN_DEBUG, "Decrypted session key:\n"); 1102 if (unlikely(ecryptfs_verbosity > 0)) {
1027 if (ecryptfs_verbosity > 0) 1103 ecryptfs_printk(KERN_DEBUG, "FEK of size [%d]:\n",
1104 crypt_stat->key_size);
1028 ecryptfs_dump_hex(crypt_stat->key, 1105 ecryptfs_dump_hex(crypt_stat->key,
1029 crypt_stat->key_size); 1106 crypt_stat->key_size);
1030out_free_memory: 1107 }
1031 memset(encrypted_session_key, 0, PAGE_CACHE_SIZE);
1032 free_page((unsigned long)encrypted_session_key);
1033 memset(session_key, 0, PAGE_CACHE_SIZE);
1034 free_page((unsigned long)session_key);
1035out_free_tfm:
1036 if (tfm_mutex)
1037 mutex_unlock(tfm_mutex);
1038 else
1039 crypto_free_blkcipher(desc.tfm);
1040out: 1108out:
1041 return rc; 1109 return rc;
1042} 1110}
1043 1111
1044/** 1112/**
1045 * ecryptfs_parse_packet_set 1113 * ecryptfs_parse_packet_set
1046 * @dest: The header page in memory 1114 * @crypt_stat: The cryptographic context
1047 * @version: Version of file format, to guide parsing behavior 1115 * @src: Virtual address of region of memory containing the packets
1116 * @ecryptfs_dentry: The eCryptfs dentry associated with the packet set
1048 * 1117 *
1049 * Get crypt_stat to have the file's session key if the requisite key 1118 * Get crypt_stat to have the file's session key if the requisite key
1050 * is available to decrypt the session key. 1119 * is available to decrypt the session key.
@@ -1058,25 +1127,22 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
1058 struct dentry *ecryptfs_dentry) 1127 struct dentry *ecryptfs_dentry)
1059{ 1128{
1060 size_t i = 0; 1129 size_t i = 0;
1061 size_t found_auth_tok = 0; 1130 size_t found_auth_tok;
1062 size_t next_packet_is_auth_tok_packet; 1131 size_t next_packet_is_auth_tok_packet;
1063 char sig[ECRYPTFS_SIG_SIZE_HEX];
1064 struct list_head auth_tok_list; 1132 struct list_head auth_tok_list;
1065 struct list_head *walker; 1133 struct ecryptfs_auth_tok *matching_auth_tok;
1066 struct ecryptfs_auth_tok *chosen_auth_tok = NULL; 1134 struct ecryptfs_auth_tok *candidate_auth_tok;
1067 struct ecryptfs_mount_crypt_stat *mount_crypt_stat = 1135 char *candidate_auth_tok_sig;
1068 &ecryptfs_superblock_to_private(
1069 ecryptfs_dentry->d_sb)->mount_crypt_stat;
1070 struct ecryptfs_auth_tok *candidate_auth_tok = NULL;
1071 size_t packet_size; 1136 size_t packet_size;
1072 struct ecryptfs_auth_tok *new_auth_tok; 1137 struct ecryptfs_auth_tok *new_auth_tok;
1073 unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE]; 1138 unsigned char sig_tmp_space[ECRYPTFS_SIG_SIZE];
1139 struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
1074 size_t tag_11_contents_size; 1140 size_t tag_11_contents_size;
1075 size_t tag_11_packet_size; 1141 size_t tag_11_packet_size;
1076 int rc = 0; 1142 int rc = 0;
1077 1143
1078 INIT_LIST_HEAD(&auth_tok_list); 1144 INIT_LIST_HEAD(&auth_tok_list);
1079 /* Parse the header to find as many packets as we can, these will be 1145 /* Parse the header to find as many packets as we can; these will be
1080 * added the our &auth_tok_list */ 1146 * added the our &auth_tok_list */
1081 next_packet_is_auth_tok_packet = 1; 1147 next_packet_is_auth_tok_packet = 1;
1082 while (next_packet_is_auth_tok_packet) { 1148 while (next_packet_is_auth_tok_packet) {
@@ -1155,73 +1221,85 @@ int ecryptfs_parse_packet_set(struct ecryptfs_crypt_stat *crypt_stat,
1155 } 1221 }
1156 } 1222 }
1157 if (list_empty(&auth_tok_list)) { 1223 if (list_empty(&auth_tok_list)) {
1158 rc = -EINVAL; /* Do not support non-encrypted files in 1224 printk(KERN_ERR "The lower file appears to be a non-encrypted "
1159 * the 0.1 release */ 1225 "eCryptfs file; this is not supported in this version "
1226 "of the eCryptfs kernel module\n");
1227 rc = -EINVAL;
1160 goto out; 1228 goto out;
1161 } 1229 }
1162 /* If we have a global auth tok, then we should try to use 1230 /* auth_tok_list contains the set of authentication tokens
1163 * it */ 1231 * parsed from the metadata. We need to find a matching
1164 if (mount_crypt_stat->global_auth_tok) { 1232 * authentication token that has the secret component(s)
1165 memcpy(sig, mount_crypt_stat->global_auth_tok_sig, 1233 * necessary to decrypt the EFEK in the auth_tok parsed from
1166 ECRYPTFS_SIG_SIZE_HEX); 1234 * the metadata. There may be several potential matches, but
1167 chosen_auth_tok = mount_crypt_stat->global_auth_tok; 1235 * just one will be sufficient to decrypt to get the FEK. */
1168 } else 1236find_next_matching_auth_tok:
1169 BUG(); /* We should always have a global auth tok in 1237 found_auth_tok = 0;
1170 * the 0.1 release */ 1238 list_for_each_entry(auth_tok_list_item, &auth_tok_list, list) {
1171 /* Scan list to see if our chosen_auth_tok works */
1172 list_for_each(walker, &auth_tok_list) {
1173 struct ecryptfs_auth_tok_list_item *auth_tok_list_item;
1174 auth_tok_list_item =
1175 list_entry(walker, struct ecryptfs_auth_tok_list_item,
1176 list);
1177 candidate_auth_tok = &auth_tok_list_item->auth_tok; 1239 candidate_auth_tok = &auth_tok_list_item->auth_tok;
1178 if (unlikely(ecryptfs_verbosity > 0)) { 1240 if (unlikely(ecryptfs_verbosity > 0)) {
1179 ecryptfs_printk(KERN_DEBUG, 1241 ecryptfs_printk(KERN_DEBUG,
1180 "Considering cadidate auth tok:\n"); 1242 "Considering cadidate auth tok:\n");
1181 ecryptfs_dump_auth_tok(candidate_auth_tok); 1243 ecryptfs_dump_auth_tok(candidate_auth_tok);
1182 } 1244 }
1183 /* TODO: Replace ECRYPTFS_SIG_SIZE_HEX w/ dynamic value */ 1245 rc = ecryptfs_get_auth_tok_sig(&candidate_auth_tok_sig,
1184 if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD 1246 candidate_auth_tok);
1185 && !strncmp(candidate_auth_tok->token.password.signature, 1247 if (rc) {
1186 sig, ECRYPTFS_SIG_SIZE_HEX)) { 1248 printk(KERN_ERR
1187 found_auth_tok = 1; 1249 "Unrecognized candidate auth tok type: [%d]\n",
1188 goto leave_list; 1250 candidate_auth_tok->token_type);
1189 /* TODO: Transfer the common salt into the 1251 rc = -EINVAL;
1190 * crypt_stat salt */ 1252 goto out_wipe_list;
1191 } else if ((candidate_auth_tok->token_type 1253 }
1192 == ECRYPTFS_PRIVATE_KEY) 1254 ecryptfs_find_auth_tok_for_sig(&matching_auth_tok, crypt_stat,
1193 && !strncmp(candidate_auth_tok->token.private_key.signature, 1255 candidate_auth_tok_sig);
1194 sig, ECRYPTFS_SIG_SIZE_HEX)) { 1256 if (matching_auth_tok) {
1195 found_auth_tok = 1; 1257 found_auth_tok = 1;
1196 goto leave_list; 1258 goto found_matching_auth_tok;
1197 } 1259 }
1198 } 1260 }
1199 if (!found_auth_tok) { 1261 if (!found_auth_tok) {
1200 ecryptfs_printk(KERN_ERR, "Could not find authentication " 1262 ecryptfs_printk(KERN_ERR, "Could not find a usable "
1201 "token on temporary list for sig [%.*s]\n", 1263 "authentication token\n");
1202 ECRYPTFS_SIG_SIZE_HEX, sig);
1203 rc = -EIO; 1264 rc = -EIO;
1204 goto out_wipe_list; 1265 goto out_wipe_list;
1205 } 1266 }
1206leave_list: 1267found_matching_auth_tok:
1207 rc = -ENOTSUPP;
1208 if (candidate_auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { 1268 if (candidate_auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) {
1209 memcpy(&(candidate_auth_tok->token.private_key), 1269 memcpy(&(candidate_auth_tok->token.private_key),
1210 &(chosen_auth_tok->token.private_key), 1270 &(matching_auth_tok->token.private_key),
1211 sizeof(struct ecryptfs_private_key)); 1271 sizeof(struct ecryptfs_private_key));
1212 rc = decrypt_pki_encrypted_session_key(mount_crypt_stat, 1272 rc = decrypt_pki_encrypted_session_key(candidate_auth_tok,
1213 candidate_auth_tok,
1214 crypt_stat); 1273 crypt_stat);
1215 } else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) { 1274 } else if (candidate_auth_tok->token_type == ECRYPTFS_PASSWORD) {
1216 memcpy(&(candidate_auth_tok->token.password), 1275 memcpy(&(candidate_auth_tok->token.password),
1217 &(chosen_auth_tok->token.password), 1276 &(matching_auth_tok->token.password),
1218 sizeof(struct ecryptfs_password)); 1277 sizeof(struct ecryptfs_password));
1219 rc = decrypt_session_key(candidate_auth_tok, crypt_stat); 1278 rc = decrypt_passphrase_encrypted_session_key(
1279 candidate_auth_tok, crypt_stat);
1220 } 1280 }
1221 if (rc) { 1281 if (rc) {
1222 ecryptfs_printk(KERN_ERR, "Error decrypting the " 1282 struct ecryptfs_auth_tok_list_item *auth_tok_list_item_tmp;
1223 "session key; rc = [%d]\n", rc); 1283
1224 goto out_wipe_list; 1284 ecryptfs_printk(KERN_WARNING, "Error decrypting the "
1285 "session key for authentication token with sig "
1286 "[%.*s]; rc = [%d]. Removing auth tok "
1287 "candidate from the list and searching for "
1288 "the next match.\n", candidate_auth_tok_sig,
1289 ECRYPTFS_SIG_SIZE_HEX, rc);
1290 list_for_each_entry_safe(auth_tok_list_item,
1291 auth_tok_list_item_tmp,
1292 &auth_tok_list, list) {
1293 if (candidate_auth_tok
1294 == &auth_tok_list_item->auth_tok) {
1295 list_del(&auth_tok_list_item->list);
1296 kmem_cache_free(
1297 ecryptfs_auth_tok_list_item_cache,
1298 auth_tok_list_item);
1299 goto find_next_matching_auth_tok;
1300 }
1301 }
1302 BUG();
1225 } 1303 }
1226 rc = ecryptfs_compute_root_iv(crypt_stat); 1304 rc = ecryptfs_compute_root_iv(crypt_stat);
1227 if (rc) { 1305 if (rc) {
@@ -1240,6 +1318,7 @@ out_wipe_list:
1240out: 1318out:
1241 return rc; 1319 return rc;
1242} 1320}
1321
1243static int 1322static int
1244pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok, 1323pki_encrypt_session_key(struct ecryptfs_auth_tok *auth_tok,
1245 struct ecryptfs_crypt_stat *crypt_stat, 1324 struct ecryptfs_crypt_stat *crypt_stat,
@@ -1284,22 +1363,25 @@ out:
1284/** 1363/**
1285 * write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet 1364 * write_tag_1_packet - Write an RFC2440-compatible tag 1 (public key) packet
1286 * @dest: Buffer into which to write the packet 1365 * @dest: Buffer into which to write the packet
1287 * @max: Maximum number of bytes that can be writtn 1366 * @remaining_bytes: Maximum number of bytes that can be writtn
1367 * @auth_tok: The authentication token used for generating the tag 1 packet
1368 * @crypt_stat: The cryptographic context
1369 * @key_rec: The key record struct for the tag 1 packet
1288 * @packet_size: This function will write the number of bytes that end 1370 * @packet_size: This function will write the number of bytes that end
1289 * up constituting the packet; set to zero on error 1371 * up constituting the packet; set to zero on error
1290 * 1372 *
1291 * Returns zero on success; non-zero on error. 1373 * Returns zero on success; non-zero on error.
1292 */ 1374 */
1293static int 1375static int
1294write_tag_1_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, 1376write_tag_1_packet(char *dest, size_t *remaining_bytes,
1377 struct ecryptfs_auth_tok *auth_tok,
1295 struct ecryptfs_crypt_stat *crypt_stat, 1378 struct ecryptfs_crypt_stat *crypt_stat,
1296 struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
1297 struct ecryptfs_key_record *key_rec, size_t *packet_size) 1379 struct ecryptfs_key_record *key_rec, size_t *packet_size)
1298{ 1380{
1299 size_t i; 1381 size_t i;
1300 size_t encrypted_session_key_valid = 0; 1382 size_t encrypted_session_key_valid = 0;
1301 size_t key_rec_size;
1302 size_t packet_size_length; 1383 size_t packet_size_length;
1384 size_t max_packet_size;
1303 int rc = 0; 1385 int rc = 0;
1304 1386
1305 (*packet_size) = 0; 1387 (*packet_size) = 0;
@@ -1329,37 +1411,23 @@ write_tag_1_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
1329 ecryptfs_dump_hex(key_rec->enc_key, key_rec->enc_key_size); 1411 ecryptfs_dump_hex(key_rec->enc_key, key_rec->enc_key_size);
1330 } 1412 }
1331encrypted_session_key_set: 1413encrypted_session_key_set:
1332 /* Now we have a valid key_rec. Append it to the 1414 /* This format is inspired by OpenPGP; see RFC 2440
1333 * key_rec set. */ 1415 * packet tag 1 */
1334 key_rec_size = (sizeof(struct ecryptfs_key_record) 1416 max_packet_size = (1 /* Tag 1 identifier */
1335 - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES 1417 + 3 /* Max Tag 1 packet size */
1336 + (key_rec->enc_key_size)); 1418 + 1 /* Version */
1337 /* TODO: Include a packet size limit as a parameter to this 1419 + ECRYPTFS_SIG_SIZE /* Key identifier */
1338 * function once we have multi-packet headers (for versions 1420 + 1 /* Cipher identifier */
1339 * later than 0.1 */ 1421 + key_rec->enc_key_size); /* Encrypted key size */
1340 if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) { 1422 if (max_packet_size > (*remaining_bytes)) {
1341 ecryptfs_printk(KERN_ERR, "Keyset too large\n"); 1423 printk(KERN_ERR "Packet length larger than maximum allowable; "
1342 rc = -EINVAL; 1424 "need up to [%td] bytes, but there are only [%td] "
1343 goto out; 1425 "available\n", max_packet_size, (*remaining_bytes));
1344 }
1345 /* ***** TAG 1 Packet Format *****
1346 * | version number | 1 byte |
1347 * | key ID | 8 bytes |
1348 * | public key algorithm | 1 byte |
1349 * | encrypted session key | arbitrary |
1350 */
1351 if ((0x02 + ECRYPTFS_SIG_SIZE + key_rec->enc_key_size) >= max) {
1352 ecryptfs_printk(KERN_ERR,
1353 "Authentication token is too large\n");
1354 rc = -EINVAL; 1426 rc = -EINVAL;
1355 goto out; 1427 goto out;
1356 } 1428 }
1357 dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE; 1429 dest[(*packet_size)++] = ECRYPTFS_TAG_1_PACKET_TYPE;
1358 /* This format is inspired by OpenPGP; see RFC 2440 1430 rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4),
1359 * packet tag 1 */
1360 rc = write_packet_length(&dest[(*packet_size)],
1361 (0x02 + ECRYPTFS_SIG_SIZE +
1362 key_rec->enc_key_size),
1363 &packet_size_length); 1431 &packet_size_length);
1364 if (rc) { 1432 if (rc) {
1365 ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet " 1433 ecryptfs_printk(KERN_ERR, "Error generating tag 1 packet "
@@ -1377,13 +1445,15 @@ encrypted_session_key_set:
1377out: 1445out:
1378 if (rc) 1446 if (rc)
1379 (*packet_size) = 0; 1447 (*packet_size) = 0;
1448 else
1449 (*remaining_bytes) -= (*packet_size);
1380 return rc; 1450 return rc;
1381} 1451}
1382 1452
1383/** 1453/**
1384 * write_tag_11_packet 1454 * write_tag_11_packet
1385 * @dest: Target into which Tag 11 packet is to be written 1455 * @dest: Target into which Tag 11 packet is to be written
1386 * @max: Maximum packet length 1456 * @remaining_bytes: Maximum packet length
1387 * @contents: Byte array of contents to copy in 1457 * @contents: Byte array of contents to copy in
1388 * @contents_length: Number of bytes in contents 1458 * @contents_length: Number of bytes in contents
1389 * @packet_length: Length of the Tag 11 packet written; zero on error 1459 * @packet_length: Length of the Tag 11 packet written; zero on error
@@ -1391,54 +1461,59 @@ out:
1391 * Returns zero on success; non-zero on error. 1461 * Returns zero on success; non-zero on error.
1392 */ 1462 */
1393static int 1463static int
1394write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length, 1464write_tag_11_packet(char *dest, size_t *remaining_bytes, char *contents,
1395 size_t *packet_length) 1465 size_t contents_length, size_t *packet_length)
1396{ 1466{
1397 size_t packet_size_length; 1467 size_t packet_size_length;
1468 size_t max_packet_size;
1398 int rc = 0; 1469 int rc = 0;
1399 1470
1400 (*packet_length) = 0; 1471 (*packet_length) = 0;
1401 if ((13 + contents_length) > max) { 1472 /* This format is inspired by OpenPGP; see RFC 2440
1473 * packet tag 11 */
1474 max_packet_size = (1 /* Tag 11 identifier */
1475 + 3 /* Max Tag 11 packet size */
1476 + 1 /* Binary format specifier */
1477 + 1 /* Filename length */
1478 + 8 /* Filename ("_CONSOLE") */
1479 + 4 /* Modification date */
1480 + contents_length); /* Literal data */
1481 if (max_packet_size > (*remaining_bytes)) {
1482 printk(KERN_ERR "Packet length larger than maximum allowable; "
1483 "need up to [%td] bytes, but there are only [%td] "
1484 "available\n", max_packet_size, (*remaining_bytes));
1402 rc = -EINVAL; 1485 rc = -EINVAL;
1403 ecryptfs_printk(KERN_ERR, "Packet length larger than "
1404 "maximum allowable\n");
1405 goto out; 1486 goto out;
1406 } 1487 }
1407 /* General packet header */
1408 /* Packet tag */
1409 dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE; 1488 dest[(*packet_length)++] = ECRYPTFS_TAG_11_PACKET_TYPE;
1410 /* Packet length */
1411 rc = write_packet_length(&dest[(*packet_length)], 1489 rc = write_packet_length(&dest[(*packet_length)],
1412 (13 + contents_length), &packet_size_length); 1490 (max_packet_size - 4), &packet_size_length);
1413 if (rc) { 1491 if (rc) {
1414 ecryptfs_printk(KERN_ERR, "Error generating tag 11 packet " 1492 printk(KERN_ERR "Error generating tag 11 packet header; cannot "
1415 "header; cannot generate packet length\n"); 1493 "generate packet length. rc = [%d]\n", rc);
1416 goto out; 1494 goto out;
1417 } 1495 }
1418 (*packet_length) += packet_size_length; 1496 (*packet_length) += packet_size_length;
1419 /* Tag 11 specific */ 1497 dest[(*packet_length)++] = 0x62; /* binary data format specifier */
1420 /* One-octet field that describes how the data is formatted */
1421 dest[(*packet_length)++] = 0x62; /* binary data */
1422 /* One-octet filename length followed by filename */
1423 dest[(*packet_length)++] = 8; 1498 dest[(*packet_length)++] = 8;
1424 memcpy(&dest[(*packet_length)], "_CONSOLE", 8); 1499 memcpy(&dest[(*packet_length)], "_CONSOLE", 8);
1425 (*packet_length) += 8; 1500 (*packet_length) += 8;
1426 /* Four-octet number indicating modification date */
1427 memset(&dest[(*packet_length)], 0x00, 4); 1501 memset(&dest[(*packet_length)], 0x00, 4);
1428 (*packet_length) += 4; 1502 (*packet_length) += 4;
1429 /* Remainder is literal data */
1430 memcpy(&dest[(*packet_length)], contents, contents_length); 1503 memcpy(&dest[(*packet_length)], contents, contents_length);
1431 (*packet_length) += contents_length; 1504 (*packet_length) += contents_length;
1432 out: 1505 out:
1433 if (rc) 1506 if (rc)
1434 (*packet_length) = 0; 1507 (*packet_length) = 0;
1508 else
1509 (*remaining_bytes) -= (*packet_length);
1435 return rc; 1510 return rc;
1436} 1511}
1437 1512
1438/** 1513/**
1439 * write_tag_3_packet 1514 * write_tag_3_packet
1440 * @dest: Buffer into which to write the packet 1515 * @dest: Buffer into which to write the packet
1441 * @max: Maximum number of bytes that can be written 1516 * @remaining_bytes: Maximum number of bytes that can be written
1442 * @auth_tok: Authentication token 1517 * @auth_tok: Authentication token
1443 * @crypt_stat: The cryptographic context 1518 * @crypt_stat: The cryptographic context
1444 * @key_rec: encrypted key 1519 * @key_rec: encrypted key
@@ -1448,19 +1523,22 @@ write_tag_11_packet(char *dest, int max, char *contents, size_t contents_length,
1448 * Returns zero on success; non-zero on error. 1523 * Returns zero on success; non-zero on error.
1449 */ 1524 */
1450static int 1525static int
1451write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok, 1526write_tag_3_packet(char *dest, size_t *remaining_bytes,
1527 struct ecryptfs_auth_tok *auth_tok,
1452 struct ecryptfs_crypt_stat *crypt_stat, 1528 struct ecryptfs_crypt_stat *crypt_stat,
1453 struct ecryptfs_key_record *key_rec, size_t *packet_size) 1529 struct ecryptfs_key_record *key_rec, size_t *packet_size)
1454{ 1530{
1455 size_t i; 1531 size_t i;
1456 size_t encrypted_session_key_valid = 0; 1532 size_t encrypted_session_key_valid = 0;
1457 char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES]; 1533 char session_key_encryption_key[ECRYPTFS_MAX_KEY_BYTES];
1458 struct scatterlist dest_sg[2]; 1534 struct scatterlist dst_sg;
1459 struct scatterlist src_sg[2]; 1535 struct scatterlist src_sg;
1460 struct mutex *tfm_mutex = NULL; 1536 struct mutex *tfm_mutex = NULL;
1461 size_t key_rec_size;
1462 size_t packet_size_length;
1463 size_t cipher_code; 1537 size_t cipher_code;
1538 size_t packet_size_length;
1539 size_t max_packet_size;
1540 struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
1541 crypt_stat->mount_crypt_stat;
1464 struct blkcipher_desc desc = { 1542 struct blkcipher_desc desc = {
1465 .tfm = NULL, 1543 .tfm = NULL,
1466 .flags = CRYPTO_TFM_REQ_MAY_SLEEP 1544 .flags = CRYPTO_TFM_REQ_MAY_SLEEP
@@ -1470,16 +1548,25 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
1470 (*packet_size) = 0; 1548 (*packet_size) = 0;
1471 ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature, 1549 ecryptfs_from_hex(key_rec->sig, auth_tok->token.password.signature,
1472 ECRYPTFS_SIG_SIZE); 1550 ECRYPTFS_SIG_SIZE);
1473 encrypted_session_key_valid = 0; 1551 rc = ecryptfs_get_tfm_and_mutex_for_cipher_name(&desc.tfm, &tfm_mutex,
1474 for (i = 0; i < crypt_stat->key_size; i++) 1552 crypt_stat->cipher);
1475 encrypted_session_key_valid |= 1553 if (unlikely(rc)) {
1476 auth_tok->session_key.encrypted_key[i]; 1554 printk(KERN_ERR "Internal error whilst attempting to get "
1477 if (encrypted_session_key_valid) { 1555 "tfm and mutex for cipher name [%s]; rc = [%d]\n",
1478 memcpy(key_rec->enc_key, 1556 crypt_stat->cipher, rc);
1479 auth_tok->session_key.encrypted_key, 1557 goto out;
1480 auth_tok->session_key.encrypted_key_size); 1558 }
1481 goto encrypted_session_key_set; 1559 if (mount_crypt_stat->global_default_cipher_key_size == 0) {
1560 struct blkcipher_alg *alg = crypto_blkcipher_alg(desc.tfm);
1561
1562 printk(KERN_WARNING "No key size specified at mount; "
1563 "defaulting to [%d]\n", alg->max_keysize);
1564 mount_crypt_stat->global_default_cipher_key_size =
1565 alg->max_keysize;
1482 } 1566 }
1567 if (crypt_stat->key_size == 0)
1568 crypt_stat->key_size =
1569 mount_crypt_stat->global_default_cipher_key_size;
1483 if (auth_tok->session_key.encrypted_key_size == 0) 1570 if (auth_tok->session_key.encrypted_key_size == 0)
1484 auth_tok->session_key.encrypted_key_size = 1571 auth_tok->session_key.encrypted_key_size =
1485 crypt_stat->key_size; 1572 crypt_stat->key_size;
@@ -1487,9 +1574,24 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
1487 && strcmp("aes", crypt_stat->cipher) == 0) { 1574 && strcmp("aes", crypt_stat->cipher) == 0) {
1488 memset((crypt_stat->key + 24), 0, 8); 1575 memset((crypt_stat->key + 24), 0, 8);
1489 auth_tok->session_key.encrypted_key_size = 32; 1576 auth_tok->session_key.encrypted_key_size = 32;
1490 } 1577 } else
1578 auth_tok->session_key.encrypted_key_size = crypt_stat->key_size;
1491 key_rec->enc_key_size = 1579 key_rec->enc_key_size =
1492 auth_tok->session_key.encrypted_key_size; 1580 auth_tok->session_key.encrypted_key_size;
1581 encrypted_session_key_valid = 0;
1582 for (i = 0; i < auth_tok->session_key.encrypted_key_size; i++)
1583 encrypted_session_key_valid |=
1584 auth_tok->session_key.encrypted_key[i];
1585 if (encrypted_session_key_valid) {
1586 ecryptfs_printk(KERN_DEBUG, "encrypted_session_key_valid != 0; "
1587 "using auth_tok->session_key.encrypted_key, "
1588 "where key_rec->enc_key_size = [%d]\n",
1589 key_rec->enc_key_size);
1590 memcpy(key_rec->enc_key,
1591 auth_tok->session_key.encrypted_key,
1592 key_rec->enc_key_size);
1593 goto encrypted_session_key_set;
1594 }
1493 if (auth_tok->token.password.flags & 1595 if (auth_tok->token.password.flags &
1494 ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) { 1596 ECRYPTFS_SESSION_KEY_ENCRYPTION_KEY_SET) {
1495 ecryptfs_printk(KERN_DEBUG, "Using previously generated " 1597 ecryptfs_printk(KERN_DEBUG, "Using previously generated "
@@ -1508,54 +1610,32 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
1508 ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n"); 1610 ecryptfs_printk(KERN_DEBUG, "Session key encryption key:\n");
1509 ecryptfs_dump_hex(session_key_encryption_key, 16); 1611 ecryptfs_dump_hex(session_key_encryption_key, 16);
1510 } 1612 }
1511 rc = virt_to_scatterlist(crypt_stat->key, 1613 rc = virt_to_scatterlist(crypt_stat->key, key_rec->enc_key_size,
1512 key_rec->enc_key_size, src_sg, 2); 1614 &src_sg, 1);
1513 if (!rc) { 1615 if (rc != 1) {
1514 ecryptfs_printk(KERN_ERR, "Error generating scatterlist " 1616 ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
1515 "for crypt_stat session key\n"); 1617 "for crypt_stat session key; expected rc = 1; "
1618 "got rc = [%d]. key_rec->enc_key_size = [%d]\n",
1619 rc, key_rec->enc_key_size);
1516 rc = -ENOMEM; 1620 rc = -ENOMEM;
1517 goto out; 1621 goto out;
1518 } 1622 }
1519 rc = virt_to_scatterlist(key_rec->enc_key, 1623 rc = virt_to_scatterlist(key_rec->enc_key, key_rec->enc_key_size,
1520 key_rec->enc_key_size, dest_sg, 2); 1624 &dst_sg, 1);
1521 if (!rc) { 1625 if (rc != 1) {
1522 ecryptfs_printk(KERN_ERR, "Error generating scatterlist " 1626 ecryptfs_printk(KERN_ERR, "Error generating scatterlist "
1523 "for crypt_stat encrypted session key\n"); 1627 "for crypt_stat encrypted session key; "
1628 "expected rc = 1; got rc = [%d]. "
1629 "key_rec->enc_key_size = [%d]\n", rc,
1630 key_rec->enc_key_size);
1524 rc = -ENOMEM; 1631 rc = -ENOMEM;
1525 goto out; 1632 goto out;
1526 } 1633 }
1527 if (!strcmp(crypt_stat->cipher, 1634 mutex_lock(tfm_mutex);
1528 crypt_stat->mount_crypt_stat->global_default_cipher_name)
1529 && crypt_stat->mount_crypt_stat->global_key_tfm) {
1530 desc.tfm = crypt_stat->mount_crypt_stat->global_key_tfm;
1531 tfm_mutex = &crypt_stat->mount_crypt_stat->global_key_tfm_mutex;
1532 } else {
1533 char *full_alg_name;
1534
1535 rc = ecryptfs_crypto_api_algify_cipher_name(&full_alg_name,
1536 crypt_stat->cipher,
1537 "ecb");
1538 if (rc)
1539 goto out;
1540 desc.tfm = crypto_alloc_blkcipher(full_alg_name, 0,
1541 CRYPTO_ALG_ASYNC);
1542 kfree(full_alg_name);
1543 if (IS_ERR(desc.tfm)) {
1544 rc = PTR_ERR(desc.tfm);
1545 ecryptfs_printk(KERN_ERR, "Could not initialize crypto "
1546 "context for cipher [%s]; rc = [%d]\n",
1547 crypt_stat->cipher, rc);
1548 goto out;
1549 }
1550 crypto_blkcipher_set_flags(desc.tfm, CRYPTO_TFM_REQ_WEAK_KEY);
1551 }
1552 if (tfm_mutex)
1553 mutex_lock(tfm_mutex);
1554 rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key, 1635 rc = crypto_blkcipher_setkey(desc.tfm, session_key_encryption_key,
1555 crypt_stat->key_size); 1636 crypt_stat->key_size);
1556 if (rc < 0) { 1637 if (rc < 0) {
1557 if (tfm_mutex) 1638 mutex_unlock(tfm_mutex);
1558 mutex_unlock(tfm_mutex);
1559 ecryptfs_printk(KERN_ERR, "Error setting key for crypto " 1639 ecryptfs_printk(KERN_ERR, "Error setting key for crypto "
1560 "context; rc = [%d]\n", rc); 1640 "context; rc = [%d]\n", rc);
1561 goto out; 1641 goto out;
@@ -1563,56 +1643,53 @@ write_tag_3_packet(char *dest, size_t max, struct ecryptfs_auth_tok *auth_tok,
1563 rc = 0; 1643 rc = 0;
1564 ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n", 1644 ecryptfs_printk(KERN_DEBUG, "Encrypting [%d] bytes of the key\n",
1565 crypt_stat->key_size); 1645 crypt_stat->key_size);
1566 rc = crypto_blkcipher_encrypt(&desc, dest_sg, src_sg, 1646 rc = crypto_blkcipher_encrypt(&desc, &dst_sg, &src_sg,
1567 (*key_rec).enc_key_size); 1647 (*key_rec).enc_key_size);
1648 mutex_unlock(tfm_mutex);
1568 if (rc) { 1649 if (rc) {
1569 printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc); 1650 printk(KERN_ERR "Error encrypting; rc = [%d]\n", rc);
1570 goto out; 1651 goto out;
1571 } 1652 }
1572 if (tfm_mutex)
1573 mutex_unlock(tfm_mutex);
1574 ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n"); 1653 ecryptfs_printk(KERN_DEBUG, "This should be the encrypted key:\n");
1575 if (ecryptfs_verbosity > 0) 1654 if (ecryptfs_verbosity > 0) {
1655 ecryptfs_printk(KERN_DEBUG, "EFEK of size [%d]:\n",
1656 key_rec->enc_key_size);
1576 ecryptfs_dump_hex(key_rec->enc_key, 1657 ecryptfs_dump_hex(key_rec->enc_key,
1577 key_rec->enc_key_size); 1658 key_rec->enc_key_size);
1578encrypted_session_key_set:
1579 /* Now we have a valid key_rec. Append it to the
1580 * key_rec set. */
1581 key_rec_size = (sizeof(struct ecryptfs_key_record)
1582 - ECRYPTFS_MAX_ENCRYPTED_KEY_BYTES
1583 + (key_rec->enc_key_size));
1584 /* TODO: Include a packet size limit as a parameter to this
1585 * function once we have multi-packet headers (for versions
1586 * later than 0.1 */
1587 if (key_rec_size >= ECRYPTFS_MAX_KEYSET_SIZE) {
1588 ecryptfs_printk(KERN_ERR, "Keyset too large\n");
1589 rc = -EINVAL;
1590 goto out;
1591 } 1659 }
1592 /* TODO: Packet size limit */ 1660encrypted_session_key_set:
1593 /* We have 5 bytes of surrounding packet data */ 1661 /* This format is inspired by OpenPGP; see RFC 2440
1594 if ((0x05 + ECRYPTFS_SALT_SIZE 1662 * packet tag 3 */
1595 + key_rec->enc_key_size) >= max) { 1663 max_packet_size = (1 /* Tag 3 identifier */
1596 ecryptfs_printk(KERN_ERR, "Authentication token is too " 1664 + 3 /* Max Tag 3 packet size */
1597 "large\n"); 1665 + 1 /* Version */
1666 + 1 /* Cipher code */
1667 + 1 /* S2K specifier */
1668 + 1 /* Hash identifier */
1669 + ECRYPTFS_SALT_SIZE /* Salt */
1670 + 1 /* Hash iterations */
1671 + key_rec->enc_key_size); /* Encrypted key size */
1672 if (max_packet_size > (*remaining_bytes)) {
1673 printk(KERN_ERR "Packet too large; need up to [%td] bytes, but "
1674 "there are only [%td] available\n", max_packet_size,
1675 (*remaining_bytes));
1598 rc = -EINVAL; 1676 rc = -EINVAL;
1599 goto out; 1677 goto out;
1600 } 1678 }
1601 /* This format is inspired by OpenPGP; see RFC 2440
1602 * packet tag 3 */
1603 dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE; 1679 dest[(*packet_size)++] = ECRYPTFS_TAG_3_PACKET_TYPE;
1604 /* ver+cipher+s2k+hash+salt+iter+enc_key */ 1680 /* Chop off the Tag 3 identifier(1) and Tag 3 packet size(3)
1605 rc = write_packet_length(&dest[(*packet_size)], 1681 * to get the number of octets in the actual Tag 3 packet */
1606 (0x05 + ECRYPTFS_SALT_SIZE 1682 rc = write_packet_length(&dest[(*packet_size)], (max_packet_size - 4),
1607 + key_rec->enc_key_size),
1608 &packet_size_length); 1683 &packet_size_length);
1609 if (rc) { 1684 if (rc) {
1610 ecryptfs_printk(KERN_ERR, "Error generating tag 3 packet " 1685 printk(KERN_ERR "Error generating tag 3 packet header; cannot "
1611 "header; cannot generate packet length\n"); 1686 "generate packet length. rc = [%d]\n", rc);
1612 goto out; 1687 goto out;
1613 } 1688 }
1614 (*packet_size) += packet_size_length; 1689 (*packet_size) += packet_size_length;
1615 dest[(*packet_size)++] = 0x04; /* version 4 */ 1690 dest[(*packet_size)++] = 0x04; /* version 4 */
1691 /* TODO: Break from RFC2440 so that arbitrary ciphers can be
1692 * specified with strings */
1616 cipher_code = ecryptfs_code_for_cipher_string(crypt_stat); 1693 cipher_code = ecryptfs_code_for_cipher_string(crypt_stat);
1617 if (cipher_code == 0) { 1694 if (cipher_code == 0) {
1618 ecryptfs_printk(KERN_WARNING, "Unable to generate code for " 1695 ecryptfs_printk(KERN_WARNING, "Unable to generate code for "
@@ -1631,10 +1708,10 @@ encrypted_session_key_set:
1631 key_rec->enc_key_size); 1708 key_rec->enc_key_size);
1632 (*packet_size) += key_rec->enc_key_size; 1709 (*packet_size) += key_rec->enc_key_size;
1633out: 1710out:
1634 if (desc.tfm && !tfm_mutex)
1635 crypto_free_blkcipher(desc.tfm);
1636 if (rc) 1711 if (rc)
1637 (*packet_size) = 0; 1712 (*packet_size) = 0;
1713 else
1714 (*remaining_bytes) -= (*packet_size);
1638 return rc; 1715 return rc;
1639} 1716}
1640 1717
@@ -1642,7 +1719,7 @@ struct kmem_cache *ecryptfs_key_record_cache;
1642 1719
1643/** 1720/**
1644 * ecryptfs_generate_key_packet_set 1721 * ecryptfs_generate_key_packet_set
1645 * @dest: Virtual address from which to write the key record set 1722 * @dest_base: Virtual address from which to write the key record set
1646 * @crypt_stat: The cryptographic context from which the 1723 * @crypt_stat: The cryptographic context from which the
1647 * authentication tokens will be retrieved 1724 * authentication tokens will be retrieved
1648 * @ecryptfs_dentry: The dentry, used to retrieve the mount crypt stat 1725 * @ecryptfs_dentry: The dentry, used to retrieve the mount crypt stat
@@ -1662,24 +1739,43 @@ ecryptfs_generate_key_packet_set(char *dest_base,
1662 size_t max) 1739 size_t max)
1663{ 1740{
1664 struct ecryptfs_auth_tok *auth_tok; 1741 struct ecryptfs_auth_tok *auth_tok;
1742 struct ecryptfs_global_auth_tok *global_auth_tok;
1665 struct ecryptfs_mount_crypt_stat *mount_crypt_stat = 1743 struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
1666 &ecryptfs_superblock_to_private( 1744 &ecryptfs_superblock_to_private(
1667 ecryptfs_dentry->d_sb)->mount_crypt_stat; 1745 ecryptfs_dentry->d_sb)->mount_crypt_stat;
1668 size_t written; 1746 size_t written;
1669 struct ecryptfs_key_record *key_rec; 1747 struct ecryptfs_key_record *key_rec;
1748 struct ecryptfs_key_sig *key_sig;
1670 int rc = 0; 1749 int rc = 0;
1671 1750
1672 (*len) = 0; 1751 (*len) = 0;
1752 mutex_lock(&crypt_stat->keysig_list_mutex);
1673 key_rec = kmem_cache_alloc(ecryptfs_key_record_cache, GFP_KERNEL); 1753 key_rec = kmem_cache_alloc(ecryptfs_key_record_cache, GFP_KERNEL);
1674 if (!key_rec) { 1754 if (!key_rec) {
1675 rc = -ENOMEM; 1755 rc = -ENOMEM;
1676 goto out; 1756 goto out;
1677 } 1757 }
1678 if (mount_crypt_stat->global_auth_tok) { 1758 list_for_each_entry(key_sig, &crypt_stat->keysig_list,
1679 auth_tok = mount_crypt_stat->global_auth_tok; 1759 crypt_stat_list) {
1760 memset(key_rec, 0, sizeof(*key_rec));
1761 rc = ecryptfs_find_global_auth_tok_for_sig(&global_auth_tok,
1762 mount_crypt_stat,
1763 key_sig->keysig);
1764 if (rc) {
1765 printk(KERN_ERR "Error attempting to get the global "
1766 "auth_tok; rc = [%d]\n", rc);
1767 goto out_free;
1768 }
1769 if (global_auth_tok->flags & ECRYPTFS_AUTH_TOK_INVALID) {
1770 printk(KERN_WARNING
1771 "Skipping invalid auth tok with sig = [%s]\n",
1772 global_auth_tok->sig);
1773 continue;
1774 }
1775 auth_tok = global_auth_tok->global_auth_tok;
1680 if (auth_tok->token_type == ECRYPTFS_PASSWORD) { 1776 if (auth_tok->token_type == ECRYPTFS_PASSWORD) {
1681 rc = write_tag_3_packet((dest_base + (*len)), 1777 rc = write_tag_3_packet((dest_base + (*len)),
1682 max, auth_tok, 1778 &max, auth_tok,
1683 crypt_stat, key_rec, 1779 crypt_stat, key_rec,
1684 &written); 1780 &written);
1685 if (rc) { 1781 if (rc) {
@@ -1689,10 +1785,9 @@ ecryptfs_generate_key_packet_set(char *dest_base,
1689 } 1785 }
1690 (*len) += written; 1786 (*len) += written;
1691 /* Write auth tok signature packet */ 1787 /* Write auth tok signature packet */
1692 rc = write_tag_11_packet( 1788 rc = write_tag_11_packet((dest_base + (*len)), &max,
1693 (dest_base + (*len)), 1789 key_rec->sig,
1694 (max - (*len)), 1790 ECRYPTFS_SIG_SIZE, &written);
1695 key_rec->sig, ECRYPTFS_SIG_SIZE, &written);
1696 if (rc) { 1791 if (rc) {
1697 ecryptfs_printk(KERN_ERR, "Error writing " 1792 ecryptfs_printk(KERN_ERR, "Error writing "
1698 "auth tok signature packet\n"); 1793 "auth tok signature packet\n");
@@ -1701,9 +1796,8 @@ ecryptfs_generate_key_packet_set(char *dest_base,
1701 (*len) += written; 1796 (*len) += written;
1702 } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) { 1797 } else if (auth_tok->token_type == ECRYPTFS_PRIVATE_KEY) {
1703 rc = write_tag_1_packet(dest_base + (*len), 1798 rc = write_tag_1_packet(dest_base + (*len),
1704 max, auth_tok, 1799 &max, auth_tok,
1705 crypt_stat,mount_crypt_stat, 1800 crypt_stat, key_rec, &written);
1706 key_rec, &written);
1707 if (rc) { 1801 if (rc) {
1708 ecryptfs_printk(KERN_WARNING, "Error " 1802 ecryptfs_printk(KERN_WARNING, "Error "
1709 "writing tag 1 packet\n"); 1803 "writing tag 1 packet\n");
@@ -1716,19 +1810,69 @@ ecryptfs_generate_key_packet_set(char *dest_base,
1716 rc = -EINVAL; 1810 rc = -EINVAL;
1717 goto out_free; 1811 goto out_free;
1718 } 1812 }
1719 } else 1813 }
1720 BUG(); 1814 if (likely(max > 0)) {
1721 if (likely((max - (*len)) > 0)) {
1722 dest_base[(*len)] = 0x00; 1815 dest_base[(*len)] = 0x00;
1723 } else { 1816 } else {
1724 ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n"); 1817 ecryptfs_printk(KERN_ERR, "Error writing boundary byte\n");
1725 rc = -EIO; 1818 rc = -EIO;
1726 } 1819 }
1727
1728out_free: 1820out_free:
1729 kmem_cache_free(ecryptfs_key_record_cache, key_rec); 1821 kmem_cache_free(ecryptfs_key_record_cache, key_rec);
1730out: 1822out:
1731 if (rc) 1823 if (rc)
1732 (*len) = 0; 1824 (*len) = 0;
1825 mutex_unlock(&crypt_stat->keysig_list_mutex);
1733 return rc; 1826 return rc;
1734} 1827}
1828
1829struct kmem_cache *ecryptfs_key_sig_cache;
1830
1831int ecryptfs_add_keysig(struct ecryptfs_crypt_stat *crypt_stat, char *sig)
1832{
1833 struct ecryptfs_key_sig *new_key_sig;
1834 int rc = 0;
1835
1836 new_key_sig = kmem_cache_alloc(ecryptfs_key_sig_cache, GFP_KERNEL);
1837 if (!new_key_sig) {
1838 rc = -ENOMEM;
1839 printk(KERN_ERR
1840 "Error allocating from ecryptfs_key_sig_cache\n");
1841 goto out;
1842 }
1843 memcpy(new_key_sig->keysig, sig, ECRYPTFS_SIG_SIZE_HEX);
1844 mutex_lock(&crypt_stat->keysig_list_mutex);
1845 list_add(&new_key_sig->crypt_stat_list, &crypt_stat->keysig_list);
1846 mutex_unlock(&crypt_stat->keysig_list_mutex);
1847out:
1848 return rc;
1849}
1850
1851struct kmem_cache *ecryptfs_global_auth_tok_cache;
1852
1853int
1854ecryptfs_add_global_auth_tok(struct ecryptfs_mount_crypt_stat *mount_crypt_stat,
1855 char *sig)
1856{
1857 struct ecryptfs_global_auth_tok *new_auth_tok;
1858 int rc = 0;
1859
1860 new_auth_tok = kmem_cache_alloc(ecryptfs_global_auth_tok_cache,
1861 GFP_KERNEL);
1862 if (!new_auth_tok) {
1863 rc = -ENOMEM;
1864 printk(KERN_ERR "Error allocating from "
1865 "ecryptfs_global_auth_tok_cache\n");
1866 goto out;
1867 }
1868 memcpy(new_auth_tok->sig, sig, ECRYPTFS_SIG_SIZE_HEX);
1869 new_auth_tok->sig[ECRYPTFS_SIG_SIZE_HEX] = '\0';
1870 mutex_lock(&mount_crypt_stat->global_auth_tok_list_mutex);
1871 list_add(&new_auth_tok->mount_crypt_stat_list,
1872 &mount_crypt_stat->global_auth_tok_list);
1873 mount_crypt_stat->num_global_auth_toks++;
1874 mutex_unlock(&mount_crypt_stat->global_auth_tok_list_mutex);
1875out:
1876 return rc;
1877}
1878
diff --git a/fs/ecryptfs/main.c b/fs/ecryptfs/main.c
index a98497264fe8..97e6801f722c 100644
--- a/fs/ecryptfs/main.c
+++ b/fs/ecryptfs/main.c
@@ -99,6 +99,64 @@ void __ecryptfs_printk(const char *fmt, ...)
99} 99}
100 100
101/** 101/**
102 * ecryptfs_init_persistent_file
103 * @ecryptfs_dentry: Fully initialized eCryptfs dentry object, with
104 * the lower dentry and the lower mount set
105 *
106 * eCryptfs only ever keeps a single open file for every lower
107 * inode. All I/O operations to the lower inode occur through that
108 * file. When the first eCryptfs dentry that interposes with the first
109 * lower dentry for that inode is created, this function creates the
110 * persistent file struct and associates it with the eCryptfs
111 * inode. When the eCryptfs inode is destroyed, the file is closed.
112 *
113 * The persistent file will be opened with read/write permissions, if
114 * possible. Otherwise, it is opened read-only.
115 *
116 * This function does nothing if a lower persistent file is already
117 * associated with the eCryptfs inode.
118 *
119 * Returns zero on success; non-zero otherwise
120 */
121int ecryptfs_init_persistent_file(struct dentry *ecryptfs_dentry)
122{
123 struct ecryptfs_inode_info *inode_info =
124 ecryptfs_inode_to_private(ecryptfs_dentry->d_inode);
125 int rc = 0;
126
127 mutex_lock(&inode_info->lower_file_mutex);
128 if (!inode_info->lower_file) {
129 struct dentry *lower_dentry;
130 struct vfsmount *lower_mnt =
131 ecryptfs_dentry_to_lower_mnt(ecryptfs_dentry);
132
133 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry);
134 /* Corresponding dput() and mntput() are done when the
135 * persistent file is fput() when the eCryptfs inode
136 * is destroyed. */
137 dget(lower_dentry);
138 mntget(lower_mnt);
139 inode_info->lower_file = dentry_open(lower_dentry,
140 lower_mnt,
141 (O_RDWR | O_LARGEFILE));
142 if (IS_ERR(inode_info->lower_file))
143 inode_info->lower_file = dentry_open(lower_dentry,
144 lower_mnt,
145 (O_RDONLY
146 | O_LARGEFILE));
147 if (IS_ERR(inode_info->lower_file)) {
148 printk(KERN_ERR "Error opening lower persistent file "
149 "for lower_dentry [0x%p] and lower_mnt [0x%p]\n",
150 lower_dentry, lower_mnt);
151 rc = PTR_ERR(inode_info->lower_file);
152 inode_info->lower_file = NULL;
153 }
154 }
155 mutex_unlock(&inode_info->lower_file_mutex);
156 return rc;
157}
158
159/**
102 * ecryptfs_interpose 160 * ecryptfs_interpose
103 * @lower_dentry: Existing dentry in the lower filesystem 161 * @lower_dentry: Existing dentry in the lower filesystem
104 * @dentry: ecryptfs' dentry 162 * @dentry: ecryptfs' dentry
@@ -155,6 +213,13 @@ int ecryptfs_interpose(struct dentry *lower_dentry, struct dentry *dentry,
155 /* This size will be overwritten for real files w/ headers and 213 /* This size will be overwritten for real files w/ headers and
156 * other metadata */ 214 * other metadata */
157 fsstack_copy_inode_size(inode, lower_inode); 215 fsstack_copy_inode_size(inode, lower_inode);
216 rc = ecryptfs_init_persistent_file(dentry);
217 if (rc) {
218 printk(KERN_ERR "%s: Error attempting to initialize the "
219 "persistent file for the dentry with name [%s]; "
220 "rc = [%d]\n", __FUNCTION__, dentry->d_name.name, rc);
221 goto out;
222 }
158out: 223out:
159 return rc; 224 return rc;
160} 225}
@@ -179,38 +244,41 @@ static match_table_t tokens = {
179 {ecryptfs_opt_err, NULL} 244 {ecryptfs_opt_err, NULL}
180}; 245};
181 246
182/** 247static int ecryptfs_init_global_auth_toks(
183 * ecryptfs_verify_version 248 struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
184 * @version: The version number to confirm
185 *
186 * Returns zero on good version; non-zero otherwise
187 */
188static int ecryptfs_verify_version(u16 version)
189{ 249{
250 struct ecryptfs_global_auth_tok *global_auth_tok;
190 int rc = 0; 251 int rc = 0;
191 unsigned char major; 252
192 unsigned char minor; 253 list_for_each_entry(global_auth_tok,
193 254 &mount_crypt_stat->global_auth_tok_list,
194 major = ((version >> 8) & 0xFF); 255 mount_crypt_stat_list) {
195 minor = (version & 0xFF); 256 rc = ecryptfs_keyring_auth_tok_for_sig(
196 if (major != ECRYPTFS_VERSION_MAJOR) { 257 &global_auth_tok->global_auth_tok_key,
197 ecryptfs_printk(KERN_ERR, "Major version number mismatch. " 258 &global_auth_tok->global_auth_tok,
198 "Expected [%d]; got [%d]\n", 259 global_auth_tok->sig);
199 ECRYPTFS_VERSION_MAJOR, major); 260 if (rc) {
200 rc = -EINVAL; 261 printk(KERN_ERR "Could not find valid key in user "
201 goto out; 262 "session keyring for sig specified in mount "
202 } 263 "option: [%s]\n", global_auth_tok->sig);
203 if (minor != ECRYPTFS_VERSION_MINOR) { 264 global_auth_tok->flags |= ECRYPTFS_AUTH_TOK_INVALID;
204 ecryptfs_printk(KERN_ERR, "Minor version number mismatch. " 265 rc = 0;
205 "Expected [%d]; got [%d]\n", 266 } else
206 ECRYPTFS_VERSION_MINOR, minor); 267 global_auth_tok->flags &= ~ECRYPTFS_AUTH_TOK_INVALID;
207 rc = -EINVAL;
208 goto out;
209 } 268 }
210out:
211 return rc; 269 return rc;
212} 270}
213 271
272static void ecryptfs_init_mount_crypt_stat(
273 struct ecryptfs_mount_crypt_stat *mount_crypt_stat)
274{
275 memset((void *)mount_crypt_stat, 0,
276 sizeof(struct ecryptfs_mount_crypt_stat));
277 INIT_LIST_HEAD(&mount_crypt_stat->global_auth_tok_list);
278 mutex_init(&mount_crypt_stat->global_auth_tok_list_mutex);
279 mount_crypt_stat->flags |= ECRYPTFS_MOUNT_CRYPT_STAT_INITIALIZED;
280}
281
214/** 282/**
215 * ecryptfs_parse_options 283 * ecryptfs_parse_options
216 * @sb: The ecryptfs super block 284 * @sb: The ecryptfs super block
@@ -238,14 +306,11 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
238 int cipher_name_set = 0; 306 int cipher_name_set = 0;
239 int cipher_key_bytes; 307 int cipher_key_bytes;
240 int cipher_key_bytes_set = 0; 308 int cipher_key_bytes_set = 0;
241 struct key *auth_tok_key = NULL;
242 struct ecryptfs_auth_tok *auth_tok = NULL;
243 struct ecryptfs_mount_crypt_stat *mount_crypt_stat = 309 struct ecryptfs_mount_crypt_stat *mount_crypt_stat =
244 &ecryptfs_superblock_to_private(sb)->mount_crypt_stat; 310 &ecryptfs_superblock_to_private(sb)->mount_crypt_stat;
245 substring_t args[MAX_OPT_ARGS]; 311 substring_t args[MAX_OPT_ARGS];
246 int token; 312 int token;
247 char *sig_src; 313 char *sig_src;
248 char *sig_dst;
249 char *debug_src; 314 char *debug_src;
250 char *cipher_name_dst; 315 char *cipher_name_dst;
251 char *cipher_name_src; 316 char *cipher_name_src;
@@ -256,6 +321,7 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
256 rc = -EINVAL; 321 rc = -EINVAL;
257 goto out; 322 goto out;
258 } 323 }
324 ecryptfs_init_mount_crypt_stat(mount_crypt_stat);
259 while ((p = strsep(&options, ",")) != NULL) { 325 while ((p = strsep(&options, ",")) != NULL) {
260 if (!*p) 326 if (!*p)
261 continue; 327 continue;
@@ -264,14 +330,13 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
264 case ecryptfs_opt_sig: 330 case ecryptfs_opt_sig:
265 case ecryptfs_opt_ecryptfs_sig: 331 case ecryptfs_opt_ecryptfs_sig:
266 sig_src = args[0].from; 332 sig_src = args[0].from;
267 sig_dst = 333 rc = ecryptfs_add_global_auth_tok(mount_crypt_stat,
268 mount_crypt_stat->global_auth_tok_sig; 334 sig_src);
269 memcpy(sig_dst, sig_src, ECRYPTFS_SIG_SIZE_HEX); 335 if (rc) {
270 sig_dst[ECRYPTFS_SIG_SIZE_HEX] = '\0'; 336 printk(KERN_ERR "Error attempting to register "
271 ecryptfs_printk(KERN_DEBUG, 337 "global sig; rc = [%d]\n", rc);
272 "The mount_crypt_stat " 338 goto out;
273 "global_auth_tok_sig set to: " 339 }
274 "[%s]\n", sig_dst);
275 sig_set = 1; 340 sig_set = 1;
276 break; 341 break;
277 case ecryptfs_opt_debug: 342 case ecryptfs_opt_debug:
@@ -333,12 +398,10 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
333 p); 398 p);
334 } 399 }
335 } 400 }
336 /* Do not support lack of mount-wide signature in 0.1
337 * release */
338 if (!sig_set) { 401 if (!sig_set) {
339 rc = -EINVAL; 402 rc = -EINVAL;
340 ecryptfs_printk(KERN_ERR, "You must supply a valid " 403 ecryptfs_printk(KERN_ERR, "You must supply at least one valid "
341 "passphrase auth tok signature as a mount " 404 "auth tok signature as a mount "
342 "parameter; see the eCryptfs README\n"); 405 "parameter; see the eCryptfs README\n");
343 goto out; 406 goto out;
344 } 407 }
@@ -358,55 +421,23 @@ static int ecryptfs_parse_options(struct super_block *sb, char *options)
358 if (!cipher_key_bytes_set) { 421 if (!cipher_key_bytes_set) {
359 mount_crypt_stat->global_default_cipher_key_size = 0; 422 mount_crypt_stat->global_default_cipher_key_size = 0;
360 } 423 }
361 rc = ecryptfs_process_cipher( 424 rc = ecryptfs_add_new_key_tfm(
362 &mount_crypt_stat->global_key_tfm, 425 NULL, mount_crypt_stat->global_default_cipher_name,
363 mount_crypt_stat->global_default_cipher_name, 426 mount_crypt_stat->global_default_cipher_key_size);
364 &mount_crypt_stat->global_default_cipher_key_size);
365 if (rc) { 427 if (rc) {
366 printk(KERN_ERR "Error attempting to initialize cipher [%s] " 428 printk(KERN_ERR "Error attempting to initialize cipher with "
367 "with key size [%Zd] bytes; rc = [%d]\n", 429 "name = [%s] and key size = [%td]; rc = [%d]\n",
368 mount_crypt_stat->global_default_cipher_name, 430 mount_crypt_stat->global_default_cipher_name,
369 mount_crypt_stat->global_default_cipher_key_size, rc); 431 mount_crypt_stat->global_default_cipher_key_size, rc);
370 mount_crypt_stat->global_key_tfm = NULL;
371 mount_crypt_stat->global_auth_tok_key = NULL;
372 rc = -EINVAL; 432 rc = -EINVAL;
373 goto out; 433 goto out;
374 } 434 }
375 mutex_init(&mount_crypt_stat->global_key_tfm_mutex); 435 rc = ecryptfs_init_global_auth_toks(mount_crypt_stat);
376 ecryptfs_printk(KERN_DEBUG, "Requesting the key with description: " 436 if (rc) {
377 "[%s]\n", mount_crypt_stat->global_auth_tok_sig); 437 printk(KERN_WARNING "One or more global auth toks could not "
378 /* The reference to this key is held until umount is done The 438 "properly register; rc = [%d]\n", rc);
379 * call to key_put is done in ecryptfs_put_super() */
380 auth_tok_key = request_key(&key_type_user,
381 mount_crypt_stat->global_auth_tok_sig,
382 NULL);
383 if (!auth_tok_key || IS_ERR(auth_tok_key)) {
384 ecryptfs_printk(KERN_ERR, "Could not find key with "
385 "description: [%s]\n",
386 mount_crypt_stat->global_auth_tok_sig);
387 process_request_key_err(PTR_ERR(auth_tok_key));
388 rc = -EINVAL;
389 goto out;
390 }
391 auth_tok = ecryptfs_get_key_payload_data(auth_tok_key);
392 if (ecryptfs_verify_version(auth_tok->version)) {
393 ecryptfs_printk(KERN_ERR, "Data structure version mismatch. "
394 "Userspace tools must match eCryptfs kernel "
395 "module with major version [%d] and minor "
396 "version [%d]\n", ECRYPTFS_VERSION_MAJOR,
397 ECRYPTFS_VERSION_MINOR);
398 rc = -EINVAL;
399 goto out;
400 }
401 if (auth_tok->token_type != ECRYPTFS_PASSWORD
402 && auth_tok->token_type != ECRYPTFS_PRIVATE_KEY) {
403 ecryptfs_printk(KERN_ERR, "Invalid auth_tok structure "
404 "returned from key query\n");
405 rc = -EINVAL;
406 goto out;
407 } 439 }
408 mount_crypt_stat->global_auth_tok_key = auth_tok_key; 440 rc = 0;
409 mount_crypt_stat->global_auth_tok = auth_tok;
410out: 441out:
411 return rc; 442 return rc;
412} 443}
@@ -495,7 +526,8 @@ static int ecryptfs_read_super(struct super_block *sb, const char *dev_name)
495 sb->s_maxbytes = lower_root->d_sb->s_maxbytes; 526 sb->s_maxbytes = lower_root->d_sb->s_maxbytes;
496 ecryptfs_set_dentry_lower(sb->s_root, lower_root); 527 ecryptfs_set_dentry_lower(sb->s_root, lower_root);
497 ecryptfs_set_dentry_lower_mnt(sb->s_root, lower_mnt); 528 ecryptfs_set_dentry_lower_mnt(sb->s_root, lower_mnt);
498 if ((rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0))) 529 rc = ecryptfs_interpose(lower_root, sb->s_root, sb, 0);
530 if (rc)
499 goto out_free; 531 goto out_free;
500 rc = 0; 532 rc = 0;
501 goto out; 533 goto out;
@@ -639,15 +671,25 @@ static struct ecryptfs_cache_info {
639 .size = PAGE_CACHE_SIZE, 671 .size = PAGE_CACHE_SIZE,
640 }, 672 },
641 { 673 {
642 .cache = &ecryptfs_lower_page_cache,
643 .name = "ecryptfs_lower_page_cache",
644 .size = PAGE_CACHE_SIZE,
645 },
646 {
647 .cache = &ecryptfs_key_record_cache, 674 .cache = &ecryptfs_key_record_cache,
648 .name = "ecryptfs_key_record_cache", 675 .name = "ecryptfs_key_record_cache",
649 .size = sizeof(struct ecryptfs_key_record), 676 .size = sizeof(struct ecryptfs_key_record),
650 }, 677 },
678 {
679 .cache = &ecryptfs_key_sig_cache,
680 .name = "ecryptfs_key_sig_cache",
681 .size = sizeof(struct ecryptfs_key_sig),
682 },
683 {
684 .cache = &ecryptfs_global_auth_tok_cache,
685 .name = "ecryptfs_global_auth_tok_cache",
686 .size = sizeof(struct ecryptfs_global_auth_tok),
687 },
688 {
689 .cache = &ecryptfs_key_tfm_cache,
690 .name = "ecryptfs_key_tfm_cache",
691 .size = sizeof(struct ecryptfs_key_tfm),
692 },
651}; 693};
652 694
653static void ecryptfs_free_kmem_caches(void) 695static void ecryptfs_free_kmem_caches(void)
@@ -750,7 +792,8 @@ static struct ecryptfs_version_str_map_elem {
750 {ECRYPTFS_VERSIONING_PUBKEY, "pubkey"}, 792 {ECRYPTFS_VERSIONING_PUBKEY, "pubkey"},
751 {ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"}, 793 {ECRYPTFS_VERSIONING_PLAINTEXT_PASSTHROUGH, "plaintext passthrough"},
752 {ECRYPTFS_VERSIONING_POLICY, "policy"}, 794 {ECRYPTFS_VERSIONING_POLICY, "policy"},
753 {ECRYPTFS_VERSIONING_XATTR, "metadata in extended attribute"} 795 {ECRYPTFS_VERSIONING_XATTR, "metadata in extended attribute"},
796 {ECRYPTFS_VERSIONING_MULTKEY, "multiple keys per file"}
754}; 797};
755 798
756static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff) 799static ssize_t version_str_show(struct ecryptfs_obj *obj, char *buff)
@@ -786,7 +829,8 @@ static int do_sysfs_registration(void)
786{ 829{
787 int rc; 830 int rc;
788 831
789 if ((rc = subsystem_register(&ecryptfs_subsys))) { 832 rc = subsystem_register(&ecryptfs_subsys);
833 if (rc) {
790 printk(KERN_ERR 834 printk(KERN_ERR
791 "Unable to register ecryptfs sysfs subsystem\n"); 835 "Unable to register ecryptfs sysfs subsystem\n");
792 goto out; 836 goto out;
@@ -845,33 +889,49 @@ static int __init ecryptfs_init(void)
845 rc = register_filesystem(&ecryptfs_fs_type); 889 rc = register_filesystem(&ecryptfs_fs_type);
846 if (rc) { 890 if (rc) {
847 printk(KERN_ERR "Failed to register filesystem\n"); 891 printk(KERN_ERR "Failed to register filesystem\n");
848 ecryptfs_free_kmem_caches(); 892 goto out_free_kmem_caches;
849 goto out;
850 } 893 }
851 kobj_set_kset_s(&ecryptfs_subsys, fs_subsys); 894 kobj_set_kset_s(&ecryptfs_subsys, fs_subsys);
852 rc = do_sysfs_registration(); 895 rc = do_sysfs_registration();
853 if (rc) { 896 if (rc) {
854 printk(KERN_ERR "sysfs registration failed\n"); 897 printk(KERN_ERR "sysfs registration failed\n");
855 unregister_filesystem(&ecryptfs_fs_type); 898 goto out_unregister_filesystem;
856 ecryptfs_free_kmem_caches();
857 goto out;
858 } 899 }
859 rc = ecryptfs_init_messaging(ecryptfs_transport); 900 rc = ecryptfs_init_messaging(ecryptfs_transport);
860 if (rc) { 901 if (rc) {
861 ecryptfs_printk(KERN_ERR, "Failure occured while attempting to " 902 ecryptfs_printk(KERN_ERR, "Failure occured while attempting to "
862 "initialize the eCryptfs netlink socket\n"); 903 "initialize the eCryptfs netlink socket\n");
863 do_sysfs_unregistration(); 904 goto out_do_sysfs_unregistration;
864 unregister_filesystem(&ecryptfs_fs_type); 905 }
865 ecryptfs_free_kmem_caches(); 906 rc = ecryptfs_init_crypto();
907 if (rc) {
908 printk(KERN_ERR "Failure whilst attempting to init crypto; "
909 "rc = [%d]\n", rc);
910 goto out_release_messaging;
866 } 911 }
912 goto out;
913out_release_messaging:
914 ecryptfs_release_messaging(ecryptfs_transport);
915out_do_sysfs_unregistration:
916 do_sysfs_unregistration();
917out_unregister_filesystem:
918 unregister_filesystem(&ecryptfs_fs_type);
919out_free_kmem_caches:
920 ecryptfs_free_kmem_caches();
867out: 921out:
868 return rc; 922 return rc;
869} 923}
870 924
871static void __exit ecryptfs_exit(void) 925static void __exit ecryptfs_exit(void)
872{ 926{
873 do_sysfs_unregistration(); 927 int rc;
928
929 rc = ecryptfs_destroy_crypto();
930 if (rc)
931 printk(KERN_ERR "Failure whilst attempting to destroy crypto; "
932 "rc = [%d]\n", rc);
874 ecryptfs_release_messaging(ecryptfs_transport); 933 ecryptfs_release_messaging(ecryptfs_transport);
934 do_sysfs_unregistration();
875 unregister_filesystem(&ecryptfs_fs_type); 935 unregister_filesystem(&ecryptfs_fs_type);
876 ecryptfs_free_kmem_caches(); 936 ecryptfs_free_kmem_caches();
877} 937}
diff --git a/fs/ecryptfs/messaging.c b/fs/ecryptfs/messaging.c
index a9d87c47f72d..a96d341d154d 100644
--- a/fs/ecryptfs/messaging.c
+++ b/fs/ecryptfs/messaging.c
@@ -419,8 +419,9 @@ int ecryptfs_init_messaging(unsigned int transport)
419 } 419 }
420 mutex_init(&ecryptfs_daemon_id_hash_mux); 420 mutex_init(&ecryptfs_daemon_id_hash_mux);
421 mutex_lock(&ecryptfs_daemon_id_hash_mux); 421 mutex_lock(&ecryptfs_daemon_id_hash_mux);
422 ecryptfs_hash_buckets = 0; 422 ecryptfs_hash_buckets = 1;
423 while (ecryptfs_number_of_users >> ++ecryptfs_hash_buckets); 423 while (ecryptfs_number_of_users >> ecryptfs_hash_buckets)
424 ecryptfs_hash_buckets++;
424 ecryptfs_daemon_id_hash = kmalloc(sizeof(struct hlist_head) 425 ecryptfs_daemon_id_hash = kmalloc(sizeof(struct hlist_head)
425 * ecryptfs_hash_buckets, GFP_KERNEL); 426 * ecryptfs_hash_buckets, GFP_KERNEL);
426 if (!ecryptfs_daemon_id_hash) { 427 if (!ecryptfs_daemon_id_hash) {
diff --git a/fs/ecryptfs/mmap.c b/fs/ecryptfs/mmap.c
index fd3f94d4a668..16a7a555f392 100644
--- a/fs/ecryptfs/mmap.c
+++ b/fs/ecryptfs/mmap.c
@@ -37,130 +37,27 @@
37struct kmem_cache *ecryptfs_lower_page_cache; 37struct kmem_cache *ecryptfs_lower_page_cache;
38 38
39/** 39/**
40 * ecryptfs_get1page 40 * ecryptfs_get_locked_page
41 * 41 *
42 * Get one page from cache or lower f/s, return error otherwise. 42 * Get one page from cache or lower f/s, return error otherwise.
43 * 43 *
44 * Returns unlocked and up-to-date page (if ok), with increased 44 * Returns locked and up-to-date page (if ok), with increased
45 * refcnt. 45 * refcnt.
46 */ 46 */
47static struct page *ecryptfs_get1page(struct file *file, int index) 47struct page *ecryptfs_get_locked_page(struct file *file, loff_t index)
48{ 48{
49 struct dentry *dentry; 49 struct dentry *dentry;
50 struct inode *inode; 50 struct inode *inode;
51 struct address_space *mapping; 51 struct address_space *mapping;
52 struct page *page;
52 53
53 dentry = file->f_path.dentry; 54 dentry = file->f_path.dentry;
54 inode = dentry->d_inode; 55 inode = dentry->d_inode;
55 mapping = inode->i_mapping; 56 mapping = inode->i_mapping;
56 return read_mapping_page(mapping, index, (void *)file); 57 page = read_mapping_page(mapping, index, (void *)file);
57} 58 if (!IS_ERR(page))
58 59 lock_page(page);
59/** 60 return page;
60 * ecryptfs_fill_zeros
61 * @file: The ecryptfs file
62 * @new_length: The new length of the data in the underlying file;
63 * everything between the prior end of the file and the
64 * new end of the file will be filled with zero's.
65 * new_length must be greater than current length
66 *
67 * Function for handling lseek-ing past the end of the file.
68 *
69 * This function does not support shrinking, only growing a file.
70 *
71 * Returns zero on success; non-zero otherwise.
72 */
73int ecryptfs_fill_zeros(struct file *file, loff_t new_length)
74{
75 int rc = 0;
76 struct dentry *dentry = file->f_path.dentry;
77 struct inode *inode = dentry->d_inode;
78 pgoff_t old_end_page_index = 0;
79 pgoff_t index = old_end_page_index;
80 int old_end_pos_in_page = -1;
81 pgoff_t new_end_page_index;
82 int new_end_pos_in_page;
83 loff_t cur_length = i_size_read(inode);
84
85 if (cur_length != 0) {
86 index = old_end_page_index =
87 ((cur_length - 1) >> PAGE_CACHE_SHIFT);
88 old_end_pos_in_page = ((cur_length - 1) & ~PAGE_CACHE_MASK);
89 }
90 new_end_page_index = ((new_length - 1) >> PAGE_CACHE_SHIFT);
91 new_end_pos_in_page = ((new_length - 1) & ~PAGE_CACHE_MASK);
92 ecryptfs_printk(KERN_DEBUG, "old_end_page_index = [0x%.16x]; "
93 "old_end_pos_in_page = [%d]; "
94 "new_end_page_index = [0x%.16x]; "
95 "new_end_pos_in_page = [%d]\n",
96 old_end_page_index, old_end_pos_in_page,
97 new_end_page_index, new_end_pos_in_page);
98 if (old_end_page_index == new_end_page_index) {
99 /* Start and end are in the same page; we just need to
100 * set a portion of the existing page to zero's */
101 rc = ecryptfs_write_zeros(file, index,
102 (old_end_pos_in_page + 1),
103 (new_end_pos_in_page
104 - old_end_pos_in_page));
105 if (rc)
106 ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros("
107 "file=[%p], "
108 "index=[0x%.16x], "
109 "old_end_pos_in_page=[d], "
110 "(PAGE_CACHE_SIZE - new_end_pos_in_page"
111 "=[%d]"
112 ")=[d]) returned [%d]\n", file, index,
113 old_end_pos_in_page,
114 new_end_pos_in_page,
115 (PAGE_CACHE_SIZE - new_end_pos_in_page),
116 rc);
117 goto out;
118 }
119 /* Fill the remainder of the previous last page with zeros */
120 rc = ecryptfs_write_zeros(file, index, (old_end_pos_in_page + 1),
121 ((PAGE_CACHE_SIZE - 1) - old_end_pos_in_page));
122 if (rc) {
123 ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file=[%p], "
124 "index=[0x%.16x], old_end_pos_in_page=[d], "
125 "(PAGE_CACHE_SIZE - old_end_pos_in_page)=[d]) "
126 "returned [%d]\n", file, index,
127 old_end_pos_in_page,
128 (PAGE_CACHE_SIZE - old_end_pos_in_page), rc);
129 goto out;
130 }
131 index++;
132 while (index < new_end_page_index) {
133 /* Fill all intermediate pages with zeros */
134 rc = ecryptfs_write_zeros(file, index, 0, PAGE_CACHE_SIZE);
135 if (rc) {
136 ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros("
137 "file=[%p], "
138 "index=[0x%.16x], "
139 "old_end_pos_in_page=[d], "
140 "(PAGE_CACHE_SIZE - new_end_pos_in_page"
141 "=[%d]"
142 ")=[d]) returned [%d]\n", file, index,
143 old_end_pos_in_page,
144 new_end_pos_in_page,
145 (PAGE_CACHE_SIZE - new_end_pos_in_page),
146 rc);
147 goto out;
148 }
149 index++;
150 }
151 /* Fill the portion at the beginning of the last new page with
152 * zero's */
153 rc = ecryptfs_write_zeros(file, index, 0, (new_end_pos_in_page + 1));
154 if (rc) {
155 ecryptfs_printk(KERN_ERR, "ecryptfs_write_zeros(file="
156 "[%p], index=[0x%.16x], 0, "
157 "new_end_pos_in_page=[%d]"
158 "returned [%d]\n", file, index,
159 new_end_pos_in_page, rc);
160 goto out;
161 }
162out:
163 return rc;
164} 61}
165 62
166/** 63/**
@@ -171,13 +68,9 @@ out:
171 */ 68 */
172static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc) 69static int ecryptfs_writepage(struct page *page, struct writeback_control *wbc)
173{ 70{
174 struct ecryptfs_page_crypt_context ctx;
175 int rc; 71 int rc;
176 72
177 ctx.page = page; 73 rc = ecryptfs_encrypt_page(page);
178 ctx.mode = ECRYPTFS_WRITEPAGE_MODE;
179 ctx.param.wbc = wbc;
180 rc = ecryptfs_encrypt_page(&ctx);
181 if (rc) { 74 if (rc) {
182 ecryptfs_printk(KERN_WARNING, "Error encrypting " 75 ecryptfs_printk(KERN_WARNING, "Error encrypting "
183 "page (upper index [0x%.16x])\n", page->index); 76 "page (upper index [0x%.16x])\n", page->index);
@@ -191,58 +84,6 @@ out:
191} 84}
192 85
193/** 86/**
194 * Reads the data from the lower file file at index lower_page_index
195 * and copies that data into page.
196 *
197 * @param page Page to fill
198 * @param lower_page_index Index of the page in the lower file to get
199 */
200int ecryptfs_do_readpage(struct file *file, struct page *page,
201 pgoff_t lower_page_index)
202{
203 int rc;
204 struct dentry *dentry;
205 struct file *lower_file;
206 struct dentry *lower_dentry;
207 struct inode *inode;
208 struct inode *lower_inode;
209 char *page_data;
210 struct page *lower_page = NULL;
211 char *lower_page_data;
212 const struct address_space_operations *lower_a_ops;
213
214 dentry = file->f_path.dentry;
215 lower_file = ecryptfs_file_to_lower(file);
216 lower_dentry = ecryptfs_dentry_to_lower(dentry);
217 inode = dentry->d_inode;
218 lower_inode = ecryptfs_inode_to_lower(inode);
219 lower_a_ops = lower_inode->i_mapping->a_ops;
220 lower_page = read_cache_page(lower_inode->i_mapping, lower_page_index,
221 (filler_t *)lower_a_ops->readpage,
222 (void *)lower_file);
223 if (IS_ERR(lower_page)) {
224 rc = PTR_ERR(lower_page);
225 lower_page = NULL;
226 ecryptfs_printk(KERN_ERR, "Error reading from page cache\n");
227 goto out;
228 }
229 page_data = kmap_atomic(page, KM_USER0);
230 lower_page_data = kmap_atomic(lower_page, KM_USER1);
231 memcpy(page_data, lower_page_data, PAGE_CACHE_SIZE);
232 kunmap_atomic(lower_page_data, KM_USER1);
233 kunmap_atomic(page_data, KM_USER0);
234 flush_dcache_page(page);
235 rc = 0;
236out:
237 if (likely(lower_page))
238 page_cache_release(lower_page);
239 if (rc == 0)
240 SetPageUptodate(page);
241 else
242 ClearPageUptodate(page);
243 return rc;
244}
245/**
246 * Header Extent: 87 * Header Extent:
247 * Octets 0-7: Unencrypted file size (big-endian) 88 * Octets 0-7: Unencrypted file size (big-endian)
248 * Octets 8-15: eCryptfs special marker 89 * Octets 8-15: eCryptfs special marker
@@ -271,9 +112,77 @@ static void set_header_info(char *page_virt,
271} 112}
272 113
273/** 114/**
115 * ecryptfs_copy_up_encrypted_with_header
116 * @page: Sort of a ``virtual'' representation of the encrypted lower
117 * file. The actual lower file does not have the metadata in
118 * the header. This is locked.
119 * @crypt_stat: The eCryptfs inode's cryptographic context
120 *
121 * The ``view'' is the version of the file that userspace winds up
122 * seeing, with the header information inserted.
123 */
124static int
125ecryptfs_copy_up_encrypted_with_header(struct page *page,
126 struct ecryptfs_crypt_stat *crypt_stat)
127{
128 loff_t extent_num_in_page = 0;
129 loff_t num_extents_per_page = (PAGE_CACHE_SIZE
130 / crypt_stat->extent_size);
131 int rc = 0;
132
133 while (extent_num_in_page < num_extents_per_page) {
134 loff_t view_extent_num = ((((loff_t)page->index)
135 * num_extents_per_page)
136 + extent_num_in_page);
137
138 if (view_extent_num < crypt_stat->num_header_extents_at_front) {
139 /* This is a header extent */
140 char *page_virt;
141
142 page_virt = kmap_atomic(page, KM_USER0);
143 memset(page_virt, 0, PAGE_CACHE_SIZE);
144 /* TODO: Support more than one header extent */
145 if (view_extent_num == 0) {
146 rc = ecryptfs_read_xattr_region(
147 page_virt, page->mapping->host);
148 set_header_info(page_virt, crypt_stat);
149 }
150 kunmap_atomic(page_virt, KM_USER0);
151 flush_dcache_page(page);
152 if (rc) {
153 printk(KERN_ERR "%s: Error reading xattr "
154 "region; rc = [%d]\n", __FUNCTION__, rc);
155 goto out;
156 }
157 } else {
158 /* This is an encrypted data extent */
159 loff_t lower_offset =
160 ((view_extent_num -
161 crypt_stat->num_header_extents_at_front)
162 * crypt_stat->extent_size);
163
164 rc = ecryptfs_read_lower_page_segment(
165 page, (lower_offset >> PAGE_CACHE_SHIFT),
166 (lower_offset & ~PAGE_CACHE_MASK),
167 crypt_stat->extent_size, page->mapping->host);
168 if (rc) {
169 printk(KERN_ERR "%s: Error attempting to read "
170 "extent at offset [%lld] in the lower "
171 "file; rc = [%d]\n", __FUNCTION__,
172 lower_offset, rc);
173 goto out;
174 }
175 }
176 extent_num_in_page++;
177 }
178out:
179 return rc;
180}
181
182/**
274 * ecryptfs_readpage 183 * ecryptfs_readpage
275 * @file: This is an ecryptfs file 184 * @file: An eCryptfs file
276 * @page: ecryptfs associated page to stick the read data into 185 * @page: Page from eCryptfs inode mapping into which to stick the read data
277 * 186 *
278 * Read in a page, decrypting if necessary. 187 * Read in a page, decrypting if necessary.
279 * 188 *
@@ -281,59 +190,35 @@ static void set_header_info(char *page_virt,
281 */ 190 */
282static int ecryptfs_readpage(struct file *file, struct page *page) 191static int ecryptfs_readpage(struct file *file, struct page *page)
283{ 192{
193 struct ecryptfs_crypt_stat *crypt_stat =
194 &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
284 int rc = 0; 195 int rc = 0;
285 struct ecryptfs_crypt_stat *crypt_stat;
286 196
287 BUG_ON(!(file && file->f_path.dentry && file->f_path.dentry->d_inode));
288 crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)
289 ->crypt_stat;
290 if (!crypt_stat 197 if (!crypt_stat
291 || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED) 198 || !(crypt_stat->flags & ECRYPTFS_ENCRYPTED)
292 || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) { 199 || (crypt_stat->flags & ECRYPTFS_NEW_FILE)) {
293 ecryptfs_printk(KERN_DEBUG, 200 ecryptfs_printk(KERN_DEBUG,
294 "Passing through unencrypted page\n"); 201 "Passing through unencrypted page\n");
295 rc = ecryptfs_do_readpage(file, page, page->index); 202 rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
296 if (rc) { 203 PAGE_CACHE_SIZE,
297 ecryptfs_printk(KERN_ERR, "Error reading page; rc = " 204 page->mapping->host);
298 "[%d]\n", rc);
299 goto out;
300 }
301 } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) { 205 } else if (crypt_stat->flags & ECRYPTFS_VIEW_AS_ENCRYPTED) {
302 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) { 206 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) {
303 int num_pages_in_header_region = 207 rc = ecryptfs_copy_up_encrypted_with_header(page,
304 (crypt_stat->header_extent_size 208 crypt_stat);
305 / PAGE_CACHE_SIZE); 209 if (rc) {
306 210 printk(KERN_ERR "%s: Error attempting to copy "
307 if (page->index < num_pages_in_header_region) { 211 "the encrypted content from the lower "
308 char *page_virt; 212 "file whilst inserting the metadata "
309 213 "from the xattr into the header; rc = "
310 page_virt = kmap_atomic(page, KM_USER0); 214 "[%d]\n", __FUNCTION__, rc);
311 memset(page_virt, 0, PAGE_CACHE_SIZE); 215 goto out;
312 if (page->index == 0) {
313 rc = ecryptfs_read_xattr_region(
314 page_virt, file->f_path.dentry);
315 set_header_info(page_virt, crypt_stat);
316 }
317 kunmap_atomic(page_virt, KM_USER0);
318 flush_dcache_page(page);
319 if (rc) {
320 printk(KERN_ERR "Error reading xattr "
321 "region\n");
322 goto out;
323 }
324 } else {
325 rc = ecryptfs_do_readpage(
326 file, page,
327 (page->index
328 - num_pages_in_header_region));
329 if (rc) {
330 printk(KERN_ERR "Error reading page; "
331 "rc = [%d]\n", rc);
332 goto out;
333 }
334 } 216 }
217
335 } else { 218 } else {
336 rc = ecryptfs_do_readpage(file, page, page->index); 219 rc = ecryptfs_read_lower_page_segment(
220 page, page->index, 0, PAGE_CACHE_SIZE,
221 page->mapping->host);
337 if (rc) { 222 if (rc) {
338 printk(KERN_ERR "Error reading page; rc = " 223 printk(KERN_ERR "Error reading page; rc = "
339 "[%d]\n", rc); 224 "[%d]\n", rc);
@@ -341,17 +226,18 @@ static int ecryptfs_readpage(struct file *file, struct page *page)
341 } 226 }
342 } 227 }
343 } else { 228 } else {
344 rc = ecryptfs_decrypt_page(file, page); 229 rc = ecryptfs_decrypt_page(page);
345 if (rc) { 230 if (rc) {
346 ecryptfs_printk(KERN_ERR, "Error decrypting page; " 231 ecryptfs_printk(KERN_ERR, "Error decrypting page; "
347 "rc = [%d]\n", rc); 232 "rc = [%d]\n", rc);
348 goto out; 233 goto out;
349 } 234 }
350 } 235 }
351 SetPageUptodate(page);
352out: 236out:
353 if (rc) 237 if (rc)
354 ClearPageUptodate(page); 238 ClearPageUptodate(page);
239 else
240 SetPageUptodate(page);
355 ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n", 241 ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
356 page->index); 242 page->index);
357 unlock_page(page); 243 unlock_page(page);
@@ -377,27 +263,6 @@ out:
377 return 0; 263 return 0;
378} 264}
379 265
380/**
381 * eCryptfs does not currently support holes. When writing after a
382 * seek past the end of the file, eCryptfs fills in 0's through to the
383 * current location. The code to fill in the 0's to all the
384 * intermediate pages calls ecryptfs_prepare_write_no_truncate().
385 */
386static int
387ecryptfs_prepare_write_no_truncate(struct file *file, struct page *page,
388 unsigned from, unsigned to)
389{
390 int rc = 0;
391
392 if (from == 0 && to == PAGE_CACHE_SIZE)
393 goto out; /* If we are writing a full page, it will be
394 up to date. */
395 if (!PageUptodate(page))
396 rc = ecryptfs_do_readpage(file, page, page->index);
397out:
398 return rc;
399}
400
401static int ecryptfs_prepare_write(struct file *file, struct page *page, 266static int ecryptfs_prepare_write(struct file *file, struct page *page,
402 unsigned from, unsigned to) 267 unsigned from, unsigned to)
403{ 268{
@@ -406,10 +271,21 @@ static int ecryptfs_prepare_write(struct file *file, struct page *page,
406 if (from == 0 && to == PAGE_CACHE_SIZE) 271 if (from == 0 && to == PAGE_CACHE_SIZE)
407 goto out; /* If we are writing a full page, it will be 272 goto out; /* If we are writing a full page, it will be
408 up to date. */ 273 up to date. */
409 if (!PageUptodate(page)) 274 if (!PageUptodate(page)) {
410 rc = ecryptfs_do_readpage(file, page, page->index); 275 rc = ecryptfs_read_lower_page_segment(page, page->index, 0,
276 PAGE_CACHE_SIZE,
277 page->mapping->host);
278 if (rc) {
279 printk(KERN_ERR "%s: Error attemping to read lower "
280 "page segment; rc = [%d]\n", __FUNCTION__, rc);
281 ClearPageUptodate(page);
282 goto out;
283 } else
284 SetPageUptodate(page);
285 }
411 if (page->index != 0) { 286 if (page->index != 0) {
412 loff_t end_of_prev_pg_pos = page_offset(page) - 1; 287 loff_t end_of_prev_pg_pos =
288 (((loff_t)page->index << PAGE_CACHE_SHIFT) - 1);
413 289
414 if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) { 290 if (end_of_prev_pg_pos > i_size_read(page->mapping->host)) {
415 rc = ecryptfs_truncate(file->f_path.dentry, 291 rc = ecryptfs_truncate(file->f_path.dentry,
@@ -428,32 +304,6 @@ out:
428 return rc; 304 return rc;
429} 305}
430 306
431int ecryptfs_writepage_and_release_lower_page(struct page *lower_page,
432 struct inode *lower_inode,
433 struct writeback_control *wbc)
434{
435 int rc = 0;
436
437 rc = lower_inode->i_mapping->a_ops->writepage(lower_page, wbc);
438 if (rc) {
439 ecryptfs_printk(KERN_ERR, "Error calling lower writepage(); "
440 "rc = [%d]\n", rc);
441 goto out;
442 }
443 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
444 page_cache_release(lower_page);
445out:
446 return rc;
447}
448
449static
450void ecryptfs_release_lower_page(struct page *lower_page, int page_locked)
451{
452 if (page_locked)
453 unlock_page(lower_page);
454 page_cache_release(lower_page);
455}
456
457/** 307/**
458 * ecryptfs_write_inode_size_to_header 308 * ecryptfs_write_inode_size_to_header
459 * 309 *
@@ -461,67 +311,48 @@ void ecryptfs_release_lower_page(struct page *lower_page, int page_locked)
461 * 311 *
462 * Returns zero on success; non-zero on error. 312 * Returns zero on success; non-zero on error.
463 */ 313 */
464static int ecryptfs_write_inode_size_to_header(struct file *lower_file, 314static int ecryptfs_write_inode_size_to_header(struct inode *ecryptfs_inode)
465 struct inode *lower_inode,
466 struct inode *inode)
467{ 315{
468 int rc = 0;
469 struct page *header_page;
470 char *header_virt;
471 const struct address_space_operations *lower_a_ops;
472 u64 file_size; 316 u64 file_size;
317 char *file_size_virt;
318 int rc;
473 319
474retry: 320 file_size_virt = kmalloc(sizeof(u64), GFP_KERNEL);
475 header_page = grab_cache_page(lower_inode->i_mapping, 0); 321 if (!file_size_virt) {
476 if (!header_page) { 322 rc = -ENOMEM;
477 ecryptfs_printk(KERN_ERR, "grab_cache_page for "
478 "lower_page_index 0 failed\n");
479 rc = -EINVAL;
480 goto out;
481 }
482 lower_a_ops = lower_inode->i_mapping->a_ops;
483 rc = lower_a_ops->prepare_write(lower_file, header_page, 0, 8);
484 if (rc) {
485 if (rc == AOP_TRUNCATED_PAGE) {
486 ecryptfs_release_lower_page(header_page, 0);
487 goto retry;
488 } else
489 ecryptfs_release_lower_page(header_page, 1);
490 goto out; 323 goto out;
491 } 324 }
492 file_size = (u64)i_size_read(inode); 325 file_size = (u64)i_size_read(ecryptfs_inode);
493 ecryptfs_printk(KERN_DEBUG, "Writing size: [0x%.16x]\n", file_size);
494 file_size = cpu_to_be64(file_size); 326 file_size = cpu_to_be64(file_size);
495 header_virt = kmap_atomic(header_page, KM_USER0); 327 memcpy(file_size_virt, &file_size, sizeof(u64));
496 memcpy(header_virt, &file_size, sizeof(u64)); 328 rc = ecryptfs_write_lower(ecryptfs_inode, file_size_virt, 0,
497 kunmap_atomic(header_virt, KM_USER0); 329 sizeof(u64));
498 flush_dcache_page(header_page); 330 kfree(file_size_virt);
499 rc = lower_a_ops->commit_write(lower_file, header_page, 0, 8); 331 if (rc)
500 if (rc < 0) 332 printk(KERN_ERR "%s: Error writing file size to header; "
501 ecryptfs_printk(KERN_ERR, "Error commiting header page " 333 "rc = [%d]\n", __FUNCTION__, rc);
502 "write\n");
503 if (rc == AOP_TRUNCATED_PAGE) {
504 ecryptfs_release_lower_page(header_page, 0);
505 goto retry;
506 } else
507 ecryptfs_release_lower_page(header_page, 1);
508 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
509 mark_inode_dirty_sync(inode);
510out: 334out:
511 return rc; 335 return rc;
512} 336}
513 337
514static int ecryptfs_write_inode_size_to_xattr(struct inode *lower_inode, 338struct kmem_cache *ecryptfs_xattr_cache;
515 struct inode *inode, 339
516 struct dentry *ecryptfs_dentry, 340static int ecryptfs_write_inode_size_to_xattr(struct inode *ecryptfs_inode)
517 int lower_i_mutex_held)
518{ 341{
519 ssize_t size; 342 ssize_t size;
520 void *xattr_virt; 343 void *xattr_virt;
521 struct dentry *lower_dentry; 344 struct dentry *lower_dentry =
345 ecryptfs_inode_to_private(ecryptfs_inode)->lower_file->f_dentry;
346 struct inode *lower_inode = lower_dentry->d_inode;
522 u64 file_size; 347 u64 file_size;
523 int rc; 348 int rc;
524 349
350 if (!lower_inode->i_op->getxattr || !lower_inode->i_op->setxattr) {
351 printk(KERN_WARNING
352 "No support for setting xattr in lower filesystem\n");
353 rc = -ENOSYS;
354 goto out;
355 }
525 xattr_virt = kmem_cache_alloc(ecryptfs_xattr_cache, GFP_KERNEL); 356 xattr_virt = kmem_cache_alloc(ecryptfs_xattr_cache, GFP_KERNEL);
526 if (!xattr_virt) { 357 if (!xattr_virt) {
527 printk(KERN_ERR "Out of memory whilst attempting to write " 358 printk(KERN_ERR "Out of memory whilst attempting to write "
@@ -529,35 +360,17 @@ static int ecryptfs_write_inode_size_to_xattr(struct inode *lower_inode,
529 rc = -ENOMEM; 360 rc = -ENOMEM;
530 goto out; 361 goto out;
531 } 362 }
532 lower_dentry = ecryptfs_dentry_to_lower(ecryptfs_dentry); 363 mutex_lock(&lower_inode->i_mutex);
533 if (!lower_dentry->d_inode->i_op->getxattr || 364 size = lower_inode->i_op->getxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
534 !lower_dentry->d_inode->i_op->setxattr) { 365 xattr_virt, PAGE_CACHE_SIZE);
535 printk(KERN_WARNING
536 "No support for setting xattr in lower filesystem\n");
537 rc = -ENOSYS;
538 kmem_cache_free(ecryptfs_xattr_cache, xattr_virt);
539 goto out;
540 }
541 if (!lower_i_mutex_held)
542 mutex_lock(&lower_dentry->d_inode->i_mutex);
543 size = lower_dentry->d_inode->i_op->getxattr(lower_dentry,
544 ECRYPTFS_XATTR_NAME,
545 xattr_virt,
546 PAGE_CACHE_SIZE);
547 if (!lower_i_mutex_held)
548 mutex_unlock(&lower_dentry->d_inode->i_mutex);
549 if (size < 0) 366 if (size < 0)
550 size = 8; 367 size = 8;
551 file_size = (u64)i_size_read(inode); 368 file_size = (u64)i_size_read(ecryptfs_inode);
552 file_size = cpu_to_be64(file_size); 369 file_size = cpu_to_be64(file_size);
553 memcpy(xattr_virt, &file_size, sizeof(u64)); 370 memcpy(xattr_virt, &file_size, sizeof(u64));
554 if (!lower_i_mutex_held) 371 rc = lower_inode->i_op->setxattr(lower_dentry, ECRYPTFS_XATTR_NAME,
555 mutex_lock(&lower_dentry->d_inode->i_mutex); 372 xattr_virt, size, 0);
556 rc = lower_dentry->d_inode->i_op->setxattr(lower_dentry, 373 mutex_unlock(&lower_inode->i_mutex);
557 ECRYPTFS_XATTR_NAME,
558 xattr_virt, size, 0);
559 if (!lower_i_mutex_held)
560 mutex_unlock(&lower_dentry->d_inode->i_mutex);
561 if (rc) 374 if (rc)
562 printk(KERN_ERR "Error whilst attempting to write inode size " 375 printk(KERN_ERR "Error whilst attempting to write inode size "
563 "to lower file xattr; rc = [%d]\n", rc); 376 "to lower file xattr; rc = [%d]\n", rc);
@@ -566,122 +379,18 @@ out:
566 return rc; 379 return rc;
567} 380}
568 381
569int 382int ecryptfs_write_inode_size_to_metadata(struct inode *ecryptfs_inode)
570ecryptfs_write_inode_size_to_metadata(struct file *lower_file,
571 struct inode *lower_inode,
572 struct inode *inode,
573 struct dentry *ecryptfs_dentry,
574 int lower_i_mutex_held)
575{ 383{
576 struct ecryptfs_crypt_stat *crypt_stat; 384 struct ecryptfs_crypt_stat *crypt_stat;
577 385
578 crypt_stat = &ecryptfs_inode_to_private(inode)->crypt_stat; 386 crypt_stat = &ecryptfs_inode_to_private(ecryptfs_inode)->crypt_stat;
579 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR) 387 if (crypt_stat->flags & ECRYPTFS_METADATA_IN_XATTR)
580 return ecryptfs_write_inode_size_to_xattr(lower_inode, inode, 388 return ecryptfs_write_inode_size_to_xattr(ecryptfs_inode);
581 ecryptfs_dentry,
582 lower_i_mutex_held);
583 else 389 else
584 return ecryptfs_write_inode_size_to_header(lower_file, 390 return ecryptfs_write_inode_size_to_header(ecryptfs_inode);
585 lower_inode,
586 inode);
587}
588
589int ecryptfs_get_lower_page(struct page **lower_page, struct inode *lower_inode,
590 struct file *lower_file,
591 unsigned long lower_page_index, int byte_offset,
592 int region_bytes)
593{
594 int rc = 0;
595
596retry:
597 *lower_page = grab_cache_page(lower_inode->i_mapping, lower_page_index);
598 if (!(*lower_page)) {
599 rc = -EINVAL;
600 ecryptfs_printk(KERN_ERR, "Error attempting to grab "
601 "lower page with index [0x%.16x]\n",
602 lower_page_index);
603 goto out;
604 }
605 rc = lower_inode->i_mapping->a_ops->prepare_write(lower_file,
606 (*lower_page),
607 byte_offset,
608 region_bytes);
609 if (rc) {
610 if (rc == AOP_TRUNCATED_PAGE) {
611 ecryptfs_release_lower_page(*lower_page, 0);
612 goto retry;
613 } else {
614 ecryptfs_printk(KERN_ERR, "prepare_write for "
615 "lower_page_index = [0x%.16x] failed; rc = "
616 "[%d]\n", lower_page_index, rc);
617 ecryptfs_release_lower_page(*lower_page, 1);
618 (*lower_page) = NULL;
619 }
620 }
621out:
622 return rc;
623}
624
625/**
626 * ecryptfs_commit_lower_page
627 *
628 * Returns zero on success; non-zero on error
629 */
630int
631ecryptfs_commit_lower_page(struct page *lower_page, struct inode *lower_inode,
632 struct file *lower_file, int byte_offset,
633 int region_size)
634{
635 int page_locked = 1;
636 int rc = 0;
637
638 rc = lower_inode->i_mapping->a_ops->commit_write(
639 lower_file, lower_page, byte_offset, region_size);
640 if (rc == AOP_TRUNCATED_PAGE)
641 page_locked = 0;
642 if (rc < 0) {
643 ecryptfs_printk(KERN_ERR,
644 "Error committing write; rc = [%d]\n", rc);
645 } else
646 rc = 0;
647 ecryptfs_release_lower_page(lower_page, page_locked);
648 return rc;
649} 391}
650 392
651/** 393/**
652 * ecryptfs_copy_page_to_lower
653 *
654 * Used for plaintext pass-through; no page index interpolation
655 * required.
656 */
657int ecryptfs_copy_page_to_lower(struct page *page, struct inode *lower_inode,
658 struct file *lower_file)
659{
660 int rc = 0;
661 struct page *lower_page;
662
663 rc = ecryptfs_get_lower_page(&lower_page, lower_inode, lower_file,
664 page->index, 0, PAGE_CACHE_SIZE);
665 if (rc) {
666 ecryptfs_printk(KERN_ERR, "Error attempting to get page "
667 "at index [0x%.16x]\n", page->index);
668 goto out;
669 }
670 /* TODO: aops */
671 memcpy((char *)page_address(lower_page), page_address(page),
672 PAGE_CACHE_SIZE);
673 rc = ecryptfs_commit_lower_page(lower_page, lower_inode, lower_file,
674 0, PAGE_CACHE_SIZE);
675 if (rc)
676 ecryptfs_printk(KERN_ERR, "Error attempting to commit page "
677 "at index [0x%.16x]\n", page->index);
678out:
679 return rc;
680}
681
682struct kmem_cache *ecryptfs_xattr_cache;
683
684/**
685 * ecryptfs_commit_write 394 * ecryptfs_commit_write
686 * @file: The eCryptfs file object 395 * @file: The eCryptfs file object
687 * @page: The eCryptfs page 396 * @page: The eCryptfs page
@@ -695,20 +404,12 @@ struct kmem_cache *ecryptfs_xattr_cache;
695static int ecryptfs_commit_write(struct file *file, struct page *page, 404static int ecryptfs_commit_write(struct file *file, struct page *page,
696 unsigned from, unsigned to) 405 unsigned from, unsigned to)
697{ 406{
698 struct ecryptfs_page_crypt_context ctx;
699 loff_t pos; 407 loff_t pos;
700 struct inode *inode; 408 struct inode *ecryptfs_inode = page->mapping->host;
701 struct inode *lower_inode; 409 struct ecryptfs_crypt_stat *crypt_stat =
702 struct file *lower_file; 410 &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)->crypt_stat;
703 struct ecryptfs_crypt_stat *crypt_stat;
704 int rc; 411 int rc;
705 412
706 inode = page->mapping->host;
707 lower_inode = ecryptfs_inode_to_lower(inode);
708 lower_file = ecryptfs_file_to_lower(file);
709 mutex_lock(&lower_inode->i_mutex);
710 crypt_stat = &ecryptfs_inode_to_private(file->f_path.dentry->d_inode)
711 ->crypt_stat;
712 if (crypt_stat->flags & ECRYPTFS_NEW_FILE) { 413 if (crypt_stat->flags & ECRYPTFS_NEW_FILE) {
713 ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in " 414 ecryptfs_printk(KERN_DEBUG, "ECRYPTFS_NEW_FILE flag set in "
714 "crypt_stat at memory location [%p]\n", crypt_stat); 415 "crypt_stat at memory location [%p]\n", crypt_stat);
@@ -718,6 +419,7 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
718 ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page" 419 ecryptfs_printk(KERN_DEBUG, "Calling fill_zeros_to_end_of_page"
719 "(page w/ index = [0x%.16x], to = [%d])\n", page->index, 420 "(page w/ index = [0x%.16x], to = [%d])\n", page->index,
720 to); 421 to);
422 /* Fills in zeros if 'to' goes beyond inode size */
721 rc = fill_zeros_to_end_of_page(page, to); 423 rc = fill_zeros_to_end_of_page(page, to);
722 if (rc) { 424 if (rc) {
723 ecryptfs_printk(KERN_WARNING, "Error attempting to fill " 425 ecryptfs_printk(KERN_WARNING, "Error attempting to fill "
@@ -725,82 +427,22 @@ static int ecryptfs_commit_write(struct file *file, struct page *page,
725 page->index); 427 page->index);
726 goto out; 428 goto out;
727 } 429 }
728 ctx.page = page; 430 rc = ecryptfs_encrypt_page(page);
729 ctx.mode = ECRYPTFS_PREPARE_COMMIT_MODE;
730 ctx.param.lower_file = lower_file;
731 rc = ecryptfs_encrypt_page(&ctx);
732 if (rc) { 431 if (rc) {
733 ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper " 432 ecryptfs_printk(KERN_WARNING, "Error encrypting page (upper "
734 "index [0x%.16x])\n", page->index); 433 "index [0x%.16x])\n", page->index);
735 goto out; 434 goto out;
736 } 435 }
737 inode->i_blocks = lower_inode->i_blocks; 436 pos = (((loff_t)page->index) << PAGE_CACHE_SHIFT) + to;
738 pos = page_offset(page) + to; 437 if (pos > i_size_read(ecryptfs_inode)) {
739 if (pos > i_size_read(inode)) { 438 i_size_write(ecryptfs_inode, pos);
740 i_size_write(inode, pos);
741 ecryptfs_printk(KERN_DEBUG, "Expanded file size to " 439 ecryptfs_printk(KERN_DEBUG, "Expanded file size to "
742 "[0x%.16x]\n", i_size_read(inode)); 440 "[0x%.16x]\n", i_size_read(ecryptfs_inode));
743 } 441 }
744 rc = ecryptfs_write_inode_size_to_metadata(lower_file, lower_inode, 442 rc = ecryptfs_write_inode_size_to_metadata(ecryptfs_inode);
745 inode, file->f_dentry,
746 ECRYPTFS_LOWER_I_MUTEX_HELD);
747 if (rc) 443 if (rc)
748 printk(KERN_ERR "Error writing inode size to metadata; " 444 printk(KERN_ERR "Error writing inode size to metadata; "
749 "rc = [%d]\n", rc); 445 "rc = [%d]\n", rc);
750 lower_inode->i_mtime = lower_inode->i_ctime = CURRENT_TIME;
751 mark_inode_dirty_sync(inode);
752out:
753 if (rc < 0)
754 ClearPageUptodate(page);
755 else
756 SetPageUptodate(page);
757 mutex_unlock(&lower_inode->i_mutex);
758 return rc;
759}
760
761/**
762 * ecryptfs_write_zeros
763 * @file: The ecryptfs file
764 * @index: The index in which we are writing
765 * @start: The position after the last block of data
766 * @num_zeros: The number of zeros to write
767 *
768 * Write a specified number of zero's to a page.
769 *
770 * (start + num_zeros) must be less than or equal to PAGE_CACHE_SIZE
771 */
772int
773ecryptfs_write_zeros(struct file *file, pgoff_t index, int start, int num_zeros)
774{
775 int rc = 0;
776 struct page *tmp_page;
777
778 tmp_page = ecryptfs_get1page(file, index);
779 if (IS_ERR(tmp_page)) {
780 ecryptfs_printk(KERN_ERR, "Error getting page at index "
781 "[0x%.16x]\n", index);
782 rc = PTR_ERR(tmp_page);
783 goto out;
784 }
785 if ((rc = ecryptfs_prepare_write_no_truncate(file, tmp_page, start,
786 (start + num_zeros)))) {
787 ecryptfs_printk(KERN_ERR, "Error preparing to write zero's "
788 "to page at index [0x%.16x]\n",
789 index);
790 page_cache_release(tmp_page);
791 goto out;
792 }
793 zero_user_page(tmp_page, start, num_zeros, KM_USER0);
794 rc = ecryptfs_commit_write(file, tmp_page, start, start + num_zeros);
795 if (rc < 0) {
796 ecryptfs_printk(KERN_ERR, "Error attempting to write zero's "
797 "to remainder of page at index [0x%.16x]\n",
798 index);
799 page_cache_release(tmp_page);
800 goto out;
801 }
802 rc = 0;
803 page_cache_release(tmp_page);
804out: 446out:
805 return rc; 447 return rc;
806} 448}
@@ -819,34 +461,10 @@ static sector_t ecryptfs_bmap(struct address_space *mapping, sector_t block)
819 return rc; 461 return rc;
820} 462}
821 463
822static void ecryptfs_sync_page(struct page *page)
823{
824 struct inode *inode;
825 struct inode *lower_inode;
826 struct page *lower_page;
827
828 inode = page->mapping->host;
829 lower_inode = ecryptfs_inode_to_lower(inode);
830 /* NOTE: Recently swapped with grab_cache_page(), since
831 * sync_page() just makes sure that pending I/O gets done. */
832 lower_page = find_lock_page(lower_inode->i_mapping, page->index);
833 if (!lower_page) {
834 ecryptfs_printk(KERN_DEBUG, "find_lock_page failed\n");
835 return;
836 }
837 if (lower_page->mapping->a_ops->sync_page)
838 lower_page->mapping->a_ops->sync_page(lower_page);
839 ecryptfs_printk(KERN_DEBUG, "Unlocking page with index = [0x%.16x]\n",
840 lower_page->index);
841 unlock_page(lower_page);
842 page_cache_release(lower_page);
843}
844
845struct address_space_operations ecryptfs_aops = { 464struct address_space_operations ecryptfs_aops = {
846 .writepage = ecryptfs_writepage, 465 .writepage = ecryptfs_writepage,
847 .readpage = ecryptfs_readpage, 466 .readpage = ecryptfs_readpage,
848 .prepare_write = ecryptfs_prepare_write, 467 .prepare_write = ecryptfs_prepare_write,
849 .commit_write = ecryptfs_commit_write, 468 .commit_write = ecryptfs_commit_write,
850 .bmap = ecryptfs_bmap, 469 .bmap = ecryptfs_bmap,
851 .sync_page = ecryptfs_sync_page,
852}; 470};
diff --git a/fs/ecryptfs/read_write.c b/fs/ecryptfs/read_write.c
new file mode 100644
index 000000000000..2150edf9a58e
--- /dev/null
+++ b/fs/ecryptfs/read_write.c
@@ -0,0 +1,358 @@
1/**
2 * eCryptfs: Linux filesystem encryption layer
3 *
4 * Copyright (C) 2007 International Business Machines Corp.
5 * Author(s): Michael A. Halcrow <mahalcro@us.ibm.com>
6 *
7 * This program is free software; you can redistribute it and/or
8 * modify it under the terms of the GNU General Public License as
9 * published by the Free Software Foundation; either version 2 of the
10 * License, or (at your option) any later version.
11 *
12 * This program is distributed in the hope that it will be useful, but
13 * WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15 * General Public License for more details.
16 *
17 * You should have received a copy of the GNU General Public License
18 * along with this program; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
20 * 02111-1307, USA.
21 */
22
23#include <linux/fs.h>
24#include <linux/pagemap.h>
25#include "ecryptfs_kernel.h"
26
27/**
28 * ecryptfs_write_lower
29 * @ecryptfs_inode: The eCryptfs inode
30 * @data: Data to write
31 * @offset: Byte offset in the lower file to which to write the data
32 * @size: Number of bytes from @data to write at @offset in the lower
33 * file
34 *
35 * Write data to the lower file.
36 *
37 * Returns zero on success; non-zero on error
38 */
39int ecryptfs_write_lower(struct inode *ecryptfs_inode, char *data,
40 loff_t offset, size_t size)
41{
42 struct ecryptfs_inode_info *inode_info;
43 ssize_t octets_written;
44 mm_segment_t fs_save;
45 int rc = 0;
46
47 inode_info = ecryptfs_inode_to_private(ecryptfs_inode);
48 mutex_lock(&inode_info->lower_file_mutex);
49 BUG_ON(!inode_info->lower_file);
50 inode_info->lower_file->f_pos = offset;
51 fs_save = get_fs();
52 set_fs(get_ds());
53 octets_written = vfs_write(inode_info->lower_file, data, size,
54 &inode_info->lower_file->f_pos);
55 set_fs(fs_save);
56 if (octets_written < 0) {
57 printk(KERN_ERR "%s: octets_written = [%td]; "
58 "expected [%td]\n", __FUNCTION__, octets_written, size);
59 rc = -EINVAL;
60 }
61 mutex_unlock(&inode_info->lower_file_mutex);
62 mark_inode_dirty_sync(ecryptfs_inode);
63 return rc;
64}
65
66/**
67 * ecryptfs_write_lower_page_segment
68 * @ecryptfs_inode: The eCryptfs inode
69 * @page_for_lower: The page containing the data to be written to the
70 * lower file
71 * @offset_in_page: The offset in the @page_for_lower from which to
72 * start writing the data
73 * @size: The amount of data from @page_for_lower to write to the
74 * lower file
75 *
76 * Determines the byte offset in the file for the given page and
77 * offset within the page, maps the page, and makes the call to write
78 * the contents of @page_for_lower to the lower inode.
79 *
80 * Returns zero on success; non-zero otherwise
81 */
82int ecryptfs_write_lower_page_segment(struct inode *ecryptfs_inode,
83 struct page *page_for_lower,
84 size_t offset_in_page, size_t size)
85{
86 char *virt;
87 loff_t offset;
88 int rc;
89
90 offset = ((((off_t)page_for_lower->index) << PAGE_CACHE_SHIFT)
91 + offset_in_page);
92 virt = kmap(page_for_lower);
93 rc = ecryptfs_write_lower(ecryptfs_inode, virt, offset, size);
94 kunmap(page_for_lower);
95 return rc;
96}
97
98/**
99 * ecryptfs_write
100 * @ecryptfs_file: The eCryptfs file into which to write
101 * @data: Virtual address where data to write is located
102 * @offset: Offset in the eCryptfs file at which to begin writing the
103 * data from @data
104 * @size: The number of bytes to write from @data
105 *
106 * Write an arbitrary amount of data to an arbitrary location in the
107 * eCryptfs inode page cache. This is done on a page-by-page, and then
108 * by an extent-by-extent, basis; individual extents are encrypted and
109 * written to the lower page cache (via VFS writes). This function
110 * takes care of all the address translation to locations in the lower
111 * filesystem; it also handles truncate events, writing out zeros
112 * where necessary.
113 *
114 * Returns zero on success; non-zero otherwise
115 */
116int ecryptfs_write(struct file *ecryptfs_file, char *data, loff_t offset,
117 size_t size)
118{
119 struct page *ecryptfs_page;
120 char *ecryptfs_page_virt;
121 loff_t ecryptfs_file_size =
122 i_size_read(ecryptfs_file->f_dentry->d_inode);
123 loff_t data_offset = 0;
124 loff_t pos;
125 int rc = 0;
126
127 if (offset > ecryptfs_file_size)
128 pos = ecryptfs_file_size;
129 else
130 pos = offset;
131 while (pos < (offset + size)) {
132 pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
133 size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
134 size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
135 size_t total_remaining_bytes = ((offset + size) - pos);
136
137 if (num_bytes > total_remaining_bytes)
138 num_bytes = total_remaining_bytes;
139 if (pos < offset) {
140 size_t total_remaining_zeros = (offset - pos);
141
142 if (num_bytes > total_remaining_zeros)
143 num_bytes = total_remaining_zeros;
144 }
145 ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file,
146 ecryptfs_page_idx);
147 if (IS_ERR(ecryptfs_page)) {
148 rc = PTR_ERR(ecryptfs_page);
149 printk(KERN_ERR "%s: Error getting page at "
150 "index [%ld] from eCryptfs inode "
151 "mapping; rc = [%d]\n", __FUNCTION__,
152 ecryptfs_page_idx, rc);
153 goto out;
154 }
155 if (start_offset_in_page) {
156 /* Read in the page from the lower
157 * into the eCryptfs inode page cache,
158 * decrypting */
159 rc = ecryptfs_decrypt_page(ecryptfs_page);
160 if (rc) {
161 printk(KERN_ERR "%s: Error decrypting "
162 "page; rc = [%d]\n",
163 __FUNCTION__, rc);
164 ClearPageUptodate(ecryptfs_page);
165 page_cache_release(ecryptfs_page);
166 goto out;
167 }
168 }
169 ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0);
170 if (pos >= offset) {
171 memcpy(((char *)ecryptfs_page_virt
172 + start_offset_in_page),
173 (data + data_offset), num_bytes);
174 data_offset += num_bytes;
175 } else {
176 /* We are extending past the previous end of the file.
177 * Fill in zero values up to the start of where we
178 * will be writing data. */
179 memset(((char *)ecryptfs_page_virt
180 + start_offset_in_page), 0, num_bytes);
181 }
182 kunmap_atomic(ecryptfs_page_virt, KM_USER0);
183 flush_dcache_page(ecryptfs_page);
184 SetPageUptodate(ecryptfs_page);
185 unlock_page(ecryptfs_page);
186 rc = ecryptfs_encrypt_page(ecryptfs_page);
187 page_cache_release(ecryptfs_page);
188 if (rc) {
189 printk(KERN_ERR "%s: Error encrypting "
190 "page; rc = [%d]\n", __FUNCTION__, rc);
191 goto out;
192 }
193 pos += num_bytes;
194 }
195 if ((offset + size) > ecryptfs_file_size) {
196 i_size_write(ecryptfs_file->f_dentry->d_inode, (offset + size));
197 rc = ecryptfs_write_inode_size_to_metadata(
198 ecryptfs_file->f_dentry->d_inode);
199 if (rc) {
200 printk(KERN_ERR "Problem with "
201 "ecryptfs_write_inode_size_to_metadata; "
202 "rc = [%d]\n", rc);
203 goto out;
204 }
205 }
206out:
207 return rc;
208}
209
210/**
211 * ecryptfs_read_lower
212 * @data: The read data is stored here by this function
213 * @offset: Byte offset in the lower file from which to read the data
214 * @size: Number of bytes to read from @offset of the lower file and
215 * store into @data
216 * @ecryptfs_inode: The eCryptfs inode
217 *
218 * Read @size bytes of data at byte offset @offset from the lower
219 * inode into memory location @data.
220 *
221 * Returns zero on success; non-zero on error
222 */
223int ecryptfs_read_lower(char *data, loff_t offset, size_t size,
224 struct inode *ecryptfs_inode)
225{
226 struct ecryptfs_inode_info *inode_info =
227 ecryptfs_inode_to_private(ecryptfs_inode);
228 ssize_t octets_read;
229 mm_segment_t fs_save;
230 int rc = 0;
231
232 mutex_lock(&inode_info->lower_file_mutex);
233 BUG_ON(!inode_info->lower_file);
234 inode_info->lower_file->f_pos = offset;
235 fs_save = get_fs();
236 set_fs(get_ds());
237 octets_read = vfs_read(inode_info->lower_file, data, size,
238 &inode_info->lower_file->f_pos);
239 set_fs(fs_save);
240 if (octets_read < 0) {
241 printk(KERN_ERR "%s: octets_read = [%td]; "
242 "expected [%td]\n", __FUNCTION__, octets_read, size);
243 rc = -EINVAL;
244 }
245 mutex_unlock(&inode_info->lower_file_mutex);
246 return rc;
247}
248
249/**
250 * ecryptfs_read_lower_page_segment
251 * @page_for_ecryptfs: The page into which data for eCryptfs will be
252 * written
253 * @offset_in_page: Offset in @page_for_ecryptfs from which to start
254 * writing
255 * @size: The number of bytes to write into @page_for_ecryptfs
256 * @ecryptfs_inode: The eCryptfs inode
257 *
258 * Determines the byte offset in the file for the given page and
259 * offset within the page, maps the page, and makes the call to read
260 * the contents of @page_for_ecryptfs from the lower inode.
261 *
262 * Returns zero on success; non-zero otherwise
263 */
264int ecryptfs_read_lower_page_segment(struct page *page_for_ecryptfs,
265 pgoff_t page_index,
266 size_t offset_in_page, size_t size,
267 struct inode *ecryptfs_inode)
268{
269 char *virt;
270 loff_t offset;
271 int rc;
272
273 offset = ((((loff_t)page_index) << PAGE_CACHE_SHIFT) + offset_in_page);
274 virt = kmap(page_for_ecryptfs);
275 rc = ecryptfs_read_lower(virt, offset, size, ecryptfs_inode);
276 kunmap(page_for_ecryptfs);
277 flush_dcache_page(page_for_ecryptfs);
278 return rc;
279}
280
281/**
282 * ecryptfs_read
283 * @data: The virtual address into which to write the data read (and
284 * possibly decrypted) from the lower file
285 * @offset: The offset in the decrypted view of the file from which to
286 * read into @data
287 * @size: The number of bytes to read into @data
288 * @ecryptfs_file: The eCryptfs file from which to read
289 *
290 * Read an arbitrary amount of data from an arbitrary location in the
291 * eCryptfs page cache. This is done on an extent-by-extent basis;
292 * individual extents are decrypted and read from the lower page
293 * cache (via VFS reads). This function takes care of all the
294 * address translation to locations in the lower filesystem.
295 *
296 * Returns zero on success; non-zero otherwise
297 */
298int ecryptfs_read(char *data, loff_t offset, size_t size,
299 struct file *ecryptfs_file)
300{
301 struct page *ecryptfs_page;
302 char *ecryptfs_page_virt;
303 loff_t ecryptfs_file_size =
304 i_size_read(ecryptfs_file->f_dentry->d_inode);
305 loff_t data_offset = 0;
306 loff_t pos;
307 int rc = 0;
308
309 if ((offset + size) > ecryptfs_file_size) {
310 rc = -EINVAL;
311 printk(KERN_ERR "%s: Attempt to read data past the end of the "
312 "file; offset = [%lld]; size = [%td]; "
313 "ecryptfs_file_size = [%lld]\n",
314 __FUNCTION__, offset, size, ecryptfs_file_size);
315 goto out;
316 }
317 pos = offset;
318 while (pos < (offset + size)) {
319 pgoff_t ecryptfs_page_idx = (pos >> PAGE_CACHE_SHIFT);
320 size_t start_offset_in_page = (pos & ~PAGE_CACHE_MASK);
321 size_t num_bytes = (PAGE_CACHE_SIZE - start_offset_in_page);
322 size_t total_remaining_bytes = ((offset + size) - pos);
323
324 if (num_bytes > total_remaining_bytes)
325 num_bytes = total_remaining_bytes;
326 ecryptfs_page = ecryptfs_get_locked_page(ecryptfs_file,
327 ecryptfs_page_idx);
328 if (IS_ERR(ecryptfs_page)) {
329 rc = PTR_ERR(ecryptfs_page);
330 printk(KERN_ERR "%s: Error getting page at "
331 "index [%ld] from eCryptfs inode "
332 "mapping; rc = [%d]\n", __FUNCTION__,
333 ecryptfs_page_idx, rc);
334 goto out;
335 }
336 rc = ecryptfs_decrypt_page(ecryptfs_page);
337 if (rc) {
338 printk(KERN_ERR "%s: Error decrypting "
339 "page; rc = [%d]\n", __FUNCTION__, rc);
340 ClearPageUptodate(ecryptfs_page);
341 page_cache_release(ecryptfs_page);
342 goto out;
343 }
344 ecryptfs_page_virt = kmap_atomic(ecryptfs_page, KM_USER0);
345 memcpy((data + data_offset),
346 ((char *)ecryptfs_page_virt + start_offset_in_page),
347 num_bytes);
348 kunmap_atomic(ecryptfs_page_virt, KM_USER0);
349 flush_dcache_page(ecryptfs_page);
350 SetPageUptodate(ecryptfs_page);
351 unlock_page(ecryptfs_page);
352 page_cache_release(ecryptfs_page);
353 pos += num_bytes;
354 data_offset += num_bytes;
355 }
356out:
357 return rc;
358}
diff --git a/fs/ecryptfs/super.c b/fs/ecryptfs/super.c
index 7b3f0cc09a6f..f8cdab2bee3d 100644
--- a/fs/ecryptfs/super.c
+++ b/fs/ecryptfs/super.c
@@ -27,6 +27,7 @@
27#include <linux/mount.h> 27#include <linux/mount.h>
28#include <linux/key.h> 28#include <linux/key.h>
29#include <linux/seq_file.h> 29#include <linux/seq_file.h>
30#include <linux/file.h>
30#include <linux/crypto.h> 31#include <linux/crypto.h>
31#include "ecryptfs_kernel.h" 32#include "ecryptfs_kernel.h"
32 33
@@ -46,15 +47,16 @@ struct kmem_cache *ecryptfs_inode_info_cache;
46 */ 47 */
47static struct inode *ecryptfs_alloc_inode(struct super_block *sb) 48static struct inode *ecryptfs_alloc_inode(struct super_block *sb)
48{ 49{
49 struct ecryptfs_inode_info *ecryptfs_inode; 50 struct ecryptfs_inode_info *inode_info;
50 struct inode *inode = NULL; 51 struct inode *inode = NULL;
51 52
52 ecryptfs_inode = kmem_cache_alloc(ecryptfs_inode_info_cache, 53 inode_info = kmem_cache_alloc(ecryptfs_inode_info_cache, GFP_KERNEL);
53 GFP_KERNEL); 54 if (unlikely(!inode_info))
54 if (unlikely(!ecryptfs_inode))
55 goto out; 55 goto out;
56 ecryptfs_init_crypt_stat(&ecryptfs_inode->crypt_stat); 56 ecryptfs_init_crypt_stat(&inode_info->crypt_stat);
57 inode = &ecryptfs_inode->vfs_inode; 57 mutex_init(&inode_info->lower_file_mutex);
58 inode_info->lower_file = NULL;
59 inode = &inode_info->vfs_inode;
58out: 60out:
59 return inode; 61 return inode;
60} 62}
@@ -63,9 +65,10 @@ out:
63 * ecryptfs_destroy_inode 65 * ecryptfs_destroy_inode
64 * @inode: The ecryptfs inode 66 * @inode: The ecryptfs inode
65 * 67 *
66 * This is used during the final destruction of the inode. 68 * This is used during the final destruction of the inode. All
67 * All allocation of memory related to the inode, including allocated 69 * allocation of memory related to the inode, including allocated
68 * memory in the crypt_stat struct, will be released here. 70 * memory in the crypt_stat struct, will be released here. This
71 * function also fput()'s the persistent file for the lower inode.
69 * There should be no chance that this deallocation will be missed. 72 * There should be no chance that this deallocation will be missed.
70 */ 73 */
71static void ecryptfs_destroy_inode(struct inode *inode) 74static void ecryptfs_destroy_inode(struct inode *inode)
@@ -73,7 +76,21 @@ static void ecryptfs_destroy_inode(struct inode *inode)
73 struct ecryptfs_inode_info *inode_info; 76 struct ecryptfs_inode_info *inode_info;
74 77
75 inode_info = ecryptfs_inode_to_private(inode); 78 inode_info = ecryptfs_inode_to_private(inode);
76 ecryptfs_destruct_crypt_stat(&inode_info->crypt_stat); 79 mutex_lock(&inode_info->lower_file_mutex);
80 if (inode_info->lower_file) {
81 struct dentry *lower_dentry =
82 inode_info->lower_file->f_dentry;
83
84 BUG_ON(!lower_dentry);
85 if (lower_dentry->d_inode) {
86 fput(inode_info->lower_file);
87 inode_info->lower_file = NULL;
88 d_drop(lower_dentry);
89 d_delete(lower_dentry);
90 }
91 }
92 mutex_unlock(&inode_info->lower_file_mutex);
93 ecryptfs_destroy_crypt_stat(&inode_info->crypt_stat);
77 kmem_cache_free(ecryptfs_inode_info_cache, inode_info); 94 kmem_cache_free(ecryptfs_inode_info_cache, inode_info);
78} 95}
79 96
@@ -104,7 +121,7 @@ static void ecryptfs_put_super(struct super_block *sb)
104{ 121{
105 struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb); 122 struct ecryptfs_sb_info *sb_info = ecryptfs_superblock_to_private(sb);
106 123
107 ecryptfs_destruct_mount_crypt_stat(&sb_info->mount_crypt_stat); 124 ecryptfs_destroy_mount_crypt_stat(&sb_info->mount_crypt_stat);
108 kmem_cache_free(ecryptfs_sb_info_cache, sb_info); 125 kmem_cache_free(ecryptfs_sb_info_cache, sb_info);
109 ecryptfs_set_superblock_private(sb, NULL); 126 ecryptfs_set_superblock_private(sb, NULL);
110} 127}
diff --git a/fs/ext2/dir.c b/fs/ext2/dir.c
index 2bf49d7ef841..05d9342bb64e 100644
--- a/fs/ext2/dir.c
+++ b/fs/ext2/dir.c
@@ -22,7 +22,9 @@
22 */ 22 */
23 23
24#include "ext2.h" 24#include "ext2.h"
25#include <linux/buffer_head.h>
25#include <linux/pagemap.h> 26#include <linux/pagemap.h>
27#include <linux/swap.h>
26 28
27typedef struct ext2_dir_entry_2 ext2_dirent; 29typedef struct ext2_dir_entry_2 ext2_dirent;
28 30
@@ -61,16 +63,25 @@ ext2_last_byte(struct inode *inode, unsigned long page_nr)
61 return last_byte; 63 return last_byte;
62} 64}
63 65
64static int ext2_commit_chunk(struct page *page, unsigned from, unsigned to) 66static int ext2_commit_chunk(struct page *page, loff_t pos, unsigned len)
65{ 67{
66 struct inode *dir = page->mapping->host; 68 struct address_space *mapping = page->mapping;
69 struct inode *dir = mapping->host;
67 int err = 0; 70 int err = 0;
71
68 dir->i_version++; 72 dir->i_version++;
69 page->mapping->a_ops->commit_write(NULL, page, from, to); 73 block_write_end(NULL, mapping, pos, len, len, page, NULL);
74
75 if (pos+len > dir->i_size) {
76 i_size_write(dir, pos+len);
77 mark_inode_dirty(dir);
78 }
79
70 if (IS_DIRSYNC(dir)) 80 if (IS_DIRSYNC(dir))
71 err = write_one_page(page, 1); 81 err = write_one_page(page, 1);
72 else 82 else
73 unlock_page(page); 83 unlock_page(page);
84
74 return err; 85 return err;
75} 86}
76 87
@@ -412,16 +423,18 @@ ino_t ext2_inode_by_name(struct inode * dir, struct dentry *dentry)
412void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de, 423void ext2_set_link(struct inode *dir, struct ext2_dir_entry_2 *de,
413 struct page *page, struct inode *inode) 424 struct page *page, struct inode *inode)
414{ 425{
415 unsigned from = (char *) de - (char *) page_address(page); 426 loff_t pos = page_offset(page) +
416 unsigned to = from + le16_to_cpu(de->rec_len); 427 (char *) de - (char *) page_address(page);
428 unsigned len = le16_to_cpu(de->rec_len);
417 int err; 429 int err;
418 430
419 lock_page(page); 431 lock_page(page);
420 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 432 err = __ext2_write_begin(NULL, page->mapping, pos, len,
433 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
421 BUG_ON(err); 434 BUG_ON(err);
422 de->inode = cpu_to_le32(inode->i_ino); 435 de->inode = cpu_to_le32(inode->i_ino);
423 ext2_set_de_type (de, inode); 436 ext2_set_de_type(de, inode);
424 err = ext2_commit_chunk(page, from, to); 437 err = ext2_commit_chunk(page, pos, len);
425 ext2_put_page(page); 438 ext2_put_page(page);
426 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 439 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
427 EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL; 440 EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
@@ -444,7 +457,7 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
444 unsigned long npages = dir_pages(dir); 457 unsigned long npages = dir_pages(dir);
445 unsigned long n; 458 unsigned long n;
446 char *kaddr; 459 char *kaddr;
447 unsigned from, to; 460 loff_t pos;
448 int err; 461 int err;
449 462
450 /* 463 /*
@@ -497,9 +510,10 @@ int ext2_add_link (struct dentry *dentry, struct inode *inode)
497 return -EINVAL; 510 return -EINVAL;
498 511
499got_it: 512got_it:
500 from = (char*)de - (char*)page_address(page); 513 pos = page_offset(page) +
501 to = from + rec_len; 514 (char*)de - (char*)page_address(page);
502 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 515 err = __ext2_write_begin(NULL, page->mapping, pos, rec_len, 0,
516 &page, NULL);
503 if (err) 517 if (err)
504 goto out_unlock; 518 goto out_unlock;
505 if (de->inode) { 519 if (de->inode) {
@@ -509,10 +523,10 @@ got_it:
509 de = de1; 523 de = de1;
510 } 524 }
511 de->name_len = namelen; 525 de->name_len = namelen;
512 memcpy (de->name, name, namelen); 526 memcpy(de->name, name, namelen);
513 de->inode = cpu_to_le32(inode->i_ino); 527 de->inode = cpu_to_le32(inode->i_ino);
514 ext2_set_de_type (de, inode); 528 ext2_set_de_type (de, inode);
515 err = ext2_commit_chunk(page, from, to); 529 err = ext2_commit_chunk(page, pos, rec_len);
516 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 530 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
517 EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL; 531 EXT2_I(dir)->i_flags &= ~EXT2_BTREE_FL;
518 mark_inode_dirty(dir); 532 mark_inode_dirty(dir);
@@ -537,6 +551,7 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
537 char *kaddr = page_address(page); 551 char *kaddr = page_address(page);
538 unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1); 552 unsigned from = ((char*)dir - kaddr) & ~(ext2_chunk_size(inode)-1);
539 unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len); 553 unsigned to = ((char*)dir - kaddr) + le16_to_cpu(dir->rec_len);
554 loff_t pos;
540 ext2_dirent * pde = NULL; 555 ext2_dirent * pde = NULL;
541 ext2_dirent * de = (ext2_dirent *) (kaddr + from); 556 ext2_dirent * de = (ext2_dirent *) (kaddr + from);
542 int err; 557 int err;
@@ -553,13 +568,15 @@ int ext2_delete_entry (struct ext2_dir_entry_2 * dir, struct page * page )
553 } 568 }
554 if (pde) 569 if (pde)
555 from = (char*)pde - (char*)page_address(page); 570 from = (char*)pde - (char*)page_address(page);
571 pos = page_offset(page) + from;
556 lock_page(page); 572 lock_page(page);
557 err = mapping->a_ops->prepare_write(NULL, page, from, to); 573 err = __ext2_write_begin(NULL, page->mapping, pos, to - from, 0,
574 &page, NULL);
558 BUG_ON(err); 575 BUG_ON(err);
559 if (pde) 576 if (pde)
560 pde->rec_len = cpu_to_le16(to-from); 577 pde->rec_len = cpu_to_le16(to - from);
561 dir->inode = 0; 578 dir->inode = 0;
562 err = ext2_commit_chunk(page, from, to); 579 err = ext2_commit_chunk(page, pos, to - from);
563 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; 580 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
564 EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL; 581 EXT2_I(inode)->i_flags &= ~EXT2_BTREE_FL;
565 mark_inode_dirty(inode); 582 mark_inode_dirty(inode);
@@ -582,7 +599,9 @@ int ext2_make_empty(struct inode *inode, struct inode *parent)
582 599
583 if (!page) 600 if (!page)
584 return -ENOMEM; 601 return -ENOMEM;
585 err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size); 602
603 err = __ext2_write_begin(NULL, page->mapping, 0, chunk_size, 0,
604 &page, NULL);
586 if (err) { 605 if (err) {
587 unlock_page(page); 606 unlock_page(page);
588 goto fail; 607 goto fail;
diff --git a/fs/ext2/ext2.h b/fs/ext2/ext2.h
index 9fd0ec5ba0d0..a08052d2c008 100644
--- a/fs/ext2/ext2.h
+++ b/fs/ext2/ext2.h
@@ -134,6 +134,9 @@ extern void ext2_truncate (struct inode *);
134extern int ext2_setattr (struct dentry *, struct iattr *); 134extern int ext2_setattr (struct dentry *, struct iattr *);
135extern void ext2_set_inode_flags(struct inode *inode); 135extern void ext2_set_inode_flags(struct inode *inode);
136extern void ext2_get_inode_flags(struct ext2_inode_info *); 136extern void ext2_get_inode_flags(struct ext2_inode_info *);
137int __ext2_write_begin(struct file *file, struct address_space *mapping,
138 loff_t pos, unsigned len, unsigned flags,
139 struct page **pagep, void **fsdata);
137 140
138/* ioctl.c */ 141/* ioctl.c */
139extern int ext2_ioctl (struct inode *, struct file *, unsigned int, 142extern int ext2_ioctl (struct inode *, struct file *, unsigned int,
diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c
index 0079b2cd5314..1b102a1ccebb 100644
--- a/fs/ext2/inode.c
+++ b/fs/ext2/inode.c
@@ -642,18 +642,35 @@ ext2_readpages(struct file *file, struct address_space *mapping,
642 return mpage_readpages(mapping, pages, nr_pages, ext2_get_block); 642 return mpage_readpages(mapping, pages, nr_pages, ext2_get_block);
643} 643}
644 644
645int __ext2_write_begin(struct file *file, struct address_space *mapping,
646 loff_t pos, unsigned len, unsigned flags,
647 struct page **pagep, void **fsdata)
648{
649 return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
650 ext2_get_block);
651}
652
645static int 653static int
646ext2_prepare_write(struct file *file, struct page *page, 654ext2_write_begin(struct file *file, struct address_space *mapping,
647 unsigned from, unsigned to) 655 loff_t pos, unsigned len, unsigned flags,
656 struct page **pagep, void **fsdata)
648{ 657{
649 return block_prepare_write(page,from,to,ext2_get_block); 658 *pagep = NULL;
659 return __ext2_write_begin(file, mapping, pos, len, flags, pagep,fsdata);
650} 660}
651 661
652static int 662static int
653ext2_nobh_prepare_write(struct file *file, struct page *page, 663ext2_nobh_write_begin(struct file *file, struct address_space *mapping,
654 unsigned from, unsigned to) 664 loff_t pos, unsigned len, unsigned flags,
665 struct page **pagep, void **fsdata)
655{ 666{
656 return nobh_prepare_write(page,from,to,ext2_get_block); 667 /*
668 * Dir-in-pagecache still uses ext2_write_begin. Would have to rework
669 * directory handling code to pass around offsets rather than struct
670 * pages in order to make this work easily.
671 */
672 return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
673 ext2_get_block);
657} 674}
658 675
659static int ext2_nobh_writepage(struct page *page, 676static int ext2_nobh_writepage(struct page *page,
@@ -689,8 +706,8 @@ const struct address_space_operations ext2_aops = {
689 .readpages = ext2_readpages, 706 .readpages = ext2_readpages,
690 .writepage = ext2_writepage, 707 .writepage = ext2_writepage,
691 .sync_page = block_sync_page, 708 .sync_page = block_sync_page,
692 .prepare_write = ext2_prepare_write, 709 .write_begin = ext2_write_begin,
693 .commit_write = generic_commit_write, 710 .write_end = generic_write_end,
694 .bmap = ext2_bmap, 711 .bmap = ext2_bmap,
695 .direct_IO = ext2_direct_IO, 712 .direct_IO = ext2_direct_IO,
696 .writepages = ext2_writepages, 713 .writepages = ext2_writepages,
@@ -707,8 +724,8 @@ const struct address_space_operations ext2_nobh_aops = {
707 .readpages = ext2_readpages, 724 .readpages = ext2_readpages,
708 .writepage = ext2_nobh_writepage, 725 .writepage = ext2_nobh_writepage,
709 .sync_page = block_sync_page, 726 .sync_page = block_sync_page,
710 .prepare_write = ext2_nobh_prepare_write, 727 .write_begin = ext2_nobh_write_begin,
711 .commit_write = nobh_commit_write, 728 .write_end = nobh_write_end,
712 .bmap = ext2_bmap, 729 .bmap = ext2_bmap,
713 .direct_IO = ext2_direct_IO, 730 .direct_IO = ext2_direct_IO,
714 .writepages = ext2_writepages, 731 .writepages = ext2_writepages,
@@ -925,7 +942,8 @@ void ext2_truncate (struct inode * inode)
925 if (mapping_is_xip(inode->i_mapping)) 942 if (mapping_is_xip(inode->i_mapping))
926 xip_truncate_page(inode->i_mapping, inode->i_size); 943 xip_truncate_page(inode->i_mapping, inode->i_size);
927 else if (test_opt(inode->i_sb, NOBH)) 944 else if (test_opt(inode->i_sb, NOBH))
928 nobh_truncate_page(inode->i_mapping, inode->i_size); 945 nobh_truncate_page(inode->i_mapping,
946 inode->i_size, ext2_get_block);
929 else 947 else
930 block_truncate_page(inode->i_mapping, 948 block_truncate_page(inode->i_mapping,
931 inode->i_size, ext2_get_block); 949 inode->i_size, ext2_get_block);
diff --git a/fs/ext3/dir.c b/fs/ext3/dir.c
index c00723a99f44..c2c3491b18cf 100644
--- a/fs/ext3/dir.c
+++ b/fs/ext3/dir.c
@@ -143,7 +143,7 @@ static int ext3_readdir(struct file * filp,
143 sb->s_bdev->bd_inode->i_mapping, 143 sb->s_bdev->bd_inode->i_mapping,
144 &filp->f_ra, filp, 144 &filp->f_ra, filp,
145 index, 1); 145 index, 1);
146 filp->f_ra.prev_index = index; 146 filp->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT;
147 bh = ext3_bread(NULL, inode, blk, 0, &err); 147 bh = ext3_bread(NULL, inode, blk, 0, &err);
148 } 148 }
149 149
diff --git a/fs/ext3/inode.c b/fs/ext3/inode.c
index de4e3161e479..2f2b6864db10 100644
--- a/fs/ext3/inode.c
+++ b/fs/ext3/inode.c
@@ -1147,51 +1147,68 @@ static int do_journal_get_write_access(handle_t *handle,
1147 return ext3_journal_get_write_access(handle, bh); 1147 return ext3_journal_get_write_access(handle, bh);
1148} 1148}
1149 1149
1150static int ext3_prepare_write(struct file *file, struct page *page, 1150static int ext3_write_begin(struct file *file, struct address_space *mapping,
1151 unsigned from, unsigned to) 1151 loff_t pos, unsigned len, unsigned flags,
1152 struct page **pagep, void **fsdata)
1152{ 1153{
1153 struct inode *inode = page->mapping->host; 1154 struct inode *inode = mapping->host;
1154 int ret, needed_blocks = ext3_writepage_trans_blocks(inode); 1155 int ret, needed_blocks = ext3_writepage_trans_blocks(inode);
1155 handle_t *handle; 1156 handle_t *handle;
1156 int retries = 0; 1157 int retries = 0;
1158 struct page *page;
1159 pgoff_t index;
1160 unsigned from, to;
1161
1162 index = pos >> PAGE_CACHE_SHIFT;
1163 from = pos & (PAGE_CACHE_SIZE - 1);
1164 to = from + len;
1157 1165
1158retry: 1166retry:
1167 page = __grab_cache_page(mapping, index);
1168 if (!page)
1169 return -ENOMEM;
1170 *pagep = page;
1171
1159 handle = ext3_journal_start(inode, needed_blocks); 1172 handle = ext3_journal_start(inode, needed_blocks);
1160 if (IS_ERR(handle)) { 1173 if (IS_ERR(handle)) {
1174 unlock_page(page);
1175 page_cache_release(page);
1161 ret = PTR_ERR(handle); 1176 ret = PTR_ERR(handle);
1162 goto out; 1177 goto out;
1163 } 1178 }
1164 if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) 1179 ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
1165 ret = nobh_prepare_write(page, from, to, ext3_get_block); 1180 ext3_get_block);
1166 else
1167 ret = block_prepare_write(page, from, to, ext3_get_block);
1168 if (ret) 1181 if (ret)
1169 goto prepare_write_failed; 1182 goto write_begin_failed;
1170 1183
1171 if (ext3_should_journal_data(inode)) { 1184 if (ext3_should_journal_data(inode)) {
1172 ret = walk_page_buffers(handle, page_buffers(page), 1185 ret = walk_page_buffers(handle, page_buffers(page),
1173 from, to, NULL, do_journal_get_write_access); 1186 from, to, NULL, do_journal_get_write_access);
1174 } 1187 }
1175prepare_write_failed: 1188write_begin_failed:
1176 if (ret) 1189 if (ret) {
1177 ext3_journal_stop(handle); 1190 ext3_journal_stop(handle);
1191 unlock_page(page);
1192 page_cache_release(page);
1193 }
1178 if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries)) 1194 if (ret == -ENOSPC && ext3_should_retry_alloc(inode->i_sb, &retries))
1179 goto retry; 1195 goto retry;
1180out: 1196out:
1181 return ret; 1197 return ret;
1182} 1198}
1183 1199
1200
1184int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh) 1201int ext3_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
1185{ 1202{
1186 int err = journal_dirty_data(handle, bh); 1203 int err = journal_dirty_data(handle, bh);
1187 if (err) 1204 if (err)
1188 ext3_journal_abort_handle(__FUNCTION__, __FUNCTION__, 1205 ext3_journal_abort_handle(__FUNCTION__, __FUNCTION__,
1189 bh, handle,err); 1206 bh, handle, err);
1190 return err; 1207 return err;
1191} 1208}
1192 1209
1193/* For commit_write() in data=journal mode */ 1210/* For write_end() in data=journal mode */
1194static int commit_write_fn(handle_t *handle, struct buffer_head *bh) 1211static int write_end_fn(handle_t *handle, struct buffer_head *bh)
1195{ 1212{
1196 if (!buffer_mapped(bh) || buffer_freed(bh)) 1213 if (!buffer_mapped(bh) || buffer_freed(bh))
1197 return 0; 1214 return 0;
@@ -1200,84 +1217,130 @@ static int commit_write_fn(handle_t *handle, struct buffer_head *bh)
1200} 1217}
1201 1218
1202/* 1219/*
1220 * Generic write_end handler for ordered and writeback ext3 journal modes.
1221 * We can't use generic_write_end, because that unlocks the page and we need to
1222 * unlock the page after ext3_journal_stop, but ext3_journal_stop must run
1223 * after block_write_end.
1224 */
1225static int ext3_generic_write_end(struct file *file,
1226 struct address_space *mapping,
1227 loff_t pos, unsigned len, unsigned copied,
1228 struct page *page, void *fsdata)
1229{
1230 struct inode *inode = file->f_mapping->host;
1231
1232 copied = block_write_end(file, mapping, pos, len, copied, page, fsdata);
1233
1234 if (pos+copied > inode->i_size) {
1235 i_size_write(inode, pos+copied);
1236 mark_inode_dirty(inode);
1237 }
1238
1239 return copied;
1240}
1241
1242/*
1203 * We need to pick up the new inode size which generic_commit_write gave us 1243 * We need to pick up the new inode size which generic_commit_write gave us
1204 * `file' can be NULL - eg, when called from page_symlink(). 1244 * `file' can be NULL - eg, when called from page_symlink().
1205 * 1245 *
1206 * ext3 never places buffers on inode->i_mapping->private_list. metadata 1246 * ext3 never places buffers on inode->i_mapping->private_list. metadata
1207 * buffers are managed internally. 1247 * buffers are managed internally.
1208 */ 1248 */
1209static int ext3_ordered_commit_write(struct file *file, struct page *page, 1249static int ext3_ordered_write_end(struct file *file,
1210 unsigned from, unsigned to) 1250 struct address_space *mapping,
1251 loff_t pos, unsigned len, unsigned copied,
1252 struct page *page, void *fsdata)
1211{ 1253{
1212 handle_t *handle = ext3_journal_current_handle(); 1254 handle_t *handle = ext3_journal_current_handle();
1213 struct inode *inode = page->mapping->host; 1255 struct inode *inode = file->f_mapping->host;
1256 unsigned from, to;
1214 int ret = 0, ret2; 1257 int ret = 0, ret2;
1215 1258
1259 from = pos & (PAGE_CACHE_SIZE - 1);
1260 to = from + len;
1261
1216 ret = walk_page_buffers(handle, page_buffers(page), 1262 ret = walk_page_buffers(handle, page_buffers(page),
1217 from, to, NULL, ext3_journal_dirty_data); 1263 from, to, NULL, ext3_journal_dirty_data);
1218 1264
1219 if (ret == 0) { 1265 if (ret == 0) {
1220 /* 1266 /*
1221 * generic_commit_write() will run mark_inode_dirty() if i_size 1267 * generic_write_end() will run mark_inode_dirty() if i_size
1222 * changes. So let's piggyback the i_disksize mark_inode_dirty 1268 * changes. So let's piggyback the i_disksize mark_inode_dirty
1223 * into that. 1269 * into that.
1224 */ 1270 */
1225 loff_t new_i_size; 1271 loff_t new_i_size;
1226 1272
1227 new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; 1273 new_i_size = pos + copied;
1228 if (new_i_size > EXT3_I(inode)->i_disksize) 1274 if (new_i_size > EXT3_I(inode)->i_disksize)
1229 EXT3_I(inode)->i_disksize = new_i_size; 1275 EXT3_I(inode)->i_disksize = new_i_size;
1230 ret = generic_commit_write(file, page, from, to); 1276 copied = ext3_generic_write_end(file, mapping, pos, len, copied,
1277 page, fsdata);
1278 if (copied < 0)
1279 ret = copied;
1231 } 1280 }
1232 ret2 = ext3_journal_stop(handle); 1281 ret2 = ext3_journal_stop(handle);
1233 if (!ret) 1282 if (!ret)
1234 ret = ret2; 1283 ret = ret2;
1235 return ret; 1284 unlock_page(page);
1285 page_cache_release(page);
1286
1287 return ret ? ret : copied;
1236} 1288}
1237 1289
1238static int ext3_writeback_commit_write(struct file *file, struct page *page, 1290static int ext3_writeback_write_end(struct file *file,
1239 unsigned from, unsigned to) 1291 struct address_space *mapping,
1292 loff_t pos, unsigned len, unsigned copied,
1293 struct page *page, void *fsdata)
1240{ 1294{
1241 handle_t *handle = ext3_journal_current_handle(); 1295 handle_t *handle = ext3_journal_current_handle();
1242 struct inode *inode = page->mapping->host; 1296 struct inode *inode = file->f_mapping->host;
1243 int ret = 0, ret2; 1297 int ret = 0, ret2;
1244 loff_t new_i_size; 1298 loff_t new_i_size;
1245 1299
1246 new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; 1300 new_i_size = pos + copied;
1247 if (new_i_size > EXT3_I(inode)->i_disksize) 1301 if (new_i_size > EXT3_I(inode)->i_disksize)
1248 EXT3_I(inode)->i_disksize = new_i_size; 1302 EXT3_I(inode)->i_disksize = new_i_size;
1249 1303
1250 if (test_opt(inode->i_sb, NOBH) && ext3_should_writeback_data(inode)) 1304 copied = ext3_generic_write_end(file, mapping, pos, len, copied,
1251 ret = nobh_commit_write(file, page, from, to); 1305 page, fsdata);
1252 else 1306 if (copied < 0)
1253 ret = generic_commit_write(file, page, from, to); 1307 ret = copied;
1254 1308
1255 ret2 = ext3_journal_stop(handle); 1309 ret2 = ext3_journal_stop(handle);
1256 if (!ret) 1310 if (!ret)
1257 ret = ret2; 1311 ret = ret2;
1258 return ret; 1312 unlock_page(page);
1313 page_cache_release(page);
1314
1315 return ret ? ret : copied;
1259} 1316}
1260 1317
1261static int ext3_journalled_commit_write(struct file *file, 1318static int ext3_journalled_write_end(struct file *file,
1262 struct page *page, unsigned from, unsigned to) 1319 struct address_space *mapping,
1320 loff_t pos, unsigned len, unsigned copied,
1321 struct page *page, void *fsdata)
1263{ 1322{
1264 handle_t *handle = ext3_journal_current_handle(); 1323 handle_t *handle = ext3_journal_current_handle();
1265 struct inode *inode = page->mapping->host; 1324 struct inode *inode = mapping->host;
1266 int ret = 0, ret2; 1325 int ret = 0, ret2;
1267 int partial = 0; 1326 int partial = 0;
1268 loff_t pos; 1327 unsigned from, to;
1269 1328
1270 /* 1329 from = pos & (PAGE_CACHE_SIZE - 1);
1271 * Here we duplicate the generic_commit_write() functionality 1330 to = from + len;
1272 */ 1331
1273 pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; 1332 if (copied < len) {
1333 if (!PageUptodate(page))
1334 copied = 0;
1335 page_zero_new_buffers(page, from+copied, to);
1336 }
1274 1337
1275 ret = walk_page_buffers(handle, page_buffers(page), from, 1338 ret = walk_page_buffers(handle, page_buffers(page), from,
1276 to, &partial, commit_write_fn); 1339 to, &partial, write_end_fn);
1277 if (!partial) 1340 if (!partial)
1278 SetPageUptodate(page); 1341 SetPageUptodate(page);
1279 if (pos > inode->i_size) 1342 if (pos+copied > inode->i_size)
1280 i_size_write(inode, pos); 1343 i_size_write(inode, pos+copied);
1281 EXT3_I(inode)->i_state |= EXT3_STATE_JDATA; 1344 EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
1282 if (inode->i_size > EXT3_I(inode)->i_disksize) { 1345 if (inode->i_size > EXT3_I(inode)->i_disksize) {
1283 EXT3_I(inode)->i_disksize = inode->i_size; 1346 EXT3_I(inode)->i_disksize = inode->i_size;
@@ -1285,10 +1348,14 @@ static int ext3_journalled_commit_write(struct file *file,
1285 if (!ret) 1348 if (!ret)
1286 ret = ret2; 1349 ret = ret2;
1287 } 1350 }
1351
1288 ret2 = ext3_journal_stop(handle); 1352 ret2 = ext3_journal_stop(handle);
1289 if (!ret) 1353 if (!ret)
1290 ret = ret2; 1354 ret = ret2;
1291 return ret; 1355 unlock_page(page);
1356 page_cache_release(page);
1357
1358 return ret ? ret : copied;
1292} 1359}
1293 1360
1294/* 1361/*
@@ -1546,7 +1613,7 @@ static int ext3_journalled_writepage(struct page *page,
1546 PAGE_CACHE_SIZE, NULL, do_journal_get_write_access); 1613 PAGE_CACHE_SIZE, NULL, do_journal_get_write_access);
1547 1614
1548 err = walk_page_buffers(handle, page_buffers(page), 0, 1615 err = walk_page_buffers(handle, page_buffers(page), 0,
1549 PAGE_CACHE_SIZE, NULL, commit_write_fn); 1616 PAGE_CACHE_SIZE, NULL, write_end_fn);
1550 if (ret == 0) 1617 if (ret == 0)
1551 ret = err; 1618 ret = err;
1552 EXT3_I(inode)->i_state |= EXT3_STATE_JDATA; 1619 EXT3_I(inode)->i_state |= EXT3_STATE_JDATA;
@@ -1706,8 +1773,8 @@ static const struct address_space_operations ext3_ordered_aops = {
1706 .readpages = ext3_readpages, 1773 .readpages = ext3_readpages,
1707 .writepage = ext3_ordered_writepage, 1774 .writepage = ext3_ordered_writepage,
1708 .sync_page = block_sync_page, 1775 .sync_page = block_sync_page,
1709 .prepare_write = ext3_prepare_write, 1776 .write_begin = ext3_write_begin,
1710 .commit_write = ext3_ordered_commit_write, 1777 .write_end = ext3_ordered_write_end,
1711 .bmap = ext3_bmap, 1778 .bmap = ext3_bmap,
1712 .invalidatepage = ext3_invalidatepage, 1779 .invalidatepage = ext3_invalidatepage,
1713 .releasepage = ext3_releasepage, 1780 .releasepage = ext3_releasepage,
@@ -1720,8 +1787,8 @@ static const struct address_space_operations ext3_writeback_aops = {
1720 .readpages = ext3_readpages, 1787 .readpages = ext3_readpages,
1721 .writepage = ext3_writeback_writepage, 1788 .writepage = ext3_writeback_writepage,
1722 .sync_page = block_sync_page, 1789 .sync_page = block_sync_page,
1723 .prepare_write = ext3_prepare_write, 1790 .write_begin = ext3_write_begin,
1724 .commit_write = ext3_writeback_commit_write, 1791 .write_end = ext3_writeback_write_end,
1725 .bmap = ext3_bmap, 1792 .bmap = ext3_bmap,
1726 .invalidatepage = ext3_invalidatepage, 1793 .invalidatepage = ext3_invalidatepage,
1727 .releasepage = ext3_releasepage, 1794 .releasepage = ext3_releasepage,
@@ -1734,8 +1801,8 @@ static const struct address_space_operations ext3_journalled_aops = {
1734 .readpages = ext3_readpages, 1801 .readpages = ext3_readpages,
1735 .writepage = ext3_journalled_writepage, 1802 .writepage = ext3_journalled_writepage,
1736 .sync_page = block_sync_page, 1803 .sync_page = block_sync_page,
1737 .prepare_write = ext3_prepare_write, 1804 .write_begin = ext3_write_begin,
1738 .commit_write = ext3_journalled_commit_write, 1805 .write_end = ext3_journalled_write_end,
1739 .set_page_dirty = ext3_journalled_set_page_dirty, 1806 .set_page_dirty = ext3_journalled_set_page_dirty,
1740 .bmap = ext3_bmap, 1807 .bmap = ext3_bmap,
1741 .invalidatepage = ext3_invalidatepage, 1808 .invalidatepage = ext3_invalidatepage,
diff --git a/fs/ext4/dir.c b/fs/ext4/dir.c
index 3ab01c04e00c..e11890acfa21 100644
--- a/fs/ext4/dir.c
+++ b/fs/ext4/dir.c
@@ -142,7 +142,7 @@ static int ext4_readdir(struct file * filp,
142 sb->s_bdev->bd_inode->i_mapping, 142 sb->s_bdev->bd_inode->i_mapping,
143 &filp->f_ra, filp, 143 &filp->f_ra, filp,
144 index, 1); 144 index, 1);
145 filp->f_ra.prev_index = index; 145 filp->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT;
146 bh = ext4_bread(NULL, inode, blk, 0, &err); 146 bh = ext4_bread(NULL, inode, blk, 0, &err);
147 } 147 }
148 148
diff --git a/fs/ext4/inode.c b/fs/ext4/inode.c
index a4848e04a5ed..0df2b1e06d0b 100644
--- a/fs/ext4/inode.c
+++ b/fs/ext4/inode.c
@@ -1146,34 +1146,50 @@ static int do_journal_get_write_access(handle_t *handle,
1146 return ext4_journal_get_write_access(handle, bh); 1146 return ext4_journal_get_write_access(handle, bh);
1147} 1147}
1148 1148
1149static int ext4_prepare_write(struct file *file, struct page *page, 1149static int ext4_write_begin(struct file *file, struct address_space *mapping,
1150 unsigned from, unsigned to) 1150 loff_t pos, unsigned len, unsigned flags,
1151 struct page **pagep, void **fsdata)
1151{ 1152{
1152 struct inode *inode = page->mapping->host; 1153 struct inode *inode = mapping->host;
1153 int ret, needed_blocks = ext4_writepage_trans_blocks(inode); 1154 int ret, needed_blocks = ext4_writepage_trans_blocks(inode);
1154 handle_t *handle; 1155 handle_t *handle;
1155 int retries = 0; 1156 int retries = 0;
1157 struct page *page;
1158 pgoff_t index;
1159 unsigned from, to;
1160
1161 index = pos >> PAGE_CACHE_SHIFT;
1162 from = pos & (PAGE_CACHE_SIZE - 1);
1163 to = from + len;
1156 1164
1157retry: 1165retry:
1158 handle = ext4_journal_start(inode, needed_blocks); 1166 page = __grab_cache_page(mapping, index);
1159 if (IS_ERR(handle)) { 1167 if (!page)
1160 ret = PTR_ERR(handle); 1168 return -ENOMEM;
1161 goto out; 1169 *pagep = page;
1170
1171 handle = ext4_journal_start(inode, needed_blocks);
1172 if (IS_ERR(handle)) {
1173 unlock_page(page);
1174 page_cache_release(page);
1175 ret = PTR_ERR(handle);
1176 goto out;
1162 } 1177 }
1163 if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode))
1164 ret = nobh_prepare_write(page, from, to, ext4_get_block);
1165 else
1166 ret = block_prepare_write(page, from, to, ext4_get_block);
1167 if (ret)
1168 goto prepare_write_failed;
1169 1178
1170 if (ext4_should_journal_data(inode)) { 1179 ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
1180 ext4_get_block);
1181
1182 if (!ret && ext4_should_journal_data(inode)) {
1171 ret = walk_page_buffers(handle, page_buffers(page), 1183 ret = walk_page_buffers(handle, page_buffers(page),
1172 from, to, NULL, do_journal_get_write_access); 1184 from, to, NULL, do_journal_get_write_access);
1173 } 1185 }
1174prepare_write_failed: 1186
1175 if (ret) 1187 if (ret) {
1176 ext4_journal_stop(handle); 1188 ext4_journal_stop(handle);
1189 unlock_page(page);
1190 page_cache_release(page);
1191 }
1192
1177 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries)) 1193 if (ret == -ENOSPC && ext4_should_retry_alloc(inode->i_sb, &retries))
1178 goto retry; 1194 goto retry;
1179out: 1195out:
@@ -1185,12 +1201,12 @@ int ext4_journal_dirty_data(handle_t *handle, struct buffer_head *bh)
1185 int err = jbd2_journal_dirty_data(handle, bh); 1201 int err = jbd2_journal_dirty_data(handle, bh);
1186 if (err) 1202 if (err)
1187 ext4_journal_abort_handle(__FUNCTION__, __FUNCTION__, 1203 ext4_journal_abort_handle(__FUNCTION__, __FUNCTION__,
1188 bh, handle,err); 1204 bh, handle, err);
1189 return err; 1205 return err;
1190} 1206}
1191 1207
1192/* For commit_write() in data=journal mode */ 1208/* For write_end() in data=journal mode */
1193static int commit_write_fn(handle_t *handle, struct buffer_head *bh) 1209static int write_end_fn(handle_t *handle, struct buffer_head *bh)
1194{ 1210{
1195 if (!buffer_mapped(bh) || buffer_freed(bh)) 1211 if (!buffer_mapped(bh) || buffer_freed(bh))
1196 return 0; 1212 return 0;
@@ -1199,84 +1215,130 @@ static int commit_write_fn(handle_t *handle, struct buffer_head *bh)
1199} 1215}
1200 1216
1201/* 1217/*
1218 * Generic write_end handler for ordered and writeback ext4 journal modes.
1219 * We can't use generic_write_end, because that unlocks the page and we need to
1220 * unlock the page after ext4_journal_stop, but ext4_journal_stop must run
1221 * after block_write_end.
1222 */
1223static int ext4_generic_write_end(struct file *file,
1224 struct address_space *mapping,
1225 loff_t pos, unsigned len, unsigned copied,
1226 struct page *page, void *fsdata)
1227{
1228 struct inode *inode = file->f_mapping->host;
1229
1230 copied = block_write_end(file, mapping, pos, len, copied, page, fsdata);
1231
1232 if (pos+copied > inode->i_size) {
1233 i_size_write(inode, pos+copied);
1234 mark_inode_dirty(inode);
1235 }
1236
1237 return copied;
1238}
1239
1240/*
1202 * We need to pick up the new inode size which generic_commit_write gave us 1241 * We need to pick up the new inode size which generic_commit_write gave us
1203 * `file' can be NULL - eg, when called from page_symlink(). 1242 * `file' can be NULL - eg, when called from page_symlink().
1204 * 1243 *
1205 * ext4 never places buffers on inode->i_mapping->private_list. metadata 1244 * ext4 never places buffers on inode->i_mapping->private_list. metadata
1206 * buffers are managed internally. 1245 * buffers are managed internally.
1207 */ 1246 */
1208static int ext4_ordered_commit_write(struct file *file, struct page *page, 1247static int ext4_ordered_write_end(struct file *file,
1209 unsigned from, unsigned to) 1248 struct address_space *mapping,
1249 loff_t pos, unsigned len, unsigned copied,
1250 struct page *page, void *fsdata)
1210{ 1251{
1211 handle_t *handle = ext4_journal_current_handle(); 1252 handle_t *handle = ext4_journal_current_handle();
1212 struct inode *inode = page->mapping->host; 1253 struct inode *inode = file->f_mapping->host;
1254 unsigned from, to;
1213 int ret = 0, ret2; 1255 int ret = 0, ret2;
1214 1256
1257 from = pos & (PAGE_CACHE_SIZE - 1);
1258 to = from + len;
1259
1215 ret = walk_page_buffers(handle, page_buffers(page), 1260 ret = walk_page_buffers(handle, page_buffers(page),
1216 from, to, NULL, ext4_journal_dirty_data); 1261 from, to, NULL, ext4_journal_dirty_data);
1217 1262
1218 if (ret == 0) { 1263 if (ret == 0) {
1219 /* 1264 /*
1220 * generic_commit_write() will run mark_inode_dirty() if i_size 1265 * generic_write_end() will run mark_inode_dirty() if i_size
1221 * changes. So let's piggyback the i_disksize mark_inode_dirty 1266 * changes. So let's piggyback the i_disksize mark_inode_dirty
1222 * into that. 1267 * into that.
1223 */ 1268 */
1224 loff_t new_i_size; 1269 loff_t new_i_size;
1225 1270
1226 new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; 1271 new_i_size = pos + copied;
1227 if (new_i_size > EXT4_I(inode)->i_disksize) 1272 if (new_i_size > EXT4_I(inode)->i_disksize)
1228 EXT4_I(inode)->i_disksize = new_i_size; 1273 EXT4_I(inode)->i_disksize = new_i_size;
1229 ret = generic_commit_write(file, page, from, to); 1274 copied = ext4_generic_write_end(file, mapping, pos, len, copied,
1275 page, fsdata);
1276 if (copied < 0)
1277 ret = copied;
1230 } 1278 }
1231 ret2 = ext4_journal_stop(handle); 1279 ret2 = ext4_journal_stop(handle);
1232 if (!ret) 1280 if (!ret)
1233 ret = ret2; 1281 ret = ret2;
1234 return ret; 1282 unlock_page(page);
1283 page_cache_release(page);
1284
1285 return ret ? ret : copied;
1235} 1286}
1236 1287
1237static int ext4_writeback_commit_write(struct file *file, struct page *page, 1288static int ext4_writeback_write_end(struct file *file,
1238 unsigned from, unsigned to) 1289 struct address_space *mapping,
1290 loff_t pos, unsigned len, unsigned copied,
1291 struct page *page, void *fsdata)
1239{ 1292{
1240 handle_t *handle = ext4_journal_current_handle(); 1293 handle_t *handle = ext4_journal_current_handle();
1241 struct inode *inode = page->mapping->host; 1294 struct inode *inode = file->f_mapping->host;
1242 int ret = 0, ret2; 1295 int ret = 0, ret2;
1243 loff_t new_i_size; 1296 loff_t new_i_size;
1244 1297
1245 new_i_size = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; 1298 new_i_size = pos + copied;
1246 if (new_i_size > EXT4_I(inode)->i_disksize) 1299 if (new_i_size > EXT4_I(inode)->i_disksize)
1247 EXT4_I(inode)->i_disksize = new_i_size; 1300 EXT4_I(inode)->i_disksize = new_i_size;
1248 1301
1249 if (test_opt(inode->i_sb, NOBH) && ext4_should_writeback_data(inode)) 1302 copied = ext4_generic_write_end(file, mapping, pos, len, copied,
1250 ret = nobh_commit_write(file, page, from, to); 1303 page, fsdata);
1251 else 1304 if (copied < 0)
1252 ret = generic_commit_write(file, page, from, to); 1305 ret = copied;
1253 1306
1254 ret2 = ext4_journal_stop(handle); 1307 ret2 = ext4_journal_stop(handle);
1255 if (!ret) 1308 if (!ret)
1256 ret = ret2; 1309 ret = ret2;
1257 return ret; 1310 unlock_page(page);
1311 page_cache_release(page);
1312
1313 return ret ? ret : copied;
1258} 1314}
1259 1315
1260static int ext4_journalled_commit_write(struct file *file, 1316static int ext4_journalled_write_end(struct file *file,
1261 struct page *page, unsigned from, unsigned to) 1317 struct address_space *mapping,
1318 loff_t pos, unsigned len, unsigned copied,
1319 struct page *page, void *fsdata)
1262{ 1320{
1263 handle_t *handle = ext4_journal_current_handle(); 1321 handle_t *handle = ext4_journal_current_handle();
1264 struct inode *inode = page->mapping->host; 1322 struct inode *inode = mapping->host;
1265 int ret = 0, ret2; 1323 int ret = 0, ret2;
1266 int partial = 0; 1324 int partial = 0;
1267 loff_t pos; 1325 unsigned from, to;
1268 1326
1269 /* 1327 from = pos & (PAGE_CACHE_SIZE - 1);
1270 * Here we duplicate the generic_commit_write() functionality 1328 to = from + len;
1271 */ 1329
1272 pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to; 1330 if (copied < len) {
1331 if (!PageUptodate(page))
1332 copied = 0;
1333 page_zero_new_buffers(page, from+copied, to);
1334 }
1273 1335
1274 ret = walk_page_buffers(handle, page_buffers(page), from, 1336 ret = walk_page_buffers(handle, page_buffers(page), from,
1275 to, &partial, commit_write_fn); 1337 to, &partial, write_end_fn);
1276 if (!partial) 1338 if (!partial)
1277 SetPageUptodate(page); 1339 SetPageUptodate(page);
1278 if (pos > inode->i_size) 1340 if (pos+copied > inode->i_size)
1279 i_size_write(inode, pos); 1341 i_size_write(inode, pos+copied);
1280 EXT4_I(inode)->i_state |= EXT4_STATE_JDATA; 1342 EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
1281 if (inode->i_size > EXT4_I(inode)->i_disksize) { 1343 if (inode->i_size > EXT4_I(inode)->i_disksize) {
1282 EXT4_I(inode)->i_disksize = inode->i_size; 1344 EXT4_I(inode)->i_disksize = inode->i_size;
@@ -1284,10 +1346,14 @@ static int ext4_journalled_commit_write(struct file *file,
1284 if (!ret) 1346 if (!ret)
1285 ret = ret2; 1347 ret = ret2;
1286 } 1348 }
1349
1287 ret2 = ext4_journal_stop(handle); 1350 ret2 = ext4_journal_stop(handle);
1288 if (!ret) 1351 if (!ret)
1289 ret = ret2; 1352 ret = ret2;
1290 return ret; 1353 unlock_page(page);
1354 page_cache_release(page);
1355
1356 return ret ? ret : copied;
1291} 1357}
1292 1358
1293/* 1359/*
@@ -1545,7 +1611,7 @@ static int ext4_journalled_writepage(struct page *page,
1545 PAGE_CACHE_SIZE, NULL, do_journal_get_write_access); 1611 PAGE_CACHE_SIZE, NULL, do_journal_get_write_access);
1546 1612
1547 err = walk_page_buffers(handle, page_buffers(page), 0, 1613 err = walk_page_buffers(handle, page_buffers(page), 0,
1548 PAGE_CACHE_SIZE, NULL, commit_write_fn); 1614 PAGE_CACHE_SIZE, NULL, write_end_fn);
1549 if (ret == 0) 1615 if (ret == 0)
1550 ret = err; 1616 ret = err;
1551 EXT4_I(inode)->i_state |= EXT4_STATE_JDATA; 1617 EXT4_I(inode)->i_state |= EXT4_STATE_JDATA;
@@ -1705,8 +1771,8 @@ static const struct address_space_operations ext4_ordered_aops = {
1705 .readpages = ext4_readpages, 1771 .readpages = ext4_readpages,
1706 .writepage = ext4_ordered_writepage, 1772 .writepage = ext4_ordered_writepage,
1707 .sync_page = block_sync_page, 1773 .sync_page = block_sync_page,
1708 .prepare_write = ext4_prepare_write, 1774 .write_begin = ext4_write_begin,
1709 .commit_write = ext4_ordered_commit_write, 1775 .write_end = ext4_ordered_write_end,
1710 .bmap = ext4_bmap, 1776 .bmap = ext4_bmap,
1711 .invalidatepage = ext4_invalidatepage, 1777 .invalidatepage = ext4_invalidatepage,
1712 .releasepage = ext4_releasepage, 1778 .releasepage = ext4_releasepage,
@@ -1719,8 +1785,8 @@ static const struct address_space_operations ext4_writeback_aops = {
1719 .readpages = ext4_readpages, 1785 .readpages = ext4_readpages,
1720 .writepage = ext4_writeback_writepage, 1786 .writepage = ext4_writeback_writepage,
1721 .sync_page = block_sync_page, 1787 .sync_page = block_sync_page,
1722 .prepare_write = ext4_prepare_write, 1788 .write_begin = ext4_write_begin,
1723 .commit_write = ext4_writeback_commit_write, 1789 .write_end = ext4_writeback_write_end,
1724 .bmap = ext4_bmap, 1790 .bmap = ext4_bmap,
1725 .invalidatepage = ext4_invalidatepage, 1791 .invalidatepage = ext4_invalidatepage,
1726 .releasepage = ext4_releasepage, 1792 .releasepage = ext4_releasepage,
@@ -1733,8 +1799,8 @@ static const struct address_space_operations ext4_journalled_aops = {
1733 .readpages = ext4_readpages, 1799 .readpages = ext4_readpages,
1734 .writepage = ext4_journalled_writepage, 1800 .writepage = ext4_journalled_writepage,
1735 .sync_page = block_sync_page, 1801 .sync_page = block_sync_page,
1736 .prepare_write = ext4_prepare_write, 1802 .write_begin = ext4_write_begin,
1737 .commit_write = ext4_journalled_commit_write, 1803 .write_end = ext4_journalled_write_end,
1738 .set_page_dirty = ext4_journalled_set_page_dirty, 1804 .set_page_dirty = ext4_journalled_set_page_dirty,
1739 .bmap = ext4_bmap, 1805 .bmap = ext4_bmap,
1740 .invalidatepage = ext4_invalidatepage, 1806 .invalidatepage = ext4_invalidatepage,
diff --git a/fs/fat/inode.c b/fs/fat/inode.c
index 4baa5f205368..46b8a67f55c6 100644
--- a/fs/fat/inode.c
+++ b/fs/fat/inode.c
@@ -141,19 +141,24 @@ static int fat_readpages(struct file *file, struct address_space *mapping,
141 return mpage_readpages(mapping, pages, nr_pages, fat_get_block); 141 return mpage_readpages(mapping, pages, nr_pages, fat_get_block);
142} 142}
143 143
144static int fat_prepare_write(struct file *file, struct page *page, 144static int fat_write_begin(struct file *file, struct address_space *mapping,
145 unsigned from, unsigned to) 145 loff_t pos, unsigned len, unsigned flags,
146 struct page **pagep, void **fsdata)
146{ 147{
147 return cont_prepare_write(page, from, to, fat_get_block, 148 *pagep = NULL;
148 &MSDOS_I(page->mapping->host)->mmu_private); 149 return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
150 fat_get_block,
151 &MSDOS_I(mapping->host)->mmu_private);
149} 152}
150 153
151static int fat_commit_write(struct file *file, struct page *page, 154static int fat_write_end(struct file *file, struct address_space *mapping,
152 unsigned from, unsigned to) 155 loff_t pos, unsigned len, unsigned copied,
156 struct page *pagep, void *fsdata)
153{ 157{
154 struct inode *inode = page->mapping->host; 158 struct inode *inode = mapping->host;
155 int err = generic_commit_write(file, page, from, to); 159 int err;
156 if (!err && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) { 160 err = generic_write_end(file, mapping, pos, len, copied, pagep, fsdata);
161 if (!(err < 0) && !(MSDOS_I(inode)->i_attrs & ATTR_ARCH)) {
157 inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC; 162 inode->i_mtime = inode->i_ctime = CURRENT_TIME_SEC;
158 MSDOS_I(inode)->i_attrs |= ATTR_ARCH; 163 MSDOS_I(inode)->i_attrs |= ATTR_ARCH;
159 mark_inode_dirty(inode); 164 mark_inode_dirty(inode);
@@ -202,8 +207,8 @@ static const struct address_space_operations fat_aops = {
202 .writepage = fat_writepage, 207 .writepage = fat_writepage,
203 .writepages = fat_writepages, 208 .writepages = fat_writepages,
204 .sync_page = block_sync_page, 209 .sync_page = block_sync_page,
205 .prepare_write = fat_prepare_write, 210 .write_begin = fat_write_begin,
206 .commit_write = fat_commit_write, 211 .write_end = fat_write_end,
207 .direct_IO = fat_direct_IO, 212 .direct_IO = fat_direct_IO,
208 .bmap = _fat_bmap 213 .bmap = _fat_bmap
209}; 214};
diff --git a/fs/fuse/file.c b/fs/fuse/file.c
index f79de7c8cdfa..11f22a3d728a 100644
--- a/fs/fuse/file.c
+++ b/fs/fuse/file.c
@@ -444,22 +444,25 @@ static size_t fuse_send_write(struct fuse_req *req, struct file *file,
444 return outarg.size; 444 return outarg.size;
445} 445}
446 446
447static int fuse_prepare_write(struct file *file, struct page *page, 447static int fuse_write_begin(struct file *file, struct address_space *mapping,
448 unsigned offset, unsigned to) 448 loff_t pos, unsigned len, unsigned flags,
449 struct page **pagep, void **fsdata)
449{ 450{
450 /* No op */ 451 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
452
453 *pagep = __grab_cache_page(mapping, index);
454 if (!*pagep)
455 return -ENOMEM;
451 return 0; 456 return 0;
452} 457}
453 458
454static int fuse_commit_write(struct file *file, struct page *page, 459static int fuse_buffered_write(struct file *file, struct inode *inode,
455 unsigned offset, unsigned to) 460 loff_t pos, unsigned count, struct page *page)
456{ 461{
457 int err; 462 int err;
458 size_t nres; 463 size_t nres;
459 unsigned count = to - offset;
460 struct inode *inode = page->mapping->host;
461 struct fuse_conn *fc = get_fuse_conn(inode); 464 struct fuse_conn *fc = get_fuse_conn(inode);
462 loff_t pos = page_offset(page) + offset; 465 unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
463 struct fuse_req *req; 466 struct fuse_req *req;
464 467
465 if (is_bad_inode(inode)) 468 if (is_bad_inode(inode))
@@ -475,20 +478,35 @@ static int fuse_commit_write(struct file *file, struct page *page,
475 nres = fuse_send_write(req, file, inode, pos, count); 478 nres = fuse_send_write(req, file, inode, pos, count);
476 err = req->out.h.error; 479 err = req->out.h.error;
477 fuse_put_request(fc, req); 480 fuse_put_request(fc, req);
478 if (!err && nres != count) 481 if (!err && !nres)
479 err = -EIO; 482 err = -EIO;
480 if (!err) { 483 if (!err) {
481 pos += count; 484 pos += nres;
482 spin_lock(&fc->lock); 485 spin_lock(&fc->lock);
483 if (pos > inode->i_size) 486 if (pos > inode->i_size)
484 i_size_write(inode, pos); 487 i_size_write(inode, pos);
485 spin_unlock(&fc->lock); 488 spin_unlock(&fc->lock);
486 489
487 if (offset == 0 && to == PAGE_CACHE_SIZE) 490 if (count == PAGE_CACHE_SIZE)
488 SetPageUptodate(page); 491 SetPageUptodate(page);
489 } 492 }
490 fuse_invalidate_attr(inode); 493 fuse_invalidate_attr(inode);
491 return err; 494 return err ? err : nres;
495}
496
497static int fuse_write_end(struct file *file, struct address_space *mapping,
498 loff_t pos, unsigned len, unsigned copied,
499 struct page *page, void *fsdata)
500{
501 struct inode *inode = mapping->host;
502 int res = 0;
503
504 if (copied)
505 res = fuse_buffered_write(file, inode, pos, copied, page);
506
507 unlock_page(page);
508 page_cache_release(page);
509 return res;
492} 510}
493 511
494static void fuse_release_user_pages(struct fuse_req *req, int write) 512static void fuse_release_user_pages(struct fuse_req *req, int write)
@@ -819,8 +837,8 @@ static const struct file_operations fuse_direct_io_file_operations = {
819 837
820static const struct address_space_operations fuse_file_aops = { 838static const struct address_space_operations fuse_file_aops = {
821 .readpage = fuse_readpage, 839 .readpage = fuse_readpage,
822 .prepare_write = fuse_prepare_write, 840 .write_begin = fuse_write_begin,
823 .commit_write = fuse_commit_write, 841 .write_end = fuse_write_end,
824 .readpages = fuse_readpages, 842 .readpages = fuse_readpages,
825 .set_page_dirty = fuse_set_page_dirty, 843 .set_page_dirty = fuse_set_page_dirty,
826 .bmap = fuse_bmap, 844 .bmap = fuse_bmap,
diff --git a/fs/gfs2/ops_address.c b/fs/gfs2/ops_address.c
index 873a511ef2be..9679f8b9870d 100644
--- a/fs/gfs2/ops_address.c
+++ b/fs/gfs2/ops_address.c
@@ -17,6 +17,7 @@
17#include <linux/mpage.h> 17#include <linux/mpage.h>
18#include <linux/fs.h> 18#include <linux/fs.h>
19#include <linux/writeback.h> 19#include <linux/writeback.h>
20#include <linux/swap.h>
20#include <linux/gfs2_ondisk.h> 21#include <linux/gfs2_ondisk.h>
21#include <linux/lm_interface.h> 22#include <linux/lm_interface.h>
22 23
@@ -349,45 +350,49 @@ out_unlock:
349} 350}
350 351
351/** 352/**
352 * gfs2_prepare_write - Prepare to write a page to a file 353 * gfs2_write_begin - Begin to write to a file
353 * @file: The file to write to 354 * @file: The file to write to
354 * @page: The page which is to be prepared for writing 355 * @mapping: The mapping in which to write
355 * @from: From (byte range within page) 356 * @pos: The file offset at which to start writing
356 * @to: To (byte range within page) 357 * @len: Length of the write
358 * @flags: Various flags
359 * @pagep: Pointer to return the page
360 * @fsdata: Pointer to return fs data (unused by GFS2)
357 * 361 *
358 * Returns: errno 362 * Returns: errno
359 */ 363 */
360 364
361static int gfs2_prepare_write(struct file *file, struct page *page, 365static int gfs2_write_begin(struct file *file, struct address_space *mapping,
362 unsigned from, unsigned to) 366 loff_t pos, unsigned len, unsigned flags,
367 struct page **pagep, void **fsdata)
363{ 368{
364 struct gfs2_inode *ip = GFS2_I(page->mapping->host); 369 struct gfs2_inode *ip = GFS2_I(mapping->host);
365 struct gfs2_sbd *sdp = GFS2_SB(page->mapping->host); 370 struct gfs2_sbd *sdp = GFS2_SB(mapping->host);
366 unsigned int data_blocks, ind_blocks, rblocks; 371 unsigned int data_blocks, ind_blocks, rblocks;
367 int alloc_required; 372 int alloc_required;
368 int error = 0; 373 int error = 0;
369 loff_t pos = ((loff_t)page->index << PAGE_CACHE_SHIFT) + from;
370 loff_t end = ((loff_t)page->index << PAGE_CACHE_SHIFT) + to;
371 struct gfs2_alloc *al; 374 struct gfs2_alloc *al;
372 unsigned int write_len = to - from; 375 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
376 unsigned from = pos & (PAGE_CACHE_SIZE - 1);
377 unsigned to = from + len;
378 struct page *page;
373 379
374 380 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME, &ip->i_gh);
375 gfs2_holder_init(ip->i_gl, LM_ST_EXCLUSIVE, GL_ATIME|LM_FLAG_TRY_1CB, &ip->i_gh);
376 error = gfs2_glock_nq_atime(&ip->i_gh); 381 error = gfs2_glock_nq_atime(&ip->i_gh);
377 if (unlikely(error)) { 382 if (unlikely(error))
378 if (error == GLR_TRYFAILED) {
379 unlock_page(page);
380 error = AOP_TRUNCATED_PAGE;
381 yield();
382 }
383 goto out_uninit; 383 goto out_uninit;
384 }
385 384
386 gfs2_write_calc_reserv(ip, write_len, &data_blocks, &ind_blocks); 385 error = -ENOMEM;
386 page = __grab_cache_page(mapping, index);
387 *pagep = page;
388 if (!page)
389 goto out_unlock;
390
391 gfs2_write_calc_reserv(ip, len, &data_blocks, &ind_blocks);
387 392
388 error = gfs2_write_alloc_required(ip, pos, write_len, &alloc_required); 393 error = gfs2_write_alloc_required(ip, pos, len, &alloc_required);
389 if (error) 394 if (error)
390 goto out_unlock; 395 goto out_putpage;
391 396
392 397
393 ip->i_alloc.al_requested = 0; 398 ip->i_alloc.al_requested = 0;
@@ -420,7 +425,7 @@ static int gfs2_prepare_write(struct file *file, struct page *page,
420 goto out_trans_fail; 425 goto out_trans_fail;
421 426
422 if (gfs2_is_stuffed(ip)) { 427 if (gfs2_is_stuffed(ip)) {
423 if (end > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) { 428 if (pos + len > sdp->sd_sb.sb_bsize - sizeof(struct gfs2_dinode)) {
424 error = gfs2_unstuff_dinode(ip, page); 429 error = gfs2_unstuff_dinode(ip, page);
425 if (error == 0) 430 if (error == 0)
426 goto prepare_write; 431 goto prepare_write;
@@ -443,6 +448,10 @@ out_qunlock:
443out_alloc_put: 448out_alloc_put:
444 gfs2_alloc_put(ip); 449 gfs2_alloc_put(ip);
445 } 450 }
451out_putpage:
452 page_cache_release(page);
453 if (pos + len > ip->i_inode.i_size)
454 vmtruncate(&ip->i_inode, ip->i_inode.i_size);
446out_unlock: 455out_unlock:
447 gfs2_glock_dq_m(1, &ip->i_gh); 456 gfs2_glock_dq_m(1, &ip->i_gh);
448out_uninit: 457out_uninit:
@@ -478,65 +487,117 @@ static void adjust_fs_space(struct inode *inode)
478} 487}
479 488
480/** 489/**
481 * gfs2_commit_write - Commit write to a file 490 * gfs2_stuffed_write_end - Write end for stuffed files
491 * @inode: The inode
492 * @dibh: The buffer_head containing the on-disk inode
493 * @pos: The file position
494 * @len: The length of the write
495 * @copied: How much was actually copied by the VFS
496 * @page: The page
497 *
498 * This copies the data from the page into the inode block after
499 * the inode data structure itself.
500 *
501 * Returns: errno
502 */
503static int gfs2_stuffed_write_end(struct inode *inode, struct buffer_head *dibh,
504 loff_t pos, unsigned len, unsigned copied,
505 struct page *page)
506{
507 struct gfs2_inode *ip = GFS2_I(inode);
508 struct gfs2_sbd *sdp = GFS2_SB(inode);
509 u64 to = pos + copied;
510 void *kaddr;
511 unsigned char *buf = dibh->b_data + sizeof(struct gfs2_dinode);
512 struct gfs2_dinode *di = (struct gfs2_dinode *)dibh->b_data;
513
514 BUG_ON((pos + len) > (dibh->b_size - sizeof(struct gfs2_dinode)));
515 kaddr = kmap_atomic(page, KM_USER0);
516 memcpy(buf + pos, kaddr + pos, copied);
517 memset(kaddr + pos + copied, 0, len - copied);
518 flush_dcache_page(page);
519 kunmap_atomic(kaddr, KM_USER0);
520
521 if (!PageUptodate(page))
522 SetPageUptodate(page);
523 unlock_page(page);
524 page_cache_release(page);
525
526 if (inode->i_size < to) {
527 i_size_write(inode, to);
528 ip->i_di.di_size = inode->i_size;
529 di->di_size = cpu_to_be64(inode->i_size);
530 mark_inode_dirty(inode);
531 }
532
533 if (inode == sdp->sd_rindex)
534 adjust_fs_space(inode);
535
536 brelse(dibh);
537 gfs2_trans_end(sdp);
538 gfs2_glock_dq(&ip->i_gh);
539 gfs2_holder_uninit(&ip->i_gh);
540 return copied;
541}
542
543/**
544 * gfs2_write_end
482 * @file: The file to write to 545 * @file: The file to write to
483 * @page: The page containing the data 546 * @mapping: The address space to write to
484 * @from: From (byte range within page) 547 * @pos: The file position
485 * @to: To (byte range within page) 548 * @len: The length of the data
549 * @copied:
550 * @page: The page that has been written
551 * @fsdata: The fsdata (unused in GFS2)
552 *
553 * The main write_end function for GFS2. We have a separate one for
554 * stuffed files as they are slightly different, otherwise we just
555 * put our locking around the VFS provided functions.
486 * 556 *
487 * Returns: errno 557 * Returns: errno
488 */ 558 */
489 559
490static int gfs2_commit_write(struct file *file, struct page *page, 560static int gfs2_write_end(struct file *file, struct address_space *mapping,
491 unsigned from, unsigned to) 561 loff_t pos, unsigned len, unsigned copied,
562 struct page *page, void *fsdata)
492{ 563{
493 struct inode *inode = page->mapping->host; 564 struct inode *inode = page->mapping->host;
494 struct gfs2_inode *ip = GFS2_I(inode); 565 struct gfs2_inode *ip = GFS2_I(inode);
495 struct gfs2_sbd *sdp = GFS2_SB(inode); 566 struct gfs2_sbd *sdp = GFS2_SB(inode);
496 int error = -EOPNOTSUPP;
497 struct buffer_head *dibh; 567 struct buffer_head *dibh;
498 struct gfs2_alloc *al = &ip->i_alloc; 568 struct gfs2_alloc *al = &ip->i_alloc;
499 struct gfs2_dinode *di; 569 struct gfs2_dinode *di;
570 unsigned int from = pos & (PAGE_CACHE_SIZE - 1);
571 unsigned int to = from + len;
572 int ret;
500 573
501 if (gfs2_assert_withdraw(sdp, gfs2_glock_is_locked_by_me(ip->i_gl))) 574 BUG_ON(gfs2_glock_is_locked_by_me(ip->i_gl) == 0);
502 goto fail_nounlock;
503 575
504 error = gfs2_meta_inode_buffer(ip, &dibh); 576 ret = gfs2_meta_inode_buffer(ip, &dibh);
505 if (error) 577 if (unlikely(ret)) {
506 goto fail_endtrans; 578 unlock_page(page);
579 page_cache_release(page);
580 goto failed;
581 }
507 582
508 gfs2_trans_add_bh(ip->i_gl, dibh, 1); 583 gfs2_trans_add_bh(ip->i_gl, dibh, 1);
509 di = (struct gfs2_dinode *)dibh->b_data;
510
511 if (gfs2_is_stuffed(ip)) {
512 u64 file_size;
513 void *kaddr;
514 584
515 file_size = ((u64)page->index << PAGE_CACHE_SHIFT) + to; 585 if (gfs2_is_stuffed(ip))
586 return gfs2_stuffed_write_end(inode, dibh, pos, len, copied, page);
516 587
517 kaddr = kmap_atomic(page, KM_USER0); 588 if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED || gfs2_is_jdata(ip))
518 memcpy(dibh->b_data + sizeof(struct gfs2_dinode) + from, 589 gfs2_page_add_databufs(ip, page, from, to);
519 kaddr + from, to - from);
520 kunmap_atomic(kaddr, KM_USER0);
521 590
522 SetPageUptodate(page); 591 ret = generic_write_end(file, mapping, pos, len, copied, page, fsdata);
523 592
524 if (inode->i_size < file_size) { 593 if (likely(ret >= 0)) {
525 i_size_write(inode, file_size); 594 copied = ret;
595 if ((pos + copied) > inode->i_size) {
596 di = (struct gfs2_dinode *)dibh->b_data;
597 ip->i_di.di_size = inode->i_size;
598 di->di_size = cpu_to_be64(inode->i_size);
526 mark_inode_dirty(inode); 599 mark_inode_dirty(inode);
527 } 600 }
528 } else {
529 if (sdp->sd_args.ar_data == GFS2_DATA_ORDERED ||
530 gfs2_is_jdata(ip))
531 gfs2_page_add_databufs(ip, page, from, to);
532 error = generic_commit_write(file, page, from, to);
533 if (error)
534 goto fail;
535 }
536
537 if (ip->i_di.di_size < inode->i_size) {
538 ip->i_di.di_size = inode->i_size;
539 di->di_size = cpu_to_be64(inode->i_size);
540 } 601 }
541 602
542 if (inode == sdp->sd_rindex) 603 if (inode == sdp->sd_rindex)
@@ -544,33 +605,15 @@ static int gfs2_commit_write(struct file *file, struct page *page,
544 605
545 brelse(dibh); 606 brelse(dibh);
546 gfs2_trans_end(sdp); 607 gfs2_trans_end(sdp);
608failed:
547 if (al->al_requested) { 609 if (al->al_requested) {
548 gfs2_inplace_release(ip); 610 gfs2_inplace_release(ip);
549 gfs2_quota_unlock(ip); 611 gfs2_quota_unlock(ip);
550 gfs2_alloc_put(ip); 612 gfs2_alloc_put(ip);
551 } 613 }
552 unlock_page(page); 614 gfs2_glock_dq(&ip->i_gh);
553 gfs2_glock_dq_m(1, &ip->i_gh);
554 lock_page(page);
555 gfs2_holder_uninit(&ip->i_gh); 615 gfs2_holder_uninit(&ip->i_gh);
556 return 0; 616 return ret;
557
558fail:
559 brelse(dibh);
560fail_endtrans:
561 gfs2_trans_end(sdp);
562 if (al->al_requested) {
563 gfs2_inplace_release(ip);
564 gfs2_quota_unlock(ip);
565 gfs2_alloc_put(ip);
566 }
567 unlock_page(page);
568 gfs2_glock_dq_m(1, &ip->i_gh);
569 lock_page(page);
570 gfs2_holder_uninit(&ip->i_gh);
571fail_nounlock:
572 ClearPageUptodate(page);
573 return error;
574} 617}
575 618
576/** 619/**
@@ -799,8 +842,8 @@ const struct address_space_operations gfs2_file_aops = {
799 .readpage = gfs2_readpage, 842 .readpage = gfs2_readpage,
800 .readpages = gfs2_readpages, 843 .readpages = gfs2_readpages,
801 .sync_page = block_sync_page, 844 .sync_page = block_sync_page,
802 .prepare_write = gfs2_prepare_write, 845 .write_begin = gfs2_write_begin,
803 .commit_write = gfs2_commit_write, 846 .write_end = gfs2_write_end,
804 .set_page_dirty = gfs2_set_page_dirty, 847 .set_page_dirty = gfs2_set_page_dirty,
805 .bmap = gfs2_bmap, 848 .bmap = gfs2_bmap,
806 .invalidatepage = gfs2_invalidatepage, 849 .invalidatepage = gfs2_invalidatepage,
diff --git a/fs/hfs/extent.c b/fs/hfs/extent.c
index 5ea6b3d45eaa..c176f67ba0a5 100644
--- a/fs/hfs/extent.c
+++ b/fs/hfs/extent.c
@@ -464,23 +464,20 @@ void hfs_file_truncate(struct inode *inode)
464 (long long)HFS_I(inode)->phys_size, inode->i_size); 464 (long long)HFS_I(inode)->phys_size, inode->i_size);
465 if (inode->i_size > HFS_I(inode)->phys_size) { 465 if (inode->i_size > HFS_I(inode)->phys_size) {
466 struct address_space *mapping = inode->i_mapping; 466 struct address_space *mapping = inode->i_mapping;
467 void *fsdata;
467 struct page *page; 468 struct page *page;
468 int res; 469 int res;
469 470
471 /* XXX: Can use generic_cont_expand? */
470 size = inode->i_size - 1; 472 size = inode->i_size - 1;
471 page = grab_cache_page(mapping, size >> PAGE_CACHE_SHIFT); 473 res = pagecache_write_begin(NULL, mapping, size+1, 0,
472 if (!page) 474 AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata);
473 return; 475 if (!res) {
474 size &= PAGE_CACHE_SIZE - 1; 476 res = pagecache_write_end(NULL, mapping, size+1, 0, 0,
475 size++; 477 page, fsdata);
476 res = mapping->a_ops->prepare_write(NULL, page, size, size); 478 }
477 if (!res)
478 res = mapping->a_ops->commit_write(NULL, page, size, size);
479 if (res) 479 if (res)
480 inode->i_size = HFS_I(inode)->phys_size; 480 inode->i_size = HFS_I(inode)->phys_size;
481 unlock_page(page);
482 page_cache_release(page);
483 mark_inode_dirty(inode);
484 return; 481 return;
485 } else if (inode->i_size == HFS_I(inode)->phys_size) 482 } else if (inode->i_size == HFS_I(inode)->phys_size)
486 return; 483 return;
diff --git a/fs/hfs/inode.c b/fs/hfs/inode.c
index bc835f272a6e..97f8446c4ff4 100644
--- a/fs/hfs/inode.c
+++ b/fs/hfs/inode.c
@@ -35,10 +35,14 @@ static int hfs_readpage(struct file *file, struct page *page)
35 return block_read_full_page(page, hfs_get_block); 35 return block_read_full_page(page, hfs_get_block);
36} 36}
37 37
38static int hfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) 38static int hfs_write_begin(struct file *file, struct address_space *mapping,
39 loff_t pos, unsigned len, unsigned flags,
40 struct page **pagep, void **fsdata)
39{ 41{
40 return cont_prepare_write(page, from, to, hfs_get_block, 42 *pagep = NULL;
41 &HFS_I(page->mapping->host)->phys_size); 43 return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
44 hfs_get_block,
45 &HFS_I(mapping->host)->phys_size);
42} 46}
43 47
44static sector_t hfs_bmap(struct address_space *mapping, sector_t block) 48static sector_t hfs_bmap(struct address_space *mapping, sector_t block)
@@ -119,8 +123,8 @@ const struct address_space_operations hfs_btree_aops = {
119 .readpage = hfs_readpage, 123 .readpage = hfs_readpage,
120 .writepage = hfs_writepage, 124 .writepage = hfs_writepage,
121 .sync_page = block_sync_page, 125 .sync_page = block_sync_page,
122 .prepare_write = hfs_prepare_write, 126 .write_begin = hfs_write_begin,
123 .commit_write = generic_commit_write, 127 .write_end = generic_write_end,
124 .bmap = hfs_bmap, 128 .bmap = hfs_bmap,
125 .releasepage = hfs_releasepage, 129 .releasepage = hfs_releasepage,
126}; 130};
@@ -129,8 +133,8 @@ const struct address_space_operations hfs_aops = {
129 .readpage = hfs_readpage, 133 .readpage = hfs_readpage,
130 .writepage = hfs_writepage, 134 .writepage = hfs_writepage,
131 .sync_page = block_sync_page, 135 .sync_page = block_sync_page,
132 .prepare_write = hfs_prepare_write, 136 .write_begin = hfs_write_begin,
133 .commit_write = generic_commit_write, 137 .write_end = generic_write_end,
134 .bmap = hfs_bmap, 138 .bmap = hfs_bmap,
135 .direct_IO = hfs_direct_IO, 139 .direct_IO = hfs_direct_IO,
136 .writepages = hfs_writepages, 140 .writepages = hfs_writepages,
diff --git a/fs/hfsplus/extents.c b/fs/hfsplus/extents.c
index 1a7480089e82..12e899cd7886 100644
--- a/fs/hfsplus/extents.c
+++ b/fs/hfsplus/extents.c
@@ -443,21 +443,18 @@ void hfsplus_file_truncate(struct inode *inode)
443 if (inode->i_size > HFSPLUS_I(inode).phys_size) { 443 if (inode->i_size > HFSPLUS_I(inode).phys_size) {
444 struct address_space *mapping = inode->i_mapping; 444 struct address_space *mapping = inode->i_mapping;
445 struct page *page; 445 struct page *page;
446 u32 size = inode->i_size - 1; 446 void *fsdata;
447 u32 size = inode->i_size;
447 int res; 448 int res;
448 449
449 page = grab_cache_page(mapping, size >> PAGE_CACHE_SHIFT); 450 res = pagecache_write_begin(NULL, mapping, size, 0,
450 if (!page) 451 AOP_FLAG_UNINTERRUPTIBLE,
451 return; 452 &page, &fsdata);
452 size &= PAGE_CACHE_SIZE - 1;
453 size++;
454 res = mapping->a_ops->prepare_write(NULL, page, size, size);
455 if (!res)
456 res = mapping->a_ops->commit_write(NULL, page, size, size);
457 if (res) 453 if (res)
458 inode->i_size = HFSPLUS_I(inode).phys_size; 454 return;
459 unlock_page(page); 455 res = pagecache_write_end(NULL, mapping, size, 0, 0, page, fsdata);
460 page_cache_release(page); 456 if (res < 0)
457 return;
461 mark_inode_dirty(inode); 458 mark_inode_dirty(inode);
462 return; 459 return;
463 } else if (inode->i_size == HFSPLUS_I(inode).phys_size) 460 } else if (inode->i_size == HFSPLUS_I(inode).phys_size)
diff --git a/fs/hfsplus/inode.c b/fs/hfsplus/inode.c
index 6f7c662174db..37744cf3706a 100644
--- a/fs/hfsplus/inode.c
+++ b/fs/hfsplus/inode.c
@@ -27,10 +27,14 @@ static int hfsplus_writepage(struct page *page, struct writeback_control *wbc)
27 return block_write_full_page(page, hfsplus_get_block, wbc); 27 return block_write_full_page(page, hfsplus_get_block, wbc);
28} 28}
29 29
30static int hfsplus_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) 30static int hfsplus_write_begin(struct file *file, struct address_space *mapping,
31 loff_t pos, unsigned len, unsigned flags,
32 struct page **pagep, void **fsdata)
31{ 33{
32 return cont_prepare_write(page, from, to, hfsplus_get_block, 34 *pagep = NULL;
33 &HFSPLUS_I(page->mapping->host).phys_size); 35 return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
36 hfsplus_get_block,
37 &HFSPLUS_I(mapping->host).phys_size);
34} 38}
35 39
36static sector_t hfsplus_bmap(struct address_space *mapping, sector_t block) 40static sector_t hfsplus_bmap(struct address_space *mapping, sector_t block)
@@ -114,8 +118,8 @@ const struct address_space_operations hfsplus_btree_aops = {
114 .readpage = hfsplus_readpage, 118 .readpage = hfsplus_readpage,
115 .writepage = hfsplus_writepage, 119 .writepage = hfsplus_writepage,
116 .sync_page = block_sync_page, 120 .sync_page = block_sync_page,
117 .prepare_write = hfsplus_prepare_write, 121 .write_begin = hfsplus_write_begin,
118 .commit_write = generic_commit_write, 122 .write_end = generic_write_end,
119 .bmap = hfsplus_bmap, 123 .bmap = hfsplus_bmap,
120 .releasepage = hfsplus_releasepage, 124 .releasepage = hfsplus_releasepage,
121}; 125};
@@ -124,8 +128,8 @@ const struct address_space_operations hfsplus_aops = {
124 .readpage = hfsplus_readpage, 128 .readpage = hfsplus_readpage,
125 .writepage = hfsplus_writepage, 129 .writepage = hfsplus_writepage,
126 .sync_page = block_sync_page, 130 .sync_page = block_sync_page,
127 .prepare_write = hfsplus_prepare_write, 131 .write_begin = hfsplus_write_begin,
128 .commit_write = generic_commit_write, 132 .write_end = generic_write_end,
129 .bmap = hfsplus_bmap, 133 .bmap = hfsplus_bmap,
130 .direct_IO = hfsplus_direct_IO, 134 .direct_IO = hfsplus_direct_IO,
131 .writepages = hfsplus_writepages, 135 .writepages = hfsplus_writepages,
diff --git a/fs/hostfs/hostfs.h b/fs/hostfs/hostfs.h
index 06e5930515fe..6ae9011b95eb 100644
--- a/fs/hostfs/hostfs.h
+++ b/fs/hostfs/hostfs.h
@@ -3,7 +3,8 @@
3 3
4#include "os.h" 4#include "os.h"
5 5
6/* These are exactly the same definitions as in fs.h, but the names are 6/*
7 * These are exactly the same definitions as in fs.h, but the names are
7 * changed so that this file can be included in both kernel and user files. 8 * changed so that this file can be included in both kernel and user files.
8 */ 9 */
9 10
@@ -21,7 +22,8 @@
21#define HOSTFS_ATTR_FORCE 512 /* Not a change, but a change it */ 22#define HOSTFS_ATTR_FORCE 512 /* Not a change, but a change it */
22#define HOSTFS_ATTR_ATTR_FLAG 1024 23#define HOSTFS_ATTR_ATTR_FLAG 1024
23 24
24/* If you are very careful, you'll notice that these two are missing: 25/*
26 * If you are very careful, you'll notice that these two are missing:
25 * 27 *
26 * #define ATTR_KILL_SUID 2048 28 * #define ATTR_KILL_SUID 2048
27 * #define ATTR_KILL_SGID 4096 29 * #define ATTR_KILL_SGID 4096
@@ -76,7 +78,8 @@ extern int make_symlink(const char *from, const char *to);
76extern int unlink_file(const char *file); 78extern int unlink_file(const char *file);
77extern int do_mkdir(const char *file, int mode); 79extern int do_mkdir(const char *file, int mode);
78extern int do_rmdir(const char *file); 80extern int do_rmdir(const char *file);
79extern int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor); 81extern int do_mknod(const char *file, int mode, unsigned int major,
82 unsigned int minor);
80extern int link_file(const char *from, const char *to); 83extern int link_file(const char *from, const char *to);
81extern int do_readlink(char *file, char *buf, int size); 84extern int do_readlink(char *file, char *buf, int size);
82extern int rename_file(char *from, char *to); 85extern int rename_file(char *from, char *to);
diff --git a/fs/hostfs/hostfs_kern.c b/fs/hostfs/hostfs_kern.c
index c77862032e84..8966b050196e 100644
--- a/fs/hostfs/hostfs_kern.c
+++ b/fs/hostfs/hostfs_kern.c
@@ -6,21 +6,14 @@
6 * 2003-02-10 Petr Baudis <pasky@ucw.cz> 6 * 2003-02-10 Petr Baudis <pasky@ucw.cz>
7 */ 7 */
8 8
9#include <linux/stddef.h>
10#include <linux/fs.h> 9#include <linux/fs.h>
11#include <linux/module.h> 10#include <linux/module.h>
12#include <linux/init.h> 11#include <linux/mm.h>
13#include <linux/slab.h>
14#include <linux/pagemap.h> 12#include <linux/pagemap.h>
15#include <linux/blkdev.h>
16#include <linux/list.h>
17#include <linux/statfs.h> 13#include <linux/statfs.h>
18#include <linux/kdev_t.h>
19#include <asm/uaccess.h>
20#include "hostfs.h" 14#include "hostfs.h"
21#include "kern_util.h"
22#include "kern.h"
23#include "init.h" 15#include "init.h"
16#include "kern.h"
24 17
25struct hostfs_inode_info { 18struct hostfs_inode_info {
26 char *host_filename; 19 char *host_filename;
@@ -61,18 +54,18 @@ static int __init hostfs_args(char *options, int *add)
61 char *ptr; 54 char *ptr;
62 55
63 ptr = strchr(options, ','); 56 ptr = strchr(options, ',');
64 if(ptr != NULL) 57 if (ptr != NULL)
65 *ptr++ = '\0'; 58 *ptr++ = '\0';
66 if(*options != '\0') 59 if (*options != '\0')
67 root_ino = options; 60 root_ino = options;
68 61
69 options = ptr; 62 options = ptr;
70 while(options){ 63 while (options) {
71 ptr = strchr(options, ','); 64 ptr = strchr(options, ',');
72 if(ptr != NULL) 65 if (ptr != NULL)
73 *ptr++ = '\0'; 66 *ptr++ = '\0';
74 if(*options != '\0'){ 67 if (*options != '\0') {
75 if(!strcmp(options, "append")) 68 if (!strcmp(options, "append"))
76 append = 1; 69 append = 1;
77 else printf("hostfs_args - unsupported option - %s\n", 70 else printf("hostfs_args - unsupported option - %s\n",
78 options); 71 options);
@@ -102,7 +95,7 @@ static char *dentry_name(struct dentry *dentry, int extra)
102 95
103 len = 0; 96 len = 0;
104 parent = dentry; 97 parent = dentry;
105 while(parent->d_parent != parent){ 98 while (parent->d_parent != parent) {
106 len += parent->d_name.len + 1; 99 len += parent->d_name.len + 1;
107 parent = parent->d_parent; 100 parent = parent->d_parent;
108 } 101 }
@@ -110,12 +103,12 @@ static char *dentry_name(struct dentry *dentry, int extra)
110 root = HOSTFS_I(parent->d_inode)->host_filename; 103 root = HOSTFS_I(parent->d_inode)->host_filename;
111 len += strlen(root); 104 len += strlen(root);
112 name = kmalloc(len + extra + 1, GFP_KERNEL); 105 name = kmalloc(len + extra + 1, GFP_KERNEL);
113 if(name == NULL) 106 if (name == NULL)
114 return NULL; 107 return NULL;
115 108
116 name[len] = '\0'; 109 name[len] = '\0';
117 parent = dentry; 110 parent = dentry;
118 while(parent->d_parent != parent){ 111 while (parent->d_parent != parent) {
119 len -= parent->d_name.len + 1; 112 len -= parent->d_name.len + 1;
120 name[len] = '/'; 113 name[len] = '/';
121 strncpy(&name[len + 1], parent->d_name.name, 114 strncpy(&name[len + 1], parent->d_name.name,
@@ -136,7 +129,8 @@ static char *inode_name(struct inode *ino, int extra)
136 129
137static int read_name(struct inode *ino, char *name) 130static int read_name(struct inode *ino, char *name)
138{ 131{
139 /* The non-int inode fields are copied into ints by stat_file and 132 /*
133 * The non-int inode fields are copied into ints by stat_file and
140 * then copied into the inode because passing the actual pointers 134 * then copied into the inode because passing the actual pointers
141 * in and having them treated as int * breaks on big-endian machines 135 * in and having them treated as int * breaks on big-endian machines
142 */ 136 */
@@ -149,7 +143,7 @@ static int read_name(struct inode *ino, char *name)
149 err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid, 143 err = stat_file(name, &i_ino, &i_mode, &i_nlink, &ino->i_uid,
150 &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime, 144 &ino->i_gid, &i_size, &ino->i_atime, &ino->i_mtime,
151 &ino->i_ctime, &i_blksize, &i_blocks, -1); 145 &ino->i_ctime, &i_blksize, &i_blocks, -1);
152 if(err) 146 if (err)
153 return err; 147 return err;
154 148
155 ino->i_ino = i_ino; 149 ino->i_ino = i_ino;
@@ -166,33 +160,33 @@ static char *follow_link(char *link)
166 char *name, *resolved, *end; 160 char *name, *resolved, *end;
167 161
168 len = 64; 162 len = 64;
169 while(1){ 163 while (1) {
170 n = -ENOMEM; 164 n = -ENOMEM;
171 name = kmalloc(len, GFP_KERNEL); 165 name = kmalloc(len, GFP_KERNEL);
172 if(name == NULL) 166 if (name == NULL)
173 goto out; 167 goto out;
174 168
175 n = do_readlink(link, name, len); 169 n = do_readlink(link, name, len);
176 if(n < len) 170 if (n < len)
177 break; 171 break;
178 len *= 2; 172 len *= 2;
179 kfree(name); 173 kfree(name);
180 } 174 }
181 if(n < 0) 175 if (n < 0)
182 goto out_free; 176 goto out_free;
183 177
184 if(*name == '/') 178 if (*name == '/')
185 return name; 179 return name;
186 180
187 end = strrchr(link, '/'); 181 end = strrchr(link, '/');
188 if(end == NULL) 182 if (end == NULL)
189 return name; 183 return name;
190 184
191 *(end + 1) = '\0'; 185 *(end + 1) = '\0';
192 len = strlen(link) + strlen(name) + 1; 186 len = strlen(link) + strlen(name) + 1;
193 187
194 resolved = kmalloc(len, GFP_KERNEL); 188 resolved = kmalloc(len, GFP_KERNEL);
195 if(resolved == NULL){ 189 if (resolved == NULL) {
196 n = -ENOMEM; 190 n = -ENOMEM;
197 goto out_free; 191 goto out_free;
198 } 192 }
@@ -213,20 +207,21 @@ static int read_inode(struct inode *ino)
213 char *name; 207 char *name;
214 int err = 0; 208 int err = 0;
215 209
216 /* Unfortunately, we are called from iget() when we don't have a dentry 210 /*
211 * Unfortunately, we are called from iget() when we don't have a dentry
217 * allocated yet. 212 * allocated yet.
218 */ 213 */
219 if(list_empty(&ino->i_dentry)) 214 if (list_empty(&ino->i_dentry))
220 goto out; 215 goto out;
221 216
222 err = -ENOMEM; 217 err = -ENOMEM;
223 name = inode_name(ino, 0); 218 name = inode_name(ino, 0);
224 if(name == NULL) 219 if (name == NULL)
225 goto out; 220 goto out;
226 221
227 if(file_type(name, NULL, NULL) == OS_TYPE_SYMLINK){ 222 if (file_type(name, NULL, NULL) == OS_TYPE_SYMLINK) {
228 name = follow_link(name); 223 name = follow_link(name);
229 if(IS_ERR(name)){ 224 if (IS_ERR(name)) {
230 err = PTR_ERR(name); 225 err = PTR_ERR(name);
231 goto out; 226 goto out;
232 } 227 }
@@ -240,7 +235,8 @@ static int read_inode(struct inode *ino)
240 235
241int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf) 236int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
242{ 237{
243 /* do_statfs uses struct statfs64 internally, but the linux kernel 238 /*
239 * do_statfs uses struct statfs64 internally, but the linux kernel
244 * struct statfs still has 32-bit versions for most of these fields, 240 * struct statfs still has 32-bit versions for most of these fields,
245 * so we convert them here 241 * so we convert them here
246 */ 242 */
@@ -255,7 +251,7 @@ int hostfs_statfs(struct dentry *dentry, struct kstatfs *sf)
255 &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files, 251 &sf->f_bsize, &f_blocks, &f_bfree, &f_bavail, &f_files,
256 &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid), 252 &f_ffree, &sf->f_fsid, sizeof(sf->f_fsid),
257 &sf->f_namelen, sf->f_spare); 253 &sf->f_namelen, sf->f_spare);
258 if(err) 254 if (err)
259 return err; 255 return err;
260 sf->f_blocks = f_blocks; 256 sf->f_blocks = f_blocks;
261 sf->f_bfree = f_bfree; 257 sf->f_bfree = f_bfree;
@@ -271,7 +267,7 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb)
271 struct hostfs_inode_info *hi; 267 struct hostfs_inode_info *hi;
272 268
273 hi = kmalloc(sizeof(*hi), GFP_KERNEL); 269 hi = kmalloc(sizeof(*hi), GFP_KERNEL);
274 if(hi == NULL) 270 if (hi == NULL)
275 return NULL; 271 return NULL;
276 272
277 *hi = ((struct hostfs_inode_info) { .host_filename = NULL, 273 *hi = ((struct hostfs_inode_info) { .host_filename = NULL,
@@ -284,7 +280,7 @@ static struct inode *hostfs_alloc_inode(struct super_block *sb)
284static void hostfs_delete_inode(struct inode *inode) 280static void hostfs_delete_inode(struct inode *inode)
285{ 281{
286 truncate_inode_pages(&inode->i_data, 0); 282 truncate_inode_pages(&inode->i_data, 0);
287 if(HOSTFS_I(inode)->fd != -1) { 283 if (HOSTFS_I(inode)->fd != -1) {
288 close_file(&HOSTFS_I(inode)->fd); 284 close_file(&HOSTFS_I(inode)->fd);
289 HOSTFS_I(inode)->fd = -1; 285 HOSTFS_I(inode)->fd = -1;
290 } 286 }
@@ -295,9 +291,11 @@ static void hostfs_destroy_inode(struct inode *inode)
295{ 291{
296 kfree(HOSTFS_I(inode)->host_filename); 292 kfree(HOSTFS_I(inode)->host_filename);
297 293
298 /*XXX: This should not happen, probably. The check is here for 294 /*
299 * additional safety.*/ 295 * XXX: This should not happen, probably. The check is here for
300 if(HOSTFS_I(inode)->fd != -1) { 296 * additional safety.
297 */
298 if (HOSTFS_I(inode)->fd != -1) {
301 close_file(&HOSTFS_I(inode)->fd); 299 close_file(&HOSTFS_I(inode)->fd);
302 printk(KERN_DEBUG "Closing host fd in .destroy_inode\n"); 300 printk(KERN_DEBUG "Closing host fd in .destroy_inode\n");
303 } 301 }
@@ -327,17 +325,17 @@ int hostfs_readdir(struct file *file, void *ent, filldir_t filldir)
327 int error, len; 325 int error, len;
328 326
329 name = dentry_name(file->f_path.dentry, 0); 327 name = dentry_name(file->f_path.dentry, 0);
330 if(name == NULL) 328 if (name == NULL)
331 return -ENOMEM; 329 return -ENOMEM;
332 dir = open_dir(name, &error); 330 dir = open_dir(name, &error);
333 kfree(name); 331 kfree(name);
334 if(dir == NULL) 332 if (dir == NULL)
335 return -error; 333 return -error;
336 next = file->f_pos; 334 next = file->f_pos;
337 while((name = read_dir(dir, &next, &ino, &len)) != NULL){ 335 while ((name = read_dir(dir, &next, &ino, &len)) != NULL) {
338 error = (*filldir)(ent, name, len, file->f_pos, 336 error = (*filldir)(ent, name, len, file->f_pos,
339 ino, DT_UNKNOWN); 337 ino, DT_UNKNOWN);
340 if(error) break; 338 if (error) break;
341 file->f_pos = next; 339 file->f_pos = next;
342 } 340 }
343 close_dir(dir); 341 close_dir(dir);
@@ -350,32 +348,33 @@ int hostfs_file_open(struct inode *ino, struct file *file)
350 int mode = 0, r = 0, w = 0, fd; 348 int mode = 0, r = 0, w = 0, fd;
351 349
352 mode = file->f_mode & (FMODE_READ | FMODE_WRITE); 350 mode = file->f_mode & (FMODE_READ | FMODE_WRITE);
353 if((mode & HOSTFS_I(ino)->mode) == mode) 351 if ((mode & HOSTFS_I(ino)->mode) == mode)
354 return 0; 352 return 0;
355 353
356 /* The file may already have been opened, but with the wrong access, 354 /*
355 * The file may already have been opened, but with the wrong access,
357 * so this resets things and reopens the file with the new access. 356 * so this resets things and reopens the file with the new access.
358 */ 357 */
359 if(HOSTFS_I(ino)->fd != -1){ 358 if (HOSTFS_I(ino)->fd != -1) {
360 close_file(&HOSTFS_I(ino)->fd); 359 close_file(&HOSTFS_I(ino)->fd);
361 HOSTFS_I(ino)->fd = -1; 360 HOSTFS_I(ino)->fd = -1;
362 } 361 }
363 362
364 HOSTFS_I(ino)->mode |= mode; 363 HOSTFS_I(ino)->mode |= mode;
365 if(HOSTFS_I(ino)->mode & FMODE_READ) 364 if (HOSTFS_I(ino)->mode & FMODE_READ)
366 r = 1; 365 r = 1;
367 if(HOSTFS_I(ino)->mode & FMODE_WRITE) 366 if (HOSTFS_I(ino)->mode & FMODE_WRITE)
368 w = 1; 367 w = 1;
369 if(w) 368 if (w)
370 r = 1; 369 r = 1;
371 370
372 name = dentry_name(file->f_path.dentry, 0); 371 name = dentry_name(file->f_path.dentry, 0);
373 if(name == NULL) 372 if (name == NULL)
374 return -ENOMEM; 373 return -ENOMEM;
375 374
376 fd = open_file(name, r, w, append); 375 fd = open_file(name, r, w, append);
377 kfree(name); 376 kfree(name);
378 if(fd < 0) 377 if (fd < 0)
379 return fd; 378 return fd;
380 FILE_HOSTFS_I(file)->fd = fd; 379 FILE_HOSTFS_I(file)->fd = fd;
381 380
@@ -423,7 +422,7 @@ int hostfs_writepage(struct page *page, struct writeback_control *wbc)
423 base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT; 422 base = ((unsigned long long) page->index) << PAGE_CACHE_SHIFT;
424 423
425 err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count); 424 err = write_file(HOSTFS_I(inode)->fd, &base, buffer, count);
426 if(err != count){ 425 if (err != count) {
427 ClearPageUptodate(page); 426 ClearPageUptodate(page);
428 goto out; 427 goto out;
429 } 428 }
@@ -452,7 +451,8 @@ int hostfs_readpage(struct file *file, struct page *page)
452 buffer = kmap(page); 451 buffer = kmap(page);
453 err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer, 452 err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer,
454 PAGE_CACHE_SIZE); 453 PAGE_CACHE_SIZE);
455 if(err < 0) goto out; 454 if (err < 0)
455 goto out;
456 456
457 memset(&buffer[err], 0, PAGE_CACHE_SIZE - err); 457 memset(&buffer[err], 0, PAGE_CACHE_SIZE - err);
458 458
@@ -466,56 +466,43 @@ int hostfs_readpage(struct file *file, struct page *page)
466 return err; 466 return err;
467} 467}
468 468
469int hostfs_prepare_write(struct file *file, struct page *page, 469int hostfs_write_begin(struct file *file, struct address_space *mapping,
470 unsigned int from, unsigned int to) 470 loff_t pos, unsigned len, unsigned flags,
471 struct page **pagep, void **fsdata)
471{ 472{
472 char *buffer; 473 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
473 long long start, tmp;
474 int err;
475 474
476 start = (long long) page->index << PAGE_CACHE_SHIFT; 475 *pagep = __grab_cache_page(mapping, index);
477 buffer = kmap(page); 476 if (!*pagep)
478 if(from != 0){ 477 return -ENOMEM;
479 tmp = start; 478 return 0;
480 err = read_file(FILE_HOSTFS_I(file)->fd, &tmp, buffer,
481 from);
482 if(err < 0) goto out;
483 }
484 if(to != PAGE_CACHE_SIZE){
485 start += to;
486 err = read_file(FILE_HOSTFS_I(file)->fd, &start, buffer + to,
487 PAGE_CACHE_SIZE - to);
488 if(err < 0) goto out;
489 }
490 err = 0;
491 out:
492 kunmap(page);
493 return err;
494} 479}
495 480
496int hostfs_commit_write(struct file *file, struct page *page, unsigned from, 481int hostfs_write_end(struct file *file, struct address_space *mapping,
497 unsigned to) 482 loff_t pos, unsigned len, unsigned copied,
483 struct page *page, void *fsdata)
498{ 484{
499 struct address_space *mapping = page->mapping;
500 struct inode *inode = mapping->host; 485 struct inode *inode = mapping->host;
501 char *buffer; 486 void *buffer;
502 long long start; 487 unsigned from = pos & (PAGE_CACHE_SIZE - 1);
503 int err = 0; 488 int err;
504 489
505 start = (((long long) page->index) << PAGE_CACHE_SHIFT) + from;
506 buffer = kmap(page); 490 buffer = kmap(page);
507 err = write_file(FILE_HOSTFS_I(file)->fd, &start, buffer + from, 491 err = write_file(FILE_HOSTFS_I(file)->fd, &pos, buffer + from, copied);
508 to - from); 492 kunmap(page);
509 if(err > 0) err = 0;
510 493
511 /* Actually, if !err, write_file has added to-from to start, so, despite 494 if (!PageUptodate(page) && err == PAGE_CACHE_SIZE)
512 * the appearance, we are comparing i_size against the _last_ written 495 SetPageUptodate(page);
513 * location, as we should. */
514 496
515 if(!err && (start > inode->i_size)) 497 /*
516 inode->i_size = start; 498 * If err > 0, write_file has added err to pos, so we are comparing
499 * i_size against the last byte written.
500 */
501 if (err > 0 && (pos > inode->i_size))
502 inode->i_size = pos;
503 unlock_page(page);
504 page_cache_release(page);
517 505
518 kunmap(page);
519 return err; 506 return err;
520} 507}
521 508
@@ -523,8 +510,8 @@ static const struct address_space_operations hostfs_aops = {
523 .writepage = hostfs_writepage, 510 .writepage = hostfs_writepage,
524 .readpage = hostfs_readpage, 511 .readpage = hostfs_readpage,
525 .set_page_dirty = __set_page_dirty_nobuffers, 512 .set_page_dirty = __set_page_dirty_nobuffers,
526 .prepare_write = hostfs_prepare_write, 513 .write_begin = hostfs_write_begin,
527 .commit_write = hostfs_commit_write 514 .write_end = hostfs_write_end,
528}; 515};
529 516
530static int init_inode(struct inode *inode, struct dentry *dentry) 517static int init_inode(struct inode *inode, struct dentry *dentry)
@@ -534,28 +521,28 @@ static int init_inode(struct inode *inode, struct dentry *dentry)
534 int maj, min; 521 int maj, min;
535 dev_t rdev = 0; 522 dev_t rdev = 0;
536 523
537 if(dentry){ 524 if (dentry) {
538 name = dentry_name(dentry, 0); 525 name = dentry_name(dentry, 0);
539 if(name == NULL) 526 if (name == NULL)
540 goto out; 527 goto out;
541 type = file_type(name, &maj, &min); 528 type = file_type(name, &maj, &min);
542 /*Reencode maj and min with the kernel encoding.*/ 529 /* Reencode maj and min with the kernel encoding.*/
543 rdev = MKDEV(maj, min); 530 rdev = MKDEV(maj, min);
544 kfree(name); 531 kfree(name);
545 } 532 }
546 else type = OS_TYPE_DIR; 533 else type = OS_TYPE_DIR;
547 534
548 err = 0; 535 err = 0;
549 if(type == OS_TYPE_SYMLINK) 536 if (type == OS_TYPE_SYMLINK)
550 inode->i_op = &page_symlink_inode_operations; 537 inode->i_op = &page_symlink_inode_operations;
551 else if(type == OS_TYPE_DIR) 538 else if (type == OS_TYPE_DIR)
552 inode->i_op = &hostfs_dir_iops; 539 inode->i_op = &hostfs_dir_iops;
553 else inode->i_op = &hostfs_iops; 540 else inode->i_op = &hostfs_iops;
554 541
555 if(type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops; 542 if (type == OS_TYPE_DIR) inode->i_fop = &hostfs_dir_fops;
556 else inode->i_fop = &hostfs_file_fops; 543 else inode->i_fop = &hostfs_file_fops;
557 544
558 if(type == OS_TYPE_SYMLINK) 545 if (type == OS_TYPE_SYMLINK)
559 inode->i_mapping->a_ops = &hostfs_link_aops; 546 inode->i_mapping->a_ops = &hostfs_link_aops;
560 else inode->i_mapping->a_ops = &hostfs_aops; 547 else inode->i_mapping->a_ops = &hostfs_aops;
561 548
@@ -578,7 +565,7 @@ static int init_inode(struct inode *inode, struct dentry *dentry)
578} 565}
579 566
580int hostfs_create(struct inode *dir, struct dentry *dentry, int mode, 567int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
581 struct nameidata *nd) 568 struct nameidata *nd)
582{ 569{
583 struct inode *inode; 570 struct inode *inode;
584 char *name; 571 char *name;
@@ -586,27 +573,28 @@ int hostfs_create(struct inode *dir, struct dentry *dentry, int mode,
586 573
587 error = -ENOMEM; 574 error = -ENOMEM;
588 inode = iget(dir->i_sb, 0); 575 inode = iget(dir->i_sb, 0);
589 if(inode == NULL) goto out; 576 if (inode == NULL)
577 goto out;
590 578
591 error = init_inode(inode, dentry); 579 error = init_inode(inode, dentry);
592 if(error) 580 if (error)
593 goto out_put; 581 goto out_put;
594 582
595 error = -ENOMEM; 583 error = -ENOMEM;
596 name = dentry_name(dentry, 0); 584 name = dentry_name(dentry, 0);
597 if(name == NULL) 585 if (name == NULL)
598 goto out_put; 586 goto out_put;
599 587
600 fd = file_create(name, 588 fd = file_create(name,
601 mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR, 589 mode & S_IRUSR, mode & S_IWUSR, mode & S_IXUSR,
602 mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP, 590 mode & S_IRGRP, mode & S_IWGRP, mode & S_IXGRP,
603 mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH); 591 mode & S_IROTH, mode & S_IWOTH, mode & S_IXOTH);
604 if(fd < 0) 592 if (fd < 0)
605 error = fd; 593 error = fd;
606 else error = read_name(inode, name); 594 else error = read_name(inode, name);
607 595
608 kfree(name); 596 kfree(name);
609 if(error) 597 if (error)
610 goto out_put; 598 goto out_put;
611 599
612 HOSTFS_I(inode)->fd = fd; 600 HOSTFS_I(inode)->fd = fd;
@@ -629,25 +617,25 @@ struct dentry *hostfs_lookup(struct inode *ino, struct dentry *dentry,
629 617
630 err = -ENOMEM; 618 err = -ENOMEM;
631 inode = iget(ino->i_sb, 0); 619 inode = iget(ino->i_sb, 0);
632 if(inode == NULL) 620 if (inode == NULL)
633 goto out; 621 goto out;
634 622
635 err = init_inode(inode, dentry); 623 err = init_inode(inode, dentry);
636 if(err) 624 if (err)
637 goto out_put; 625 goto out_put;
638 626
639 err = -ENOMEM; 627 err = -ENOMEM;
640 name = dentry_name(dentry, 0); 628 name = dentry_name(dentry, 0);
641 if(name == NULL) 629 if (name == NULL)
642 goto out_put; 630 goto out_put;
643 631
644 err = read_name(inode, name); 632 err = read_name(inode, name);
645 kfree(name); 633 kfree(name);
646 if(err == -ENOENT){ 634 if (err == -ENOENT) {
647 iput(inode); 635 iput(inode);
648 inode = NULL; 636 inode = NULL;
649 } 637 }
650 else if(err) 638 else if (err)
651 goto out_put; 639 goto out_put;
652 640
653 d_add(dentry, inode); 641 d_add(dentry, inode);
@@ -666,7 +654,7 @@ static char *inode_dentry_name(struct inode *ino, struct dentry *dentry)
666 int len; 654 int len;
667 655
668 file = inode_name(ino, dentry->d_name.len + 1); 656 file = inode_name(ino, dentry->d_name.len + 1);
669 if(file == NULL) 657 if (file == NULL)
670 return NULL; 658 return NULL;
671 strcat(file, "/"); 659 strcat(file, "/");
672 len = strlen(file); 660 len = strlen(file);
@@ -680,10 +668,10 @@ int hostfs_link(struct dentry *to, struct inode *ino, struct dentry *from)
680 char *from_name, *to_name; 668 char *from_name, *to_name;
681 int err; 669 int err;
682 670
683 if((from_name = inode_dentry_name(ino, from)) == NULL) 671 if ((from_name = inode_dentry_name(ino, from)) == NULL)
684 return -ENOMEM; 672 return -ENOMEM;
685 to_name = dentry_name(to, 0); 673 to_name = dentry_name(to, 0);
686 if(to_name == NULL){ 674 if (to_name == NULL) {
687 kfree(from_name); 675 kfree(from_name);
688 return -ENOMEM; 676 return -ENOMEM;
689 } 677 }
@@ -698,9 +686,9 @@ int hostfs_unlink(struct inode *ino, struct dentry *dentry)
698 char *file; 686 char *file;
699 int err; 687 int err;
700 688
701 if((file = inode_dentry_name(ino, dentry)) == NULL) 689 if ((file = inode_dentry_name(ino, dentry)) == NULL)
702 return -ENOMEM; 690 return -ENOMEM;
703 if(append) 691 if (append)
704 return -EPERM; 692 return -EPERM;
705 693
706 err = unlink_file(file); 694 err = unlink_file(file);
@@ -713,7 +701,7 @@ int hostfs_symlink(struct inode *ino, struct dentry *dentry, const char *to)
713 char *file; 701 char *file;
714 int err; 702 int err;
715 703
716 if((file = inode_dentry_name(ino, dentry)) == NULL) 704 if ((file = inode_dentry_name(ino, dentry)) == NULL)
717 return -ENOMEM; 705 return -ENOMEM;
718 err = make_symlink(file, to); 706 err = make_symlink(file, to);
719 kfree(file); 707 kfree(file);
@@ -725,7 +713,7 @@ int hostfs_mkdir(struct inode *ino, struct dentry *dentry, int mode)
725 char *file; 713 char *file;
726 int err; 714 int err;
727 715
728 if((file = inode_dentry_name(ino, dentry)) == NULL) 716 if ((file = inode_dentry_name(ino, dentry)) == NULL)
729 return -ENOMEM; 717 return -ENOMEM;
730 err = do_mkdir(file, mode); 718 err = do_mkdir(file, mode);
731 kfree(file); 719 kfree(file);
@@ -737,7 +725,7 @@ int hostfs_rmdir(struct inode *ino, struct dentry *dentry)
737 char *file; 725 char *file;
738 int err; 726 int err;
739 727
740 if((file = inode_dentry_name(ino, dentry)) == NULL) 728 if ((file = inode_dentry_name(ino, dentry)) == NULL)
741 return -ENOMEM; 729 return -ENOMEM;
742 err = do_rmdir(file); 730 err = do_rmdir(file);
743 kfree(file); 731 kfree(file);
@@ -751,26 +739,26 @@ int hostfs_mknod(struct inode *dir, struct dentry *dentry, int mode, dev_t dev)
751 int err = -ENOMEM; 739 int err = -ENOMEM;
752 740
753 inode = iget(dir->i_sb, 0); 741 inode = iget(dir->i_sb, 0);
754 if(inode == NULL) 742 if (inode == NULL)
755 goto out; 743 goto out;
756 744
757 err = init_inode(inode, dentry); 745 err = init_inode(inode, dentry);
758 if(err) 746 if (err)
759 goto out_put; 747 goto out_put;
760 748
761 err = -ENOMEM; 749 err = -ENOMEM;
762 name = dentry_name(dentry, 0); 750 name = dentry_name(dentry, 0);
763 if(name == NULL) 751 if (name == NULL)
764 goto out_put; 752 goto out_put;
765 753
766 init_special_inode(inode, mode, dev); 754 init_special_inode(inode, mode, dev);
767 err = do_mknod(name, mode, MAJOR(dev), MINOR(dev)); 755 err = do_mknod(name, mode, MAJOR(dev), MINOR(dev));
768 if(err) 756 if (err)
769 goto out_free; 757 goto out_free;
770 758
771 err = read_name(inode, name); 759 err = read_name(inode, name);
772 kfree(name); 760 kfree(name);
773 if(err) 761 if (err)
774 goto out_put; 762 goto out_put;
775 763
776 d_instantiate(dentry, inode); 764 d_instantiate(dentry, inode);
@@ -790,9 +778,9 @@ int hostfs_rename(struct inode *from_ino, struct dentry *from,
790 char *from_name, *to_name; 778 char *from_name, *to_name;
791 int err; 779 int err;
792 780
793 if((from_name = inode_dentry_name(from_ino, from)) == NULL) 781 if ((from_name = inode_dentry_name(from_ino, from)) == NULL)
794 return -ENOMEM; 782 return -ENOMEM;
795 if((to_name = inode_dentry_name(to_ino, to)) == NULL){ 783 if ((to_name = inode_dentry_name(to_ino, to)) == NULL) {
796 kfree(from_name); 784 kfree(from_name);
797 return -ENOMEM; 785 return -ENOMEM;
798 } 786 }
@@ -815,12 +803,12 @@ int hostfs_permission(struct inode *ino, int desired, struct nameidata *nd)
815 return -ENOMEM; 803 return -ENOMEM;
816 804
817 if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) || 805 if (S_ISCHR(ino->i_mode) || S_ISBLK(ino->i_mode) ||
818 S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode)) 806 S_ISFIFO(ino->i_mode) || S_ISSOCK(ino->i_mode))
819 err = 0; 807 err = 0;
820 else 808 else
821 err = access_file(name, r, w, x); 809 err = access_file(name, r, w, x);
822 kfree(name); 810 kfree(name);
823 if(!err) 811 if (!err)
824 err = generic_permission(ino, desired, NULL); 812 err = generic_permission(ino, desired, NULL);
825 return err; 813 return err;
826} 814}
@@ -837,62 +825,55 @@ int hostfs_setattr(struct dentry *dentry, struct iattr *attr)
837 if (err) 825 if (err)
838 return err; 826 return err;
839 827
840 if(append) 828 if (append)
841 attr->ia_valid &= ~ATTR_SIZE; 829 attr->ia_valid &= ~ATTR_SIZE;
842 830
843 attrs.ia_valid = 0; 831 attrs.ia_valid = 0;
844 if(attr->ia_valid & ATTR_MODE){ 832 if (attr->ia_valid & ATTR_MODE) {
845 attrs.ia_valid |= HOSTFS_ATTR_MODE; 833 attrs.ia_valid |= HOSTFS_ATTR_MODE;
846 attrs.ia_mode = attr->ia_mode; 834 attrs.ia_mode = attr->ia_mode;
847 } 835 }
848 if(attr->ia_valid & ATTR_UID){ 836 if (attr->ia_valid & ATTR_UID) {
849 attrs.ia_valid |= HOSTFS_ATTR_UID; 837 attrs.ia_valid |= HOSTFS_ATTR_UID;
850 attrs.ia_uid = attr->ia_uid; 838 attrs.ia_uid = attr->ia_uid;
851 } 839 }
852 if(attr->ia_valid & ATTR_GID){ 840 if (attr->ia_valid & ATTR_GID) {
853 attrs.ia_valid |= HOSTFS_ATTR_GID; 841 attrs.ia_valid |= HOSTFS_ATTR_GID;
854 attrs.ia_gid = attr->ia_gid; 842 attrs.ia_gid = attr->ia_gid;
855 } 843 }
856 if(attr->ia_valid & ATTR_SIZE){ 844 if (attr->ia_valid & ATTR_SIZE) {
857 attrs.ia_valid |= HOSTFS_ATTR_SIZE; 845 attrs.ia_valid |= HOSTFS_ATTR_SIZE;
858 attrs.ia_size = attr->ia_size; 846 attrs.ia_size = attr->ia_size;
859 } 847 }
860 if(attr->ia_valid & ATTR_ATIME){ 848 if (attr->ia_valid & ATTR_ATIME) {
861 attrs.ia_valid |= HOSTFS_ATTR_ATIME; 849 attrs.ia_valid |= HOSTFS_ATTR_ATIME;
862 attrs.ia_atime = attr->ia_atime; 850 attrs.ia_atime = attr->ia_atime;
863 } 851 }
864 if(attr->ia_valid & ATTR_MTIME){ 852 if (attr->ia_valid & ATTR_MTIME) {
865 attrs.ia_valid |= HOSTFS_ATTR_MTIME; 853 attrs.ia_valid |= HOSTFS_ATTR_MTIME;
866 attrs.ia_mtime = attr->ia_mtime; 854 attrs.ia_mtime = attr->ia_mtime;
867 } 855 }
868 if(attr->ia_valid & ATTR_CTIME){ 856 if (attr->ia_valid & ATTR_CTIME) {
869 attrs.ia_valid |= HOSTFS_ATTR_CTIME; 857 attrs.ia_valid |= HOSTFS_ATTR_CTIME;
870 attrs.ia_ctime = attr->ia_ctime; 858 attrs.ia_ctime = attr->ia_ctime;
871 } 859 }
872 if(attr->ia_valid & ATTR_ATIME_SET){ 860 if (attr->ia_valid & ATTR_ATIME_SET) {
873 attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET; 861 attrs.ia_valid |= HOSTFS_ATTR_ATIME_SET;
874 } 862 }
875 if(attr->ia_valid & ATTR_MTIME_SET){ 863 if (attr->ia_valid & ATTR_MTIME_SET) {
876 attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET; 864 attrs.ia_valid |= HOSTFS_ATTR_MTIME_SET;
877 } 865 }
878 name = dentry_name(dentry, 0); 866 name = dentry_name(dentry, 0);
879 if(name == NULL) 867 if (name == NULL)
880 return -ENOMEM; 868 return -ENOMEM;
881 err = set_attr(name, &attrs, fd); 869 err = set_attr(name, &attrs, fd);
882 kfree(name); 870 kfree(name);
883 if(err) 871 if (err)
884 return err; 872 return err;
885 873
886 return inode_setattr(dentry->d_inode, attr); 874 return inode_setattr(dentry->d_inode, attr);
887} 875}
888 876
889int hostfs_getattr(struct vfsmount *mnt, struct dentry *dentry,
890 struct kstat *stat)
891{
892 generic_fillattr(dentry->d_inode, stat);
893 return 0;
894}
895
896static const struct inode_operations hostfs_iops = { 877static const struct inode_operations hostfs_iops = {
897 .create = hostfs_create, 878 .create = hostfs_create,
898 .link = hostfs_link, 879 .link = hostfs_link,
@@ -904,7 +885,6 @@ static const struct inode_operations hostfs_iops = {
904 .rename = hostfs_rename, 885 .rename = hostfs_rename,
905 .permission = hostfs_permission, 886 .permission = hostfs_permission,
906 .setattr = hostfs_setattr, 887 .setattr = hostfs_setattr,
907 .getattr = hostfs_getattr,
908}; 888};
909 889
910static const struct inode_operations hostfs_dir_iops = { 890static const struct inode_operations hostfs_dir_iops = {
@@ -919,7 +899,6 @@ static const struct inode_operations hostfs_dir_iops = {
919 .rename = hostfs_rename, 899 .rename = hostfs_rename,
920 .permission = hostfs_permission, 900 .permission = hostfs_permission,
921 .setattr = hostfs_setattr, 901 .setattr = hostfs_setattr,
922 .getattr = hostfs_getattr,
923}; 902};
924 903
925int hostfs_link_readpage(struct file *file, struct page *page) 904int hostfs_link_readpage(struct file *file, struct page *page)
@@ -929,13 +908,13 @@ int hostfs_link_readpage(struct file *file, struct page *page)
929 908
930 buffer = kmap(page); 909 buffer = kmap(page);
931 name = inode_name(page->mapping->host, 0); 910 name = inode_name(page->mapping->host, 0);
932 if(name == NULL) 911 if (name == NULL)
933 return -ENOMEM; 912 return -ENOMEM;
934 err = do_readlink(name, buffer, PAGE_CACHE_SIZE); 913 err = do_readlink(name, buffer, PAGE_CACHE_SIZE);
935 kfree(name); 914 kfree(name);
936 if(err == PAGE_CACHE_SIZE) 915 if (err == PAGE_CACHE_SIZE)
937 err = -E2BIG; 916 err = -E2BIG;
938 else if(err > 0){ 917 else if (err > 0) {
939 flush_dcache_page(page); 918 flush_dcache_page(page);
940 SetPageUptodate(page); 919 SetPageUptodate(page);
941 if (PageError(page)) ClearPageError(page); 920 if (PageError(page)) ClearPageError(page);
@@ -968,31 +947,33 @@ static int hostfs_fill_sb_common(struct super_block *sb, void *d, int silent)
968 err = -ENOMEM; 947 err = -ENOMEM;
969 host_root_path = kmalloc(strlen(root_ino) + 1 948 host_root_path = kmalloc(strlen(root_ino) + 1
970 + strlen(req_root) + 1, GFP_KERNEL); 949 + strlen(req_root) + 1, GFP_KERNEL);
971 if(host_root_path == NULL) 950 if (host_root_path == NULL)
972 goto out; 951 goto out;
973 952
974 sprintf(host_root_path, "%s/%s", root_ino, req_root); 953 sprintf(host_root_path, "%s/%s", root_ino, req_root);
975 954
976 root_inode = iget(sb, 0); 955 root_inode = iget(sb, 0);
977 if(root_inode == NULL) 956 if (root_inode == NULL)
978 goto out_free; 957 goto out_free;
979 958
980 err = init_inode(root_inode, NULL); 959 err = init_inode(root_inode, NULL);
981 if(err) 960 if (err)
982 goto out_put; 961 goto out_put;
983 962
984 HOSTFS_I(root_inode)->host_filename = host_root_path; 963 HOSTFS_I(root_inode)->host_filename = host_root_path;
985 /* Avoid that in the error path, iput(root_inode) frees again 964 /*
986 * host_root_path through hostfs_destroy_inode! */ 965 * Avoid that in the error path, iput(root_inode) frees again
966 * host_root_path through hostfs_destroy_inode!
967 */
987 host_root_path = NULL; 968 host_root_path = NULL;
988 969
989 err = -ENOMEM; 970 err = -ENOMEM;
990 sb->s_root = d_alloc_root(root_inode); 971 sb->s_root = d_alloc_root(root_inode);
991 if(sb->s_root == NULL) 972 if (sb->s_root == NULL)
992 goto out_put; 973 goto out_put;
993 974
994 err = read_inode(root_inode); 975 err = read_inode(root_inode);
995 if(err){ 976 if (err) {
996 /* No iput in this case because the dput does that for us */ 977 /* No iput in this case because the dput does that for us */
997 dput(sb->s_root); 978 dput(sb->s_root);
998 sb->s_root = NULL; 979 sb->s_root = NULL;
diff --git a/fs/hostfs/hostfs_user.c b/fs/hostfs/hostfs_user.c
index 5625e2481dd3..35c1a9f33f47 100644
--- a/fs/hostfs/hostfs_user.c
+++ b/fs/hostfs/hostfs_user.c
@@ -3,19 +3,21 @@
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
6#include <unistd.h>
7#include <stdio.h> 6#include <stdio.h>
8#include <fcntl.h> 7#include <stddef.h>
8#include <unistd.h>
9#include <dirent.h> 9#include <dirent.h>
10#include <errno.h> 10#include <errno.h>
11#include <utime.h> 11#include <fcntl.h>
12#include <string.h> 12#include <string.h>
13#include <sys/stat.h> 13#include <sys/stat.h>
14#include <sys/time.h> 14#include <sys/time.h>
15#include <sys/types.h>
15#include <sys/vfs.h> 16#include <sys/vfs.h>
16#include "hostfs.h" 17#include "hostfs.h"
17#include "kern_util.h" 18#include "os.h"
18#include "user.h" 19#include "user.h"
20#include <utime.h>
19 21
20int stat_file(const char *path, unsigned long long *inode_out, int *mode_out, 22int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
21 int *nlink_out, int *uid_out, int *gid_out, 23 int *nlink_out, int *uid_out, int *gid_out,
@@ -25,33 +27,41 @@ int stat_file(const char *path, unsigned long long *inode_out, int *mode_out,
25{ 27{
26 struct stat64 buf; 28 struct stat64 buf;
27 29
28 if(fd >= 0) { 30 if (fd >= 0) {
29 if (fstat64(fd, &buf) < 0) 31 if (fstat64(fd, &buf) < 0)
30 return -errno; 32 return -errno;
31 } else if(lstat64(path, &buf) < 0) { 33 } else if (lstat64(path, &buf) < 0) {
32 return -errno; 34 return -errno;
33 } 35 }
34 36
35 if(inode_out != NULL) *inode_out = buf.st_ino; 37 if (inode_out != NULL)
36 if(mode_out != NULL) *mode_out = buf.st_mode; 38 *inode_out = buf.st_ino;
37 if(nlink_out != NULL) *nlink_out = buf.st_nlink; 39 if (mode_out != NULL)
38 if(uid_out != NULL) *uid_out = buf.st_uid; 40 *mode_out = buf.st_mode;
39 if(gid_out != NULL) *gid_out = buf.st_gid; 41 if (nlink_out != NULL)
40 if(size_out != NULL) *size_out = buf.st_size; 42 *nlink_out = buf.st_nlink;
41 if(atime_out != NULL) { 43 if (uid_out != NULL)
44 *uid_out = buf.st_uid;
45 if (gid_out != NULL)
46 *gid_out = buf.st_gid;
47 if (size_out != NULL)
48 *size_out = buf.st_size;
49 if (atime_out != NULL) {
42 atime_out->tv_sec = buf.st_atime; 50 atime_out->tv_sec = buf.st_atime;
43 atime_out->tv_nsec = 0; 51 atime_out->tv_nsec = 0;
44 } 52 }
45 if(mtime_out != NULL) { 53 if (mtime_out != NULL) {
46 mtime_out->tv_sec = buf.st_mtime; 54 mtime_out->tv_sec = buf.st_mtime;
47 mtime_out->tv_nsec = 0; 55 mtime_out->tv_nsec = 0;
48 } 56 }
49 if(ctime_out != NULL) { 57 if (ctime_out != NULL) {
50 ctime_out->tv_sec = buf.st_ctime; 58 ctime_out->tv_sec = buf.st_ctime;
51 ctime_out->tv_nsec = 0; 59 ctime_out->tv_nsec = 0;
52 } 60 }
53 if(blksize_out != NULL) *blksize_out = buf.st_blksize; 61 if (blksize_out != NULL)
54 if(blocks_out != NULL) *blocks_out = buf.st_blocks; 62 *blksize_out = buf.st_blksize;
63 if (blocks_out != NULL)
64 *blocks_out = buf.st_blocks;
55 return 0; 65 return 0;
56} 66}
57 67
@@ -59,21 +69,29 @@ int file_type(const char *path, int *maj, int *min)
59{ 69{
60 struct stat64 buf; 70 struct stat64 buf;
61 71
62 if(lstat64(path, &buf) < 0) 72 if (lstat64(path, &buf) < 0)
63 return -errno; 73 return -errno;
64 /*We cannot pass rdev as is because glibc and the kernel disagree 74 /*
65 *about its definition.*/ 75 * We cannot pass rdev as is because glibc and the kernel disagree
66 if(maj != NULL) 76 * about its definition.
77 */
78 if (maj != NULL)
67 *maj = major(buf.st_rdev); 79 *maj = major(buf.st_rdev);
68 if(min != NULL) 80 if (min != NULL)
69 *min = minor(buf.st_rdev); 81 *min = minor(buf.st_rdev);
70 82
71 if(S_ISDIR(buf.st_mode)) return OS_TYPE_DIR; 83 if (S_ISDIR(buf.st_mode))
72 else if(S_ISLNK(buf.st_mode)) return OS_TYPE_SYMLINK; 84 return OS_TYPE_DIR;
73 else if(S_ISCHR(buf.st_mode)) return OS_TYPE_CHARDEV; 85 else if (S_ISLNK(buf.st_mode))
74 else if(S_ISBLK(buf.st_mode)) return OS_TYPE_BLOCKDEV; 86 return OS_TYPE_SYMLINK;
75 else if(S_ISFIFO(buf.st_mode))return OS_TYPE_FIFO; 87 else if (S_ISCHR(buf.st_mode))
76 else if(S_ISSOCK(buf.st_mode))return OS_TYPE_SOCK; 88 return OS_TYPE_CHARDEV;
89 else if (S_ISBLK(buf.st_mode))
90 return OS_TYPE_BLOCKDEV;
91 else if (S_ISFIFO(buf.st_mode))
92 return OS_TYPE_FIFO;
93 else if (S_ISSOCK(buf.st_mode))
94 return OS_TYPE_SOCK;
77 else return OS_TYPE_FILE; 95 else return OS_TYPE_FILE;
78} 96}
79 97
@@ -81,10 +99,13 @@ int access_file(char *path, int r, int w, int x)
81{ 99{
82 int mode = 0; 100 int mode = 0;
83 101
84 if(r) mode = R_OK; 102 if (r)
85 if(w) mode |= W_OK; 103 mode = R_OK;
86 if(x) mode |= X_OK; 104 if (w)
87 if(access(path, mode) != 0) 105 mode |= W_OK;
106 if (x)
107 mode |= X_OK;
108 if (access(path, mode) != 0)
88 return -errno; 109 return -errno;
89 else return 0; 110 else return 0;
90} 111}
@@ -93,18 +114,18 @@ int open_file(char *path, int r, int w, int append)
93{ 114{
94 int mode = 0, fd; 115 int mode = 0, fd;
95 116
96 if(r && !w) 117 if (r && !w)
97 mode = O_RDONLY; 118 mode = O_RDONLY;
98 else if(!r && w) 119 else if (!r && w)
99 mode = O_WRONLY; 120 mode = O_WRONLY;
100 else if(r && w) 121 else if (r && w)
101 mode = O_RDWR; 122 mode = O_RDWR;
102 else panic("Impossible mode in open_file"); 123 else panic("Impossible mode in open_file");
103 124
104 if(append) 125 if (append)
105 mode |= O_APPEND; 126 mode |= O_APPEND;
106 fd = open64(path, mode); 127 fd = open64(path, mode);
107 if(fd < 0) 128 if (fd < 0)
108 return -errno; 129 return -errno;
109 else return fd; 130 else return fd;
110} 131}
@@ -115,7 +136,7 @@ void *open_dir(char *path, int *err_out)
115 136
116 dir = opendir(path); 137 dir = opendir(path);
117 *err_out = errno; 138 *err_out = errno;
118 if(dir == NULL) 139 if (dir == NULL)
119 return NULL; 140 return NULL;
120 return dir; 141 return dir;
121} 142}
@@ -128,7 +149,7 @@ char *read_dir(void *stream, unsigned long long *pos,
128 149
129 seekdir(dir, *pos); 150 seekdir(dir, *pos);
130 ent = readdir(dir); 151 ent = readdir(dir);
131 if(ent == NULL) 152 if (ent == NULL)
132 return NULL; 153 return NULL;
133 *len_out = strlen(ent->d_name); 154 *len_out = strlen(ent->d_name);
134 *ino_out = ent->d_ino; 155 *ino_out = ent->d_ino;
@@ -141,7 +162,7 @@ int read_file(int fd, unsigned long long *offset, char *buf, int len)
141 int n; 162 int n;
142 163
143 n = pread64(fd, buf, len, *offset); 164 n = pread64(fd, buf, len, *offset);
144 if(n < 0) 165 if (n < 0)
145 return -errno; 166 return -errno;
146 *offset += n; 167 *offset += n;
147 return n; 168 return n;
@@ -152,7 +173,7 @@ int write_file(int fd, unsigned long long *offset, const char *buf, int len)
152 int n; 173 int n;
153 174
154 n = pwrite64(fd, buf, len, *offset); 175 n = pwrite64(fd, buf, len, *offset);
155 if(n < 0) 176 if (n < 0)
156 return -errno; 177 return -errno;
157 *offset += n; 178 *offset += n;
158 return n; 179 return n;
@@ -163,7 +184,7 @@ int lseek_file(int fd, long long offset, int whence)
163 int ret; 184 int ret;
164 185
165 ret = lseek64(fd, offset, whence); 186 ret = lseek64(fd, offset, whence);
166 if(ret < 0) 187 if (ret < 0)
167 return -errno; 188 return -errno;
168 return 0; 189 return 0;
169} 190}
@@ -207,7 +228,7 @@ int file_create(char *name, int ur, int uw, int ux, int gr,
207 mode |= ow ? S_IWOTH : 0; 228 mode |= ow ? S_IWOTH : 0;
208 mode |= ox ? S_IXOTH : 0; 229 mode |= ox ? S_IXOTH : 0;
209 fd = open64(name, O_CREAT | O_RDWR, mode); 230 fd = open64(name, O_CREAT | O_RDWR, mode);
210 if(fd < 0) 231 if (fd < 0)
211 return -errno; 232 return -errno;
212 return fd; 233 return fd;
213} 234}
@@ -230,7 +251,7 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
230 if (fd >= 0) { 251 if (fd >= 0) {
231 if (fchown(fd, attrs->ia_uid, -1)) 252 if (fchown(fd, attrs->ia_uid, -1))
232 return -errno; 253 return -errno;
233 } else if(chown(file, attrs->ia_uid, -1)) { 254 } else if (chown(file, attrs->ia_uid, -1)) {
234 return -errno; 255 return -errno;
235 } 256 }
236 } 257 }
@@ -251,9 +272,11 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
251 } 272 }
252 } 273 }
253 274
254 /* Update accessed and/or modified time, in two parts: first set 275 /*
276 * Update accessed and/or modified time, in two parts: first set
255 * times according to the changes to perform, and then call futimes() 277 * times according to the changes to perform, and then call futimes()
256 * or utimes() to apply them. */ 278 * or utimes() to apply them.
279 */
257 ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET); 280 ma = (HOSTFS_ATTR_ATIME_SET | HOSTFS_ATTR_MTIME_SET);
258 if (attrs->ia_valid & ma) { 281 if (attrs->ia_valid & ma) {
259 err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, 282 err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
@@ -283,12 +306,12 @@ int set_attr(const char *file, struct hostfs_iattr *attrs, int fd)
283 } 306 }
284 } 307 }
285 308
286 if(attrs->ia_valid & HOSTFS_ATTR_CTIME) ; 309 /* Note: ctime is not handled */
287 if(attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)){ 310 if (attrs->ia_valid & (HOSTFS_ATTR_ATIME | HOSTFS_ATTR_MTIME)) {
288 err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL, 311 err = stat_file(file, NULL, NULL, NULL, NULL, NULL, NULL,
289 &attrs->ia_atime, &attrs->ia_mtime, NULL, 312 &attrs->ia_atime, &attrs->ia_mtime, NULL,
290 NULL, NULL, fd); 313 NULL, NULL, fd);
291 if(err != 0) 314 if (err != 0)
292 return err; 315 return err;
293 } 316 }
294 return 0; 317 return 0;
@@ -299,7 +322,7 @@ int make_symlink(const char *from, const char *to)
299 int err; 322 int err;
300 323
301 err = symlink(to, from); 324 err = symlink(to, from);
302 if(err) 325 if (err)
303 return -errno; 326 return -errno;
304 return 0; 327 return 0;
305} 328}
@@ -309,7 +332,7 @@ int unlink_file(const char *file)
309 int err; 332 int err;
310 333
311 err = unlink(file); 334 err = unlink(file);
312 if(err) 335 if (err)
313 return -errno; 336 return -errno;
314 return 0; 337 return 0;
315} 338}
@@ -319,7 +342,7 @@ int do_mkdir(const char *file, int mode)
319 int err; 342 int err;
320 343
321 err = mkdir(file, mode); 344 err = mkdir(file, mode);
322 if(err) 345 if (err)
323 return -errno; 346 return -errno;
324 return 0; 347 return 0;
325} 348}
@@ -329,7 +352,7 @@ int do_rmdir(const char *file)
329 int err; 352 int err;
330 353
331 err = rmdir(file); 354 err = rmdir(file);
332 if(err) 355 if (err)
333 return -errno; 356 return -errno;
334 return 0; 357 return 0;
335} 358}
@@ -339,7 +362,7 @@ int do_mknod(const char *file, int mode, unsigned int major, unsigned int minor)
339 int err; 362 int err;
340 363
341 err = mknod(file, mode, makedev(major, minor)); 364 err = mknod(file, mode, makedev(major, minor));
342 if(err) 365 if (err)
343 return -errno; 366 return -errno;
344 return 0; 367 return 0;
345} 368}
@@ -349,7 +372,7 @@ int link_file(const char *to, const char *from)
349 int err; 372 int err;
350 373
351 err = link(to, from); 374 err = link(to, from);
352 if(err) 375 if (err)
353 return -errno; 376 return -errno;
354 return 0; 377 return 0;
355} 378}
@@ -359,9 +382,9 @@ int do_readlink(char *file, char *buf, int size)
359 int n; 382 int n;
360 383
361 n = readlink(file, buf, size); 384 n = readlink(file, buf, size);
362 if(n < 0) 385 if (n < 0)
363 return -errno; 386 return -errno;
364 if(n < size) 387 if (n < size)
365 buf[n] = '\0'; 388 buf[n] = '\0';
366 return n; 389 return n;
367} 390}
@@ -371,7 +394,7 @@ int rename_file(char *from, char *to)
371 int err; 394 int err;
372 395
373 err = rename(from, to); 396 err = rename(from, to);
374 if(err < 0) 397 if (err < 0)
375 return -errno; 398 return -errno;
376 return 0; 399 return 0;
377} 400}
@@ -386,7 +409,7 @@ int do_statfs(char *root, long *bsize_out, long long *blocks_out,
386 int err; 409 int err;
387 410
388 err = statfs64(root, &buf); 411 err = statfs64(root, &buf);
389 if(err < 0) 412 if (err < 0)
390 return -errno; 413 return -errno;
391 414
392 *bsize_out = buf.f_bsize; 415 *bsize_out = buf.f_bsize;
diff --git a/fs/hpfs/file.c b/fs/hpfs/file.c
index 5b53e5c5d8df..be8be5040e07 100644
--- a/fs/hpfs/file.c
+++ b/fs/hpfs/file.c
@@ -86,25 +86,33 @@ static int hpfs_writepage(struct page *page, struct writeback_control *wbc)
86{ 86{
87 return block_write_full_page(page,hpfs_get_block, wbc); 87 return block_write_full_page(page,hpfs_get_block, wbc);
88} 88}
89
89static int hpfs_readpage(struct file *file, struct page *page) 90static int hpfs_readpage(struct file *file, struct page *page)
90{ 91{
91 return block_read_full_page(page,hpfs_get_block); 92 return block_read_full_page(page,hpfs_get_block);
92} 93}
93static int hpfs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) 94
95static int hpfs_write_begin(struct file *file, struct address_space *mapping,
96 loff_t pos, unsigned len, unsigned flags,
97 struct page **pagep, void **fsdata)
94{ 98{
95 return cont_prepare_write(page,from,to,hpfs_get_block, 99 *pagep = NULL;
96 &hpfs_i(page->mapping->host)->mmu_private); 100 return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
101 hpfs_get_block,
102 &hpfs_i(mapping->host)->mmu_private);
97} 103}
104
98static sector_t _hpfs_bmap(struct address_space *mapping, sector_t block) 105static sector_t _hpfs_bmap(struct address_space *mapping, sector_t block)
99{ 106{
100 return generic_block_bmap(mapping,block,hpfs_get_block); 107 return generic_block_bmap(mapping,block,hpfs_get_block);
101} 108}
109
102const struct address_space_operations hpfs_aops = { 110const struct address_space_operations hpfs_aops = {
103 .readpage = hpfs_readpage, 111 .readpage = hpfs_readpage,
104 .writepage = hpfs_writepage, 112 .writepage = hpfs_writepage,
105 .sync_page = block_sync_page, 113 .sync_page = block_sync_page,
106 .prepare_write = hpfs_prepare_write, 114 .write_begin = hpfs_write_begin,
107 .commit_write = generic_commit_write, 115 .write_end = generic_write_end,
108 .bmap = _hpfs_bmap 116 .bmap = _hpfs_bmap
109}; 117};
110 118
diff --git a/fs/hugetlbfs/inode.c b/fs/hugetlbfs/inode.c
index 950c2fbb815b..04598e12c489 100644
--- a/fs/hugetlbfs/inode.c
+++ b/fs/hugetlbfs/inode.c
@@ -179,6 +179,130 @@ full_search:
179} 179}
180#endif 180#endif
181 181
182static int
183hugetlbfs_read_actor(struct page *page, unsigned long offset,
184 char __user *buf, unsigned long count,
185 unsigned long size)
186{
187 char *kaddr;
188 unsigned long left, copied = 0;
189 int i, chunksize;
190
191 if (size > count)
192 size = count;
193
194 /* Find which 4k chunk and offset with in that chunk */
195 i = offset >> PAGE_CACHE_SHIFT;
196 offset = offset & ~PAGE_CACHE_MASK;
197
198 while (size) {
199 chunksize = PAGE_CACHE_SIZE;
200 if (offset)
201 chunksize -= offset;
202 if (chunksize > size)
203 chunksize = size;
204 kaddr = kmap(&page[i]);
205 left = __copy_to_user(buf, kaddr + offset, chunksize);
206 kunmap(&page[i]);
207 if (left) {
208 copied += (chunksize - left);
209 break;
210 }
211 offset = 0;
212 size -= chunksize;
213 buf += chunksize;
214 copied += chunksize;
215 i++;
216 }
217 return copied ? copied : -EFAULT;
218}
219
220/*
221 * Support for read() - Find the page attached to f_mapping and copy out the
222 * data. Its *very* similar to do_generic_mapping_read(), we can't use that
223 * since it has PAGE_CACHE_SIZE assumptions.
224 */
225static ssize_t hugetlbfs_read(struct file *filp, char __user *buf,
226 size_t len, loff_t *ppos)
227{
228 struct address_space *mapping = filp->f_mapping;
229 struct inode *inode = mapping->host;
230 unsigned long index = *ppos >> HPAGE_SHIFT;
231 unsigned long offset = *ppos & ~HPAGE_MASK;
232 unsigned long end_index;
233 loff_t isize;
234 ssize_t retval = 0;
235
236 mutex_lock(&inode->i_mutex);
237
238 /* validate length */
239 if (len == 0)
240 goto out;
241
242 isize = i_size_read(inode);
243 if (!isize)
244 goto out;
245
246 end_index = (isize - 1) >> HPAGE_SHIFT;
247 for (;;) {
248 struct page *page;
249 int nr, ret;
250
251 /* nr is the maximum number of bytes to copy from this page */
252 nr = HPAGE_SIZE;
253 if (index >= end_index) {
254 if (index > end_index)
255 goto out;
256 nr = ((isize - 1) & ~HPAGE_MASK) + 1;
257 if (nr <= offset) {
258 goto out;
259 }
260 }
261 nr = nr - offset;
262
263 /* Find the page */
264 page = find_get_page(mapping, index);
265 if (unlikely(page == NULL)) {
266 /*
267 * We have a HOLE, zero out the user-buffer for the
268 * length of the hole or request.
269 */
270 ret = len < nr ? len : nr;
271 if (clear_user(buf, ret))
272 ret = -EFAULT;
273 } else {
274 /*
275 * We have the page, copy it to user space buffer.
276 */
277 ret = hugetlbfs_read_actor(page, offset, buf, len, nr);
278 }
279 if (ret < 0) {
280 if (retval == 0)
281 retval = ret;
282 if (page)
283 page_cache_release(page);
284 goto out;
285 }
286
287 offset += ret;
288 retval += ret;
289 len -= ret;
290 index += offset >> HPAGE_SHIFT;
291 offset &= ~HPAGE_MASK;
292
293 if (page)
294 page_cache_release(page);
295
296 /* short read or no more work */
297 if ((ret != nr) || (len == 0))
298 break;
299 }
300out:
301 *ppos = ((loff_t)index << HPAGE_SHIFT) + offset;
302 mutex_unlock(&inode->i_mutex);
303 return retval;
304}
305
182/* 306/*
183 * Read a page. Again trivial. If it didn't already exist 307 * Read a page. Again trivial. If it didn't already exist
184 * in the page cache, it is zero-filled. 308 * in the page cache, it is zero-filled.
@@ -189,15 +313,19 @@ static int hugetlbfs_readpage(struct file *file, struct page * page)
189 return -EINVAL; 313 return -EINVAL;
190} 314}
191 315
192static int hugetlbfs_prepare_write(struct file *file, 316static int hugetlbfs_write_begin(struct file *file,
193 struct page *page, unsigned offset, unsigned to) 317 struct address_space *mapping,
318 loff_t pos, unsigned len, unsigned flags,
319 struct page **pagep, void **fsdata)
194{ 320{
195 return -EINVAL; 321 return -EINVAL;
196} 322}
197 323
198static int hugetlbfs_commit_write(struct file *file, 324static int hugetlbfs_write_end(struct file *file, struct address_space *mapping,
199 struct page *page, unsigned offset, unsigned to) 325 loff_t pos, unsigned len, unsigned copied,
326 struct page *page, void *fsdata)
200{ 327{
328 BUG();
201 return -EINVAL; 329 return -EINVAL;
202} 330}
203 331
@@ -318,21 +446,15 @@ hugetlb_vmtruncate_list(struct prio_tree_root *root, pgoff_t pgoff)
318 } 446 }
319} 447}
320 448
321/*
322 * Expanding truncates are not allowed.
323 */
324static int hugetlb_vmtruncate(struct inode *inode, loff_t offset) 449static int hugetlb_vmtruncate(struct inode *inode, loff_t offset)
325{ 450{
326 pgoff_t pgoff; 451 pgoff_t pgoff;
327 struct address_space *mapping = inode->i_mapping; 452 struct address_space *mapping = inode->i_mapping;
328 453
329 if (offset > inode->i_size)
330 return -EINVAL;
331
332 BUG_ON(offset & ~HPAGE_MASK); 454 BUG_ON(offset & ~HPAGE_MASK);
333 pgoff = offset >> PAGE_SHIFT; 455 pgoff = offset >> PAGE_SHIFT;
334 456
335 inode->i_size = offset; 457 i_size_write(inode, offset);
336 spin_lock(&mapping->i_mmap_lock); 458 spin_lock(&mapping->i_mmap_lock);
337 if (!prio_tree_empty(&mapping->i_mmap)) 459 if (!prio_tree_empty(&mapping->i_mmap))
338 hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff); 460 hugetlb_vmtruncate_list(&mapping->i_mmap, pgoff);
@@ -569,8 +691,8 @@ static void hugetlbfs_destroy_inode(struct inode *inode)
569 691
570static const struct address_space_operations hugetlbfs_aops = { 692static const struct address_space_operations hugetlbfs_aops = {
571 .readpage = hugetlbfs_readpage, 693 .readpage = hugetlbfs_readpage,
572 .prepare_write = hugetlbfs_prepare_write, 694 .write_begin = hugetlbfs_write_begin,
573 .commit_write = hugetlbfs_commit_write, 695 .write_end = hugetlbfs_write_end,
574 .set_page_dirty = hugetlbfs_set_page_dirty, 696 .set_page_dirty = hugetlbfs_set_page_dirty,
575}; 697};
576 698
@@ -583,6 +705,7 @@ static void init_once(void *foo, struct kmem_cache *cachep, unsigned long flags)
583} 705}
584 706
585const struct file_operations hugetlbfs_file_operations = { 707const struct file_operations hugetlbfs_file_operations = {
708 .read = hugetlbfs_read,
586 .mmap = hugetlbfs_file_mmap, 709 .mmap = hugetlbfs_file_mmap,
587 .fsync = simple_sync_file, 710 .fsync = simple_sync_file,
588 .get_unmapped_area = hugetlb_get_unmapped_area, 711 .get_unmapped_area = hugetlb_get_unmapped_area,
diff --git a/fs/inode.c b/fs/inode.c
index f97de0aeb3b6..21dab18b2f18 100644
--- a/fs/inode.c
+++ b/fs/inode.c
@@ -568,16 +568,16 @@ EXPORT_SYMBOL(new_inode);
568void unlock_new_inode(struct inode *inode) 568void unlock_new_inode(struct inode *inode)
569{ 569{
570#ifdef CONFIG_DEBUG_LOCK_ALLOC 570#ifdef CONFIG_DEBUG_LOCK_ALLOC
571 struct file_system_type *type = inode->i_sb->s_type; 571 if (inode->i_mode & S_IFDIR) {
572 /* 572 struct file_system_type *type = inode->i_sb->s_type;
573 * ensure nobody is actually holding i_mutex 573
574 */ 574 /*
575 mutex_destroy(&inode->i_mutex); 575 * ensure nobody is actually holding i_mutex
576 mutex_init(&inode->i_mutex); 576 */
577 if (inode->i_mode & S_IFDIR) 577 mutex_destroy(&inode->i_mutex);
578 mutex_init(&inode->i_mutex);
578 lockdep_set_class(&inode->i_mutex, &type->i_mutex_dir_key); 579 lockdep_set_class(&inode->i_mutex, &type->i_mutex_dir_key);
579 else 580 }
580 lockdep_set_class(&inode->i_mutex, &type->i_mutex_key);
581#endif 581#endif
582 /* 582 /*
583 * This is special! We do not need the spinlock 583 * This is special! We do not need the spinlock
diff --git a/fs/jbd/journal.c b/fs/jbd/journal.c
index 06ab3c10b1b8..a6be78c05dce 100644
--- a/fs/jbd/journal.c
+++ b/fs/jbd/journal.c
@@ -1710,7 +1710,7 @@ static int journal_init_journal_head_cache(void)
1710 journal_head_cache = kmem_cache_create("journal_head", 1710 journal_head_cache = kmem_cache_create("journal_head",
1711 sizeof(struct journal_head), 1711 sizeof(struct journal_head),
1712 0, /* offset */ 1712 0, /* offset */
1713 0, /* flags */ 1713 SLAB_TEMPORARY, /* flags */
1714 NULL); /* ctor */ 1714 NULL); /* ctor */
1715 retval = 0; 1715 retval = 0;
1716 if (journal_head_cache == 0) { 1716 if (journal_head_cache == 0) {
@@ -2006,7 +2006,7 @@ static int __init journal_init_handle_cache(void)
2006 jbd_handle_cache = kmem_cache_create("journal_handle", 2006 jbd_handle_cache = kmem_cache_create("journal_handle",
2007 sizeof(handle_t), 2007 sizeof(handle_t),
2008 0, /* offset */ 2008 0, /* offset */
2009 0, /* flags */ 2009 SLAB_TEMPORARY, /* flags */
2010 NULL); /* ctor */ 2010 NULL); /* ctor */
2011 if (jbd_handle_cache == NULL) { 2011 if (jbd_handle_cache == NULL) {
2012 printk(KERN_EMERG "JBD: failed to create handle cache\n"); 2012 printk(KERN_EMERG "JBD: failed to create handle cache\n");
diff --git a/fs/jbd/revoke.c b/fs/jbd/revoke.c
index 62e13c8db132..ad2eacf570c6 100644
--- a/fs/jbd/revoke.c
+++ b/fs/jbd/revoke.c
@@ -170,13 +170,15 @@ int __init journal_init_revoke_caches(void)
170{ 170{
171 revoke_record_cache = kmem_cache_create("revoke_record", 171 revoke_record_cache = kmem_cache_create("revoke_record",
172 sizeof(struct jbd_revoke_record_s), 172 sizeof(struct jbd_revoke_record_s),
173 0, SLAB_HWCACHE_ALIGN, NULL); 173 0,
174 SLAB_HWCACHE_ALIGN|SLAB_TEMPORARY,
175 NULL);
174 if (revoke_record_cache == 0) 176 if (revoke_record_cache == 0)
175 return -ENOMEM; 177 return -ENOMEM;
176 178
177 revoke_table_cache = kmem_cache_create("revoke_table", 179 revoke_table_cache = kmem_cache_create("revoke_table",
178 sizeof(struct jbd_revoke_table_s), 180 sizeof(struct jbd_revoke_table_s),
179 0, 0, NULL); 181 0, SLAB_TEMPORARY, NULL);
180 if (revoke_table_cache == 0) { 182 if (revoke_table_cache == 0) {
181 kmem_cache_destroy(revoke_record_cache); 183 kmem_cache_destroy(revoke_record_cache);
182 revoke_record_cache = NULL; 184 revoke_record_cache = NULL;
diff --git a/fs/jffs2/file.c b/fs/jffs2/file.c
index c2530197be0c..023a17539dd4 100644
--- a/fs/jffs2/file.c
+++ b/fs/jffs2/file.c
@@ -19,10 +19,12 @@
19#include <linux/jffs2.h> 19#include <linux/jffs2.h>
20#include "nodelist.h" 20#include "nodelist.h"
21 21
22static int jffs2_commit_write (struct file *filp, struct page *pg, 22static int jffs2_write_end(struct file *filp, struct address_space *mapping,
23 unsigned start, unsigned end); 23 loff_t pos, unsigned len, unsigned copied,
24static int jffs2_prepare_write (struct file *filp, struct page *pg, 24 struct page *pg, void *fsdata);
25 unsigned start, unsigned end); 25static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
26 loff_t pos, unsigned len, unsigned flags,
27 struct page **pagep, void **fsdata);
26static int jffs2_readpage (struct file *filp, struct page *pg); 28static int jffs2_readpage (struct file *filp, struct page *pg);
27 29
28int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync) 30int jffs2_fsync(struct file *filp, struct dentry *dentry, int datasync)
@@ -65,8 +67,8 @@ const struct inode_operations jffs2_file_inode_operations =
65const struct address_space_operations jffs2_file_address_operations = 67const struct address_space_operations jffs2_file_address_operations =
66{ 68{
67 .readpage = jffs2_readpage, 69 .readpage = jffs2_readpage,
68 .prepare_write =jffs2_prepare_write, 70 .write_begin = jffs2_write_begin,
69 .commit_write = jffs2_commit_write 71 .write_end = jffs2_write_end,
70}; 72};
71 73
72static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg) 74static int jffs2_do_readpage_nolock (struct inode *inode, struct page *pg)
@@ -119,15 +121,23 @@ static int jffs2_readpage (struct file *filp, struct page *pg)
119 return ret; 121 return ret;
120} 122}
121 123
122static int jffs2_prepare_write (struct file *filp, struct page *pg, 124static int jffs2_write_begin(struct file *filp, struct address_space *mapping,
123 unsigned start, unsigned end) 125 loff_t pos, unsigned len, unsigned flags,
126 struct page **pagep, void **fsdata)
124{ 127{
125 struct inode *inode = pg->mapping->host; 128 struct page *pg;
129 struct inode *inode = mapping->host;
126 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 130 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
127 uint32_t pageofs = pg->index << PAGE_CACHE_SHIFT; 131 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
132 uint32_t pageofs = pos & (PAGE_CACHE_SIZE - 1);
128 int ret = 0; 133 int ret = 0;
129 134
130 D1(printk(KERN_DEBUG "jffs2_prepare_write()\n")); 135 pg = __grab_cache_page(mapping, index);
136 if (!pg)
137 return -ENOMEM;
138 *pagep = pg;
139
140 D1(printk(KERN_DEBUG "jffs2_write_begin()\n"));
131 141
132 if (pageofs > inode->i_size) { 142 if (pageofs > inode->i_size) {
133 /* Make new hole frag from old EOF to new page */ 143 /* Make new hole frag from old EOF to new page */
@@ -142,7 +152,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
142 ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len, 152 ret = jffs2_reserve_space(c, sizeof(ri), &alloc_len,
143 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE); 153 ALLOC_NORMAL, JFFS2_SUMMARY_INODE_SIZE);
144 if (ret) 154 if (ret)
145 return ret; 155 goto out_page;
146 156
147 down(&f->sem); 157 down(&f->sem);
148 memset(&ri, 0, sizeof(ri)); 158 memset(&ri, 0, sizeof(ri));
@@ -172,7 +182,7 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
172 ret = PTR_ERR(fn); 182 ret = PTR_ERR(fn);
173 jffs2_complete_reservation(c); 183 jffs2_complete_reservation(c);
174 up(&f->sem); 184 up(&f->sem);
175 return ret; 185 goto out_page;
176 } 186 }
177 ret = jffs2_add_full_dnode_to_inode(c, f, fn); 187 ret = jffs2_add_full_dnode_to_inode(c, f, fn);
178 if (f->metadata) { 188 if (f->metadata) {
@@ -181,65 +191,79 @@ static int jffs2_prepare_write (struct file *filp, struct page *pg,
181 f->metadata = NULL; 191 f->metadata = NULL;
182 } 192 }
183 if (ret) { 193 if (ret) {
184 D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in prepare_write, returned %d\n", ret)); 194 D1(printk(KERN_DEBUG "Eep. add_full_dnode_to_inode() failed in write_begin, returned %d\n", ret));
185 jffs2_mark_node_obsolete(c, fn->raw); 195 jffs2_mark_node_obsolete(c, fn->raw);
186 jffs2_free_full_dnode(fn); 196 jffs2_free_full_dnode(fn);
187 jffs2_complete_reservation(c); 197 jffs2_complete_reservation(c);
188 up(&f->sem); 198 up(&f->sem);
189 return ret; 199 goto out_page;
190 } 200 }
191 jffs2_complete_reservation(c); 201 jffs2_complete_reservation(c);
192 inode->i_size = pageofs; 202 inode->i_size = pageofs;
193 up(&f->sem); 203 up(&f->sem);
194 } 204 }
195 205
196 /* Read in the page if it wasn't already present, unless it's a whole page */ 206 /*
197 if (!PageUptodate(pg) && (start || end < PAGE_CACHE_SIZE)) { 207 * Read in the page if it wasn't already present. Cannot optimize away
208 * the whole page write case until jffs2_write_end can handle the
209 * case of a short-copy.
210 */
211 if (!PageUptodate(pg)) {
198 down(&f->sem); 212 down(&f->sem);
199 ret = jffs2_do_readpage_nolock(inode, pg); 213 ret = jffs2_do_readpage_nolock(inode, pg);
200 up(&f->sem); 214 up(&f->sem);
215 if (ret)
216 goto out_page;
201 } 217 }
202 D1(printk(KERN_DEBUG "end prepare_write(). pg->flags %lx\n", pg->flags)); 218 D1(printk(KERN_DEBUG "end write_begin(). pg->flags %lx\n", pg->flags));
219 return ret;
220
221out_page:
222 unlock_page(pg);
223 page_cache_release(pg);
203 return ret; 224 return ret;
204} 225}
205 226
206static int jffs2_commit_write (struct file *filp, struct page *pg, 227static int jffs2_write_end(struct file *filp, struct address_space *mapping,
207 unsigned start, unsigned end) 228 loff_t pos, unsigned len, unsigned copied,
229 struct page *pg, void *fsdata)
208{ 230{
209 /* Actually commit the write from the page cache page we're looking at. 231 /* Actually commit the write from the page cache page we're looking at.
210 * For now, we write the full page out each time. It sucks, but it's simple 232 * For now, we write the full page out each time. It sucks, but it's simple
211 */ 233 */
212 struct inode *inode = pg->mapping->host; 234 struct inode *inode = mapping->host;
213 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode); 235 struct jffs2_inode_info *f = JFFS2_INODE_INFO(inode);
214 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb); 236 struct jffs2_sb_info *c = JFFS2_SB_INFO(inode->i_sb);
215 struct jffs2_raw_inode *ri; 237 struct jffs2_raw_inode *ri;
238 unsigned start = pos & (PAGE_CACHE_SIZE - 1);
239 unsigned end = start + copied;
216 unsigned aligned_start = start & ~3; 240 unsigned aligned_start = start & ~3;
217 int ret = 0; 241 int ret = 0;
218 uint32_t writtenlen = 0; 242 uint32_t writtenlen = 0;
219 243
220 D1(printk(KERN_DEBUG "jffs2_commit_write(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n", 244 D1(printk(KERN_DEBUG "jffs2_write_end(): ino #%lu, page at 0x%lx, range %d-%d, flags %lx\n",
221 inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags)); 245 inode->i_ino, pg->index << PAGE_CACHE_SHIFT, start, end, pg->flags));
222 246
247 /* We need to avoid deadlock with page_cache_read() in
248 jffs2_garbage_collect_pass(). So the page must be
249 up to date to prevent page_cache_read() from trying
250 to re-lock it. */
251 BUG_ON(!PageUptodate(pg));
252
223 if (end == PAGE_CACHE_SIZE) { 253 if (end == PAGE_CACHE_SIZE) {
224 if (!start) { 254 /* When writing out the end of a page, write out the
225 /* We need to avoid deadlock with page_cache_read() in 255 _whole_ page. This helps to reduce the number of
226 jffs2_garbage_collect_pass(). So we have to mark the 256 nodes in files which have many short writes, like
227 page up to date, to prevent page_cache_read() from 257 syslog files. */
228 trying to re-lock it. */ 258 start = aligned_start = 0;
229 SetPageUptodate(pg);
230 } else {
231 /* When writing out the end of a page, write out the
232 _whole_ page. This helps to reduce the number of
233 nodes in files which have many short writes, like
234 syslog files. */
235 start = aligned_start = 0;
236 }
237 } 259 }
238 260
239 ri = jffs2_alloc_raw_inode(); 261 ri = jffs2_alloc_raw_inode();
240 262
241 if (!ri) { 263 if (!ri) {
242 D1(printk(KERN_DEBUG "jffs2_commit_write(): Allocation of raw inode failed\n")); 264 D1(printk(KERN_DEBUG "jffs2_write_end(): Allocation of raw inode failed\n"));
265 unlock_page(pg);
266 page_cache_release(pg);
243 return -ENOMEM; 267 return -ENOMEM;
244 } 268 }
245 269
@@ -287,11 +311,14 @@ static int jffs2_commit_write (struct file *filp, struct page *pg,
287 /* generic_file_write has written more to the page cache than we've 311 /* generic_file_write has written more to the page cache than we've
288 actually written to the medium. Mark the page !Uptodate so that 312 actually written to the medium. Mark the page !Uptodate so that
289 it gets reread */ 313 it gets reread */
290 D1(printk(KERN_DEBUG "jffs2_commit_write(): Not all bytes written. Marking page !uptodate\n")); 314 D1(printk(KERN_DEBUG "jffs2_write_end(): Not all bytes written. Marking page !uptodate\n"));
291 SetPageError(pg); 315 SetPageError(pg);
292 ClearPageUptodate(pg); 316 ClearPageUptodate(pg);
293 } 317 }
294 318
295 D1(printk(KERN_DEBUG "jffs2_commit_write() returning %d\n",start+writtenlen==end?0:ret)); 319 D1(printk(KERN_DEBUG "jffs2_write_end() returning %d\n",
296 return start+writtenlen==end?0:ret; 320 writtenlen > 0 ? writtenlen : ret));
321 unlock_page(pg);
322 page_cache_release(pg);
323 return writtenlen > 0 ? writtenlen : ret;
297} 324}
diff --git a/fs/jfs/inode.c b/fs/jfs/inode.c
index 3467dde27e5a..4672013802e1 100644
--- a/fs/jfs/inode.c
+++ b/fs/jfs/inode.c
@@ -255,7 +255,7 @@ int jfs_get_block(struct inode *ip, sector_t lblock,
255 255
256static int jfs_writepage(struct page *page, struct writeback_control *wbc) 256static int jfs_writepage(struct page *page, struct writeback_control *wbc)
257{ 257{
258 return nobh_writepage(page, jfs_get_block, wbc); 258 return block_write_full_page(page, jfs_get_block, wbc);
259} 259}
260 260
261static int jfs_writepages(struct address_space *mapping, 261static int jfs_writepages(struct address_space *mapping,
@@ -275,10 +275,12 @@ static int jfs_readpages(struct file *file, struct address_space *mapping,
275 return mpage_readpages(mapping, pages, nr_pages, jfs_get_block); 275 return mpage_readpages(mapping, pages, nr_pages, jfs_get_block);
276} 276}
277 277
278static int jfs_prepare_write(struct file *file, 278static int jfs_write_begin(struct file *file, struct address_space *mapping,
279 struct page *page, unsigned from, unsigned to) 279 loff_t pos, unsigned len, unsigned flags,
280 struct page **pagep, void **fsdata)
280{ 281{
281 return nobh_prepare_write(page, from, to, jfs_get_block); 282 return nobh_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
283 jfs_get_block);
282} 284}
283 285
284static sector_t jfs_bmap(struct address_space *mapping, sector_t block) 286static sector_t jfs_bmap(struct address_space *mapping, sector_t block)
@@ -302,8 +304,8 @@ const struct address_space_operations jfs_aops = {
302 .writepage = jfs_writepage, 304 .writepage = jfs_writepage,
303 .writepages = jfs_writepages, 305 .writepages = jfs_writepages,
304 .sync_page = block_sync_page, 306 .sync_page = block_sync_page,
305 .prepare_write = jfs_prepare_write, 307 .write_begin = jfs_write_begin,
306 .commit_write = nobh_commit_write, 308 .write_end = nobh_write_end,
307 .bmap = jfs_bmap, 309 .bmap = jfs_bmap,
308 .direct_IO = jfs_direct_IO, 310 .direct_IO = jfs_direct_IO,
309}; 311};
@@ -356,7 +358,7 @@ void jfs_truncate(struct inode *ip)
356{ 358{
357 jfs_info("jfs_truncate: size = 0x%lx", (ulong) ip->i_size); 359 jfs_info("jfs_truncate: size = 0x%lx", (ulong) ip->i_size);
358 360
359 nobh_truncate_page(ip->i_mapping, ip->i_size); 361 nobh_truncate_page(ip->i_mapping, ip->i_size, jfs_get_block);
360 362
361 IWRITE_LOCK(ip, RDWRLOCK_NORMAL); 363 IWRITE_LOCK(ip, RDWRLOCK_NORMAL);
362 jfs_truncate_nolock(ip, ip->i_size); 364 jfs_truncate_nolock(ip, ip->i_size);
diff --git a/fs/libfs.c b/fs/libfs.c
index 5294de1f40c4..f2b32d3a9093 100644
--- a/fs/libfs.c
+++ b/fs/libfs.c
@@ -351,6 +351,26 @@ int simple_prepare_write(struct file *file, struct page *page,
351 return 0; 351 return 0;
352} 352}
353 353
354int simple_write_begin(struct file *file, struct address_space *mapping,
355 loff_t pos, unsigned len, unsigned flags,
356 struct page **pagep, void **fsdata)
357{
358 struct page *page;
359 pgoff_t index;
360 unsigned from;
361
362 index = pos >> PAGE_CACHE_SHIFT;
363 from = pos & (PAGE_CACHE_SIZE - 1);
364
365 page = __grab_cache_page(mapping, index);
366 if (!page)
367 return -ENOMEM;
368
369 *pagep = page;
370
371 return simple_prepare_write(file, page, from, from+len);
372}
373
354int simple_commit_write(struct file *file, struct page *page, 374int simple_commit_write(struct file *file, struct page *page,
355 unsigned from, unsigned to) 375 unsigned from, unsigned to)
356{ 376{
@@ -369,6 +389,28 @@ int simple_commit_write(struct file *file, struct page *page,
369 return 0; 389 return 0;
370} 390}
371 391
392int simple_write_end(struct file *file, struct address_space *mapping,
393 loff_t pos, unsigned len, unsigned copied,
394 struct page *page, void *fsdata)
395{
396 unsigned from = pos & (PAGE_CACHE_SIZE - 1);
397
398 /* zero the stale part of the page if we did a short copy */
399 if (copied < len) {
400 void *kaddr = kmap_atomic(page, KM_USER0);
401 memset(kaddr + from + copied, 0, len - copied);
402 flush_dcache_page(page);
403 kunmap_atomic(kaddr, KM_USER0);
404 }
405
406 simple_commit_write(file, page, from, from+copied);
407
408 unlock_page(page);
409 page_cache_release(page);
410
411 return copied;
412}
413
372/* 414/*
373 * the inodes created here are not hashed. If you use iunique to generate 415 * the inodes created here are not hashed. If you use iunique to generate
374 * unique inode values later for this filesystem, then you must take care 416 * unique inode values later for this filesystem, then you must take care
@@ -642,6 +684,8 @@ EXPORT_SYMBOL(dcache_dir_open);
642EXPORT_SYMBOL(dcache_readdir); 684EXPORT_SYMBOL(dcache_readdir);
643EXPORT_SYMBOL(generic_read_dir); 685EXPORT_SYMBOL(generic_read_dir);
644EXPORT_SYMBOL(get_sb_pseudo); 686EXPORT_SYMBOL(get_sb_pseudo);
687EXPORT_SYMBOL(simple_write_begin);
688EXPORT_SYMBOL(simple_write_end);
645EXPORT_SYMBOL(simple_commit_write); 689EXPORT_SYMBOL(simple_commit_write);
646EXPORT_SYMBOL(simple_dir_inode_operations); 690EXPORT_SYMBOL(simple_dir_inode_operations);
647EXPORT_SYMBOL(simple_dir_operations); 691EXPORT_SYMBOL(simple_dir_operations);
diff --git a/fs/minix/dir.c b/fs/minix/dir.c
index e207cbe70951..f70433816a38 100644
--- a/fs/minix/dir.c
+++ b/fs/minix/dir.c
@@ -9,8 +9,10 @@
9 */ 9 */
10 10
11#include "minix.h" 11#include "minix.h"
12#include <linux/buffer_head.h>
12#include <linux/highmem.h> 13#include <linux/highmem.h>
13#include <linux/smp_lock.h> 14#include <linux/smp_lock.h>
15#include <linux/swap.h>
14 16
15typedef struct minix_dir_entry minix_dirent; 17typedef struct minix_dir_entry minix_dirent;
16typedef struct minix3_dir_entry minix3_dirent; 18typedef struct minix3_dir_entry minix3_dirent;
@@ -48,11 +50,17 @@ static inline unsigned long dir_pages(struct inode *inode)
48 return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; 50 return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
49} 51}
50 52
51static int dir_commit_chunk(struct page *page, unsigned from, unsigned to) 53static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
52{ 54{
53 struct inode *dir = (struct inode *)page->mapping->host; 55 struct address_space *mapping = page->mapping;
56 struct inode *dir = mapping->host;
54 int err = 0; 57 int err = 0;
55 page->mapping->a_ops->commit_write(NULL, page, from, to); 58 block_write_end(NULL, mapping, pos, len, len, page, NULL);
59
60 if (pos+len > dir->i_size) {
61 i_size_write(dir, pos+len);
62 mark_inode_dirty(dir);
63 }
56 if (IS_DIRSYNC(dir)) 64 if (IS_DIRSYNC(dir))
57 err = write_one_page(page, 1); 65 err = write_one_page(page, 1);
58 else 66 else
@@ -220,7 +228,7 @@ int minix_add_link(struct dentry *dentry, struct inode *inode)
220 char *kaddr, *p; 228 char *kaddr, *p;
221 minix_dirent *de; 229 minix_dirent *de;
222 minix3_dirent *de3; 230 minix3_dirent *de3;
223 unsigned from, to; 231 loff_t pos;
224 int err; 232 int err;
225 char *namx = NULL; 233 char *namx = NULL;
226 __u32 inumber; 234 __u32 inumber;
@@ -272,9 +280,9 @@ int minix_add_link(struct dentry *dentry, struct inode *inode)
272 return -EINVAL; 280 return -EINVAL;
273 281
274got_it: 282got_it:
275 from = p - (char*)page_address(page); 283 pos = (page->index >> PAGE_CACHE_SHIFT) + p - (char*)page_address(page);
276 to = from + sbi->s_dirsize; 284 err = __minix_write_begin(NULL, page->mapping, pos, sbi->s_dirsize,
277 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 285 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
278 if (err) 286 if (err)
279 goto out_unlock; 287 goto out_unlock;
280 memcpy (namx, name, namelen); 288 memcpy (namx, name, namelen);
@@ -285,7 +293,7 @@ got_it:
285 memset (namx + namelen, 0, sbi->s_dirsize - namelen - 2); 293 memset (namx + namelen, 0, sbi->s_dirsize - namelen - 2);
286 de->inode = inode->i_ino; 294 de->inode = inode->i_ino;
287 } 295 }
288 err = dir_commit_chunk(page, from, to); 296 err = dir_commit_chunk(page, pos, sbi->s_dirsize);
289 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 297 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
290 mark_inode_dirty(dir); 298 mark_inode_dirty(dir);
291out_put: 299out_put:
@@ -302,15 +310,16 @@ int minix_delete_entry(struct minix_dir_entry *de, struct page *page)
302 struct address_space *mapping = page->mapping; 310 struct address_space *mapping = page->mapping;
303 struct inode *inode = (struct inode*)mapping->host; 311 struct inode *inode = (struct inode*)mapping->host;
304 char *kaddr = page_address(page); 312 char *kaddr = page_address(page);
305 unsigned from = (char*)de - kaddr; 313 loff_t pos = page_offset(page) + (char*)de - kaddr;
306 unsigned to = from + minix_sb(inode->i_sb)->s_dirsize; 314 unsigned len = minix_sb(inode->i_sb)->s_dirsize;
307 int err; 315 int err;
308 316
309 lock_page(page); 317 lock_page(page);
310 err = mapping->a_ops->prepare_write(NULL, page, from, to); 318 err = __minix_write_begin(NULL, mapping, pos, len,
319 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
311 if (err == 0) { 320 if (err == 0) {
312 de->inode = 0; 321 de->inode = 0;
313 err = dir_commit_chunk(page, from, to); 322 err = dir_commit_chunk(page, pos, len);
314 } else { 323 } else {
315 unlock_page(page); 324 unlock_page(page);
316 } 325 }
@@ -330,7 +339,8 @@ int minix_make_empty(struct inode *inode, struct inode *dir)
330 339
331 if (!page) 340 if (!page)
332 return -ENOMEM; 341 return -ENOMEM;
333 err = mapping->a_ops->prepare_write(NULL, page, 0, 2 * sbi->s_dirsize); 342 err = __minix_write_begin(NULL, mapping, 0, 2 * sbi->s_dirsize,
343 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
334 if (err) { 344 if (err) {
335 unlock_page(page); 345 unlock_page(page);
336 goto fail; 346 goto fail;
@@ -421,17 +431,20 @@ not_empty:
421void minix_set_link(struct minix_dir_entry *de, struct page *page, 431void minix_set_link(struct minix_dir_entry *de, struct page *page,
422 struct inode *inode) 432 struct inode *inode)
423{ 433{
424 struct inode *dir = (struct inode*)page->mapping->host; 434 struct address_space *mapping = page->mapping;
435 struct inode *dir = mapping->host;
425 struct minix_sb_info *sbi = minix_sb(dir->i_sb); 436 struct minix_sb_info *sbi = minix_sb(dir->i_sb);
426 unsigned from = (char *)de-(char*)page_address(page); 437 loff_t pos = page_offset(page) +
427 unsigned to = from + sbi->s_dirsize; 438 (char *)de-(char*)page_address(page);
428 int err; 439 int err;
429 440
430 lock_page(page); 441 lock_page(page);
431 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 442
443 err = __minix_write_begin(NULL, mapping, pos, sbi->s_dirsize,
444 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
432 if (err == 0) { 445 if (err == 0) {
433 de->inode = inode->i_ino; 446 de->inode = inode->i_ino;
434 err = dir_commit_chunk(page, from, to); 447 err = dir_commit_chunk(page, pos, sbi->s_dirsize);
435 } else { 448 } else {
436 unlock_page(page); 449 unlock_page(page);
437 } 450 }
diff --git a/fs/minix/inode.c b/fs/minix/inode.c
index 43668d7d668f..f4f3343b1800 100644
--- a/fs/minix/inode.c
+++ b/fs/minix/inode.c
@@ -346,24 +346,39 @@ static int minix_writepage(struct page *page, struct writeback_control *wbc)
346{ 346{
347 return block_write_full_page(page, minix_get_block, wbc); 347 return block_write_full_page(page, minix_get_block, wbc);
348} 348}
349
349static int minix_readpage(struct file *file, struct page *page) 350static int minix_readpage(struct file *file, struct page *page)
350{ 351{
351 return block_read_full_page(page,minix_get_block); 352 return block_read_full_page(page,minix_get_block);
352} 353}
353static int minix_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) 354
355int __minix_write_begin(struct file *file, struct address_space *mapping,
356 loff_t pos, unsigned len, unsigned flags,
357 struct page **pagep, void **fsdata)
354{ 358{
355 return block_prepare_write(page,from,to,minix_get_block); 359 return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
360 minix_get_block);
356} 361}
362
363static int minix_write_begin(struct file *file, struct address_space *mapping,
364 loff_t pos, unsigned len, unsigned flags,
365 struct page **pagep, void **fsdata)
366{
367 *pagep = NULL;
368 return __minix_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
369}
370
357static sector_t minix_bmap(struct address_space *mapping, sector_t block) 371static sector_t minix_bmap(struct address_space *mapping, sector_t block)
358{ 372{
359 return generic_block_bmap(mapping,block,minix_get_block); 373 return generic_block_bmap(mapping,block,minix_get_block);
360} 374}
375
361static const struct address_space_operations minix_aops = { 376static const struct address_space_operations minix_aops = {
362 .readpage = minix_readpage, 377 .readpage = minix_readpage,
363 .writepage = minix_writepage, 378 .writepage = minix_writepage,
364 .sync_page = block_sync_page, 379 .sync_page = block_sync_page,
365 .prepare_write = minix_prepare_write, 380 .write_begin = minix_write_begin,
366 .commit_write = generic_commit_write, 381 .write_end = generic_write_end,
367 .bmap = minix_bmap 382 .bmap = minix_bmap
368}; 383};
369 384
diff --git a/fs/minix/minix.h b/fs/minix/minix.h
index 73ef84f8fb0b..ac5d3a75cb0d 100644
--- a/fs/minix/minix.h
+++ b/fs/minix/minix.h
@@ -54,6 +54,9 @@ extern int minix_new_block(struct inode * inode);
54extern void minix_free_block(struct inode *inode, unsigned long block); 54extern void minix_free_block(struct inode *inode, unsigned long block);
55extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi); 55extern unsigned long minix_count_free_blocks(struct minix_sb_info *sbi);
56extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *); 56extern int minix_getattr(struct vfsmount *, struct dentry *, struct kstat *);
57extern int __minix_write_begin(struct file *file, struct address_space *mapping,
58 loff_t pos, unsigned len, unsigned flags,
59 struct page **pagep, void **fsdata);
57 60
58extern void V1_minix_truncate(struct inode *); 61extern void V1_minix_truncate(struct inode *);
59extern void V2_minix_truncate(struct inode *); 62extern void V2_minix_truncate(struct inode *);
diff --git a/fs/mpage.c b/fs/mpage.c
index b1c3e5890508..d54f8f897224 100644
--- a/fs/mpage.c
+++ b/fs/mpage.c
@@ -379,31 +379,25 @@ mpage_readpages(struct address_space *mapping, struct list_head *pages,
379 struct bio *bio = NULL; 379 struct bio *bio = NULL;
380 unsigned page_idx; 380 unsigned page_idx;
381 sector_t last_block_in_bio = 0; 381 sector_t last_block_in_bio = 0;
382 struct pagevec lru_pvec;
383 struct buffer_head map_bh; 382 struct buffer_head map_bh;
384 unsigned long first_logical_block = 0; 383 unsigned long first_logical_block = 0;
385 384
386 clear_buffer_mapped(&map_bh); 385 clear_buffer_mapped(&map_bh);
387 pagevec_init(&lru_pvec, 0);
388 for (page_idx = 0; page_idx < nr_pages; page_idx++) { 386 for (page_idx = 0; page_idx < nr_pages; page_idx++) {
389 struct page *page = list_entry(pages->prev, struct page, lru); 387 struct page *page = list_entry(pages->prev, struct page, lru);
390 388
391 prefetchw(&page->flags); 389 prefetchw(&page->flags);
392 list_del(&page->lru); 390 list_del(&page->lru);
393 if (!add_to_page_cache(page, mapping, 391 if (!add_to_page_cache_lru(page, mapping,
394 page->index, GFP_KERNEL)) { 392 page->index, GFP_KERNEL)) {
395 bio = do_mpage_readpage(bio, page, 393 bio = do_mpage_readpage(bio, page,
396 nr_pages - page_idx, 394 nr_pages - page_idx,
397 &last_block_in_bio, &map_bh, 395 &last_block_in_bio, &map_bh,
398 &first_logical_block, 396 &first_logical_block,
399 get_block); 397 get_block);
400 if (!pagevec_add(&lru_pvec, page))
401 __pagevec_lru_add(&lru_pvec);
402 } else {
403 page_cache_release(page);
404 } 398 }
399 page_cache_release(page);
405 } 400 }
406 pagevec_lru_add(&lru_pvec);
407 BUG_ON(!list_empty(pages)); 401 BUG_ON(!list_empty(pages));
408 if (bio) 402 if (bio)
409 mpage_bio_submit(READ, bio); 403 mpage_bio_submit(READ, bio);
diff --git a/fs/namei.c b/fs/namei.c
index a83160acd748..b40b8084eefc 100644
--- a/fs/namei.c
+++ b/fs/namei.c
@@ -2729,53 +2729,29 @@ int __page_symlink(struct inode *inode, const char *symname, int len,
2729{ 2729{
2730 struct address_space *mapping = inode->i_mapping; 2730 struct address_space *mapping = inode->i_mapping;
2731 struct page *page; 2731 struct page *page;
2732 void *fsdata;
2732 int err; 2733 int err;
2733 char *kaddr; 2734 char *kaddr;
2734 2735
2735retry: 2736retry:
2736 err = -ENOMEM; 2737 err = pagecache_write_begin(NULL, mapping, 0, len-1,
2737 page = find_or_create_page(mapping, 0, gfp_mask); 2738 AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata);
2738 if (!page)
2739 goto fail;
2740 err = mapping->a_ops->prepare_write(NULL, page, 0, len-1);
2741 if (err == AOP_TRUNCATED_PAGE) {
2742 page_cache_release(page);
2743 goto retry;
2744 }
2745 if (err) 2739 if (err)
2746 goto fail_map; 2740 goto fail;
2741
2747 kaddr = kmap_atomic(page, KM_USER0); 2742 kaddr = kmap_atomic(page, KM_USER0);
2748 memcpy(kaddr, symname, len-1); 2743 memcpy(kaddr, symname, len-1);
2749 kunmap_atomic(kaddr, KM_USER0); 2744 kunmap_atomic(kaddr, KM_USER0);
2750 err = mapping->a_ops->commit_write(NULL, page, 0, len-1); 2745
2751 if (err == AOP_TRUNCATED_PAGE) { 2746 err = pagecache_write_end(NULL, mapping, 0, len-1, len-1,
2752 page_cache_release(page); 2747 page, fsdata);
2753 goto retry;
2754 }
2755 if (err)
2756 goto fail_map;
2757 /*
2758 * Notice that we are _not_ going to block here - end of page is
2759 * unmapped, so this will only try to map the rest of page, see
2760 * that it is unmapped (typically even will not look into inode -
2761 * ->i_size will be enough for everything) and zero it out.
2762 * OTOH it's obviously correct and should make the page up-to-date.
2763 */
2764 if (!PageUptodate(page)) {
2765 err = mapping->a_ops->readpage(NULL, page);
2766 if (err != AOP_TRUNCATED_PAGE)
2767 wait_on_page_locked(page);
2768 } else {
2769 unlock_page(page);
2770 }
2771 page_cache_release(page);
2772 if (err < 0) 2748 if (err < 0)
2773 goto fail; 2749 goto fail;
2750 if (err < len-1)
2751 goto retry;
2752
2774 mark_inode_dirty(inode); 2753 mark_inode_dirty(inode);
2775 return 0; 2754 return 0;
2776fail_map:
2777 unlock_page(page);
2778 page_cache_release(page);
2779fail: 2755fail:
2780 return err; 2756 return err;
2781} 2757}
diff --git a/fs/nfs/file.c b/fs/nfs/file.c
index 08c7c7387fce..d29f90d00aa2 100644
--- a/fs/nfs/file.c
+++ b/fs/nfs/file.c
@@ -306,27 +306,50 @@ nfs_fsync(struct file *file, struct dentry *dentry, int datasync)
306} 306}
307 307
308/* 308/*
309 * This does the "real" work of the write. The generic routine has 309 * This does the "real" work of the write. We must allocate and lock the
310 * allocated the page, locked it, done all the page alignment stuff 310 * page to be sent back to the generic routine, which then copies the
311 * calculations etc. Now we should just copy the data from user 311 * data from user space.
312 * space and write it back to the real medium..
313 * 312 *
314 * If the writer ends up delaying the write, the writer needs to 313 * If the writer ends up delaying the write, the writer needs to
315 * increment the page use counts until he is done with the page. 314 * increment the page use counts until he is done with the page.
316 */ 315 */
317static int nfs_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) 316static int nfs_write_begin(struct file *file, struct address_space *mapping,
317 loff_t pos, unsigned len, unsigned flags,
318 struct page **pagep, void **fsdata)
318{ 319{
319 return nfs_flush_incompatible(file, page); 320 int ret;
321 pgoff_t index;
322 struct page *page;
323 index = pos >> PAGE_CACHE_SHIFT;
324
325 page = __grab_cache_page(mapping, index);
326 if (!page)
327 return -ENOMEM;
328 *pagep = page;
329
330 ret = nfs_flush_incompatible(file, page);
331 if (ret) {
332 unlock_page(page);
333 page_cache_release(page);
334 }
335 return ret;
320} 336}
321 337
322static int nfs_commit_write(struct file *file, struct page *page, unsigned offset, unsigned to) 338static int nfs_write_end(struct file *file, struct address_space *mapping,
339 loff_t pos, unsigned len, unsigned copied,
340 struct page *page, void *fsdata)
323{ 341{
324 long status; 342 unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
343 int status;
325 344
326 lock_kernel(); 345 lock_kernel();
327 status = nfs_updatepage(file, page, offset, to-offset); 346 status = nfs_updatepage(file, page, offset, copied);
328 unlock_kernel(); 347 unlock_kernel();
329 return status; 348
349 unlock_page(page);
350 page_cache_release(page);
351
352 return status < 0 ? status : copied;
330} 353}
331 354
332static void nfs_invalidate_page(struct page *page, unsigned long offset) 355static void nfs_invalidate_page(struct page *page, unsigned long offset)
@@ -354,8 +377,8 @@ const struct address_space_operations nfs_file_aops = {
354 .set_page_dirty = __set_page_dirty_nobuffers, 377 .set_page_dirty = __set_page_dirty_nobuffers,
355 .writepage = nfs_writepage, 378 .writepage = nfs_writepage,
356 .writepages = nfs_writepages, 379 .writepages = nfs_writepages,
357 .prepare_write = nfs_prepare_write, 380 .write_begin = nfs_write_begin,
358 .commit_write = nfs_commit_write, 381 .write_end = nfs_write_end,
359 .invalidatepage = nfs_invalidate_page, 382 .invalidatepage = nfs_invalidate_page,
360 .releasepage = nfs_release_page, 383 .releasepage = nfs_release_page,
361#ifdef CONFIG_NFS_DIRECTIO 384#ifdef CONFIG_NFS_DIRECTIO
@@ -369,18 +392,35 @@ static int nfs_vm_page_mkwrite(struct vm_area_struct *vma, struct page *page)
369 struct file *filp = vma->vm_file; 392 struct file *filp = vma->vm_file;
370 unsigned pagelen; 393 unsigned pagelen;
371 int ret = -EINVAL; 394 int ret = -EINVAL;
395 void *fsdata;
396 struct address_space *mapping;
397 loff_t offset;
372 398
373 lock_page(page); 399 lock_page(page);
374 if (page->mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) 400 mapping = page->mapping;
375 goto out_unlock; 401 if (mapping != vma->vm_file->f_path.dentry->d_inode->i_mapping) {
402 unlock_page(page);
403 return -EINVAL;
404 }
376 pagelen = nfs_page_length(page); 405 pagelen = nfs_page_length(page);
377 if (pagelen == 0) 406 offset = (loff_t)page->index << PAGE_CACHE_SHIFT;
378 goto out_unlock;
379 ret = nfs_prepare_write(filp, page, 0, pagelen);
380 if (!ret)
381 ret = nfs_commit_write(filp, page, 0, pagelen);
382out_unlock:
383 unlock_page(page); 407 unlock_page(page);
408
409 /*
410 * we can use mapping after releasing the page lock, because:
411 * we hold mmap_sem on the fault path, which should pin the vma
412 * which should pin the file, which pins the dentry which should
413 * hold a reference on inode.
414 */
415
416 if (pagelen) {
417 struct page *page2 = NULL;
418 ret = nfs_write_begin(filp, mapping, offset, pagelen,
419 0, &page2, &fsdata);
420 if (!ret)
421 ret = nfs_write_end(filp, mapping, offset, pagelen,
422 pagelen, page2, fsdata);
423 }
384 return ret; 424 return ret;
385} 425}
386 426
diff --git a/fs/nfsd/export.c b/fs/nfsd/export.c
index cba899a3494e..04b266729802 100644
--- a/fs/nfsd/export.c
+++ b/fs/nfsd/export.c
@@ -861,9 +861,9 @@ exp_get_fsid_key(svc_client *clp, int fsid)
861 return exp_find_key(clp, FSID_NUM, fsidv, NULL); 861 return exp_find_key(clp, FSID_NUM, fsidv, NULL);
862} 862}
863 863
864svc_export * 864static svc_export *exp_get_by_name(svc_client *clp, struct vfsmount *mnt,
865exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry, 865 struct dentry *dentry,
866 struct cache_req *reqp) 866 struct cache_req *reqp)
867{ 867{
868 struct svc_export *exp, key; 868 struct svc_export *exp, key;
869 int err; 869 int err;
@@ -887,9 +887,9 @@ exp_get_by_name(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry,
887/* 887/*
888 * Find the export entry for a given dentry. 888 * Find the export entry for a given dentry.
889 */ 889 */
890struct svc_export * 890static struct svc_export *exp_parent(svc_client *clp, struct vfsmount *mnt,
891exp_parent(svc_client *clp, struct vfsmount *mnt, struct dentry *dentry, 891 struct dentry *dentry,
892 struct cache_req *reqp) 892 struct cache_req *reqp)
893{ 893{
894 svc_export *exp; 894 svc_export *exp;
895 895
@@ -1214,9 +1214,8 @@ out:
1214 return err; 1214 return err;
1215} 1215}
1216 1216
1217struct svc_export * 1217static struct svc_export *exp_find(struct auth_domain *clp, int fsid_type,
1218exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv, 1218 u32 *fsidv, struct cache_req *reqp)
1219 struct cache_req *reqp)
1220{ 1219{
1221 struct svc_export *exp; 1220 struct svc_export *exp;
1222 struct svc_expkey *ek = exp_find_key(clp, fsid_type, fsidv, reqp); 1221 struct svc_expkey *ek = exp_find_key(clp, fsid_type, fsidv, reqp);
diff --git a/fs/ocfs2/aops.c b/fs/ocfs2/aops.c
index 34d10452c56d..c69c1b300155 100644
--- a/fs/ocfs2/aops.c
+++ b/fs/ocfs2/aops.c
@@ -1724,9 +1724,9 @@ out:
1724 return ret; 1724 return ret;
1725} 1725}
1726 1726
1727int ocfs2_write_begin(struct file *file, struct address_space *mapping, 1727static int ocfs2_write_begin(struct file *file, struct address_space *mapping,
1728 loff_t pos, unsigned len, unsigned flags, 1728 loff_t pos, unsigned len, unsigned flags,
1729 struct page **pagep, void **fsdata) 1729 struct page **pagep, void **fsdata)
1730{ 1730{
1731 int ret; 1731 int ret;
1732 struct buffer_head *di_bh = NULL; 1732 struct buffer_head *di_bh = NULL;
@@ -1877,9 +1877,9 @@ out_write_size:
1877 return copied; 1877 return copied;
1878} 1878}
1879 1879
1880int ocfs2_write_end(struct file *file, struct address_space *mapping, 1880static int ocfs2_write_end(struct file *file, struct address_space *mapping,
1881 loff_t pos, unsigned len, unsigned copied, 1881 loff_t pos, unsigned len, unsigned copied,
1882 struct page *page, void *fsdata) 1882 struct page *page, void *fsdata)
1883{ 1883{
1884 int ret; 1884 int ret;
1885 struct inode *inode = mapping->host; 1885 struct inode *inode = mapping->host;
@@ -1896,6 +1896,8 @@ int ocfs2_write_end(struct file *file, struct address_space *mapping,
1896const struct address_space_operations ocfs2_aops = { 1896const struct address_space_operations ocfs2_aops = {
1897 .readpage = ocfs2_readpage, 1897 .readpage = ocfs2_readpage,
1898 .writepage = ocfs2_writepage, 1898 .writepage = ocfs2_writepage,
1899 .write_begin = ocfs2_write_begin,
1900 .write_end = ocfs2_write_end,
1899 .bmap = ocfs2_bmap, 1901 .bmap = ocfs2_bmap,
1900 .sync_page = block_sync_page, 1902 .sync_page = block_sync_page,
1901 .direct_IO = ocfs2_direct_IO, 1903 .direct_IO = ocfs2_direct_IO,
diff --git a/fs/ocfs2/aops.h b/fs/ocfs2/aops.h
index 113560877dbb..503e49232e11 100644
--- a/fs/ocfs2/aops.h
+++ b/fs/ocfs2/aops.h
@@ -44,14 +44,6 @@ int walk_page_buffers( handle_t *handle,
44 int (*fn)( handle_t *handle, 44 int (*fn)( handle_t *handle,
45 struct buffer_head *bh)); 45 struct buffer_head *bh));
46 46
47int ocfs2_write_begin(struct file *file, struct address_space *mapping,
48 loff_t pos, unsigned len, unsigned flags,
49 struct page **pagep, void **fsdata);
50
51int ocfs2_write_end(struct file *file, struct address_space *mapping,
52 loff_t pos, unsigned len, unsigned copied,
53 struct page *page, void *fsdata);
54
55int ocfs2_write_end_nolock(struct address_space *mapping, 47int ocfs2_write_end_nolock(struct address_space *mapping,
56 loff_t pos, unsigned len, unsigned copied, 48 loff_t pos, unsigned len, unsigned copied,
57 struct page *page, void *fsdata); 49 struct page *page, void *fsdata);
diff --git a/fs/ocfs2/file.c b/fs/ocfs2/file.c
index a62b14eb4065..f92fe91ff260 100644
--- a/fs/ocfs2/file.c
+++ b/fs/ocfs2/file.c
@@ -1881,143 +1881,13 @@ out:
1881 return ret; 1881 return ret;
1882} 1882}
1883 1883
1884static inline void
1885ocfs2_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes)
1886{
1887 const struct iovec *iov = *iovp;
1888 size_t base = *basep;
1889
1890 do {
1891 int copy = min(bytes, iov->iov_len - base);
1892
1893 bytes -= copy;
1894 base += copy;
1895 if (iov->iov_len == base) {
1896 iov++;
1897 base = 0;
1898 }
1899 } while (bytes);
1900 *iovp = iov;
1901 *basep = base;
1902}
1903
1904static struct page * ocfs2_get_write_source(char **ret_src_buf,
1905 const struct iovec *cur_iov,
1906 size_t iov_offset)
1907{
1908 int ret;
1909 char *buf = cur_iov->iov_base + iov_offset;
1910 struct page *src_page = NULL;
1911 unsigned long off;
1912
1913 off = (unsigned long)(buf) & ~PAGE_CACHE_MASK;
1914
1915 if (!segment_eq(get_fs(), KERNEL_DS)) {
1916 /*
1917 * Pull in the user page. We want to do this outside
1918 * of the meta data locks in order to preserve locking
1919 * order in case of page fault.
1920 */
1921 ret = get_user_pages(current, current->mm,
1922 (unsigned long)buf & PAGE_CACHE_MASK, 1,
1923 0, 0, &src_page, NULL);
1924 if (ret == 1)
1925 *ret_src_buf = kmap(src_page) + off;
1926 else
1927 src_page = ERR_PTR(-EFAULT);
1928 } else {
1929 *ret_src_buf = buf;
1930 }
1931
1932 return src_page;
1933}
1934
1935static void ocfs2_put_write_source(struct page *page)
1936{
1937 if (page) {
1938 kunmap(page);
1939 page_cache_release(page);
1940 }
1941}
1942
1943static ssize_t ocfs2_file_buffered_write(struct file *file, loff_t *ppos,
1944 const struct iovec *iov,
1945 unsigned long nr_segs,
1946 size_t count,
1947 ssize_t o_direct_written)
1948{
1949 int ret = 0;
1950 ssize_t copied, total = 0;
1951 size_t iov_offset = 0, bytes;
1952 loff_t pos;
1953 const struct iovec *cur_iov = iov;
1954 struct page *user_page, *page;
1955 char * uninitialized_var(buf);
1956 char *dst;
1957 void *fsdata;
1958
1959 /*
1960 * handle partial DIO write. Adjust cur_iov if needed.
1961 */
1962 ocfs2_set_next_iovec(&cur_iov, &iov_offset, o_direct_written);
1963
1964 do {
1965 pos = *ppos;
1966
1967 user_page = ocfs2_get_write_source(&buf, cur_iov, iov_offset);
1968 if (IS_ERR(user_page)) {
1969 ret = PTR_ERR(user_page);
1970 goto out;
1971 }
1972
1973 /* Stay within our page boundaries */
1974 bytes = min((PAGE_CACHE_SIZE - ((unsigned long)pos & ~PAGE_CACHE_MASK)),
1975 (PAGE_CACHE_SIZE - ((unsigned long)buf & ~PAGE_CACHE_MASK)));
1976 /* Stay within the vector boundary */
1977 bytes = min_t(size_t, bytes, cur_iov->iov_len - iov_offset);
1978 /* Stay within count */
1979 bytes = min(bytes, count);
1980
1981 page = NULL;
1982 ret = ocfs2_write_begin(file, file->f_mapping, pos, bytes, 0,
1983 &page, &fsdata);
1984 if (ret) {
1985 mlog_errno(ret);
1986 goto out;
1987 }
1988
1989 dst = kmap_atomic(page, KM_USER0);
1990 memcpy(dst + (pos & (loff_t)(PAGE_CACHE_SIZE - 1)), buf, bytes);
1991 kunmap_atomic(dst, KM_USER0);
1992 flush_dcache_page(page);
1993 ocfs2_put_write_source(user_page);
1994
1995 copied = ocfs2_write_end(file, file->f_mapping, pos, bytes,
1996 bytes, page, fsdata);
1997 if (copied < 0) {
1998 mlog_errno(copied);
1999 ret = copied;
2000 goto out;
2001 }
2002
2003 total += copied;
2004 *ppos = pos + copied;
2005 count -= copied;
2006
2007 ocfs2_set_next_iovec(&cur_iov, &iov_offset, copied);
2008 } while(count);
2009
2010out:
2011 return total ? total : ret;
2012}
2013
2014static ssize_t ocfs2_file_aio_write(struct kiocb *iocb, 1884static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
2015 const struct iovec *iov, 1885 const struct iovec *iov,
2016 unsigned long nr_segs, 1886 unsigned long nr_segs,
2017 loff_t pos) 1887 loff_t pos)
2018{ 1888{
2019 int ret, direct_io, appending, rw_level, have_alloc_sem = 0; 1889 int ret, direct_io, appending, rw_level, have_alloc_sem = 0;
2020 int can_do_direct, sync = 0; 1890 int can_do_direct;
2021 ssize_t written = 0; 1891 ssize_t written = 0;
2022 size_t ocount; /* original count */ 1892 size_t ocount; /* original count */
2023 size_t count; /* after file limit checks */ 1893 size_t count; /* after file limit checks */
@@ -2033,12 +1903,6 @@ static ssize_t ocfs2_file_aio_write(struct kiocb *iocb,
2033 if (iocb->ki_left == 0) 1903 if (iocb->ki_left == 0)
2034 return 0; 1904 return 0;
2035 1905
2036 ret = generic_segment_checks(iov, &nr_segs, &ocount, VERIFY_READ);
2037 if (ret)
2038 return ret;
2039
2040 count = ocount;
2041
2042 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE); 1906 vfs_check_frozen(inode->i_sb, SB_FREEZE_WRITE);
2043 1907
2044 appending = file->f_flags & O_APPEND ? 1 : 0; 1908 appending = file->f_flags & O_APPEND ? 1 : 0;
@@ -2082,33 +1946,23 @@ relock:
2082 rw_level = -1; 1946 rw_level = -1;
2083 1947
2084 direct_io = 0; 1948 direct_io = 0;
2085 sync = 1;
2086 goto relock; 1949 goto relock;
2087 } 1950 }
2088 1951
2089 if (!sync && ((file->f_flags & O_SYNC) || IS_SYNC(inode)))
2090 sync = 1;
2091
2092 /*
2093 * XXX: Is it ok to execute these checks a second time?
2094 */
2095 ret = generic_write_checks(file, ppos, &count, S_ISBLK(inode->i_mode));
2096 if (ret)
2097 goto out;
2098
2099 /*
2100 * Set pos so that sync_page_range_nolock() below understands
2101 * where to start from. We might've moved it around via the
2102 * calls above. The range we want to actually sync starts from
2103 * *ppos here.
2104 *
2105 */
2106 pos = *ppos;
2107
2108 /* communicate with ocfs2_dio_end_io */ 1952 /* communicate with ocfs2_dio_end_io */
2109 ocfs2_iocb_set_rw_locked(iocb, rw_level); 1953 ocfs2_iocb_set_rw_locked(iocb, rw_level);
2110 1954
2111 if (direct_io) { 1955 if (direct_io) {
1956 ret = generic_segment_checks(iov, &nr_segs, &ocount,
1957 VERIFY_READ);
1958 if (ret)
1959 goto out_dio;
1960
1961 ret = generic_write_checks(file, ppos, &count,
1962 S_ISBLK(inode->i_mode));
1963 if (ret)
1964 goto out_dio;
1965
2112 written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos, 1966 written = generic_file_direct_write(iocb, iov, &nr_segs, *ppos,
2113 ppos, count, ocount); 1967 ppos, count, ocount);
2114 if (written < 0) { 1968 if (written < 0) {
@@ -2116,14 +1970,8 @@ relock:
2116 goto out_dio; 1970 goto out_dio;
2117 } 1971 }
2118 } else { 1972 } else {
2119 written = ocfs2_file_buffered_write(file, ppos, iov, nr_segs, 1973 written = generic_file_aio_write_nolock(iocb, iov, nr_segs,
2120 count, written); 1974 *ppos);
2121 if (written < 0) {
2122 ret = written;
2123 if (ret != -EFAULT || ret != -ENOSPC)
2124 mlog_errno(ret);
2125 goto out;
2126 }
2127 } 1975 }
2128 1976
2129out_dio: 1977out_dio:
@@ -2153,97 +2001,12 @@ out_sems:
2153 if (have_alloc_sem) 2001 if (have_alloc_sem)
2154 up_read(&inode->i_alloc_sem); 2002 up_read(&inode->i_alloc_sem);
2155 2003
2156 if (written > 0 && sync) {
2157 ssize_t err;
2158
2159 err = sync_page_range_nolock(inode, file->f_mapping, pos, count);
2160 if (err < 0)
2161 written = err;
2162 }
2163
2164 mutex_unlock(&inode->i_mutex); 2004 mutex_unlock(&inode->i_mutex);
2165 2005
2166 mlog_exit(ret); 2006 mlog_exit(ret);
2167 return written ? written : ret; 2007 return written ? written : ret;
2168} 2008}
2169 2009
2170static int ocfs2_splice_write_actor(struct pipe_inode_info *pipe,
2171 struct pipe_buffer *buf,
2172 struct splice_desc *sd)
2173{
2174 int ret, count;
2175 ssize_t copied = 0;
2176 struct file *file = sd->u.file;
2177 unsigned int offset;
2178 struct page *page = NULL;
2179 void *fsdata;
2180 char *src, *dst;
2181
2182 ret = buf->ops->confirm(pipe, buf);
2183 if (ret)
2184 goto out;
2185
2186 offset = sd->pos & ~PAGE_CACHE_MASK;
2187 count = sd->len;
2188 if (count + offset > PAGE_CACHE_SIZE)
2189 count = PAGE_CACHE_SIZE - offset;
2190
2191 ret = ocfs2_write_begin(file, file->f_mapping, sd->pos, count, 0,
2192 &page, &fsdata);
2193 if (ret) {
2194 mlog_errno(ret);
2195 goto out;
2196 }
2197
2198 src = buf->ops->map(pipe, buf, 1);
2199 dst = kmap_atomic(page, KM_USER1);
2200 memcpy(dst + offset, src + buf->offset, count);
2201 kunmap_atomic(dst, KM_USER1);
2202 buf->ops->unmap(pipe, buf, src);
2203
2204 copied = ocfs2_write_end(file, file->f_mapping, sd->pos, count, count,
2205 page, fsdata);
2206 if (copied < 0) {
2207 mlog_errno(copied);
2208 ret = copied;
2209 goto out;
2210 }
2211out:
2212
2213 return copied ? copied : ret;
2214}
2215
2216static ssize_t __ocfs2_file_splice_write(struct pipe_inode_info *pipe,
2217 struct file *out,
2218 loff_t *ppos,
2219 size_t len,
2220 unsigned int flags)
2221{
2222 int ret, err;
2223 struct address_space *mapping = out->f_mapping;
2224 struct inode *inode = mapping->host;
2225 struct splice_desc sd = {
2226 .total_len = len,
2227 .flags = flags,
2228 .pos = *ppos,
2229 .u.file = out,
2230 };
2231
2232 ret = __splice_from_pipe(pipe, &sd, ocfs2_splice_write_actor);
2233 if (ret > 0) {
2234 *ppos += ret;
2235
2236 if (unlikely((out->f_flags & O_SYNC) || IS_SYNC(inode))) {
2237 err = generic_osync_inode(inode, mapping,
2238 OSYNC_METADATA|OSYNC_DATA);
2239 if (err)
2240 ret = err;
2241 }
2242 }
2243
2244 return ret;
2245}
2246
2247static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe, 2010static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
2248 struct file *out, 2011 struct file *out,
2249 loff_t *ppos, 2012 loff_t *ppos,
@@ -2273,8 +2036,7 @@ static ssize_t ocfs2_file_splice_write(struct pipe_inode_info *pipe,
2273 goto out_unlock; 2036 goto out_unlock;
2274 } 2037 }
2275 2038
2276 /* ok, we're done with i_size and alloc work */ 2039 ret = generic_file_splice_write_nolock(pipe, out, ppos, len, flags);
2277 ret = __ocfs2_file_splice_write(pipe, out, ppos, len, flags);
2278 2040
2279out_unlock: 2041out_unlock:
2280 ocfs2_rw_unlock(inode, 1); 2042 ocfs2_rw_unlock(inode, 1);
diff --git a/fs/proc/base.c b/fs/proc/base.c
index e5d0953d4db1..78fdfea1a7f8 100644
--- a/fs/proc/base.c
+++ b/fs/proc/base.c
@@ -492,7 +492,7 @@ static ssize_t proc_info_read(struct file * file, char __user * buf,
492 count = PROC_BLOCK_SIZE; 492 count = PROC_BLOCK_SIZE;
493 493
494 length = -ENOMEM; 494 length = -ENOMEM;
495 if (!(page = __get_free_page(GFP_KERNEL))) 495 if (!(page = __get_free_page(GFP_TEMPORARY)))
496 goto out; 496 goto out;
497 497
498 length = PROC_I(inode)->op.proc_read(task, (char*)page); 498 length = PROC_I(inode)->op.proc_read(task, (char*)page);
@@ -532,7 +532,7 @@ static ssize_t mem_read(struct file * file, char __user * buf,
532 goto out; 532 goto out;
533 533
534 ret = -ENOMEM; 534 ret = -ENOMEM;
535 page = (char *)__get_free_page(GFP_USER); 535 page = (char *)__get_free_page(GFP_TEMPORARY);
536 if (!page) 536 if (!page)
537 goto out; 537 goto out;
538 538
@@ -602,7 +602,7 @@ static ssize_t mem_write(struct file * file, const char __user *buf,
602 goto out; 602 goto out;
603 603
604 copied = -ENOMEM; 604 copied = -ENOMEM;
605 page = (char *)__get_free_page(GFP_USER); 605 page = (char *)__get_free_page(GFP_TEMPORARY);
606 if (!page) 606 if (!page)
607 goto out; 607 goto out;
608 608
@@ -788,7 +788,7 @@ static ssize_t proc_loginuid_write(struct file * file, const char __user * buf,
788 /* No partial writes. */ 788 /* No partial writes. */
789 return -EINVAL; 789 return -EINVAL;
790 } 790 }
791 page = (char*)__get_free_page(GFP_USER); 791 page = (char*)__get_free_page(GFP_TEMPORARY);
792 if (!page) 792 if (!page)
793 return -ENOMEM; 793 return -ENOMEM;
794 length = -EFAULT; 794 length = -EFAULT;
@@ -954,7 +954,8 @@ static int do_proc_readlink(struct dentry *dentry, struct vfsmount *mnt,
954 char __user *buffer, int buflen) 954 char __user *buffer, int buflen)
955{ 955{
956 struct inode * inode; 956 struct inode * inode;
957 char *tmp = (char*)__get_free_page(GFP_KERNEL), *path; 957 char *tmp = (char*)__get_free_page(GFP_TEMPORARY);
958 char *path;
958 int len; 959 int len;
959 960
960 if (!tmp) 961 if (!tmp)
@@ -1726,7 +1727,7 @@ static ssize_t proc_pid_attr_write(struct file * file, const char __user * buf,
1726 goto out; 1727 goto out;
1727 1728
1728 length = -ENOMEM; 1729 length = -ENOMEM;
1729 page = (char*)__get_free_page(GFP_USER); 1730 page = (char*)__get_free_page(GFP_TEMPORARY);
1730 if (!page) 1731 if (!page)
1731 goto out; 1732 goto out;
1732 1733
diff --git a/fs/proc/generic.c b/fs/proc/generic.c
index b5e7155d30d8..1bdb62435758 100644
--- a/fs/proc/generic.c
+++ b/fs/proc/generic.c
@@ -74,7 +74,7 @@ proc_file_read(struct file *file, char __user *buf, size_t nbytes,
74 nbytes = MAX_NON_LFS - pos; 74 nbytes = MAX_NON_LFS - pos;
75 75
76 dp = PDE(inode); 76 dp = PDE(inode);
77 if (!(page = (char*) __get_free_page(GFP_KERNEL))) 77 if (!(page = (char*) __get_free_page(GFP_TEMPORARY)))
78 return -ENOMEM; 78 return -ENOMEM;
79 79
80 while ((nbytes > 0) && !eof) { 80 while ((nbytes > 0) && !eof) {
diff --git a/fs/proc/proc_misc.c b/fs/proc/proc_misc.c
index 0071939c0095..5de7f874d95c 100644
--- a/fs/proc/proc_misc.c
+++ b/fs/proc/proc_misc.c
@@ -229,6 +229,19 @@ static const struct file_operations fragmentation_file_operations = {
229 .release = seq_release, 229 .release = seq_release,
230}; 230};
231 231
232extern struct seq_operations pagetypeinfo_op;
233static int pagetypeinfo_open(struct inode *inode, struct file *file)
234{
235 return seq_open(file, &pagetypeinfo_op);
236}
237
238static const struct file_operations pagetypeinfo_file_ops = {
239 .open = pagetypeinfo_open,
240 .read = seq_read,
241 .llseek = seq_lseek,
242 .release = seq_release,
243};
244
232extern struct seq_operations zoneinfo_op; 245extern struct seq_operations zoneinfo_op;
233static int zoneinfo_open(struct inode *inode, struct file *file) 246static int zoneinfo_open(struct inode *inode, struct file *file)
234{ 247{
@@ -724,6 +737,7 @@ void __init proc_misc_init(void)
724#endif 737#endif
725#endif 738#endif
726 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations); 739 create_seq_entry("buddyinfo",S_IRUGO, &fragmentation_file_operations);
740 create_seq_entry("pagetypeinfo", S_IRUGO, &pagetypeinfo_file_ops);
727 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations); 741 create_seq_entry("vmstat",S_IRUGO, &proc_vmstat_file_operations);
728 create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations); 742 create_seq_entry("zoneinfo",S_IRUGO, &proc_zoneinfo_file_operations);
729#ifdef CONFIG_BLOCK 743#ifdef CONFIG_BLOCK
diff --git a/fs/qnx4/inode.c b/fs/qnx4/inode.c
index 1bc8d873a9e1..df8bd87e49b7 100644
--- a/fs/qnx4/inode.c
+++ b/fs/qnx4/inode.c
@@ -433,16 +433,21 @@ static int qnx4_writepage(struct page *page, struct writeback_control *wbc)
433{ 433{
434 return block_write_full_page(page,qnx4_get_block, wbc); 434 return block_write_full_page(page,qnx4_get_block, wbc);
435} 435}
436
436static int qnx4_readpage(struct file *file, struct page *page) 437static int qnx4_readpage(struct file *file, struct page *page)
437{ 438{
438 return block_read_full_page(page,qnx4_get_block); 439 return block_read_full_page(page,qnx4_get_block);
439} 440}
440static int qnx4_prepare_write(struct file *file, struct page *page, 441
441 unsigned from, unsigned to) 442static int qnx4_write_begin(struct file *file, struct address_space *mapping,
443 loff_t pos, unsigned len, unsigned flags,
444 struct page **pagep, void **fsdata)
442{ 445{
443 struct qnx4_inode_info *qnx4_inode = qnx4_i(page->mapping->host); 446 struct qnx4_inode_info *qnx4_inode = qnx4_i(mapping->host);
444 return cont_prepare_write(page, from, to, qnx4_get_block, 447 *pagep = NULL;
445 &qnx4_inode->mmu_private); 448 return cont_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
449 qnx4_get_block,
450 &qnx4_inode->mmu_private);
446} 451}
447static sector_t qnx4_bmap(struct address_space *mapping, sector_t block) 452static sector_t qnx4_bmap(struct address_space *mapping, sector_t block)
448{ 453{
@@ -452,8 +457,8 @@ static const struct address_space_operations qnx4_aops = {
452 .readpage = qnx4_readpage, 457 .readpage = qnx4_readpage,
453 .writepage = qnx4_writepage, 458 .writepage = qnx4_writepage,
454 .sync_page = block_sync_page, 459 .sync_page = block_sync_page,
455 .prepare_write = qnx4_prepare_write, 460 .write_begin = qnx4_write_begin,
456 .commit_write = generic_commit_write, 461 .write_end = generic_write_end,
457 .bmap = qnx4_bmap 462 .bmap = qnx4_bmap
458}; 463};
459 464
diff --git a/fs/ramfs/file-mmu.c b/fs/ramfs/file-mmu.c
index 97bdc0b2f9d2..b41a514b0976 100644
--- a/fs/ramfs/file-mmu.c
+++ b/fs/ramfs/file-mmu.c
@@ -29,8 +29,8 @@
29 29
30const struct address_space_operations ramfs_aops = { 30const struct address_space_operations ramfs_aops = {
31 .readpage = simple_readpage, 31 .readpage = simple_readpage,
32 .prepare_write = simple_prepare_write, 32 .write_begin = simple_write_begin,
33 .commit_write = simple_commit_write, 33 .write_end = simple_write_end,
34 .set_page_dirty = __set_page_dirty_no_writeback, 34 .set_page_dirty = __set_page_dirty_no_writeback,
35}; 35};
36 36
diff --git a/fs/ramfs/file-nommu.c b/fs/ramfs/file-nommu.c
index 237fe8b8e819..0989bc2c2f69 100644
--- a/fs/ramfs/file-nommu.c
+++ b/fs/ramfs/file-nommu.c
@@ -29,8 +29,8 @@ static int ramfs_nommu_setattr(struct dentry *, struct iattr *);
29 29
30const struct address_space_operations ramfs_aops = { 30const struct address_space_operations ramfs_aops = {
31 .readpage = simple_readpage, 31 .readpage = simple_readpage,
32 .prepare_write = simple_prepare_write, 32 .write_begin = simple_write_begin,
33 .commit_write = simple_commit_write, 33 .write_end = simple_write_end,
34 .set_page_dirty = __set_page_dirty_no_writeback, 34 .set_page_dirty = __set_page_dirty_no_writeback,
35}; 35};
36 36
diff --git a/fs/reiserfs/file.c b/fs/reiserfs/file.c
index 2070aeee2a52..a804903d31d1 100644
--- a/fs/reiserfs/file.c
+++ b/fs/reiserfs/file.c
@@ -153,608 +153,6 @@ static int reiserfs_sync_file(struct file *p_s_filp,
153 return (n_err < 0) ? -EIO : 0; 153 return (n_err < 0) ? -EIO : 0;
154} 154}
155 155
156/* I really do not want to play with memory shortage right now, so
157 to simplify the code, we are not going to write more than this much pages at
158 a time. This still should considerably improve performance compared to 4k
159 at a time case. This is 32 pages of 4k size. */
160#define REISERFS_WRITE_PAGES_AT_A_TIME (128 * 1024) / PAGE_CACHE_SIZE
161
162/* Allocates blocks for a file to fulfil write request.
163 Maps all unmapped but prepared pages from the list.
164 Updates metadata with newly allocated blocknumbers as needed */
165static int reiserfs_allocate_blocks_for_region(struct reiserfs_transaction_handle *th, struct inode *inode, /* Inode we work with */
166 loff_t pos, /* Writing position */
167 int num_pages, /* number of pages write going
168 to touch */
169 int write_bytes, /* amount of bytes to write */
170 struct page **prepared_pages, /* array of
171 prepared pages
172 */
173 int blocks_to_allocate /* Amount of blocks we
174 need to allocate to
175 fit the data into file
176 */
177 )
178{
179 struct cpu_key key; // cpu key of item that we are going to deal with
180 struct item_head *ih; // pointer to item head that we are going to deal with
181 struct buffer_head *bh; // Buffer head that contains items that we are going to deal with
182 __le32 *item; // pointer to item we are going to deal with
183 INITIALIZE_PATH(path); // path to item, that we are going to deal with.
184 b_blocknr_t *allocated_blocks; // Pointer to a place where allocated blocknumbers would be stored.
185 reiserfs_blocknr_hint_t hint; // hint structure for block allocator.
186 size_t res; // return value of various functions that we call.
187 int curr_block; // current block used to keep track of unmapped blocks.
188 int i; // loop counter
189 int itempos; // position in item
190 unsigned int from = (pos & (PAGE_CACHE_SIZE - 1)); // writing position in
191 // first page
192 unsigned int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1; /* last modified byte offset in last page */
193 __u64 hole_size; // amount of blocks for a file hole, if it needed to be created.
194 int modifying_this_item = 0; // Flag for items traversal code to keep track
195 // of the fact that we already prepared
196 // current block for journal
197 int will_prealloc = 0;
198 RFALSE(!blocks_to_allocate,
199 "green-9004: tried to allocate zero blocks?");
200
201 /* only preallocate if this is a small write */
202 if (REISERFS_I(inode)->i_prealloc_count ||
203 (!(write_bytes & (inode->i_sb->s_blocksize - 1)) &&
204 blocks_to_allocate <
205 REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize))
206 will_prealloc =
207 REISERFS_SB(inode->i_sb)->s_alloc_options.preallocsize;
208
209 allocated_blocks = kmalloc((blocks_to_allocate + will_prealloc) *
210 sizeof(b_blocknr_t), GFP_NOFS);
211 if (!allocated_blocks)
212 return -ENOMEM;
213
214 /* First we compose a key to point at the writing position, we want to do
215 that outside of any locking region. */
216 make_cpu_key(&key, inode, pos + 1, TYPE_ANY, 3 /*key length */ );
217
218 /* If we came here, it means we absolutely need to open a transaction,
219 since we need to allocate some blocks */
220 reiserfs_write_lock(inode->i_sb); // Journaling stuff and we need that.
221 res = journal_begin(th, inode->i_sb, JOURNAL_PER_BALANCE_CNT * 3 + 1 + 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb)); // Wish I know if this number enough
222 if (res)
223 goto error_exit;
224 reiserfs_update_inode_transaction(inode);
225
226 /* Look for the in-tree position of our write, need path for block allocator */
227 res = search_for_position_by_key(inode->i_sb, &key, &path);
228 if (res == IO_ERROR) {
229 res = -EIO;
230 goto error_exit;
231 }
232
233 /* Allocate blocks */
234 /* First fill in "hint" structure for block allocator */
235 hint.th = th; // transaction handle.
236 hint.path = &path; // Path, so that block allocator can determine packing locality or whatever it needs to determine.
237 hint.inode = inode; // Inode is needed by block allocator too.
238 hint.search_start = 0; // We have no hint on where to search free blocks for block allocator.
239 hint.key = key.on_disk_key; // on disk key of file.
240 hint.block = inode->i_blocks >> (inode->i_sb->s_blocksize_bits - 9); // Number of disk blocks this file occupies already.
241 hint.formatted_node = 0; // We are allocating blocks for unformatted node.
242 hint.preallocate = will_prealloc;
243
244 /* Call block allocator to allocate blocks */
245 res =
246 reiserfs_allocate_blocknrs(&hint, allocated_blocks,
247 blocks_to_allocate, blocks_to_allocate);
248 if (res != CARRY_ON) {
249 if (res == NO_DISK_SPACE) {
250 /* We flush the transaction in case of no space. This way some
251 blocks might become free */
252 SB_JOURNAL(inode->i_sb)->j_must_wait = 1;
253 res = restart_transaction(th, inode, &path);
254 if (res)
255 goto error_exit;
256
257 /* We might have scheduled, so search again */
258 res =
259 search_for_position_by_key(inode->i_sb, &key,
260 &path);
261 if (res == IO_ERROR) {
262 res = -EIO;
263 goto error_exit;
264 }
265
266 /* update changed info for hint structure. */
267 res =
268 reiserfs_allocate_blocknrs(&hint, allocated_blocks,
269 blocks_to_allocate,
270 blocks_to_allocate);
271 if (res != CARRY_ON) {
272 res = res == QUOTA_EXCEEDED ? -EDQUOT : -ENOSPC;
273 pathrelse(&path);
274 goto error_exit;
275 }
276 } else {
277 res = res == QUOTA_EXCEEDED ? -EDQUOT : -ENOSPC;
278 pathrelse(&path);
279 goto error_exit;
280 }
281 }
282#ifdef __BIG_ENDIAN
283 // Too bad, I have not found any way to convert a given region from
284 // cpu format to little endian format
285 {
286 int i;
287 for (i = 0; i < blocks_to_allocate; i++)
288 allocated_blocks[i] = cpu_to_le32(allocated_blocks[i]);
289 }
290#endif
291
292 /* Blocks allocating well might have scheduled and tree might have changed,
293 let's search the tree again */
294 /* find where in the tree our write should go */
295 res = search_for_position_by_key(inode->i_sb, &key, &path);
296 if (res == IO_ERROR) {
297 res = -EIO;
298 goto error_exit_free_blocks;
299 }
300
301 bh = get_last_bh(&path); // Get a bufferhead for last element in path.
302 ih = get_ih(&path); // Get a pointer to last item head in path.
303 item = get_item(&path); // Get a pointer to last item in path
304
305 /* Let's see what we have found */
306 if (res != POSITION_FOUND) { /* position not found, this means that we
307 might need to append file with holes
308 first */
309 // Since we are writing past the file's end, we need to find out if
310 // there is a hole that needs to be inserted before our writing
311 // position, and how many blocks it is going to cover (we need to
312 // populate pointers to file blocks representing the hole with zeros)
313
314 {
315 int item_offset = 1;
316 /*
317 * if ih is stat data, its offset is 0 and we don't want to
318 * add 1 to pos in the hole_size calculation
319 */
320 if (is_statdata_le_ih(ih))
321 item_offset = 0;
322 hole_size = (pos + item_offset -
323 (le_key_k_offset
324 (get_inode_item_key_version(inode),
325 &(ih->ih_key)) + op_bytes_number(ih,
326 inode->
327 i_sb->
328 s_blocksize)))
329 >> inode->i_sb->s_blocksize_bits;
330 }
331
332 if (hole_size > 0) {
333 int to_paste = min_t(__u64, hole_size, MAX_ITEM_LEN(inode->i_sb->s_blocksize) / UNFM_P_SIZE); // How much data to insert first time.
334 /* area filled with zeroes, to supply as list of zero blocknumbers
335 We allocate it outside of loop just in case loop would spin for
336 several iterations. */
337 char *zeros = kzalloc(to_paste * UNFM_P_SIZE, GFP_ATOMIC); // We cannot insert more than MAX_ITEM_LEN bytes anyway.
338 if (!zeros) {
339 res = -ENOMEM;
340 goto error_exit_free_blocks;
341 }
342 do {
343 to_paste =
344 min_t(__u64, hole_size,
345 MAX_ITEM_LEN(inode->i_sb->
346 s_blocksize) /
347 UNFM_P_SIZE);
348 if (is_indirect_le_ih(ih)) {
349 /* Ok, there is existing indirect item already. Need to append it */
350 /* Calculate position past inserted item */
351 make_cpu_key(&key, inode,
352 le_key_k_offset
353 (get_inode_item_key_version
354 (inode),
355 &(ih->ih_key)) +
356 op_bytes_number(ih,
357 inode->
358 i_sb->
359 s_blocksize),
360 TYPE_INDIRECT, 3);
361 res =
362 reiserfs_paste_into_item(th, &path,
363 &key,
364 inode,
365 (char *)
366 zeros,
367 UNFM_P_SIZE
368 *
369 to_paste);
370 if (res) {
371 kfree(zeros);
372 goto error_exit_free_blocks;
373 }
374 } else if (is_statdata_le_ih(ih)) {
375 /* No existing item, create it */
376 /* item head for new item */
377 struct item_head ins_ih;
378
379 /* create a key for our new item */
380 make_cpu_key(&key, inode, 1,
381 TYPE_INDIRECT, 3);
382
383 /* Create new item head for our new item */
384 make_le_item_head(&ins_ih, &key,
385 key.version, 1,
386 TYPE_INDIRECT,
387 to_paste *
388 UNFM_P_SIZE,
389 0 /* free space */ );
390
391 /* Find where such item should live in the tree */
392 res =
393 search_item(inode->i_sb, &key,
394 &path);
395 if (res != ITEM_NOT_FOUND) {
396 /* item should not exist, otherwise we have error */
397 if (res != -ENOSPC) {
398 reiserfs_warning(inode->
399 i_sb,
400 "green-9008: search_by_key (%K) returned %d",
401 &key,
402 res);
403 }
404 res = -EIO;
405 kfree(zeros);
406 goto error_exit_free_blocks;
407 }
408 res =
409 reiserfs_insert_item(th, &path,
410 &key, &ins_ih,
411 inode,
412 (char *)zeros);
413 } else {
414 reiserfs_panic(inode->i_sb,
415 "green-9011: Unexpected key type %K\n",
416 &key);
417 }
418 if (res) {
419 kfree(zeros);
420 goto error_exit_free_blocks;
421 }
422 /* Now we want to check if transaction is too full, and if it is
423 we restart it. This will also free the path. */
424 if (journal_transaction_should_end
425 (th, th->t_blocks_allocated)) {
426 inode->i_size = cpu_key_k_offset(&key) +
427 (to_paste << inode->i_blkbits);
428 res =
429 restart_transaction(th, inode,
430 &path);
431 if (res) {
432 pathrelse(&path);
433 kfree(zeros);
434 goto error_exit;
435 }
436 }
437
438 /* Well, need to recalculate path and stuff */
439 set_cpu_key_k_offset(&key,
440 cpu_key_k_offset(&key) +
441 (to_paste << inode->
442 i_blkbits));
443 res =
444 search_for_position_by_key(inode->i_sb,
445 &key, &path);
446 if (res == IO_ERROR) {
447 res = -EIO;
448 kfree(zeros);
449 goto error_exit_free_blocks;
450 }
451 bh = get_last_bh(&path);
452 ih = get_ih(&path);
453 item = get_item(&path);
454 hole_size -= to_paste;
455 } while (hole_size);
456 kfree(zeros);
457 }
458 }
459 // Go through existing indirect items first
460 // replace all zeroes with blocknumbers from list
461 // Note that if no corresponding item was found, by previous search,
462 // it means there are no existing in-tree representation for file area
463 // we are going to overwrite, so there is nothing to scan through for holes.
464 for (curr_block = 0, itempos = path.pos_in_item;
465 curr_block < blocks_to_allocate && res == POSITION_FOUND;) {
466 retry:
467
468 if (itempos >= ih_item_len(ih) / UNFM_P_SIZE) {
469 /* We run out of data in this indirect item, let's look for another
470 one. */
471 /* First if we are already modifying current item, log it */
472 if (modifying_this_item) {
473 journal_mark_dirty(th, inode->i_sb, bh);
474 modifying_this_item = 0;
475 }
476 /* Then set the key to look for a new indirect item (offset of old
477 item is added to old item length */
478 set_cpu_key_k_offset(&key,
479 le_key_k_offset
480 (get_inode_item_key_version(inode),
481 &(ih->ih_key)) +
482 op_bytes_number(ih,
483 inode->i_sb->
484 s_blocksize));
485 /* Search ofor position of new key in the tree. */
486 res =
487 search_for_position_by_key(inode->i_sb, &key,
488 &path);
489 if (res == IO_ERROR) {
490 res = -EIO;
491 goto error_exit_free_blocks;
492 }
493 bh = get_last_bh(&path);
494 ih = get_ih(&path);
495 item = get_item(&path);
496 itempos = path.pos_in_item;
497 continue; // loop to check all kinds of conditions and so on.
498 }
499 /* Ok, we have correct position in item now, so let's see if it is
500 representing file hole (blocknumber is zero) and fill it if needed */
501 if (!item[itempos]) {
502 /* Ok, a hole. Now we need to check if we already prepared this
503 block to be journaled */
504 while (!modifying_this_item) { // loop until succeed
505 /* Well, this item is not journaled yet, so we must prepare
506 it for journal first, before we can change it */
507 struct item_head tmp_ih; // We copy item head of found item,
508 // here to detect if fs changed under
509 // us while we were preparing for
510 // journal.
511 int fs_gen; // We store fs generation here to find if someone
512 // changes fs under our feet
513
514 copy_item_head(&tmp_ih, ih); // Remember itemhead
515 fs_gen = get_generation(inode->i_sb); // remember fs generation
516 reiserfs_prepare_for_journal(inode->i_sb, bh, 1); // Prepare a buffer within which indirect item is stored for changing.
517 if (fs_changed(fs_gen, inode->i_sb)
518 && item_moved(&tmp_ih, &path)) {
519 // Sigh, fs was changed under us, we need to look for new
520 // location of item we are working with
521
522 /* unmark prepaerd area as journaled and search for it's
523 new position */
524 reiserfs_restore_prepared_buffer(inode->
525 i_sb,
526 bh);
527 res =
528 search_for_position_by_key(inode->
529 i_sb,
530 &key,
531 &path);
532 if (res == IO_ERROR) {
533 res = -EIO;
534 goto error_exit_free_blocks;
535 }
536 bh = get_last_bh(&path);
537 ih = get_ih(&path);
538 item = get_item(&path);
539 itempos = path.pos_in_item;
540 goto retry;
541 }
542 modifying_this_item = 1;
543 }
544 item[itempos] = allocated_blocks[curr_block]; // Assign new block
545 curr_block++;
546 }
547 itempos++;
548 }
549
550 if (modifying_this_item) { // We need to log last-accessed block, if it
551 // was modified, but not logged yet.
552 journal_mark_dirty(th, inode->i_sb, bh);
553 }
554
555 if (curr_block < blocks_to_allocate) {
556 // Oh, well need to append to indirect item, or to create indirect item
557 // if there weren't any
558 if (is_indirect_le_ih(ih)) {
559 // Existing indirect item - append. First calculate key for append
560 // position. We do not need to recalculate path as it should
561 // already point to correct place.
562 make_cpu_key(&key, inode,
563 le_key_k_offset(get_inode_item_key_version
564 (inode),
565 &(ih->ih_key)) +
566 op_bytes_number(ih,
567 inode->i_sb->s_blocksize),
568 TYPE_INDIRECT, 3);
569 res =
570 reiserfs_paste_into_item(th, &path, &key, inode,
571 (char *)(allocated_blocks +
572 curr_block),
573 UNFM_P_SIZE *
574 (blocks_to_allocate -
575 curr_block));
576 if (res) {
577 goto error_exit_free_blocks;
578 }
579 } else if (is_statdata_le_ih(ih)) {
580 // Last found item was statdata. That means we need to create indirect item.
581 struct item_head ins_ih; /* itemhead for new item */
582
583 /* create a key for our new item */
584 make_cpu_key(&key, inode, 1, TYPE_INDIRECT, 3); // Position one,
585 // because that's
586 // where first
587 // indirect item
588 // begins
589 /* Create new item head for our new item */
590 make_le_item_head(&ins_ih, &key, key.version, 1,
591 TYPE_INDIRECT,
592 (blocks_to_allocate -
593 curr_block) * UNFM_P_SIZE,
594 0 /* free space */ );
595 /* Find where such item should live in the tree */
596 res = search_item(inode->i_sb, &key, &path);
597 if (res != ITEM_NOT_FOUND) {
598 /* Well, if we have found such item already, or some error
599 occured, we need to warn user and return error */
600 if (res != -ENOSPC) {
601 reiserfs_warning(inode->i_sb,
602 "green-9009: search_by_key (%K) "
603 "returned %d", &key,
604 res);
605 }
606 res = -EIO;
607 goto error_exit_free_blocks;
608 }
609 /* Insert item into the tree with the data as its body */
610 res =
611 reiserfs_insert_item(th, &path, &key, &ins_ih,
612 inode,
613 (char *)(allocated_blocks +
614 curr_block));
615 } else {
616 reiserfs_panic(inode->i_sb,
617 "green-9010: unexpected item type for key %K\n",
618 &key);
619 }
620 }
621 // the caller is responsible for closing the transaction
622 // unless we return an error, they are also responsible for logging
623 // the inode.
624 //
625 pathrelse(&path);
626 /*
627 * cleanup prellocation from previous writes
628 * if this is a partial block write
629 */
630 if (write_bytes & (inode->i_sb->s_blocksize - 1))
631 reiserfs_discard_prealloc(th, inode);
632 reiserfs_write_unlock(inode->i_sb);
633
634 // go through all the pages/buffers and map the buffers to newly allocated
635 // blocks (so that system knows where to write these pages later).
636 curr_block = 0;
637 for (i = 0; i < num_pages; i++) {
638 struct page *page = prepared_pages[i]; //current page
639 struct buffer_head *head = page_buffers(page); // first buffer for a page
640 int block_start, block_end; // in-page offsets for buffers.
641
642 if (!page_buffers(page))
643 reiserfs_panic(inode->i_sb,
644 "green-9005: No buffers for prepared page???");
645
646 /* For each buffer in page */
647 for (bh = head, block_start = 0; bh != head || !block_start;
648 block_start = block_end, bh = bh->b_this_page) {
649 if (!bh)
650 reiserfs_panic(inode->i_sb,
651 "green-9006: Allocated but absent buffer for a page?");
652 block_end = block_start + inode->i_sb->s_blocksize;
653 if (i == 0 && block_end <= from)
654 /* if this buffer is before requested data to map, skip it */
655 continue;
656 if (i == num_pages - 1 && block_start >= to)
657 /* If this buffer is after requested data to map, abort
658 processing of current page */
659 break;
660
661 if (!buffer_mapped(bh)) { // Ok, unmapped buffer, need to map it
662 map_bh(bh, inode->i_sb,
663 le32_to_cpu(allocated_blocks
664 [curr_block]));
665 curr_block++;
666 set_buffer_new(bh);
667 }
668 }
669 }
670
671 RFALSE(curr_block > blocks_to_allocate,
672 "green-9007: Used too many blocks? weird");
673
674 kfree(allocated_blocks);
675 return 0;
676
677// Need to deal with transaction here.
678 error_exit_free_blocks:
679 pathrelse(&path);
680 // free blocks
681 for (i = 0; i < blocks_to_allocate; i++)
682 reiserfs_free_block(th, inode, le32_to_cpu(allocated_blocks[i]),
683 1);
684
685 error_exit:
686 if (th->t_trans_id) {
687 int err;
688 // update any changes we made to blk count
689 mark_inode_dirty(inode);
690 err =
691 journal_end(th, inode->i_sb,
692 JOURNAL_PER_BALANCE_CNT * 3 + 1 +
693 2 * REISERFS_QUOTA_TRANS_BLOCKS(inode->i_sb));
694 if (err)
695 res = err;
696 }
697 reiserfs_write_unlock(inode->i_sb);
698 kfree(allocated_blocks);
699
700 return res;
701}
702
703/* Unlock pages prepared by reiserfs_prepare_file_region_for_write */
704static void reiserfs_unprepare_pages(struct page **prepared_pages, /* list of locked pages */
705 size_t num_pages /* amount of pages */ )
706{
707 int i; // loop counter
708
709 for (i = 0; i < num_pages; i++) {
710 struct page *page = prepared_pages[i];
711
712 try_to_free_buffers(page);
713 unlock_page(page);
714 page_cache_release(page);
715 }
716}
717
718/* This function will copy data from userspace to specified pages within
719 supplied byte range */
720static int reiserfs_copy_from_user_to_file_region(loff_t pos, /* In-file position */
721 int num_pages, /* Number of pages affected */
722 int write_bytes, /* Amount of bytes to write */
723 struct page **prepared_pages, /* pointer to
724 array to
725 prepared pages
726 */
727 const char __user * buf /* Pointer to user-supplied
728 data */
729 )
730{
731 long page_fault = 0; // status of copy_from_user.
732 int i; // loop counter.
733 int offset; // offset in page
734
735 for (i = 0, offset = (pos & (PAGE_CACHE_SIZE - 1)); i < num_pages;
736 i++, offset = 0) {
737 size_t count = min_t(size_t, PAGE_CACHE_SIZE - offset, write_bytes); // How much of bytes to write to this page
738 struct page *page = prepared_pages[i]; // Current page we process.
739
740 fault_in_pages_readable(buf, count);
741
742 /* Copy data from userspace to the current page */
743 kmap(page);
744 page_fault = __copy_from_user(page_address(page) + offset, buf, count); // Copy the data.
745 /* Flush processor's dcache for this page */
746 flush_dcache_page(page);
747 kunmap(page);
748 buf += count;
749 write_bytes -= count;
750
751 if (page_fault)
752 break; // Was there a fault? abort.
753 }
754
755 return page_fault ? -EFAULT : 0;
756}
757
758/* taken fs/buffer.c:__block_commit_write */ 156/* taken fs/buffer.c:__block_commit_write */
759int reiserfs_commit_page(struct inode *inode, struct page *page, 157int reiserfs_commit_page(struct inode *inode, struct page *page,
760 unsigned from, unsigned to) 158 unsigned from, unsigned to)
@@ -824,432 +222,6 @@ int reiserfs_commit_page(struct inode *inode, struct page *page,
824 return ret; 222 return ret;
825} 223}
826 224
827/* Submit pages for write. This was separated from actual file copying
828 because we might want to allocate block numbers in-between.
829 This function assumes that caller will adjust file size to correct value. */
830static int reiserfs_submit_file_region_for_write(struct reiserfs_transaction_handle *th, struct inode *inode, loff_t pos, /* Writing position offset */
831 size_t num_pages, /* Number of pages to write */
832 size_t write_bytes, /* number of bytes to write */
833 struct page **prepared_pages /* list of pages */
834 )
835{
836 int status; // return status of block_commit_write.
837 int retval = 0; // Return value we are going to return.
838 int i; // loop counter
839 int offset; // Writing offset in page.
840 int orig_write_bytes = write_bytes;
841 int sd_update = 0;
842
843 for (i = 0, offset = (pos & (PAGE_CACHE_SIZE - 1)); i < num_pages;
844 i++, offset = 0) {
845 int count = min_t(int, PAGE_CACHE_SIZE - offset, write_bytes); // How much of bytes to write to this page
846 struct page *page = prepared_pages[i]; // Current page we process.
847
848 status =
849 reiserfs_commit_page(inode, page, offset, offset + count);
850 if (status)
851 retval = status; // To not overcomplicate matters We are going to
852 // submit all the pages even if there was error.
853 // we only remember error status to report it on
854 // exit.
855 write_bytes -= count;
856 }
857 /* now that we've gotten all the ordered buffers marked dirty,
858 * we can safely update i_size and close any running transaction
859 */
860 if (pos + orig_write_bytes > inode->i_size) {
861 inode->i_size = pos + orig_write_bytes; // Set new size
862 /* If the file have grown so much that tail packing is no
863 * longer possible, reset "need to pack" flag */
864 if ((have_large_tails(inode->i_sb) &&
865 inode->i_size > i_block_size(inode) * 4) ||
866 (have_small_tails(inode->i_sb) &&
867 inode->i_size > i_block_size(inode)))
868 REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
869 else if ((have_large_tails(inode->i_sb) &&
870 inode->i_size < i_block_size(inode) * 4) ||
871 (have_small_tails(inode->i_sb) &&
872 inode->i_size < i_block_size(inode)))
873 REISERFS_I(inode)->i_flags |= i_pack_on_close_mask;
874
875 if (th->t_trans_id) {
876 reiserfs_write_lock(inode->i_sb);
877 // this sets the proper flags for O_SYNC to trigger a commit
878 mark_inode_dirty(inode);
879 reiserfs_write_unlock(inode->i_sb);
880 } else {
881 reiserfs_write_lock(inode->i_sb);
882 reiserfs_update_inode_transaction(inode);
883 mark_inode_dirty(inode);
884 reiserfs_write_unlock(inode->i_sb);
885 }
886
887 sd_update = 1;
888 }
889 if (th->t_trans_id) {
890 reiserfs_write_lock(inode->i_sb);
891 if (!sd_update)
892 mark_inode_dirty(inode);
893 status = journal_end(th, th->t_super, th->t_blocks_allocated);
894 if (status)
895 retval = status;
896 reiserfs_write_unlock(inode->i_sb);
897 }
898 th->t_trans_id = 0;
899
900 /*
901 * we have to unlock the pages after updating i_size, otherwise
902 * we race with writepage
903 */
904 for (i = 0; i < num_pages; i++) {
905 struct page *page = prepared_pages[i];
906 unlock_page(page);
907 mark_page_accessed(page);
908 page_cache_release(page);
909 }
910 return retval;
911}
912
913/* Look if passed writing region is going to touch file's tail
914 (if it is present). And if it is, convert the tail to unformatted node */
915static int reiserfs_check_for_tail_and_convert(struct inode *inode, /* inode to deal with */
916 loff_t pos, /* Writing position */
917 int write_bytes /* amount of bytes to write */
918 )
919{
920 INITIALIZE_PATH(path); // needed for search_for_position
921 struct cpu_key key; // Key that would represent last touched writing byte.
922 struct item_head *ih; // item header of found block;
923 int res; // Return value of various functions we call.
924 int cont_expand_offset; // We will put offset for generic_cont_expand here
925 // This can be int just because tails are created
926 // only for small files.
927
928/* this embodies a dependency on a particular tail policy */
929 if (inode->i_size >= inode->i_sb->s_blocksize * 4) {
930 /* such a big files do not have tails, so we won't bother ourselves
931 to look for tails, simply return */
932 return 0;
933 }
934
935 reiserfs_write_lock(inode->i_sb);
936 /* find the item containing the last byte to be written, or if
937 * writing past the end of the file then the last item of the
938 * file (and then we check its type). */
939 make_cpu_key(&key, inode, pos + write_bytes + 1, TYPE_ANY,
940 3 /*key length */ );
941 res = search_for_position_by_key(inode->i_sb, &key, &path);
942 if (res == IO_ERROR) {
943 reiserfs_write_unlock(inode->i_sb);
944 return -EIO;
945 }
946 ih = get_ih(&path);
947 res = 0;
948 if (is_direct_le_ih(ih)) {
949 /* Ok, closest item is file tail (tails are stored in "direct"
950 * items), so we need to unpack it. */
951 /* To not overcomplicate matters, we just call generic_cont_expand
952 which will in turn call other stuff and finally will boil down to
953 reiserfs_get_block() that would do necessary conversion. */
954 cont_expand_offset =
955 le_key_k_offset(get_inode_item_key_version(inode),
956 &(ih->ih_key));
957 pathrelse(&path);
958 res = generic_cont_expand(inode, cont_expand_offset);
959 } else
960 pathrelse(&path);
961
962 reiserfs_write_unlock(inode->i_sb);
963 return res;
964}
965
966/* This function locks pages starting from @pos for @inode.
967 @num_pages pages are locked and stored in
968 @prepared_pages array. Also buffers are allocated for these pages.
969 First and last page of the region is read if it is overwritten only
970 partially. If last page did not exist before write (file hole or file
971 append), it is zeroed, then.
972 Returns number of unallocated blocks that should be allocated to cover
973 new file data.*/
974static int reiserfs_prepare_file_region_for_write(struct inode *inode
975 /* Inode of the file */ ,
976 loff_t pos, /* position in the file */
977 size_t num_pages, /* number of pages to
978 prepare */
979 size_t write_bytes, /* Amount of bytes to be
980 overwritten from
981 @pos */
982 struct page **prepared_pages /* pointer to array
983 where to store
984 prepared pages */
985 )
986{
987 int res = 0; // Return values of different functions we call.
988 unsigned long index = pos >> PAGE_CACHE_SHIFT; // Offset in file in pages.
989 int from = (pos & (PAGE_CACHE_SIZE - 1)); // Writing offset in first page
990 int to = ((pos + write_bytes - 1) & (PAGE_CACHE_SIZE - 1)) + 1;
991 /* offset of last modified byte in last
992 page */
993 struct address_space *mapping = inode->i_mapping; // Pages are mapped here.
994 int i; // Simple counter
995 int blocks = 0; /* Return value (blocks that should be allocated) */
996 struct buffer_head *bh, *head; // Current bufferhead and first bufferhead
997 // of a page.
998 unsigned block_start, block_end; // Starting and ending offsets of current
999 // buffer in the page.
1000 struct buffer_head *wait[2], **wait_bh = wait; // Buffers for page, if
1001 // Page appeared to be not up
1002 // to date. Note how we have
1003 // at most 2 buffers, this is
1004 // because we at most may
1005 // partially overwrite two
1006 // buffers for one page. One at // the beginning of write area
1007 // and one at the end.
1008 // Everything inthe middle gets // overwritten totally.
1009
1010 struct cpu_key key; // cpu key of item that we are going to deal with
1011 struct item_head *ih = NULL; // pointer to item head that we are going to deal with
1012 struct buffer_head *itembuf = NULL; // Buffer head that contains items that we are going to deal with
1013 INITIALIZE_PATH(path); // path to item, that we are going to deal with.
1014 __le32 *item = NULL; // pointer to item we are going to deal with
1015 int item_pos = -1; /* Position in indirect item */
1016
1017 if (num_pages < 1) {
1018 reiserfs_warning(inode->i_sb,
1019 "green-9001: reiserfs_prepare_file_region_for_write "
1020 "called with zero number of pages to process");
1021 return -EFAULT;
1022 }
1023
1024 /* We have 2 loops for pages. In first loop we grab and lock the pages, so
1025 that nobody would touch these until we release the pages. Then
1026 we'd start to deal with mapping buffers to blocks. */
1027 for (i = 0; i < num_pages; i++) {
1028 prepared_pages[i] = grab_cache_page(mapping, index + i); // locks the page
1029 if (!prepared_pages[i]) {
1030 res = -ENOMEM;
1031 goto failed_page_grabbing;
1032 }
1033 if (!page_has_buffers(prepared_pages[i]))
1034 create_empty_buffers(prepared_pages[i],
1035 inode->i_sb->s_blocksize, 0);
1036 }
1037
1038 /* Let's count amount of blocks for a case where all the blocks
1039 overwritten are new (we will substract already allocated blocks later) */
1040 if (num_pages > 2)
1041 /* These are full-overwritten pages so we count all the blocks in
1042 these pages are counted as needed to be allocated */
1043 blocks =
1044 (num_pages - 2) << (PAGE_CACHE_SHIFT - inode->i_blkbits);
1045
1046 /* count blocks needed for first page (possibly partially written) */
1047 blocks += ((PAGE_CACHE_SIZE - from) >> inode->i_blkbits) + !!(from & (inode->i_sb->s_blocksize - 1)); /* roundup */
1048
1049 /* Now we account for last page. If last page == first page (we
1050 overwrite only one page), we substract all the blocks past the
1051 last writing position in a page out of already calculated number
1052 of blocks */
1053 blocks += ((num_pages > 1) << (PAGE_CACHE_SHIFT - inode->i_blkbits)) -
1054 ((PAGE_CACHE_SIZE - to) >> inode->i_blkbits);
1055 /* Note how we do not roundup here since partial blocks still
1056 should be allocated */
1057
1058 /* Now if all the write area lies past the file end, no point in
1059 maping blocks, since there is none, so we just zero out remaining
1060 parts of first and last pages in write area (if needed) */
1061 if ((pos & ~((loff_t) PAGE_CACHE_SIZE - 1)) > inode->i_size) {
1062 if (from != 0) /* First page needs to be partially zeroed */
1063 zero_user_page(prepared_pages[0], 0, from, KM_USER0);
1064
1065 if (to != PAGE_CACHE_SIZE) /* Last page needs to be partially zeroed */
1066 zero_user_page(prepared_pages[num_pages-1], to,
1067 PAGE_CACHE_SIZE - to, KM_USER0);
1068
1069 /* Since all blocks are new - use already calculated value */
1070 return blocks;
1071 }
1072
1073 /* Well, since we write somewhere into the middle of a file, there is
1074 possibility we are writing over some already allocated blocks, so
1075 let's map these blocks and substract number of such blocks out of blocks
1076 we need to allocate (calculated above) */
1077 /* Mask write position to start on blocksize, we do it out of the
1078 loop for performance reasons */
1079 pos &= ~((loff_t) inode->i_sb->s_blocksize - 1);
1080 /* Set cpu key to the starting position in a file (on left block boundary) */
1081 make_cpu_key(&key, inode,
1082 1 + ((pos) & ~((loff_t) inode->i_sb->s_blocksize - 1)),
1083 TYPE_ANY, 3 /*key length */ );
1084
1085 reiserfs_write_lock(inode->i_sb); // We need that for at least search_by_key()
1086 for (i = 0; i < num_pages; i++) {
1087
1088 head = page_buffers(prepared_pages[i]);
1089 /* For each buffer in the page */
1090 for (bh = head, block_start = 0; bh != head || !block_start;
1091 block_start = block_end, bh = bh->b_this_page) {
1092 if (!bh)
1093 reiserfs_panic(inode->i_sb,
1094 "green-9002: Allocated but absent buffer for a page?");
1095 /* Find where this buffer ends */
1096 block_end = block_start + inode->i_sb->s_blocksize;
1097 if (i == 0 && block_end <= from)
1098 /* if this buffer is before requested data to map, skip it */
1099 continue;
1100
1101 if (i == num_pages - 1 && block_start >= to) {
1102 /* If this buffer is after requested data to map, abort
1103 processing of current page */
1104 break;
1105 }
1106
1107 if (buffer_mapped(bh) && bh->b_blocknr != 0) {
1108 /* This is optimisation for a case where buffer is mapped
1109 and have blocknumber assigned. In case significant amount
1110 of such buffers are present, we may avoid some amount
1111 of search_by_key calls.
1112 Probably it would be possible to move parts of this code
1113 out of BKL, but I afraid that would overcomplicate code
1114 without any noticeable benefit.
1115 */
1116 item_pos++;
1117 /* Update the key */
1118 set_cpu_key_k_offset(&key,
1119 cpu_key_k_offset(&key) +
1120 inode->i_sb->s_blocksize);
1121 blocks--; // Decrease the amount of blocks that need to be
1122 // allocated
1123 continue; // Go to the next buffer
1124 }
1125
1126 if (!itembuf || /* if first iteration */
1127 item_pos >= ih_item_len(ih) / UNFM_P_SIZE) { /* or if we progressed past the
1128 current unformatted_item */
1129 /* Try to find next item */
1130 res =
1131 search_for_position_by_key(inode->i_sb,
1132 &key, &path);
1133 /* Abort if no more items */
1134 if (res != POSITION_FOUND) {
1135 /* make sure later loops don't use this item */
1136 itembuf = NULL;
1137 item = NULL;
1138 break;
1139 }
1140
1141 /* Update information about current indirect item */
1142 itembuf = get_last_bh(&path);
1143 ih = get_ih(&path);
1144 item = get_item(&path);
1145 item_pos = path.pos_in_item;
1146
1147 RFALSE(!is_indirect_le_ih(ih),
1148 "green-9003: indirect item expected");
1149 }
1150
1151 /* See if there is some block associated with the file
1152 at that position, map the buffer to this block */
1153 if (get_block_num(item, item_pos)) {
1154 map_bh(bh, inode->i_sb,
1155 get_block_num(item, item_pos));
1156 blocks--; // Decrease the amount of blocks that need to be
1157 // allocated
1158 }
1159 item_pos++;
1160 /* Update the key */
1161 set_cpu_key_k_offset(&key,
1162 cpu_key_k_offset(&key) +
1163 inode->i_sb->s_blocksize);
1164 }
1165 }
1166 pathrelse(&path); // Free the path
1167 reiserfs_write_unlock(inode->i_sb);
1168
1169 /* Now zero out unmappend buffers for the first and last pages of
1170 write area or issue read requests if page is mapped. */
1171 /* First page, see if it is not uptodate */
1172 if (!PageUptodate(prepared_pages[0])) {
1173 head = page_buffers(prepared_pages[0]);
1174
1175 /* For each buffer in page */
1176 for (bh = head, block_start = 0; bh != head || !block_start;
1177 block_start = block_end, bh = bh->b_this_page) {
1178
1179 if (!bh)
1180 reiserfs_panic(inode->i_sb,
1181 "green-9002: Allocated but absent buffer for a page?");
1182 /* Find where this buffer ends */
1183 block_end = block_start + inode->i_sb->s_blocksize;
1184 if (block_end <= from)
1185 /* if this buffer is before requested data to map, skip it */
1186 continue;
1187 if (block_start < from) { /* Aha, our partial buffer */
1188 if (buffer_mapped(bh)) { /* If it is mapped, we need to
1189 issue READ request for it to
1190 not loose data */
1191 ll_rw_block(READ, 1, &bh);
1192 *wait_bh++ = bh;
1193 } else { /* Not mapped, zero it */
1194 zero_user_page(prepared_pages[0],
1195 block_start,
1196 from - block_start, KM_USER0);
1197 set_buffer_uptodate(bh);
1198 }
1199 }
1200 }
1201 }
1202
1203 /* Last page, see if it is not uptodate, or if the last page is past the end of the file. */
1204 if (!PageUptodate(prepared_pages[num_pages - 1]) ||
1205 ((pos + write_bytes) >> PAGE_CACHE_SHIFT) >
1206 (inode->i_size >> PAGE_CACHE_SHIFT)) {
1207 head = page_buffers(prepared_pages[num_pages - 1]);
1208
1209 /* for each buffer in page */
1210 for (bh = head, block_start = 0; bh != head || !block_start;
1211 block_start = block_end, bh = bh->b_this_page) {
1212
1213 if (!bh)
1214 reiserfs_panic(inode->i_sb,
1215 "green-9002: Allocated but absent buffer for a page?");
1216 /* Find where this buffer ends */
1217 block_end = block_start + inode->i_sb->s_blocksize;
1218 if (block_start >= to)
1219 /* if this buffer is after requested data to map, skip it */
1220 break;
1221 if (block_end > to) { /* Aha, our partial buffer */
1222 if (buffer_mapped(bh)) { /* If it is mapped, we need to
1223 issue READ request for it to
1224 not loose data */
1225 ll_rw_block(READ, 1, &bh);
1226 *wait_bh++ = bh;
1227 } else { /* Not mapped, zero it */
1228 zero_user_page(prepared_pages[num_pages-1],
1229 to, block_end - to, KM_USER0);
1230 set_buffer_uptodate(bh);
1231 }
1232 }
1233 }
1234 }
1235
1236 /* Wait for read requests we made to happen, if necessary */
1237 while (wait_bh > wait) {
1238 wait_on_buffer(*--wait_bh);
1239 if (!buffer_uptodate(*wait_bh)) {
1240 res = -EIO;
1241 goto failed_read;
1242 }
1243 }
1244
1245 return blocks;
1246 failed_page_grabbing:
1247 num_pages = i;
1248 failed_read:
1249 reiserfs_unprepare_pages(prepared_pages, num_pages);
1250 return res;
1251}
1252
1253/* Write @count bytes at position @ppos in a file indicated by @file 225/* Write @count bytes at position @ppos in a file indicated by @file
1254 from the buffer @buf. 226 from the buffer @buf.
1255 227
@@ -1284,14 +256,9 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
1284 * new current position before returning. */ 256 * new current position before returning. */
1285 ) 257 )
1286{ 258{
1287 size_t already_written = 0; // Number of bytes already written to the file.
1288 loff_t pos; // Current position in the file.
1289 ssize_t res; // return value of various functions that we call.
1290 int err = 0;
1291 struct inode *inode = file->f_path.dentry->d_inode; // Inode of the file that we are writing to. 259 struct inode *inode = file->f_path.dentry->d_inode; // Inode of the file that we are writing to.
1292 /* To simplify coding at this time, we store 260 /* To simplify coding at this time, we store
1293 locked pages in array for now */ 261 locked pages in array for now */
1294 struct page *prepared_pages[REISERFS_WRITE_PAGES_AT_A_TIME];
1295 struct reiserfs_transaction_handle th; 262 struct reiserfs_transaction_handle th;
1296 th.t_trans_id = 0; 263 th.t_trans_id = 0;
1297 264
@@ -1311,212 +278,7 @@ static ssize_t reiserfs_file_write(struct file *file, /* the file we are going t
1311 count = MAX_NON_LFS - (unsigned long)*ppos; 278 count = MAX_NON_LFS - (unsigned long)*ppos;
1312 } 279 }
1313 280
1314 if (file->f_flags & O_DIRECT) 281 return do_sync_write(file, buf, count, ppos);
1315 return do_sync_write(file, buf, count, ppos);
1316
1317 if (unlikely((ssize_t) count < 0))
1318 return -EINVAL;
1319
1320 if (unlikely(!access_ok(VERIFY_READ, buf, count)))
1321 return -EFAULT;
1322
1323 mutex_lock(&inode->i_mutex); // locks the entire file for just us
1324
1325 pos = *ppos;
1326
1327 /* Check if we can write to specified region of file, file
1328 is not overly big and this kind of stuff. Adjust pos and
1329 count, if needed */
1330 res = generic_write_checks(file, &pos, &count, 0);
1331 if (res)
1332 goto out;
1333
1334 if (count == 0)
1335 goto out;
1336
1337 res = remove_suid(file->f_path.dentry);
1338 if (res)
1339 goto out;
1340
1341 file_update_time(file);
1342
1343 // Ok, we are done with all the checks.
1344
1345 // Now we should start real work
1346
1347 /* If we are going to write past the file's packed tail or if we are going
1348 to overwrite part of the tail, we need that tail to be converted into
1349 unformatted node */
1350 res = reiserfs_check_for_tail_and_convert(inode, pos, count);
1351 if (res)
1352 goto out;
1353
1354 while (count > 0) {
1355 /* This is the main loop in which we running until some error occures
1356 or until we write all of the data. */
1357 size_t num_pages; /* amount of pages we are going to write this iteration */
1358 size_t write_bytes; /* amount of bytes to write during this iteration */
1359 size_t blocks_to_allocate; /* how much blocks we need to allocate for this iteration */
1360
1361 /* (pos & (PAGE_CACHE_SIZE-1)) is an idiom for offset into a page of pos */
1362 num_pages = !!((pos + count) & (PAGE_CACHE_SIZE - 1)) + /* round up partial
1363 pages */
1364 ((count +
1365 (pos & (PAGE_CACHE_SIZE - 1))) >> PAGE_CACHE_SHIFT);
1366 /* convert size to amount of
1367 pages */
1368 reiserfs_write_lock(inode->i_sb);
1369 if (num_pages > REISERFS_WRITE_PAGES_AT_A_TIME
1370 || num_pages > reiserfs_can_fit_pages(inode->i_sb)) {
1371 /* If we were asked to write more data than we want to or if there
1372 is not that much space, then we shorten amount of data to write
1373 for this iteration. */
1374 num_pages =
1375 min_t(size_t, REISERFS_WRITE_PAGES_AT_A_TIME,
1376 reiserfs_can_fit_pages(inode->i_sb));
1377 /* Also we should not forget to set size in bytes accordingly */
1378 write_bytes = (num_pages << PAGE_CACHE_SHIFT) -
1379 (pos & (PAGE_CACHE_SIZE - 1));
1380 /* If position is not on the
1381 start of the page, we need
1382 to substract the offset
1383 within page */
1384 } else
1385 write_bytes = count;
1386
1387 /* reserve the blocks to be allocated later, so that later on
1388 we still have the space to write the blocks to */
1389 reiserfs_claim_blocks_to_be_allocated(inode->i_sb,
1390 num_pages <<
1391 (PAGE_CACHE_SHIFT -
1392 inode->i_blkbits));
1393 reiserfs_write_unlock(inode->i_sb);
1394
1395 if (!num_pages) { /* If we do not have enough space even for a single page... */
1396 if (pos >
1397 inode->i_size + inode->i_sb->s_blocksize -
1398 (pos & (inode->i_sb->s_blocksize - 1))) {
1399 res = -ENOSPC;
1400 break; // In case we are writing past the end of the last file block, break.
1401 }
1402 // Otherwise we are possibly overwriting the file, so
1403 // let's set write size to be equal or less than blocksize.
1404 // This way we get it correctly for file holes.
1405 // But overwriting files on absolutelly full volumes would not
1406 // be very efficient. Well, people are not supposed to fill
1407 // 100% of disk space anyway.
1408 write_bytes =
1409 min_t(size_t, count,
1410 inode->i_sb->s_blocksize -
1411 (pos & (inode->i_sb->s_blocksize - 1)));
1412 num_pages = 1;
1413 // No blocks were claimed before, so do it now.
1414 reiserfs_claim_blocks_to_be_allocated(inode->i_sb,
1415 1 <<
1416 (PAGE_CACHE_SHIFT
1417 -
1418 inode->
1419 i_blkbits));
1420 }
1421
1422 /* Prepare for writing into the region, read in all the
1423 partially overwritten pages, if needed. And lock the pages,
1424 so that nobody else can access these until we are done.
1425 We get number of actual blocks needed as a result. */
1426 res = reiserfs_prepare_file_region_for_write(inode, pos,
1427 num_pages,
1428 write_bytes,
1429 prepared_pages);
1430 if (res < 0) {
1431 reiserfs_release_claimed_blocks(inode->i_sb,
1432 num_pages <<
1433 (PAGE_CACHE_SHIFT -
1434 inode->i_blkbits));
1435 break;
1436 }
1437
1438 blocks_to_allocate = res;
1439
1440 /* First we correct our estimate of how many blocks we need */
1441 reiserfs_release_claimed_blocks(inode->i_sb,
1442 (num_pages <<
1443 (PAGE_CACHE_SHIFT -
1444 inode->i_sb->
1445 s_blocksize_bits)) -
1446 blocks_to_allocate);
1447
1448 if (blocks_to_allocate > 0) { /*We only allocate blocks if we need to */
1449 /* Fill in all the possible holes and append the file if needed */
1450 res =
1451 reiserfs_allocate_blocks_for_region(&th, inode, pos,
1452 num_pages,
1453 write_bytes,
1454 prepared_pages,
1455 blocks_to_allocate);
1456 }
1457
1458 /* well, we have allocated the blocks, so it is time to free
1459 the reservation we made earlier. */
1460 reiserfs_release_claimed_blocks(inode->i_sb,
1461 blocks_to_allocate);
1462 if (res) {
1463 reiserfs_unprepare_pages(prepared_pages, num_pages);
1464 break;
1465 }
1466
1467/* NOTE that allocating blocks and filling blocks can be done in reverse order
1468 and probably we would do that just to get rid of garbage in files after a
1469 crash */
1470
1471 /* Copy data from user-supplied buffer to file's pages */
1472 res =
1473 reiserfs_copy_from_user_to_file_region(pos, num_pages,
1474 write_bytes,
1475 prepared_pages, buf);
1476 if (res) {
1477 reiserfs_unprepare_pages(prepared_pages, num_pages);
1478 break;
1479 }
1480
1481 /* Send the pages to disk and unlock them. */
1482 res =
1483 reiserfs_submit_file_region_for_write(&th, inode, pos,
1484 num_pages,
1485 write_bytes,
1486 prepared_pages);
1487 if (res)
1488 break;
1489
1490 already_written += write_bytes;
1491 buf += write_bytes;
1492 *ppos = pos += write_bytes;
1493 count -= write_bytes;
1494 balance_dirty_pages_ratelimited_nr(inode->i_mapping, num_pages);
1495 }
1496
1497 /* this is only true on error */
1498 if (th.t_trans_id) {
1499 reiserfs_write_lock(inode->i_sb);
1500 err = journal_end(&th, th.t_super, th.t_blocks_allocated);
1501 reiserfs_write_unlock(inode->i_sb);
1502 if (err) {
1503 res = err;
1504 goto out;
1505 }
1506 }
1507
1508 if (likely(res >= 0) &&
1509 (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))))
1510 res = generic_osync_inode(inode, file->f_mapping,
1511 OSYNC_METADATA | OSYNC_DATA);
1512
1513 mutex_unlock(&inode->i_mutex);
1514 reiserfs_async_progress_wait(inode->i_sb);
1515 return (already_written != 0) ? already_written : res;
1516
1517 out:
1518 mutex_unlock(&inode->i_mutex); // unlock the file on exit.
1519 return res;
1520} 282}
1521 283
1522const struct file_operations reiserfs_file_operations = { 284const struct file_operations reiserfs_file_operations = {
diff --git a/fs/reiserfs/inode.c b/fs/reiserfs/inode.c
index ddde489f1cb2..95051d44a918 100644
--- a/fs/reiserfs/inode.c
+++ b/fs/reiserfs/inode.c
@@ -17,11 +17,12 @@
17#include <linux/mpage.h> 17#include <linux/mpage.h>
18#include <linux/writeback.h> 18#include <linux/writeback.h>
19#include <linux/quotaops.h> 19#include <linux/quotaops.h>
20#include <linux/swap.h>
20 21
21static int reiserfs_commit_write(struct file *f, struct page *page, 22int reiserfs_commit_write(struct file *f, struct page *page,
22 unsigned from, unsigned to); 23 unsigned from, unsigned to);
23static int reiserfs_prepare_write(struct file *f, struct page *page, 24int reiserfs_prepare_write(struct file *f, struct page *page,
24 unsigned from, unsigned to); 25 unsigned from, unsigned to);
25 26
26void reiserfs_delete_inode(struct inode *inode) 27void reiserfs_delete_inode(struct inode *inode)
27{ 28{
@@ -2550,8 +2551,78 @@ static int reiserfs_writepage(struct page *page, struct writeback_control *wbc)
2550 return reiserfs_write_full_page(page, wbc); 2551 return reiserfs_write_full_page(page, wbc);
2551} 2552}
2552 2553
2553static int reiserfs_prepare_write(struct file *f, struct page *page, 2554static int reiserfs_write_begin(struct file *file,
2554 unsigned from, unsigned to) 2555 struct address_space *mapping,
2556 loff_t pos, unsigned len, unsigned flags,
2557 struct page **pagep, void **fsdata)
2558{
2559 struct inode *inode;
2560 struct page *page;
2561 pgoff_t index;
2562 int ret;
2563 int old_ref = 0;
2564
2565 inode = mapping->host;
2566 *fsdata = 0;
2567 if (flags & AOP_FLAG_CONT_EXPAND &&
2568 (pos & (inode->i_sb->s_blocksize - 1)) == 0) {
2569 pos ++;
2570 *fsdata = (void *)(unsigned long)flags;
2571 }
2572
2573 index = pos >> PAGE_CACHE_SHIFT;
2574 page = __grab_cache_page(mapping, index);
2575 if (!page)
2576 return -ENOMEM;
2577 *pagep = page;
2578
2579 reiserfs_wait_on_write_block(inode->i_sb);
2580 fix_tail_page_for_writing(page);
2581 if (reiserfs_transaction_running(inode->i_sb)) {
2582 struct reiserfs_transaction_handle *th;
2583 th = (struct reiserfs_transaction_handle *)current->
2584 journal_info;
2585 BUG_ON(!th->t_refcount);
2586 BUG_ON(!th->t_trans_id);
2587 old_ref = th->t_refcount;
2588 th->t_refcount++;
2589 }
2590 ret = block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
2591 reiserfs_get_block);
2592 if (ret && reiserfs_transaction_running(inode->i_sb)) {
2593 struct reiserfs_transaction_handle *th = current->journal_info;
2594 /* this gets a little ugly. If reiserfs_get_block returned an
2595 * error and left a transacstion running, we've got to close it,
2596 * and we've got to free handle if it was a persistent transaction.
2597 *
2598 * But, if we had nested into an existing transaction, we need
2599 * to just drop the ref count on the handle.
2600 *
2601 * If old_ref == 0, the transaction is from reiserfs_get_block,
2602 * and it was a persistent trans. Otherwise, it was nested above.
2603 */
2604 if (th->t_refcount > old_ref) {
2605 if (old_ref)
2606 th->t_refcount--;
2607 else {
2608 int err;
2609 reiserfs_write_lock(inode->i_sb);
2610 err = reiserfs_end_persistent_transaction(th);
2611 reiserfs_write_unlock(inode->i_sb);
2612 if (err)
2613 ret = err;
2614 }
2615 }
2616 }
2617 if (ret) {
2618 unlock_page(page);
2619 page_cache_release(page);
2620 }
2621 return ret;
2622}
2623
2624int reiserfs_prepare_write(struct file *f, struct page *page,
2625 unsigned from, unsigned to)
2555{ 2626{
2556 struct inode *inode = page->mapping->host; 2627 struct inode *inode = page->mapping->host;
2557 int ret; 2628 int ret;
@@ -2604,8 +2675,102 @@ static sector_t reiserfs_aop_bmap(struct address_space *as, sector_t block)
2604 return generic_block_bmap(as, block, reiserfs_bmap); 2675 return generic_block_bmap(as, block, reiserfs_bmap);
2605} 2676}
2606 2677
2607static int reiserfs_commit_write(struct file *f, struct page *page, 2678static int reiserfs_write_end(struct file *file, struct address_space *mapping,
2608 unsigned from, unsigned to) 2679 loff_t pos, unsigned len, unsigned copied,
2680 struct page *page, void *fsdata)
2681{
2682 struct inode *inode = page->mapping->host;
2683 int ret = 0;
2684 int update_sd = 0;
2685 struct reiserfs_transaction_handle *th;
2686 unsigned start;
2687
2688 if ((unsigned long)fsdata & AOP_FLAG_CONT_EXPAND)
2689 pos ++;
2690
2691 reiserfs_wait_on_write_block(inode->i_sb);
2692 if (reiserfs_transaction_running(inode->i_sb))
2693 th = current->journal_info;
2694 else
2695 th = NULL;
2696
2697 start = pos & (PAGE_CACHE_SIZE - 1);
2698 if (unlikely(copied < len)) {
2699 if (!PageUptodate(page))
2700 copied = 0;
2701
2702 page_zero_new_buffers(page, start + copied, start + len);
2703 }
2704 flush_dcache_page(page);
2705
2706 reiserfs_commit_page(inode, page, start, start + copied);
2707
2708 /* generic_commit_write does this for us, but does not update the
2709 ** transaction tracking stuff when the size changes. So, we have
2710 ** to do the i_size updates here.
2711 */
2712 pos += copied;
2713 if (pos > inode->i_size) {
2714 struct reiserfs_transaction_handle myth;
2715 reiserfs_write_lock(inode->i_sb);
2716 /* If the file have grown beyond the border where it
2717 can have a tail, unmark it as needing a tail
2718 packing */
2719 if ((have_large_tails(inode->i_sb)
2720 && inode->i_size > i_block_size(inode) * 4)
2721 || (have_small_tails(inode->i_sb)
2722 && inode->i_size > i_block_size(inode)))
2723 REISERFS_I(inode)->i_flags &= ~i_pack_on_close_mask;
2724
2725 ret = journal_begin(&myth, inode->i_sb, 1);
2726 if (ret) {
2727 reiserfs_write_unlock(inode->i_sb);
2728 goto journal_error;
2729 }
2730 reiserfs_update_inode_transaction(inode);
2731 inode->i_size = pos;
2732 /*
2733 * this will just nest into our transaction. It's important
2734 * to use mark_inode_dirty so the inode gets pushed around on the
2735 * dirty lists, and so that O_SYNC works as expected
2736 */
2737 mark_inode_dirty(inode);
2738 reiserfs_update_sd(&myth, inode);
2739 update_sd = 1;
2740 ret = journal_end(&myth, inode->i_sb, 1);
2741 reiserfs_write_unlock(inode->i_sb);
2742 if (ret)
2743 goto journal_error;
2744 }
2745 if (th) {
2746 reiserfs_write_lock(inode->i_sb);
2747 if (!update_sd)
2748 mark_inode_dirty(inode);
2749 ret = reiserfs_end_persistent_transaction(th);
2750 reiserfs_write_unlock(inode->i_sb);
2751 if (ret)
2752 goto out;
2753 }
2754
2755 out:
2756 unlock_page(page);
2757 page_cache_release(page);
2758 return ret == 0 ? copied : ret;
2759
2760 journal_error:
2761 if (th) {
2762 reiserfs_write_lock(inode->i_sb);
2763 if (!update_sd)
2764 reiserfs_update_sd(th, inode);
2765 ret = reiserfs_end_persistent_transaction(th);
2766 reiserfs_write_unlock(inode->i_sb);
2767 }
2768
2769 goto out;
2770}
2771
2772int reiserfs_commit_write(struct file *f, struct page *page,
2773 unsigned from, unsigned to)
2609{ 2774{
2610 struct inode *inode = page->mapping->host; 2775 struct inode *inode = page->mapping->host;
2611 loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + to; 2776 loff_t pos = ((loff_t) page->index << PAGE_CACHE_SHIFT) + to;
@@ -2909,7 +3074,7 @@ int reiserfs_setattr(struct dentry *dentry, struct iattr *attr)
2909 } 3074 }
2910 /* fill in hole pointers in the expanding truncate case. */ 3075 /* fill in hole pointers in the expanding truncate case. */
2911 if (attr->ia_size > inode->i_size) { 3076 if (attr->ia_size > inode->i_size) {
2912 error = generic_cont_expand(inode, attr->ia_size); 3077 error = generic_cont_expand_simple(inode, attr->ia_size);
2913 if (REISERFS_I(inode)->i_prealloc_count > 0) { 3078 if (REISERFS_I(inode)->i_prealloc_count > 0) {
2914 int err; 3079 int err;
2915 struct reiserfs_transaction_handle th; 3080 struct reiserfs_transaction_handle th;
@@ -2999,8 +3164,8 @@ const struct address_space_operations reiserfs_address_space_operations = {
2999 .releasepage = reiserfs_releasepage, 3164 .releasepage = reiserfs_releasepage,
3000 .invalidatepage = reiserfs_invalidatepage, 3165 .invalidatepage = reiserfs_invalidatepage,
3001 .sync_page = block_sync_page, 3166 .sync_page = block_sync_page,
3002 .prepare_write = reiserfs_prepare_write, 3167 .write_begin = reiserfs_write_begin,
3003 .commit_write = reiserfs_commit_write, 3168 .write_end = reiserfs_write_end,
3004 .bmap = reiserfs_aop_bmap, 3169 .bmap = reiserfs_aop_bmap,
3005 .direct_IO = reiserfs_direct_IO, 3170 .direct_IO = reiserfs_direct_IO,
3006 .set_page_dirty = reiserfs_set_page_dirty, 3171 .set_page_dirty = reiserfs_set_page_dirty,
diff --git a/fs/reiserfs/ioctl.c b/fs/reiserfs/ioctl.c
index 11a0fcc2d402..c438a8f83f26 100644
--- a/fs/reiserfs/ioctl.c
+++ b/fs/reiserfs/ioctl.c
@@ -128,6 +128,10 @@ long reiserfs_compat_ioctl(struct file *file, unsigned int cmd,
128} 128}
129#endif 129#endif
130 130
131int reiserfs_commit_write(struct file *f, struct page *page,
132 unsigned from, unsigned to);
133int reiserfs_prepare_write(struct file *f, struct page *page,
134 unsigned from, unsigned to);
131/* 135/*
132** reiserfs_unpack 136** reiserfs_unpack
133** Function try to convert tail from direct item into indirect. 137** Function try to convert tail from direct item into indirect.
@@ -175,15 +179,13 @@ static int reiserfs_unpack(struct inode *inode, struct file *filp)
175 if (!page) { 179 if (!page) {
176 goto out; 180 goto out;
177 } 181 }
178 retval = 182 retval = reiserfs_prepare_write(NULL, page, write_from, write_from);
179 mapping->a_ops->prepare_write(NULL, page, write_from, write_from);
180 if (retval) 183 if (retval)
181 goto out_unlock; 184 goto out_unlock;
182 185
183 /* conversion can change page contents, must flush */ 186 /* conversion can change page contents, must flush */
184 flush_dcache_page(page); 187 flush_dcache_page(page);
185 retval = 188 retval = reiserfs_commit_write(NULL, page, write_from, write_from);
186 mapping->a_ops->commit_write(NULL, page, write_from, write_from);
187 REISERFS_I(inode)->i_flags |= i_nopack_mask; 189 REISERFS_I(inode)->i_flags |= i_nopack_mask;
188 190
189 out_unlock: 191 out_unlock:
diff --git a/fs/reiserfs/xattr.c b/fs/reiserfs/xattr.c
index bf6e58214538..fab4b9b2664f 100644
--- a/fs/reiserfs/xattr.c
+++ b/fs/reiserfs/xattr.c
@@ -426,6 +426,12 @@ static inline __u32 xattr_hash(const char *msg, int len)
426 return csum_partial(msg, len, 0); 426 return csum_partial(msg, len, 0);
427} 427}
428 428
429int reiserfs_commit_write(struct file *f, struct page *page,
430 unsigned from, unsigned to);
431int reiserfs_prepare_write(struct file *f, struct page *page,
432 unsigned from, unsigned to);
433
434
429/* Generic extended attribute operations that can be used by xa plugins */ 435/* Generic extended attribute operations that can be used by xa plugins */
430 436
431/* 437/*
@@ -512,15 +518,15 @@ reiserfs_xattr_set(struct inode *inode, const char *name, const void *buffer,
512 rxh->h_hash = cpu_to_le32(xahash); 518 rxh->h_hash = cpu_to_le32(xahash);
513 } 519 }
514 520
515 err = mapping->a_ops->prepare_write(fp, page, page_offset, 521 err = reiserfs_prepare_write(fp, page, page_offset,
516 page_offset + chunk + skip); 522 page_offset + chunk + skip);
517 if (!err) { 523 if (!err) {
518 if (buffer) 524 if (buffer)
519 memcpy(data + skip, buffer + buffer_pos, chunk); 525 memcpy(data + skip, buffer + buffer_pos, chunk);
520 err = 526 err =
521 mapping->a_ops->commit_write(fp, page, page_offset, 527 reiserfs_commit_write(fp, page, page_offset,
522 page_offset + chunk + 528 page_offset + chunk +
523 skip); 529 skip);
524 } 530 }
525 unlock_page(page); 531 unlock_page(page);
526 reiserfs_put_page(page); 532 reiserfs_put_page(page);
diff --git a/fs/smbfs/file.c b/fs/smbfs/file.c
index c5d78a7e492b..f5d14cebc75a 100644
--- a/fs/smbfs/file.c
+++ b/fs/smbfs/file.c
@@ -292,29 +292,45 @@ out:
292 * If the writer ends up delaying the write, the writer needs to 292 * If the writer ends up delaying the write, the writer needs to
293 * increment the page use counts until he is done with the page. 293 * increment the page use counts until he is done with the page.
294 */ 294 */
295static int smb_prepare_write(struct file *file, struct page *page, 295static int smb_write_begin(struct file *file, struct address_space *mapping,
296 unsigned offset, unsigned to) 296 loff_t pos, unsigned len, unsigned flags,
297 struct page **pagep, void **fsdata)
297{ 298{
299 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
300 *pagep = __grab_cache_page(mapping, index);
301 if (!*pagep)
302 return -ENOMEM;
298 return 0; 303 return 0;
299} 304}
300 305
301static int smb_commit_write(struct file *file, struct page *page, 306static int smb_write_end(struct file *file, struct address_space *mapping,
302 unsigned offset, unsigned to) 307 loff_t pos, unsigned len, unsigned copied,
308 struct page *page, void *fsdata)
303{ 309{
304 int status; 310 int status;
311 unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
305 312
306 status = -EFAULT;
307 lock_kernel(); 313 lock_kernel();
308 status = smb_updatepage(file, page, offset, to-offset); 314 status = smb_updatepage(file, page, offset, copied);
309 unlock_kernel(); 315 unlock_kernel();
316
317 if (!status) {
318 if (!PageUptodate(page) && copied == PAGE_CACHE_SIZE)
319 SetPageUptodate(page);
320 status = copied;
321 }
322
323 unlock_page(page);
324 page_cache_release(page);
325
310 return status; 326 return status;
311} 327}
312 328
313const struct address_space_operations smb_file_aops = { 329const struct address_space_operations smb_file_aops = {
314 .readpage = smb_readpage, 330 .readpage = smb_readpage,
315 .writepage = smb_writepage, 331 .writepage = smb_writepage,
316 .prepare_write = smb_prepare_write, 332 .write_begin = smb_write_begin,
317 .commit_write = smb_commit_write 333 .write_end = smb_write_end,
318}; 334};
319 335
320/* 336/*
diff --git a/fs/splice.c b/fs/splice.c
index e95a36228863..59a941d404d9 100644
--- a/fs/splice.c
+++ b/fs/splice.c
@@ -447,7 +447,7 @@ fill_it:
447 */ 447 */
448 while (page_nr < nr_pages) 448 while (page_nr < nr_pages)
449 page_cache_release(pages[page_nr++]); 449 page_cache_release(pages[page_nr++]);
450 in->f_ra.prev_index = index; 450 in->f_ra.prev_pos = (loff_t)index << PAGE_CACHE_SHIFT;
451 451
452 if (spd.nr_pages) 452 if (spd.nr_pages)
453 return splice_to_pipe(pipe, &spd); 453 return splice_to_pipe(pipe, &spd);
@@ -563,7 +563,7 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
563 struct address_space *mapping = file->f_mapping; 563 struct address_space *mapping = file->f_mapping;
564 unsigned int offset, this_len; 564 unsigned int offset, this_len;
565 struct page *page; 565 struct page *page;
566 pgoff_t index; 566 void *fsdata;
567 int ret; 567 int ret;
568 568
569 /* 569 /*
@@ -573,49 +573,16 @@ static int pipe_to_file(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
573 if (unlikely(ret)) 573 if (unlikely(ret))
574 return ret; 574 return ret;
575 575
576 index = sd->pos >> PAGE_CACHE_SHIFT;
577 offset = sd->pos & ~PAGE_CACHE_MASK; 576 offset = sd->pos & ~PAGE_CACHE_MASK;
578 577
579 this_len = sd->len; 578 this_len = sd->len;
580 if (this_len + offset > PAGE_CACHE_SIZE) 579 if (this_len + offset > PAGE_CACHE_SIZE)
581 this_len = PAGE_CACHE_SIZE - offset; 580 this_len = PAGE_CACHE_SIZE - offset;
582 581
583find_page: 582 ret = pagecache_write_begin(file, mapping, sd->pos, this_len,
584 page = find_lock_page(mapping, index); 583 AOP_FLAG_UNINTERRUPTIBLE, &page, &fsdata);
585 if (!page) { 584 if (unlikely(ret))
586 ret = -ENOMEM; 585 goto out;
587 page = page_cache_alloc_cold(mapping);
588 if (unlikely(!page))
589 goto out_ret;
590
591 /*
592 * This will also lock the page
593 */
594 ret = add_to_page_cache_lru(page, mapping, index,
595 GFP_KERNEL);
596 if (unlikely(ret))
597 goto out_release;
598 }
599
600 ret = mapping->a_ops->prepare_write(file, page, offset, offset+this_len);
601 if (unlikely(ret)) {
602 loff_t isize = i_size_read(mapping->host);
603
604 if (ret != AOP_TRUNCATED_PAGE)
605 unlock_page(page);
606 page_cache_release(page);
607 if (ret == AOP_TRUNCATED_PAGE)
608 goto find_page;
609
610 /*
611 * prepare_write() may have instantiated a few blocks
612 * outside i_size. Trim these off again.
613 */
614 if (sd->pos + this_len > isize)
615 vmtruncate(mapping->host, isize);
616
617 goto out_ret;
618 }
619 586
620 if (buf->page != page) { 587 if (buf->page != page) {
621 /* 588 /*
@@ -629,31 +596,9 @@ find_page:
629 kunmap_atomic(dst, KM_USER1); 596 kunmap_atomic(dst, KM_USER1);
630 buf->ops->unmap(pipe, buf, src); 597 buf->ops->unmap(pipe, buf, src);
631 } 598 }
632 599 ret = pagecache_write_end(file, mapping, sd->pos, this_len, this_len,
633 ret = mapping->a_ops->commit_write(file, page, offset, offset+this_len); 600 page, fsdata);
634 if (ret) {
635 if (ret == AOP_TRUNCATED_PAGE) {
636 page_cache_release(page);
637 goto find_page;
638 }
639 if (ret < 0)
640 goto out;
641 /*
642 * Partial write has happened, so 'ret' already initialized by
643 * number of bytes written, Where is nothing we have to do here.
644 */
645 } else
646 ret = this_len;
647 /*
648 * Return the number of bytes written and mark page as
649 * accessed, we are now done!
650 */
651 mark_page_accessed(page);
652out: 601out:
653 unlock_page(page);
654out_release:
655 page_cache_release(page);
656out_ret:
657 return ret; 602 return ret;
658} 603}
659 604
@@ -1390,10 +1335,10 @@ static int pipe_to_user(struct pipe_inode_info *pipe, struct pipe_buffer *buf,
1390 if (copy_to_user(sd->u.userptr, src + buf->offset, sd->len)) 1335 if (copy_to_user(sd->u.userptr, src + buf->offset, sd->len))
1391 ret = -EFAULT; 1336 ret = -EFAULT;
1392 1337
1338 buf->ops->unmap(pipe, buf, src);
1393out: 1339out:
1394 if (ret > 0) 1340 if (ret > 0)
1395 sd->u.userptr += ret; 1341 sd->u.userptr += ret;
1396 buf->ops->unmap(pipe, buf, src);
1397 return ret; 1342 return ret;
1398} 1343}
1399 1344
diff --git a/fs/sysfs/inode.c b/fs/sysfs/inode.c
index 9236635111f4..c4ef945d39c8 100644
--- a/fs/sysfs/inode.c
+++ b/fs/sysfs/inode.c
@@ -24,8 +24,8 @@ extern struct super_block * sysfs_sb;
24 24
25static const struct address_space_operations sysfs_aops = { 25static const struct address_space_operations sysfs_aops = {
26 .readpage = simple_readpage, 26 .readpage = simple_readpage,
27 .prepare_write = simple_prepare_write, 27 .write_begin = simple_write_begin,
28 .commit_write = simple_commit_write 28 .write_end = simple_write_end,
29}; 29};
30 30
31static struct backing_dev_info sysfs_backing_dev_info = { 31static struct backing_dev_info sysfs_backing_dev_info = {
diff --git a/fs/sysv/dir.c b/fs/sysv/dir.c
index e566b387fcf9..56f655254bfe 100644
--- a/fs/sysv/dir.c
+++ b/fs/sysv/dir.c
@@ -16,6 +16,7 @@
16#include <linux/pagemap.h> 16#include <linux/pagemap.h>
17#include <linux/highmem.h> 17#include <linux/highmem.h>
18#include <linux/smp_lock.h> 18#include <linux/smp_lock.h>
19#include <linux/swap.h>
19#include "sysv.h" 20#include "sysv.h"
20 21
21static int sysv_readdir(struct file *, void *, filldir_t); 22static int sysv_readdir(struct file *, void *, filldir_t);
@@ -37,12 +38,17 @@ static inline unsigned long dir_pages(struct inode *inode)
37 return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT; 38 return (inode->i_size+PAGE_CACHE_SIZE-1)>>PAGE_CACHE_SHIFT;
38} 39}
39 40
40static int dir_commit_chunk(struct page *page, unsigned from, unsigned to) 41static int dir_commit_chunk(struct page *page, loff_t pos, unsigned len)
41{ 42{
42 struct inode *dir = (struct inode *)page->mapping->host; 43 struct address_space *mapping = page->mapping;
44 struct inode *dir = mapping->host;
43 int err = 0; 45 int err = 0;
44 46
45 page->mapping->a_ops->commit_write(NULL, page, from, to); 47 block_write_end(NULL, mapping, pos, len, len, page, NULL);
48 if (pos+len > dir->i_size) {
49 i_size_write(dir, pos+len);
50 mark_inode_dirty(dir);
51 }
46 if (IS_DIRSYNC(dir)) 52 if (IS_DIRSYNC(dir))
47 err = write_one_page(page, 1); 53 err = write_one_page(page, 1);
48 else 54 else
@@ -186,7 +192,7 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode)
186 unsigned long npages = dir_pages(dir); 192 unsigned long npages = dir_pages(dir);
187 unsigned long n; 193 unsigned long n;
188 char *kaddr; 194 char *kaddr;
189 unsigned from, to; 195 loff_t pos;
190 int err; 196 int err;
191 197
192 /* We take care of directory expansion in the same loop */ 198 /* We take care of directory expansion in the same loop */
@@ -212,16 +218,17 @@ int sysv_add_link(struct dentry *dentry, struct inode *inode)
212 return -EINVAL; 218 return -EINVAL;
213 219
214got_it: 220got_it:
215 from = (char*)de - (char*)page_address(page); 221 pos = page_offset(page) +
216 to = from + SYSV_DIRSIZE; 222 (char*)de - (char*)page_address(page);
217 lock_page(page); 223 lock_page(page);
218 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 224 err = __sysv_write_begin(NULL, page->mapping, pos, SYSV_DIRSIZE,
225 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
219 if (err) 226 if (err)
220 goto out_unlock; 227 goto out_unlock;
221 memcpy (de->name, name, namelen); 228 memcpy (de->name, name, namelen);
222 memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2); 229 memset (de->name + namelen, 0, SYSV_DIRSIZE - namelen - 2);
223 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); 230 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
224 err = dir_commit_chunk(page, from, to); 231 err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
225 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 232 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
226 mark_inode_dirty(dir); 233 mark_inode_dirty(dir);
227out_page: 234out_page:
@@ -238,15 +245,15 @@ int sysv_delete_entry(struct sysv_dir_entry *de, struct page *page)
238 struct address_space *mapping = page->mapping; 245 struct address_space *mapping = page->mapping;
239 struct inode *inode = (struct inode*)mapping->host; 246 struct inode *inode = (struct inode*)mapping->host;
240 char *kaddr = (char*)page_address(page); 247 char *kaddr = (char*)page_address(page);
241 unsigned from = (char*)de - kaddr; 248 loff_t pos = page_offset(page) + (char *)de - kaddr;
242 unsigned to = from + SYSV_DIRSIZE;
243 int err; 249 int err;
244 250
245 lock_page(page); 251 lock_page(page);
246 err = mapping->a_ops->prepare_write(NULL, page, from, to); 252 err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
253 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
247 BUG_ON(err); 254 BUG_ON(err);
248 de->inode = 0; 255 de->inode = 0;
249 err = dir_commit_chunk(page, from, to); 256 err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
250 dir_put_page(page); 257 dir_put_page(page);
251 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; 258 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
252 mark_inode_dirty(inode); 259 mark_inode_dirty(inode);
@@ -263,12 +270,13 @@ int sysv_make_empty(struct inode *inode, struct inode *dir)
263 270
264 if (!page) 271 if (!page)
265 return -ENOMEM; 272 return -ENOMEM;
266 kmap(page); 273 err = __sysv_write_begin(NULL, mapping, 0, 2 * SYSV_DIRSIZE,
267 err = mapping->a_ops->prepare_write(NULL, page, 0, 2 * SYSV_DIRSIZE); 274 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
268 if (err) { 275 if (err) {
269 unlock_page(page); 276 unlock_page(page);
270 goto fail; 277 goto fail;
271 } 278 }
279 kmap(page);
272 280
273 base = (char*)page_address(page); 281 base = (char*)page_address(page);
274 memset(base, 0, PAGE_CACHE_SIZE); 282 memset(base, 0, PAGE_CACHE_SIZE);
@@ -280,9 +288,9 @@ int sysv_make_empty(struct inode *inode, struct inode *dir)
280 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino); 288 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), dir->i_ino);
281 strcpy(de->name,".."); 289 strcpy(de->name,"..");
282 290
291 kunmap(page);
283 err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE); 292 err = dir_commit_chunk(page, 0, 2 * SYSV_DIRSIZE);
284fail: 293fail:
285 kunmap(page);
286 page_cache_release(page); 294 page_cache_release(page);
287 return err; 295 return err;
288} 296}
@@ -336,16 +344,18 @@ not_empty:
336void sysv_set_link(struct sysv_dir_entry *de, struct page *page, 344void sysv_set_link(struct sysv_dir_entry *de, struct page *page,
337 struct inode *inode) 345 struct inode *inode)
338{ 346{
339 struct inode *dir = (struct inode*)page->mapping->host; 347 struct address_space *mapping = page->mapping;
340 unsigned from = (char *)de-(char*)page_address(page); 348 struct inode *dir = mapping->host;
341 unsigned to = from + SYSV_DIRSIZE; 349 loff_t pos = page_offset(page) +
350 (char *)de-(char*)page_address(page);
342 int err; 351 int err;
343 352
344 lock_page(page); 353 lock_page(page);
345 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 354 err = __sysv_write_begin(NULL, mapping, pos, SYSV_DIRSIZE,
355 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
346 BUG_ON(err); 356 BUG_ON(err);
347 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino); 357 de->inode = cpu_to_fs16(SYSV_SB(inode->i_sb), inode->i_ino);
348 err = dir_commit_chunk(page, from, to); 358 err = dir_commit_chunk(page, pos, SYSV_DIRSIZE);
349 dir_put_page(page); 359 dir_put_page(page);
350 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 360 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
351 mark_inode_dirty(dir); 361 mark_inode_dirty(dir);
diff --git a/fs/sysv/itree.c b/fs/sysv/itree.c
index f2bcccd1d6fc..f042eec464c2 100644
--- a/fs/sysv/itree.c
+++ b/fs/sysv/itree.c
@@ -453,23 +453,38 @@ static int sysv_writepage(struct page *page, struct writeback_control *wbc)
453{ 453{
454 return block_write_full_page(page,get_block,wbc); 454 return block_write_full_page(page,get_block,wbc);
455} 455}
456
456static int sysv_readpage(struct file *file, struct page *page) 457static int sysv_readpage(struct file *file, struct page *page)
457{ 458{
458 return block_read_full_page(page,get_block); 459 return block_read_full_page(page,get_block);
459} 460}
460static int sysv_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) 461
462int __sysv_write_begin(struct file *file, struct address_space *mapping,
463 loff_t pos, unsigned len, unsigned flags,
464 struct page **pagep, void **fsdata)
461{ 465{
462 return block_prepare_write(page,from,to,get_block); 466 return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
467 get_block);
463} 468}
469
470static int sysv_write_begin(struct file *file, struct address_space *mapping,
471 loff_t pos, unsigned len, unsigned flags,
472 struct page **pagep, void **fsdata)
473{
474 *pagep = NULL;
475 return __sysv_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
476}
477
464static sector_t sysv_bmap(struct address_space *mapping, sector_t block) 478static sector_t sysv_bmap(struct address_space *mapping, sector_t block)
465{ 479{
466 return generic_block_bmap(mapping,block,get_block); 480 return generic_block_bmap(mapping,block,get_block);
467} 481}
482
468const struct address_space_operations sysv_aops = { 483const struct address_space_operations sysv_aops = {
469 .readpage = sysv_readpage, 484 .readpage = sysv_readpage,
470 .writepage = sysv_writepage, 485 .writepage = sysv_writepage,
471 .sync_page = block_sync_page, 486 .sync_page = block_sync_page,
472 .prepare_write = sysv_prepare_write, 487 .write_begin = sysv_write_begin,
473 .commit_write = generic_commit_write, 488 .write_end = generic_write_end,
474 .bmap = sysv_bmap 489 .bmap = sysv_bmap
475}; 490};
diff --git a/fs/sysv/sysv.h b/fs/sysv/sysv.h
index 5b4fedf17cc4..64c03bdf06a5 100644
--- a/fs/sysv/sysv.h
+++ b/fs/sysv/sysv.h
@@ -136,6 +136,9 @@ extern unsigned long sysv_count_free_blocks(struct super_block *);
136 136
137/* itree.c */ 137/* itree.c */
138extern void sysv_truncate(struct inode *); 138extern void sysv_truncate(struct inode *);
139extern int __sysv_write_begin(struct file *file, struct address_space *mapping,
140 loff_t pos, unsigned len, unsigned flags,
141 struct page **pagep, void **fsdata);
139 142
140/* inode.c */ 143/* inode.c */
141extern int sysv_write_inode(struct inode *, int); 144extern int sysv_write_inode(struct inode *, int);
diff --git a/fs/udf/file.c b/fs/udf/file.c
index 5d7a4ea27753..7c7a1b39d56c 100644
--- a/fs/udf/file.c
+++ b/fs/udf/file.c
@@ -76,36 +76,29 @@ static int udf_adinicb_writepage(struct page *page, struct writeback_control *wb
76 return 0; 76 return 0;
77} 77}
78 78
79static int udf_adinicb_prepare_write(struct file *file, struct page *page, 79static int udf_adinicb_write_end(struct file *file,
80 unsigned offset, unsigned to) 80 struct address_space *mapping,
81 loff_t pos, unsigned len, unsigned copied,
82 struct page *page, void *fsdata)
81{ 83{
82 kmap(page); 84 struct inode *inode = mapping->host;
83 return 0; 85 unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
84} 86 char *kaddr;
85
86static int udf_adinicb_commit_write(struct file *file, struct page *page,
87 unsigned offset, unsigned to)
88{
89 struct inode *inode = page->mapping->host;
90 char *kaddr = page_address(page);
91 87
88 kaddr = kmap_atomic(page, KM_USER0);
92 memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset, 89 memcpy(UDF_I_DATA(inode) + UDF_I_LENEATTR(inode) + offset,
93 kaddr + offset, to - offset); 90 kaddr + offset, copied);
94 mark_inode_dirty(inode); 91 kunmap_atomic(kaddr, KM_USER0);
95 SetPageUptodate(page); 92
96 kunmap(page); 93 return simple_write_end(file, mapping, pos, len, copied, page, fsdata);
97 /* only one page here */
98 if (to > inode->i_size)
99 inode->i_size = to;
100 return 0;
101} 94}
102 95
103const struct address_space_operations udf_adinicb_aops = { 96const struct address_space_operations udf_adinicb_aops = {
104 .readpage = udf_adinicb_readpage, 97 .readpage = udf_adinicb_readpage,
105 .writepage = udf_adinicb_writepage, 98 .writepage = udf_adinicb_writepage,
106 .sync_page = block_sync_page, 99 .sync_page = block_sync_page,
107 .prepare_write = udf_adinicb_prepare_write, 100 .write_begin = simple_write_begin,
108 .commit_write = udf_adinicb_commit_write, 101 .write_end = udf_adinicb_write_end,
109}; 102};
110 103
111static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov, 104static ssize_t udf_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
diff --git a/fs/udf/inode.c b/fs/udf/inode.c
index 1652b2c665bb..6ff8151984cf 100644
--- a/fs/udf/inode.c
+++ b/fs/udf/inode.c
@@ -133,10 +133,13 @@ static int udf_readpage(struct file *file, struct page *page)
133 return block_read_full_page(page, udf_get_block); 133 return block_read_full_page(page, udf_get_block);
134} 134}
135 135
136static int udf_prepare_write(struct file *file, struct page *page, 136static int udf_write_begin(struct file *file, struct address_space *mapping,
137 unsigned from, unsigned to) 137 loff_t pos, unsigned len, unsigned flags,
138 struct page **pagep, void **fsdata)
138{ 139{
139 return block_prepare_write(page, from, to, udf_get_block); 140 *pagep = NULL;
141 return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
142 udf_get_block);
140} 143}
141 144
142static sector_t udf_bmap(struct address_space *mapping, sector_t block) 145static sector_t udf_bmap(struct address_space *mapping, sector_t block)
@@ -148,8 +151,8 @@ const struct address_space_operations udf_aops = {
148 .readpage = udf_readpage, 151 .readpage = udf_readpage,
149 .writepage = udf_writepage, 152 .writepage = udf_writepage,
150 .sync_page = block_sync_page, 153 .sync_page = block_sync_page,
151 .prepare_write = udf_prepare_write, 154 .write_begin = udf_write_begin,
152 .commit_write = generic_commit_write, 155 .write_end = generic_write_end,
153 .bmap = udf_bmap, 156 .bmap = udf_bmap,
154}; 157};
155 158
diff --git a/fs/ufs/dir.c b/fs/ufs/dir.c
index 154452172f43..2410ec6002db 100644
--- a/fs/ufs/dir.c
+++ b/fs/ufs/dir.c
@@ -19,6 +19,7 @@
19#include <linux/time.h> 19#include <linux/time.h>
20#include <linux/fs.h> 20#include <linux/fs.h>
21#include <linux/ufs_fs.h> 21#include <linux/ufs_fs.h>
22#include <linux/swap.h>
22 23
23#include "swab.h" 24#include "swab.h"
24#include "util.h" 25#include "util.h"
@@ -38,12 +39,18 @@ static inline int ufs_match(struct super_block *sb, int len,
38 return !memcmp(name, de->d_name, len); 39 return !memcmp(name, de->d_name, len);
39} 40}
40 41
41static int ufs_commit_chunk(struct page *page, unsigned from, unsigned to) 42static int ufs_commit_chunk(struct page *page, loff_t pos, unsigned len)
42{ 43{
43 struct inode *dir = page->mapping->host; 44 struct address_space *mapping = page->mapping;
45 struct inode *dir = mapping->host;
44 int err = 0; 46 int err = 0;
47
45 dir->i_version++; 48 dir->i_version++;
46 page->mapping->a_ops->commit_write(NULL, page, from, to); 49 block_write_end(NULL, mapping, pos, len, len, page, NULL);
50 if (pos+len > dir->i_size) {
51 i_size_write(dir, pos+len);
52 mark_inode_dirty(dir);
53 }
47 if (IS_DIRSYNC(dir)) 54 if (IS_DIRSYNC(dir))
48 err = write_one_page(page, 1); 55 err = write_one_page(page, 1);
49 else 56 else
@@ -81,16 +88,20 @@ ino_t ufs_inode_by_name(struct inode *dir, struct dentry *dentry)
81void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de, 88void ufs_set_link(struct inode *dir, struct ufs_dir_entry *de,
82 struct page *page, struct inode *inode) 89 struct page *page, struct inode *inode)
83{ 90{
84 unsigned from = (char *) de - (char *) page_address(page); 91 loff_t pos = page_offset(page) +
85 unsigned to = from + fs16_to_cpu(dir->i_sb, de->d_reclen); 92 (char *) de - (char *) page_address(page);
93 unsigned len = fs16_to_cpu(dir->i_sb, de->d_reclen);
86 int err; 94 int err;
87 95
88 lock_page(page); 96 lock_page(page);
89 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 97 err = __ufs_write_begin(NULL, page->mapping, pos, len,
98 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
90 BUG_ON(err); 99 BUG_ON(err);
100
91 de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino); 101 de->d_ino = cpu_to_fs32(dir->i_sb, inode->i_ino);
92 ufs_set_de_type(dir->i_sb, de, inode->i_mode); 102 ufs_set_de_type(dir->i_sb, de, inode->i_mode);
93 err = ufs_commit_chunk(page, from, to); 103
104 err = ufs_commit_chunk(page, pos, len);
94 ufs_put_page(page); 105 ufs_put_page(page);
95 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 106 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
96 mark_inode_dirty(dir); 107 mark_inode_dirty(dir);
@@ -312,7 +323,7 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
312 unsigned long npages = ufs_dir_pages(dir); 323 unsigned long npages = ufs_dir_pages(dir);
313 unsigned long n; 324 unsigned long n;
314 char *kaddr; 325 char *kaddr;
315 unsigned from, to; 326 loff_t pos;
316 int err; 327 int err;
317 328
318 UFSD("ENTER, name %s, namelen %u\n", name, namelen); 329 UFSD("ENTER, name %s, namelen %u\n", name, namelen);
@@ -367,9 +378,10 @@ int ufs_add_link(struct dentry *dentry, struct inode *inode)
367 return -EINVAL; 378 return -EINVAL;
368 379
369got_it: 380got_it:
370 from = (char*)de - (char*)page_address(page); 381 pos = page_offset(page) +
371 to = from + rec_len; 382 (char*)de - (char*)page_address(page);
372 err = page->mapping->a_ops->prepare_write(NULL, page, from, to); 383 err = __ufs_write_begin(NULL, page->mapping, pos, rec_len,
384 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
373 if (err) 385 if (err)
374 goto out_unlock; 386 goto out_unlock;
375 if (de->d_ino) { 387 if (de->d_ino) {
@@ -386,7 +398,7 @@ got_it:
386 de->d_ino = cpu_to_fs32(sb, inode->i_ino); 398 de->d_ino = cpu_to_fs32(sb, inode->i_ino);
387 ufs_set_de_type(sb, de, inode->i_mode); 399 ufs_set_de_type(sb, de, inode->i_mode);
388 400
389 err = ufs_commit_chunk(page, from, to); 401 err = ufs_commit_chunk(page, pos, rec_len);
390 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC; 402 dir->i_mtime = dir->i_ctime = CURRENT_TIME_SEC;
391 403
392 mark_inode_dirty(dir); 404 mark_inode_dirty(dir);
@@ -509,6 +521,7 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
509 char *kaddr = page_address(page); 521 char *kaddr = page_address(page);
510 unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1); 522 unsigned from = ((char*)dir - kaddr) & ~(UFS_SB(sb)->s_uspi->s_dirblksize - 1);
511 unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen); 523 unsigned to = ((char*)dir - kaddr) + fs16_to_cpu(sb, dir->d_reclen);
524 loff_t pos;
512 struct ufs_dir_entry *pde = NULL; 525 struct ufs_dir_entry *pde = NULL;
513 struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from); 526 struct ufs_dir_entry *de = (struct ufs_dir_entry *) (kaddr + from);
514 int err; 527 int err;
@@ -532,13 +545,16 @@ int ufs_delete_entry(struct inode *inode, struct ufs_dir_entry *dir,
532 } 545 }
533 if (pde) 546 if (pde)
534 from = (char*)pde - (char*)page_address(page); 547 from = (char*)pde - (char*)page_address(page);
548
549 pos = page_offset(page) + from;
535 lock_page(page); 550 lock_page(page);
536 err = mapping->a_ops->prepare_write(NULL, page, from, to); 551 err = __ufs_write_begin(NULL, mapping, pos, to - from,
552 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
537 BUG_ON(err); 553 BUG_ON(err);
538 if (pde) 554 if (pde)
539 pde->d_reclen = cpu_to_fs16(sb, to-from); 555 pde->d_reclen = cpu_to_fs16(sb, to - from);
540 dir->d_ino = 0; 556 dir->d_ino = 0;
541 err = ufs_commit_chunk(page, from, to); 557 err = ufs_commit_chunk(page, pos, to - from);
542 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC; 558 inode->i_ctime = inode->i_mtime = CURRENT_TIME_SEC;
543 mark_inode_dirty(inode); 559 mark_inode_dirty(inode);
544out: 560out:
@@ -559,14 +575,15 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
559 575
560 if (!page) 576 if (!page)
561 return -ENOMEM; 577 return -ENOMEM;
562 kmap(page); 578
563 err = mapping->a_ops->prepare_write(NULL, page, 0, chunk_size); 579 err = __ufs_write_begin(NULL, mapping, 0, chunk_size,
580 AOP_FLAG_UNINTERRUPTIBLE, &page, NULL);
564 if (err) { 581 if (err) {
565 unlock_page(page); 582 unlock_page(page);
566 goto fail; 583 goto fail;
567 } 584 }
568 585
569 586 kmap(page);
570 base = (char*)page_address(page); 587 base = (char*)page_address(page);
571 memset(base, 0, PAGE_CACHE_SIZE); 588 memset(base, 0, PAGE_CACHE_SIZE);
572 589
@@ -584,10 +601,10 @@ int ufs_make_empty(struct inode * inode, struct inode *dir)
584 de->d_reclen = cpu_to_fs16(sb, chunk_size - UFS_DIR_REC_LEN(1)); 601 de->d_reclen = cpu_to_fs16(sb, chunk_size - UFS_DIR_REC_LEN(1));
585 ufs_set_de_namlen(sb, de, 2); 602 ufs_set_de_namlen(sb, de, 2);
586 strcpy (de->d_name, ".."); 603 strcpy (de->d_name, "..");
604 kunmap(page);
587 605
588 err = ufs_commit_chunk(page, 0, chunk_size); 606 err = ufs_commit_chunk(page, 0, chunk_size);
589fail: 607fail:
590 kunmap(page);
591 page_cache_release(page); 608 page_cache_release(page);
592 return err; 609 return err;
593} 610}
diff --git a/fs/ufs/inode.c b/fs/ufs/inode.c
index f18b79122fa3..d84d4b0f4779 100644
--- a/fs/ufs/inode.c
+++ b/fs/ufs/inode.c
@@ -558,24 +558,39 @@ static int ufs_writepage(struct page *page, struct writeback_control *wbc)
558{ 558{
559 return block_write_full_page(page,ufs_getfrag_block,wbc); 559 return block_write_full_page(page,ufs_getfrag_block,wbc);
560} 560}
561
561static int ufs_readpage(struct file *file, struct page *page) 562static int ufs_readpage(struct file *file, struct page *page)
562{ 563{
563 return block_read_full_page(page,ufs_getfrag_block); 564 return block_read_full_page(page,ufs_getfrag_block);
564} 565}
565static int ufs_prepare_write(struct file *file, struct page *page, unsigned from, unsigned to) 566
567int __ufs_write_begin(struct file *file, struct address_space *mapping,
568 loff_t pos, unsigned len, unsigned flags,
569 struct page **pagep, void **fsdata)
566{ 570{
567 return block_prepare_write(page,from,to,ufs_getfrag_block); 571 return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
572 ufs_getfrag_block);
568} 573}
574
575static int ufs_write_begin(struct file *file, struct address_space *mapping,
576 loff_t pos, unsigned len, unsigned flags,
577 struct page **pagep, void **fsdata)
578{
579 *pagep = NULL;
580 return __ufs_write_begin(file, mapping, pos, len, flags, pagep, fsdata);
581}
582
569static sector_t ufs_bmap(struct address_space *mapping, sector_t block) 583static sector_t ufs_bmap(struct address_space *mapping, sector_t block)
570{ 584{
571 return generic_block_bmap(mapping,block,ufs_getfrag_block); 585 return generic_block_bmap(mapping,block,ufs_getfrag_block);
572} 586}
587
573const struct address_space_operations ufs_aops = { 588const struct address_space_operations ufs_aops = {
574 .readpage = ufs_readpage, 589 .readpage = ufs_readpage,
575 .writepage = ufs_writepage, 590 .writepage = ufs_writepage,
576 .sync_page = block_sync_page, 591 .sync_page = block_sync_page,
577 .prepare_write = ufs_prepare_write, 592 .write_begin = ufs_write_begin,
578 .commit_write = generic_commit_write, 593 .write_end = generic_write_end,
579 .bmap = ufs_bmap 594 .bmap = ufs_bmap
580}; 595};
581 596
diff --git a/fs/ufs/util.h b/fs/ufs/util.h
index 06d344839c42..79a340a1909e 100644
--- a/fs/ufs/util.h
+++ b/fs/ufs/util.h
@@ -231,6 +231,9 @@ ufs_set_inode_gid(struct super_block *sb, struct ufs_inode *inode, u32 value)
231 231
232extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *); 232extern dev_t ufs_get_inode_dev(struct super_block *, struct ufs_inode_info *);
233extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t); 233extern void ufs_set_inode_dev(struct super_block *, struct ufs_inode_info *, dev_t);
234extern int __ufs_write_begin(struct file *file, struct address_space *mapping,
235 loff_t pos, unsigned len, unsigned flags,
236 struct page **pagep, void **fsdata);
234 237
235/* 238/*
236 * These functions manipulate ufs buffers 239 * These functions manipulate ufs buffers
diff --git a/fs/xfs/linux-2.6/xfs_aops.c b/fs/xfs/linux-2.6/xfs_aops.c
index 6f4c29e9c3d9..354d68a32d4a 100644
--- a/fs/xfs/linux-2.6/xfs_aops.c
+++ b/fs/xfs/linux-2.6/xfs_aops.c
@@ -1508,13 +1508,18 @@ xfs_vm_direct_IO(
1508} 1508}
1509 1509
1510STATIC int 1510STATIC int
1511xfs_vm_prepare_write( 1511xfs_vm_write_begin(
1512 struct file *file, 1512 struct file *file,
1513 struct page *page, 1513 struct address_space *mapping,
1514 unsigned int from, 1514 loff_t pos,
1515 unsigned int to) 1515 unsigned len,
1516 unsigned flags,
1517 struct page **pagep,
1518 void **fsdata)
1516{ 1519{
1517 return block_prepare_write(page, from, to, xfs_get_blocks); 1520 *pagep = NULL;
1521 return block_write_begin(file, mapping, pos, len, flags, pagep, fsdata,
1522 xfs_get_blocks);
1518} 1523}
1519 1524
1520STATIC sector_t 1525STATIC sector_t
@@ -1568,8 +1573,8 @@ const struct address_space_operations xfs_address_space_operations = {
1568 .sync_page = block_sync_page, 1573 .sync_page = block_sync_page,
1569 .releasepage = xfs_vm_releasepage, 1574 .releasepage = xfs_vm_releasepage,
1570 .invalidatepage = xfs_vm_invalidatepage, 1575 .invalidatepage = xfs_vm_invalidatepage,
1571 .prepare_write = xfs_vm_prepare_write, 1576 .write_begin = xfs_vm_write_begin,
1572 .commit_write = generic_commit_write, 1577 .write_end = generic_write_end,
1573 .bmap = xfs_vm_bmap, 1578 .bmap = xfs_vm_bmap,
1574 .direct_IO = xfs_vm_direct_IO, 1579 .direct_IO = xfs_vm_direct_IO,
1575 .migratepage = buffer_migrate_page, 1580 .migratepage = buffer_migrate_page,
diff --git a/fs/xfs/linux-2.6/xfs_lrw.c b/fs/xfs/linux-2.6/xfs_lrw.c
index 765ec16a6e39..7e7aeb4c8a08 100644
--- a/fs/xfs/linux-2.6/xfs_lrw.c
+++ b/fs/xfs/linux-2.6/xfs_lrw.c
@@ -134,45 +134,34 @@ xfs_iozero(
134 loff_t pos, /* offset in file */ 134 loff_t pos, /* offset in file */
135 size_t count) /* size of data to zero */ 135 size_t count) /* size of data to zero */
136{ 136{
137 unsigned bytes;
138 struct page *page; 137 struct page *page;
139 struct address_space *mapping; 138 struct address_space *mapping;
140 int status; 139 int status;
141 140
142 mapping = ip->i_mapping; 141 mapping = ip->i_mapping;
143 do { 142 do {
144 unsigned long index, offset; 143 unsigned offset, bytes;
144 void *fsdata;
145 145
146 offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ 146 offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
147 index = pos >> PAGE_CACHE_SHIFT;
148 bytes = PAGE_CACHE_SIZE - offset; 147 bytes = PAGE_CACHE_SIZE - offset;
149 if (bytes > count) 148 if (bytes > count)
150 bytes = count; 149 bytes = count;
151 150
152 status = -ENOMEM; 151 status = pagecache_write_begin(NULL, mapping, pos, bytes,
153 page = grab_cache_page(mapping, index); 152 AOP_FLAG_UNINTERRUPTIBLE,
154 if (!page) 153 &page, &fsdata);
155 break;
156
157 status = mapping->a_ops->prepare_write(NULL, page, offset,
158 offset + bytes);
159 if (status) 154 if (status)
160 goto unlock; 155 break;
161 156
162 zero_user_page(page, offset, bytes, KM_USER0); 157 zero_user_page(page, offset, bytes, KM_USER0);
163 158
164 status = mapping->a_ops->commit_write(NULL, page, offset, 159 status = pagecache_write_end(NULL, mapping, pos, bytes, bytes,
165 offset + bytes); 160 page, fsdata);
166 if (!status) { 161 WARN_ON(status <= 0); /* can't return less than zero! */
167 pos += bytes; 162 pos += bytes;
168 count -= bytes; 163 count -= bytes;
169 } 164 status = 0;
170
171unlock:
172 unlock_page(page);
173 page_cache_release(page);
174 if (status)
175 break;
176 } while (count); 165 } while (count);
177 166
178 return (-status); 167 return (-status);
diff --git a/include/asm-alpha/page.h b/include/asm-alpha/page.h
index bae7f05716d4..8cc97bfd3789 100644
--- a/include/asm-alpha/page.h
+++ b/include/asm-alpha/page.h
@@ -3,11 +3,12 @@
3 3
4#ifdef __KERNEL__ 4#ifdef __KERNEL__
5 5
6#include <linux/const.h>
6#include <asm/pal.h> 7#include <asm/pal.h>
7 8
8/* PAGE_SHIFT determines the page size */ 9/* PAGE_SHIFT determines the page size */
9#define PAGE_SHIFT 13 10#define PAGE_SHIFT 13
10#define PAGE_SIZE (1UL << PAGE_SHIFT) 11#define PAGE_SIZE (_AC(1,UL) << PAGE_SHIFT)
11#define PAGE_MASK (~(PAGE_SIZE-1)) 12#define PAGE_MASK (~(PAGE_SIZE-1))
12 13
13#ifndef __ASSEMBLY__ 14#ifndef __ASSEMBLY__
diff --git a/include/asm-alpha/ptrace.h b/include/asm-alpha/ptrace.h
index 9933b8b3612e..32c7a5cddd59 100644
--- a/include/asm-alpha/ptrace.h
+++ b/include/asm-alpha/ptrace.h
@@ -68,8 +68,6 @@ struct switch_stack {
68 68
69#ifdef __KERNEL__ 69#ifdef __KERNEL__
70 70
71#define __ARCH_SYS_PTRACE 1
72
73#define user_mode(regs) (((regs)->ps & 8) != 0) 71#define user_mode(regs) (((regs)->ps & 8) != 0)
74#define instruction_pointer(regs) ((regs)->pc) 72#define instruction_pointer(regs) ((regs)->pc)
75#define profile_pc(regs) instruction_pointer(regs) 73#define profile_pc(regs) instruction_pointer(regs)
diff --git a/include/asm-arm/arch-imx/imxfb.h b/include/asm-arm/arch-imx/imxfb.h
index 7dbc7bbba65d..3ed9ec8b9f00 100644
--- a/include/asm-arm/arch-imx/imxfb.h
+++ b/include/asm-arm/arch-imx/imxfb.h
@@ -7,6 +7,7 @@ struct imxfb_mach_info {
7 u_short xres; 7 u_short xres;
8 u_short yres; 8 u_short yres;
9 9
10 u_int nonstd;
10 u_char bpp; 11 u_char bpp;
11 u_char hsync_len; 12 u_char hsync_len;
12 u_char left_margin; 13 u_char left_margin;
diff --git a/include/asm-arm/arch-pxa/pxa-regs.h b/include/asm-arm/arch-pxa/pxa-regs.h
index 67f53e07db86..bb68b598c436 100644
--- a/include/asm-arm/arch-pxa/pxa-regs.h
+++ b/include/asm-arm/arch-pxa/pxa-regs.h
@@ -1823,6 +1823,7 @@
1823#define LCCR1 __REG(0x44000004) /* LCD Controller Control Register 1 */ 1823#define LCCR1 __REG(0x44000004) /* LCD Controller Control Register 1 */
1824#define LCCR2 __REG(0x44000008) /* LCD Controller Control Register 2 */ 1824#define LCCR2 __REG(0x44000008) /* LCD Controller Control Register 2 */
1825#define LCCR3 __REG(0x4400000C) /* LCD Controller Control Register 3 */ 1825#define LCCR3 __REG(0x4400000C) /* LCD Controller Control Register 3 */
1826#define LCCR4 __REG(0x44000010) /* LCD Controller Control Register 3 */
1826#define DFBR0 __REG(0x44000020) /* DMA Channel 0 Frame Branch Register */ 1827#define DFBR0 __REG(0x44000020) /* DMA Channel 0 Frame Branch Register */
1827#define DFBR1 __REG(0x44000024) /* DMA Channel 1 Frame Branch Register */ 1828#define DFBR1 __REG(0x44000024) /* DMA Channel 1 Frame Branch Register */
1828#define LCSR __REG(0x44000038) /* LCD Controller Status Register */ 1829#define LCSR __REG(0x44000038) /* LCD Controller Status Register */
@@ -1836,6 +1837,16 @@
1836#define LCCR3_8BPP (3 << 24) 1837#define LCCR3_8BPP (3 << 24)
1837#define LCCR3_16BPP (4 << 24) 1838#define LCCR3_16BPP (4 << 24)
1838 1839
1840#define LCCR3_PDFOR_0 (0 << 30)
1841#define LCCR3_PDFOR_1 (1 << 30)
1842#define LCCR3_PDFOR_2 (2 << 30)
1843#define LCCR3_PDFOR_3 (3 << 30)
1844
1845#define LCCR4_PAL_FOR_0 (0 << 15)
1846#define LCCR4_PAL_FOR_1 (1 << 15)
1847#define LCCR4_PAL_FOR_2 (2 << 15)
1848#define LCCR4_PAL_FOR_MASK (3 << 15)
1849
1839#define FDADR0 __REG(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */ 1850#define FDADR0 __REG(0x44000200) /* DMA Channel 0 Frame Descriptor Address Register */
1840#define FSADR0 __REG(0x44000204) /* DMA Channel 0 Frame Source Address Register */ 1851#define FSADR0 __REG(0x44000204) /* DMA Channel 0 Frame Source Address Register */
1841#define FIDR0 __REG(0x44000208) /* DMA Channel 0 Frame ID Register */ 1852#define FIDR0 __REG(0x44000208) /* DMA Channel 0 Frame ID Register */
diff --git a/include/asm-arm/arch-pxa/pxafb.h b/include/asm-arm/arch-pxa/pxafb.h
index 81c3928d608c..ea2336aa70e4 100644
--- a/include/asm-arm/arch-pxa/pxafb.h
+++ b/include/asm-arm/arch-pxa/pxafb.h
@@ -70,7 +70,12 @@ struct pxafb_mach_info {
70 * LCCR3_HSP, LCCR3_VSP, LCCR0_Pcd(x), LCCR3_Bpp 70 * LCCR3_HSP, LCCR3_VSP, LCCR0_Pcd(x), LCCR3_Bpp
71 */ 71 */
72 u_int lccr3; 72 u_int lccr3;
73 73 /* The following should be defined in LCCR4
74 * LCCR4_PAL_FOR_0 or LCCR4_PAL_FOR_1 or LCCR4_PAL_FOR_2
75 *
76 * All other bits in LCCR4 should be left alone.
77 */
78 u_int lccr4;
74 void (*pxafb_backlight_power)(int); 79 void (*pxafb_backlight_power)(int);
75 void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *); 80 void (*pxafb_lcd_power)(int, struct fb_var_screeninfo *);
76 81
diff --git a/include/asm-arm/arch-s3c2410/fb.h b/include/asm-arm/arch-s3c2410/fb.h
index 93a58e7862b0..5d0262601a7e 100644
--- a/include/asm-arm/arch-s3c2410/fb.h
+++ b/include/asm-arm/arch-s3c2410/fb.h
@@ -14,12 +14,6 @@
14 14
15#include <asm/arch/regs-lcd.h> 15#include <asm/arch/regs-lcd.h>
16 16
17struct s3c2410fb_val {
18 unsigned int defval;
19 unsigned int min;
20 unsigned int max;
21};
22
23struct s3c2410fb_hw { 17struct s3c2410fb_hw {
24 unsigned long lcdcon1; 18 unsigned long lcdcon1;
25 unsigned long lcdcon2; 19 unsigned long lcdcon2;
@@ -28,23 +22,37 @@ struct s3c2410fb_hw {
28 unsigned long lcdcon5; 22 unsigned long lcdcon5;
29}; 23};
30 24
31struct s3c2410fb_mach_info { 25/* LCD description */
32 unsigned char fixed_syncs; /* do not update sync/border */ 26struct s3c2410fb_display {
33 27 /* LCD type */
34 /* LCD types */ 28 unsigned type;
35 int type;
36 29
37 /* Screen size */ 30 /* Screen size */
38 int width; 31 unsigned short width;
39 int height; 32 unsigned short height;
40 33
41 /* Screen info */ 34 /* Screen info */
42 struct s3c2410fb_val xres; 35 unsigned short xres;
43 struct s3c2410fb_val yres; 36 unsigned short yres;
44 struct s3c2410fb_val bpp; 37 unsigned short bpp;
38
39 unsigned pixclock; /* pixclock in picoseconds */
40 unsigned short left_margin; /* value in pixels (TFT) or HCLKs (STN) */
41 unsigned short right_margin; /* value in pixels (TFT) or HCLKs (STN) */
42 unsigned short hsync_len; /* value in pixels (TFT) or HCLKs (STN) */
43 unsigned short upper_margin; /* value in lines (TFT) or 0 (STN) */
44 unsigned short lower_margin; /* value in lines (TFT) or 0 (STN) */
45 unsigned short vsync_len; /* value in lines (TFT) or 0 (STN) */
45 46
46 /* lcd configuration registers */ 47 /* lcd configuration registers */
47 struct s3c2410fb_hw regs; 48 unsigned long lcdcon5;
49};
50
51struct s3c2410fb_mach_info {
52
53 struct s3c2410fb_display *displays; /* attached diplays info */
54 unsigned num_displays; /* number of defined displays */
55 unsigned default_display;
48 56
49 /* GPIOs */ 57 /* GPIOs */
50 58
diff --git a/include/asm-avr32/kdebug.h b/include/asm-avr32/kdebug.h
index 7f54e2b15d13..fd7e99046b2f 100644
--- a/include/asm-avr32/kdebug.h
+++ b/include/asm-avr32/kdebug.h
@@ -1,26 +1,10 @@
1#ifndef __ASM_AVR32_KDEBUG_H 1#ifndef __ASM_AVR32_KDEBUG_H
2#define __ASM_AVR32_KDEBUG_H 2#define __ASM_AVR32_KDEBUG_H
3 3
4#include <linux/notifier.h>
5
6/* Grossly misnamed. */ 4/* Grossly misnamed. */
7enum die_val { 5enum die_val {
8 DIE_BREAKPOINT, 6 DIE_BREAKPOINT,
9 DIE_SSTEP, 7 DIE_SSTEP,
10}; 8};
11 9
12/*
13 * These are only here because kprobes.c wants them to implement a
14 * blatant layering violation. Will hopefully go away soon once all
15 * architectures are updated.
16 */
17static inline int register_page_fault_notifier(struct notifier_block *nb)
18{
19 return 0;
20}
21static inline int unregister_page_fault_notifier(struct notifier_block *nb)
22{
23 return 0;
24}
25
26#endif /* __ASM_AVR32_KDEBUG_H */ 10#endif /* __ASM_AVR32_KDEBUG_H */
diff --git a/include/asm-avr32/kprobes.h b/include/asm-avr32/kprobes.h
index 190a6377c809..996cb656474e 100644
--- a/include/asm-avr32/kprobes.h
+++ b/include/asm-avr32/kprobes.h
@@ -17,7 +17,7 @@ typedef u16 kprobe_opcode_t;
17#define BREAKPOINT_INSTRUCTION 0xd673 /* breakpoint */ 17#define BREAKPOINT_INSTRUCTION 0xd673 /* breakpoint */
18#define MAX_INSN_SIZE 2 18#define MAX_INSN_SIZE 2
19 19
20#define ARCH_INACTIVE_KPROBE_COUNT 1 20#define kretprobe_blacklist_size 0
21 21
22#define arch_remove_kprobe(p) do { } while (0) 22#define arch_remove_kprobe(p) do { } while (0)
23 23
diff --git a/include/asm-blackfin/mach-bf548/bf54x-lq043.h b/include/asm-blackfin/mach-bf548/bf54x-lq043.h
new file mode 100644
index 000000000000..9c7ca62a45eb
--- /dev/null
+++ b/include/asm-blackfin/mach-bf548/bf54x-lq043.h
@@ -0,0 +1,30 @@
1#ifndef BF54X_LQ043_H
2#define BF54X_LQ043_H
3
4struct bfin_bf54xfb_val {
5 unsigned int defval;
6 unsigned int min;
7 unsigned int max;
8};
9
10struct bfin_bf54xfb_mach_info {
11 unsigned char fixed_syncs; /* do not update sync/border */
12
13 /* LCD types */
14 int type;
15
16 /* Screen size */
17 int width;
18 int height;
19
20 /* Screen info */
21 struct bfin_bf54xfb_val xres;
22 struct bfin_bf54xfb_val yres;
23 struct bfin_bf54xfb_val bpp;
24
25 /* GPIOs */
26 unsigned short disp;
27
28};
29
30#endif /* BF54X_LQ043_H */
diff --git a/include/asm-frv/thread_info.h b/include/asm-frv/thread_info.h
index cc5433e78b52..348b8f1df17e 100644
--- a/include/asm-frv/thread_info.h
+++ b/include/asm-frv/thread_info.h
@@ -88,9 +88,8 @@ register struct thread_info *__current_thread_info asm("gr15");
88 ({ \ 88 ({ \
89 struct thread_info *ret; \ 89 struct thread_info *ret; \
90 \ 90 \
91 ret = kmalloc(THREAD_SIZE, GFP_KERNEL); \ 91 ret = kzalloc(THREAD_SIZE, GFP_KERNEL); \
92 if (ret) \ 92 \
93 memset(ret, 0, THREAD_SIZE); \
94 ret; \ 93 ret; \
95 }) 94 })
96#else 95#else
diff --git a/include/asm-frv/tlbflush.h b/include/asm-frv/tlbflush.h
index da3a3179a85d..8370f97e41ee 100644
--- a/include/asm-frv/tlbflush.h
+++ b/include/asm-frv/tlbflush.h
@@ -57,8 +57,7 @@ do { \
57#define __flush_tlb_global() flush_tlb_all() 57#define __flush_tlb_global() flush_tlb_all()
58#define flush_tlb() flush_tlb_all() 58#define flush_tlb() flush_tlb_all()
59#define flush_tlb_kernel_range(start, end) flush_tlb_all() 59#define flush_tlb_kernel_range(start, end) flush_tlb_all()
60#define flush_tlb_pgtables(mm,start,end) \ 60#define flush_tlb_pgtables(mm,start,end) do { } while(0)
61 asm volatile("movgs %0,scr0 ! movgs %0,scr1" :: "r"(ULONG_MAX) : "memory");
62 61
63#else 62#else
64 63
diff --git a/include/asm-generic/memory_model.h b/include/asm-generic/memory_model.h
index 30d8d33491dd..52226e14bd7d 100644
--- a/include/asm-generic/memory_model.h
+++ b/include/asm-generic/memory_model.h
@@ -46,6 +46,12 @@
46 __pgdat->node_start_pfn; \ 46 __pgdat->node_start_pfn; \
47}) 47})
48 48
49#elif defined(CONFIG_SPARSEMEM_VMEMMAP)
50
51/* memmap is virtually contigious. */
52#define __pfn_to_page(pfn) (vmemmap + (pfn))
53#define __page_to_pfn(page) ((page) - vmemmap)
54
49#elif defined(CONFIG_SPARSEMEM) 55#elif defined(CONFIG_SPARSEMEM)
50/* 56/*
51 * Note: section's mem_map is encorded to reflect its start_pfn. 57 * Note: section's mem_map is encorded to reflect its start_pfn.
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 5f0d797d33fd..44ef329531c3 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -125,10 +125,6 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addres
125#define pgd_offset_gate(mm, addr) pgd_offset(mm, addr) 125#define pgd_offset_gate(mm, addr) pgd_offset(mm, addr)
126#endif 126#endif
127 127
128#ifndef __HAVE_ARCH_LAZY_MMU_PROT_UPDATE
129#define lazy_mmu_prot_update(pte) do { } while (0)
130#endif
131
132#ifndef __HAVE_ARCH_MOVE_PTE 128#ifndef __HAVE_ARCH_MOVE_PTE
133#define move_pte(pte, prot, old_addr, new_addr) (pte) 129#define move_pte(pte, prot, old_addr, new_addr) (pte)
134#endif 130#endif
diff --git a/include/asm-ia64/dma-mapping.h b/include/asm-ia64/dma-mapping.h
index 3ca6d5c14b2e..f1735a22d0ea 100644
--- a/include/asm-ia64/dma-mapping.h
+++ b/include/asm-ia64/dma-mapping.h
@@ -6,7 +6,7 @@
6 * David Mosberger-Tang <davidm@hpl.hp.com> 6 * David Mosberger-Tang <davidm@hpl.hp.com>
7 */ 7 */
8#include <asm/machvec.h> 8#include <asm/machvec.h>
9#include <asm/scatterlist.h> 9#include <linux/scatterlist.h>
10 10
11#define dma_alloc_coherent platform_dma_alloc_coherent 11#define dma_alloc_coherent platform_dma_alloc_coherent
12/* coherent mem. is cheap */ 12/* coherent mem. is cheap */
diff --git a/include/asm-ia64/kdebug.h b/include/asm-ia64/kdebug.h
index 320cd8e754ea..35e49407d06c 100644
--- a/include/asm-ia64/kdebug.h
+++ b/include/asm-ia64/kdebug.h
@@ -26,21 +26,6 @@
26 * 2005-Oct Keith Owens <kaos@sgi.com>. Expand notify_die to cover more 26 * 2005-Oct Keith Owens <kaos@sgi.com>. Expand notify_die to cover more
27 * events. 27 * events.
28 */ 28 */
29#include <linux/notifier.h>
30
31/*
32 * These are only here because kprobes.c wants them to implement a
33 * blatant layering violation. Will hopefully go away soon once all
34 * architectures are updated.
35 */
36static inline int register_page_fault_notifier(struct notifier_block *nb)
37{
38 return 0;
39}
40static inline int unregister_page_fault_notifier(struct notifier_block *nb)
41{
42 return 0;
43}
44 29
45enum die_val { 30enum die_val {
46 DIE_BREAK = 1, 31 DIE_BREAK = 1,
diff --git a/include/asm-ia64/kprobes.h b/include/asm-ia64/kprobes.h
index 067d9dea68f9..a93ce9ef07ff 100644
--- a/include/asm-ia64/kprobes.h
+++ b/include/asm-ia64/kprobes.h
@@ -83,7 +83,7 @@ struct kprobe_ctlblk {
83}; 83};
84 84
85#define ARCH_SUPPORTS_KRETPROBES 85#define ARCH_SUPPORTS_KRETPROBES
86#define ARCH_INACTIVE_KPROBE_COUNT 1 86#define kretprobe_blacklist_size 0
87 87
88#define SLOT0_OPCODE_SHIFT (37) 88#define SLOT0_OPCODE_SHIFT (37)
89#define SLOT1_p1_OPCODE_SHIFT (37 - (64-46)) 89#define SLOT1_p1_OPCODE_SHIFT (37 - (64-46))
diff --git a/include/asm-ia64/pgtable.h b/include/asm-ia64/pgtable.h
index de6d01e24dd0..0971ec90807e 100644
--- a/include/asm-ia64/pgtable.h
+++ b/include/asm-ia64/pgtable.h
@@ -223,12 +223,6 @@ ia64_phys_addr_valid (unsigned long addr)
223 * page table. 223 * page table.
224 */ 224 */
225 225
226/*
227 * On some architectures, special things need to be done when setting
228 * the PTE in a page table. Nothing special needs to be on IA-64.
229 */
230#define set_pte(ptep, pteval) (*(ptep) = (pteval))
231#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
232 226
233#define VMALLOC_START (RGN_BASE(RGN_GATE) + 0x200000000UL) 227#define VMALLOC_START (RGN_BASE(RGN_GATE) + 0x200000000UL)
234#ifdef CONFIG_VIRTUAL_MEM_MAP 228#ifdef CONFIG_VIRTUAL_MEM_MAP
@@ -236,8 +230,14 @@ ia64_phys_addr_valid (unsigned long addr)
236# define VMALLOC_END vmalloc_end 230# define VMALLOC_END vmalloc_end
237 extern unsigned long vmalloc_end; 231 extern unsigned long vmalloc_end;
238#else 232#else
233#if defined(CONFIG_SPARSEMEM) && defined(CONFIG_SPARSEMEM_VMEMMAP)
234/* SPARSEMEM_VMEMMAP uses half of vmalloc... */
235# define VMALLOC_END (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 10)))
236# define vmemmap ((struct page *)VMALLOC_END)
237#else
239# define VMALLOC_END (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 9))) 238# define VMALLOC_END (RGN_BASE(RGN_GATE) + (1UL << (4*PAGE_SHIFT - 9)))
240#endif 239#endif
240#endif
241 241
242/* fs/proc/kcore.c */ 242/* fs/proc/kcore.c */
243#define kc_vaddr_to_offset(v) ((v) - RGN_BASE(RGN_GATE)) 243#define kc_vaddr_to_offset(v) ((v) - RGN_BASE(RGN_GATE))
@@ -315,6 +315,36 @@ ia64_phys_addr_valid (unsigned long addr)
315#define pte_mkhuge(pte) (__pte(pte_val(pte))) 315#define pte_mkhuge(pte) (__pte(pte_val(pte)))
316 316
317/* 317/*
318 * Because ia64's Icache and Dcache is not coherent (on a cpu), we need to
319 * sync icache and dcache when we insert *new* executable page.
320 * __ia64_sync_icache_dcache() check Pg_arch_1 bit and flush icache
321 * if necessary.
322 *
323 * set_pte() is also called by the kernel, but we can expect that the kernel
324 * flushes icache explicitly if necessary.
325 */
326#define pte_present_exec_user(pte)\
327 ((pte_val(pte) & (_PAGE_P | _PAGE_PL_MASK | _PAGE_AR_RX)) == \
328 (_PAGE_P | _PAGE_PL_3 | _PAGE_AR_RX))
329
330extern void __ia64_sync_icache_dcache(pte_t pteval);
331static inline void set_pte(pte_t *ptep, pte_t pteval)
332{
333 /* page is present && page is user && page is executable
334 * && (page swapin or new page or page migraton
335 * || copy_on_write with page copying.)
336 */
337 if (pte_present_exec_user(pteval) &&
338 (!pte_present(*ptep) ||
339 pte_pfn(*ptep) != pte_pfn(pteval)))
340 /* load_module() calles flush_icache_range() explicitly*/
341 __ia64_sync_icache_dcache(pteval);
342 *ptep = pteval;
343}
344
345#define set_pte_at(mm,addr,ptep,pteval) set_pte(ptep,pteval)
346
347/*
318 * Make page protection values cacheable, uncacheable, or write- 348 * Make page protection values cacheable, uncacheable, or write-
319 * combining. Note that "protection" is really a misnomer here as the 349 * combining. Note that "protection" is really a misnomer here as the
320 * protection value contains the memory attribute bits, dirty bits, and 350 * protection value contains the memory attribute bits, dirty bits, and
@@ -483,12 +513,6 @@ extern struct page *zero_page_memmap_ptr;
483#define HUGETLB_PGDIR_MASK (~(HUGETLB_PGDIR_SIZE-1)) 513#define HUGETLB_PGDIR_MASK (~(HUGETLB_PGDIR_SIZE-1))
484#endif 514#endif
485 515
486/*
487 * IA-64 doesn't have any external MMU info: the page tables contain all the necessary
488 * information. However, we use this routine to take care of any (delayed) i-cache
489 * flushing that may be necessary.
490 */
491extern void lazy_mmu_prot_update (pte_t pte);
492 516
493#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS 517#define __HAVE_ARCH_PTEP_SET_ACCESS_FLAGS
494/* 518/*
@@ -578,7 +602,7 @@ extern void lazy_mmu_prot_update (pte_t pte);
578#define __HAVE_ARCH_PTEP_SET_WRPROTECT 602#define __HAVE_ARCH_PTEP_SET_WRPROTECT
579#define __HAVE_ARCH_PTE_SAME 603#define __HAVE_ARCH_PTE_SAME
580#define __HAVE_ARCH_PGD_OFFSET_GATE 604#define __HAVE_ARCH_PGD_OFFSET_GATE
581#define __HAVE_ARCH_LAZY_MMU_PROT_UPDATE 605
582 606
583#ifndef CONFIG_PGTABLE_4 607#ifndef CONFIG_PGTABLE_4
584#include <asm-generic/pgtable-nopud.h> 608#include <asm-generic/pgtable-nopud.h>
diff --git a/include/asm-ia64/scatterlist.h b/include/asm-ia64/scatterlist.h
index a452ea24205a..7d5234d50312 100644
--- a/include/asm-ia64/scatterlist.h
+++ b/include/asm-ia64/scatterlist.h
@@ -30,4 +30,6 @@ struct scatterlist {
30#define sg_dma_len(sg) ((sg)->dma_length) 30#define sg_dma_len(sg) ((sg)->dma_length)
31#define sg_dma_address(sg) ((sg)->dma_address) 31#define sg_dma_address(sg) ((sg)->dma_address)
32 32
33#define ARCH_HAS_SG_CHAIN
34
33#endif /* _ASM_IA64_SCATTERLIST_H */ 35#endif /* _ASM_IA64_SCATTERLIST_H */
diff --git a/include/asm-ia64/smp.h b/include/asm-ia64/smp.h
index 6314b29e8c4d..1703c9d885bd 100644
--- a/include/asm-ia64/smp.h
+++ b/include/asm-ia64/smp.h
@@ -58,7 +58,7 @@ extern char no_int_routing __devinitdata;
58 58
59extern cpumask_t cpu_online_map; 59extern cpumask_t cpu_online_map;
60extern cpumask_t cpu_core_map[NR_CPUS]; 60extern cpumask_t cpu_core_map[NR_CPUS];
61extern cpumask_t cpu_sibling_map[NR_CPUS]; 61DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
62extern int smp_num_siblings; 62extern int smp_num_siblings;
63extern int smp_num_cpucores; 63extern int smp_num_cpucores;
64extern void __iomem *ipi_base_addr; 64extern void __iomem *ipi_base_addr;
diff --git a/include/asm-ia64/topology.h b/include/asm-ia64/topology.h
index 233f1caae048..2d67b72b18d0 100644
--- a/include/asm-ia64/topology.h
+++ b/include/asm-ia64/topology.h
@@ -112,7 +112,7 @@ void build_cpu_to_node_map(void);
112#define topology_physical_package_id(cpu) (cpu_data(cpu)->socket_id) 112#define topology_physical_package_id(cpu) (cpu_data(cpu)->socket_id)
113#define topology_core_id(cpu) (cpu_data(cpu)->core_id) 113#define topology_core_id(cpu) (cpu_data(cpu)->core_id)
114#define topology_core_siblings(cpu) (cpu_core_map[cpu]) 114#define topology_core_siblings(cpu) (cpu_core_map[cpu])
115#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu]) 115#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
116#define smt_capable() (smp_num_siblings > 1) 116#define smt_capable() (smp_num_siblings > 1)
117#endif 117#endif
118 118
diff --git a/include/asm-m32r/ptrace.h b/include/asm-m32r/ptrace.h
index 632b4ce4269a..a0755b982028 100644
--- a/include/asm-m32r/ptrace.h
+++ b/include/asm-m32r/ptrace.h
@@ -120,7 +120,10 @@ struct pt_regs {
120 120
121#include <asm/m32r.h> /* M32R_PSW_BSM, M32R_PSW_BPM */ 121#include <asm/m32r.h> /* M32R_PSW_BSM, M32R_PSW_BPM */
122 122
123#define __ARCH_SYS_PTRACE 1 123struct task_struct;
124extern void init_debug_traps(struct task_struct *);
125#define arch_ptrace_attach(child) \
126 init_debug_traps(child)
124 127
125#if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2) 128#if defined(CONFIG_ISA_M32R2) || defined(CONFIG_CHIP_VDEC2)
126#define user_mode(regs) ((M32R_PSW_BPM & (regs)->psw) != 0) 129#define user_mode(regs) ((M32R_PSW_BPM & (regs)->psw) != 0)
diff --git a/include/asm-m32r/thread_info.h b/include/asm-m32r/thread_info.h
index b7ccc3e68604..c039820dba7c 100644
--- a/include/asm-m32r/thread_info.h
+++ b/include/asm-m32r/thread_info.h
@@ -100,9 +100,8 @@ static inline struct thread_info *current_thread_info(void)
100 ({ \ 100 ({ \
101 struct thread_info *ret; \ 101 struct thread_info *ret; \
102 \ 102 \
103 ret = kmalloc(THREAD_SIZE, GFP_KERNEL); \ 103 ret = kzalloc(THREAD_SIZE, GFP_KERNEL); \
104 if (ret) \ 104 \
105 memset(ret, 0, THREAD_SIZE); \
106 ret; \ 105 ret; \
107 }) 106 })
108#else 107#else
diff --git a/include/asm-m68knommu/system.h b/include/asm-m68knommu/system.h
index 5da43a5d12a3..1bd1142685e1 100644
--- a/include/asm-m68knommu/system.h
+++ b/include/asm-m68knommu/system.h
@@ -253,8 +253,7 @@ cmpxchg(volatile int *p, int old, int new)
253 "); \ 253 "); \
254}) 254})
255#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \ 255#elif defined(CONFIG_NETtel) || defined(CONFIG_eLIA) || \
256 defined(CONFIG_DISKtel) || defined(CONFIG_SECUREEDGEMP3) || \ 256 defined(CONFIG_SECUREEDGEMP3) || defined(CONFIG_CLEOPATRA)
257 defined(CONFIG_CLEOPATRA)
258#define HARD_RESET_NOW() ({ \ 257#define HARD_RESET_NOW() ({ \
259 asm(" \ 258 asm(" \
260 movew #0x2700, %sr; \ 259 movew #0x2700, %sr; \
diff --git a/include/asm-mips/xxs1500.h b/include/asm-mips/xxs1500.h
deleted file mode 100644
index 4d84a90b0f20..000000000000
--- a/include/asm-mips/xxs1500.h
+++ /dev/null
@@ -1,35 +0,0 @@
1/*
2 * MyCable XXS1500 Referrence Board
3 *
4 * Copyright 2003 MontaVista Software Inc.
5 * Author: Pete Popov, MontaVista Software, Inc.
6 * ppopov@mvista.com or source@mvista.com
7 *
8 * ########################################################################
9 *
10 * This program is free software; you can distribute it and/or modify it
11 * under the terms of the GNU General Public License (Version 2) as
12 * published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope it will be useful, but WITHOUT
15 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
16 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
17 * for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 59 Temple Place - Suite 330, Boston MA 02111-1307, USA.
22 *
23 * ########################################################################
24 *
25 *
26 */
27#ifndef __ASM_XXS1500_H
28#define __ASM_XXS1500_H
29
30/* PCMCIA XXS1500 specific defines */
31#define PCMCIA_MAX_SOCK 0
32#define PCMCIA_NUM_SOCKS (PCMCIA_MAX_SOCK+1)
33#define PCMCIA_IRQ AU1000_GPIO_4
34
35#endif /* __ASM_XXS1500_ */
diff --git a/include/asm-powerpc/dma-mapping.h b/include/asm-powerpc/dma-mapping.h
index d05891608f74..2af321f36aba 100644
--- a/include/asm-powerpc/dma-mapping.h
+++ b/include/asm-powerpc/dma-mapping.h
@@ -6,149 +6,6 @@
6 */ 6 */
7#ifndef _ASM_DMA_MAPPING_H 7#ifndef _ASM_DMA_MAPPING_H
8#define _ASM_DMA_MAPPING_H 8#define _ASM_DMA_MAPPING_H
9#ifdef __KERNEL__
10
11#include <linux/types.h>
12#include <linux/cache.h>
13/* need struct page definitions */
14#include <linux/mm.h>
15#include <asm/scatterlist.h>
16#include <asm/io.h>
17
18#define DMA_ERROR_CODE (~(dma_addr_t)0x0)
19
20#ifdef CONFIG_NOT_COHERENT_CACHE
21/*
22 * DMA-consistent mapping functions for PowerPCs that don't support
23 * cache snooping. These allocate/free a region of uncached mapped
24 * memory space for use with DMA devices. Alternatively, you could
25 * allocate the space "normally" and use the cache management functions
26 * to ensure it is consistent.
27 */
28extern void *__dma_alloc_coherent(size_t size, dma_addr_t *handle, gfp_t gfp);
29extern void __dma_free_coherent(size_t size, void *vaddr);
30extern void __dma_sync(void *vaddr, size_t size, int direction);
31extern void __dma_sync_page(struct page *page, unsigned long offset,
32 size_t size, int direction);
33
34#else /* ! CONFIG_NOT_COHERENT_CACHE */
35/*
36 * Cache coherent cores.
37 */
38
39#define __dma_alloc_coherent(gfp, size, handle) NULL
40#define __dma_free_coherent(size, addr) ((void)0)
41#define __dma_sync(addr, size, rw) ((void)0)
42#define __dma_sync_page(pg, off, sz, rw) ((void)0)
43
44#endif /* ! CONFIG_NOT_COHERENT_CACHE */
45
46#ifdef CONFIG_PPC64
47/*
48 * DMA operations are abstracted for G5 vs. i/pSeries, PCI vs. VIO
49 */
50struct dma_mapping_ops {
51 void * (*alloc_coherent)(struct device *dev, size_t size,
52 dma_addr_t *dma_handle, gfp_t flag);
53 void (*free_coherent)(struct device *dev, size_t size,
54 void *vaddr, dma_addr_t dma_handle);
55 dma_addr_t (*map_single)(struct device *dev, void *ptr,
56 size_t size, enum dma_data_direction direction);
57 void (*unmap_single)(struct device *dev, dma_addr_t dma_addr,
58 size_t size, enum dma_data_direction direction);
59 int (*map_sg)(struct device *dev, struct scatterlist *sg,
60 int nents, enum dma_data_direction direction);
61 void (*unmap_sg)(struct device *dev, struct scatterlist *sg,
62 int nents, enum dma_data_direction direction);
63 int (*dma_supported)(struct device *dev, u64 mask);
64 int (*set_dma_mask)(struct device *dev, u64 dma_mask);
65};
66
67static inline struct dma_mapping_ops *get_dma_ops(struct device *dev)
68{
69 /* We don't handle the NULL dev case for ISA for now. We could
70 * do it via an out of line call but it is not needed for now. The
71 * only ISA DMA device we support is the floppy and we have a hack
72 * in the floppy driver directly to get a device for us.
73 */
74 if (unlikely(dev == NULL || dev->archdata.dma_ops == NULL))
75 return NULL;
76 return dev->archdata.dma_ops;
77}
78
79static inline int dma_supported(struct device *dev, u64 mask)
80{
81 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
82
83 if (unlikely(dma_ops == NULL))
84 return 0;
85 if (dma_ops->dma_supported == NULL)
86 return 1;
87 return dma_ops->dma_supported(dev, mask);
88}
89
90static inline int dma_set_mask(struct device *dev, u64 dma_mask)
91{
92 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
93
94 if (unlikely(dma_ops == NULL))
95 return -EIO;
96 if (dma_ops->set_dma_mask != NULL)
97 return dma_ops->set_dma_mask(dev, dma_mask);
98 if (!dev->dma_mask || !dma_supported(dev, dma_mask))
99 return -EIO;
100 *dev->dma_mask = dma_mask;
101 return 0;
102}
103
104static inline void *dma_alloc_coherent(struct device *dev, size_t size,
105 dma_addr_t *dma_handle, gfp_t flag)
106{
107 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
108
109 BUG_ON(!dma_ops);
110 return dma_ops->alloc_coherent(dev, size, dma_handle, flag);
111}
112
113static inline void dma_free_coherent(struct device *dev, size_t size,
114 void *cpu_addr, dma_addr_t dma_handle)
115{
116 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
117
118 BUG_ON(!dma_ops);
119 dma_ops->free_coherent(dev, size, cpu_addr, dma_handle);
120}
121
122static inline dma_addr_t dma_map_single(struct device *dev, void *cpu_addr,
123 size_t size,
124 enum dma_data_direction direction)
125{
126 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
127
128 BUG_ON(!dma_ops);
129 return dma_ops->map_single(dev, cpu_addr, size, direction);
130}
131
132static inline void dma_unmap_single(struct device *dev, dma_addr_t dma_addr,
133 size_t size,
134 enum dma_data_direction direction)
135{
136 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
137
138 BUG_ON(!dma_ops);
139 dma_ops->unmap_single(dev, dma_addr, size, direction);
140}
141
142static inline dma_addr_t dma_map_page(struct device *dev, struct page *page,
143 unsigned long offset, size_t size,
144 enum dma_data_direction direction)
145{
146 struct dma_mapping_ops *dma_ops = get_dma_ops(dev);
147
148 BUG_ON(!dma_ops);
149 return dma_ops->map_single(dev, page_address(page) + offset, size,
150 direction);
151}
152 9
153static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address, 10static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
154 size_t size, 11 size_t size,
@@ -276,14 +133,15 @@ static inline void dma_unmap_page(struct device *dev, dma_addr_t dma_address,
276} 133}
277 134
278static inline int 135static inline int
279dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, 136dma_map_sg(struct device *dev, struct scatterlist *sgl, int nents,
280 enum dma_data_direction direction) 137 enum dma_data_direction direction)
281{ 138{
139 struct scatterlist *sg;
282 int i; 140 int i;
283 141
284 BUG_ON(direction == DMA_NONE); 142 BUG_ON(direction == DMA_NONE);
285 143
286 for (i = 0; i < nents; i++, sg++) { 144 for_each_sg(sgl, sg, nents, i) {
287 BUG_ON(!sg->page); 145 BUG_ON(!sg->page);
288 __dma_sync_page(sg->page, sg->offset, sg->length, direction); 146 __dma_sync_page(sg->page, sg->offset, sg->length, direction);
289 sg->dma_address = page_to_bus(sg->page) + sg->offset; 147 sg->dma_address = page_to_bus(sg->page) + sg->offset;
@@ -318,26 +176,28 @@ static inline void dma_sync_single_for_device(struct device *dev,
318} 176}
319 177
320static inline void dma_sync_sg_for_cpu(struct device *dev, 178static inline void dma_sync_sg_for_cpu(struct device *dev,
321 struct scatterlist *sg, int nents, 179 struct scatterlist *sgl, int nents,
322 enum dma_data_direction direction) 180 enum dma_data_direction direction)
323{ 181{
182 struct scatterlist *sg;
324 int i; 183 int i;
325 184
326 BUG_ON(direction == DMA_NONE); 185 BUG_ON(direction == DMA_NONE);
327 186
328 for (i = 0; i < nents; i++, sg++) 187 for_each_sg(sgl, sg, nents, i)
329 __dma_sync_page(sg->page, sg->offset, sg->length, direction); 188 __dma_sync_page(sg->page, sg->offset, sg->length, direction);
330} 189}
331 190
332static inline void dma_sync_sg_for_device(struct device *dev, 191static inline void dma_sync_sg_for_device(struct device *dev,
333 struct scatterlist *sg, int nents, 192 struct scatterlist *sgl, int nents,
334 enum dma_data_direction direction) 193 enum dma_data_direction direction)
335{ 194{
195 struct scatterlist *sg;
336 int i; 196 int i;
337 197
338 BUG_ON(direction == DMA_NONE); 198 BUG_ON(direction == DMA_NONE);
339 199
340 for (i = 0; i < nents; i++, sg++) 200 for_each_sg(sgl, sg, nents, i)
341 __dma_sync_page(sg->page, sg->offset, sg->length, direction); 201 __dma_sync_page(sg->page, sg->offset, sg->length, direction);
342} 202}
343 203
diff --git a/include/asm-powerpc/kdebug.h b/include/asm-powerpc/kdebug.h
index 295f0162c608..ae6d206728af 100644
--- a/include/asm-powerpc/kdebug.h
+++ b/include/asm-powerpc/kdebug.h
@@ -2,25 +2,6 @@
2#define _ASM_POWERPC_KDEBUG_H 2#define _ASM_POWERPC_KDEBUG_H
3#ifdef __KERNEL__ 3#ifdef __KERNEL__
4 4
5/* nearly identical to x86_64/i386 code */
6
7#include <linux/notifier.h>
8
9/*
10 * These are only here because kprobes.c wants them to implement a
11 * blatant layering violation. Will hopefully go away soon once all
12 * architectures are updated.
13 */
14static inline int register_page_fault_notifier(struct notifier_block *nb)
15{
16 return 0;
17}
18static inline int unregister_page_fault_notifier(struct notifier_block *nb)
19{
20 return 0;
21}
22extern struct atomic_notifier_head powerpc_die_chain;
23
24/* Grossly misnamed. */ 5/* Grossly misnamed. */
25enum die_val { 6enum die_val {
26 DIE_OOPS = 1, 7 DIE_OOPS = 1,
diff --git a/include/asm-powerpc/kprobes.h b/include/asm-powerpc/kprobes.h
index 8b08b447d6f3..afabad230dbb 100644
--- a/include/asm-powerpc/kprobes.h
+++ b/include/asm-powerpc/kprobes.h
@@ -81,8 +81,8 @@ typedef unsigned int kprobe_opcode_t;
81#endif 81#endif
82 82
83#define ARCH_SUPPORTS_KRETPROBES 83#define ARCH_SUPPORTS_KRETPROBES
84#define ARCH_INACTIVE_KPROBE_COUNT 1
85#define flush_insn_slot(p) do { } while (0) 84#define flush_insn_slot(p) do { } while (0)
85#define kretprobe_blacklist_size 0
86 86
87void kretprobe_trampoline(void); 87void kretprobe_trampoline(void);
88extern void arch_remove_kprobe(struct kprobe *p); 88extern void arch_remove_kprobe(struct kprobe *p);
diff --git a/include/asm-powerpc/pgtable-ppc64.h b/include/asm-powerpc/pgtable-ppc64.h
index 300f9a199bf2..dd4c26dc57d2 100644
--- a/include/asm-powerpc/pgtable-ppc64.h
+++ b/include/asm-powerpc/pgtable-ppc64.h
@@ -68,6 +68,14 @@
68#define USER_REGION_ID (0UL) 68#define USER_REGION_ID (0UL)
69 69
70/* 70/*
71 * Defines the address of the vmemap area, in the top 16th of the
72 * kernel region.
73 */
74#define VMEMMAP_BASE (ASM_CONST(CONFIG_KERNEL_START) + \
75 (0xfUL << (REGION_SHIFT - 4)))
76#define vmemmap ((struct page *)VMEMMAP_BASE)
77
78/*
71 * Common bits in a linux-style PTE. These match the bits in the 79 * Common bits in a linux-style PTE. These match the bits in the
72 * (hardware-defined) PowerPC PTE as closely as possible. Additional 80 * (hardware-defined) PowerPC PTE as closely as possible. Additional
73 * bits may be defined in pgtable-*.h 81 * bits may be defined in pgtable-*.h
diff --git a/include/asm-powerpc/ps3av.h b/include/asm-powerpc/ps3av.h
index 7df4250802de..967930b82ed3 100644
--- a/include/asm-powerpc/ps3av.h
+++ b/include/asm-powerpc/ps3av.h
@@ -283,7 +283,7 @@
283#define PS3AV_CMD_VIDEO_CS_YUV422 0x0002 283#define PS3AV_CMD_VIDEO_CS_YUV422 0x0002
284#define PS3AV_CMD_VIDEO_CS_YUV444 0x0003 284#define PS3AV_CMD_VIDEO_CS_YUV444 0x0003
285 285
286/* for automode */ 286/* for broadcast automode */
287#define PS3AV_RESBIT_720x480P 0x0003 /* 0x0001 | 0x0002 */ 287#define PS3AV_RESBIT_720x480P 0x0003 /* 0x0001 | 0x0002 */
288#define PS3AV_RESBIT_720x576P 0x0003 /* 0x0001 | 0x0002 */ 288#define PS3AV_RESBIT_720x576P 0x0003 /* 0x0001 | 0x0002 */
289#define PS3AV_RESBIT_1280x720P 0x0004 289#define PS3AV_RESBIT_1280x720P 0x0004
@@ -298,13 +298,22 @@
298 | PS3AV_RESBIT_1920x1080I \ 298 | PS3AV_RESBIT_1920x1080I \
299 | PS3AV_RESBIT_1920x1080P) 299 | PS3AV_RESBIT_1920x1080P)
300 300
301/* for VESA automode */
302#define PS3AV_RESBIT_VGA 0x0001
303#define PS3AV_RESBIT_WXGA 0x0002
304#define PS3AV_RESBIT_SXGA 0x0004
305#define PS3AV_RESBIT_WUXGA 0x0008
306#define PS3AV_RES_MASK_VESA (PS3AV_RESBIT_WXGA |\
307 PS3AV_RESBIT_SXGA |\
308 PS3AV_RESBIT_WUXGA)
309
301#define PS3AV_MONITOR_TYPE_HDMI 1 /* HDMI */ 310#define PS3AV_MONITOR_TYPE_HDMI 1 /* HDMI */
302#define PS3AV_MONITOR_TYPE_DVI 2 /* DVI */ 311#define PS3AV_MONITOR_TYPE_DVI 2 /* DVI */
303#define PS3AV_DEFAULT_HDMI_VID_REG_60 PS3AV_CMD_VIDEO_VID_480P 312
304#define PS3AV_DEFAULT_AVMULTI_VID_REG_60 PS3AV_CMD_VIDEO_VID_480I 313#define PS3AV_DEFAULT_HDMI_MODE_ID_REG_60 2 /* 480p */
305#define PS3AV_DEFAULT_HDMI_VID_REG_50 PS3AV_CMD_VIDEO_VID_576P 314#define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_60 1 /* 480i */
306#define PS3AV_DEFAULT_AVMULTI_VID_REG_50 PS3AV_CMD_VIDEO_VID_576I 315#define PS3AV_DEFAULT_HDMI_MODE_ID_REG_50 7 /* 576p */
307#define PS3AV_DEFAULT_DVI_VID PS3AV_CMD_VIDEO_VID_480P 316#define PS3AV_DEFAULT_AVMULTI_MODE_ID_REG_50 6 /* 576i */
308 317
309#define PS3AV_REGION_60 0x01 318#define PS3AV_REGION_60 0x01
310#define PS3AV_REGION_50 0x02 319#define PS3AV_REGION_50 0x02
@@ -697,20 +706,12 @@ extern int ps3av_cmd_audio_mute(int, u32 *, u32);
697extern int ps3av_cmd_audio_active(int, u32); 706extern int ps3av_cmd_audio_active(int, u32);
698extern int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *, u32); 707extern int ps3av_cmd_avb_param(struct ps3av_pkt_avb_param *, u32);
699extern int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *); 708extern int ps3av_cmd_av_get_hw_conf(struct ps3av_pkt_av_get_hw_conf *);
700#ifdef PS3AV_DEBUG
701extern void ps3av_cmd_av_hw_conf_dump(const struct ps3av_pkt_av_get_hw_conf *);
702extern void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *);
703#else
704static inline void ps3av_cmd_av_hw_conf_dump(const struct ps3av_pkt_av_get_hw_conf *hw_conf) {}
705static inline void ps3av_cmd_av_monitor_info_dump(const struct ps3av_pkt_av_get_monitor_info *monitor_info) {}
706#endif
707extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *, 709extern int ps3av_cmd_video_get_monitor_info(struct ps3av_pkt_av_get_monitor_info *,
708 u32); 710 u32);
709 711
710extern int ps3av_set_video_mode(u32, int); 712extern int ps3av_set_video_mode(u32);
711extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32); 713extern int ps3av_set_audio_mode(u32, u32, u32, u32, u32);
712extern int ps3av_get_auto_mode(int); 714extern int ps3av_get_auto_mode(void);
713extern int ps3av_set_mode(u32, int);
714extern int ps3av_get_mode(void); 715extern int ps3av_get_mode(void);
715extern int ps3av_get_scanmode(int); 716extern int ps3av_get_scanmode(int);
716extern int ps3av_get_refresh_rate(int); 717extern int ps3av_get_refresh_rate(int);
diff --git a/include/asm-powerpc/scatterlist.h b/include/asm-powerpc/scatterlist.h
index 8c992d1491d4..b075f619c3b7 100644
--- a/include/asm-powerpc/scatterlist.h
+++ b/include/asm-powerpc/scatterlist.h
@@ -41,5 +41,7 @@ struct scatterlist {
41#define ISA_DMA_THRESHOLD (~0UL) 41#define ISA_DMA_THRESHOLD (~0UL)
42#endif 42#endif
43 43
44#define ARCH_HAS_SG_CHAIN
45
44#endif /* __KERNEL__ */ 46#endif /* __KERNEL__ */
45#endif /* _ASM_POWERPC_SCATTERLIST_H */ 47#endif /* _ASM_POWERPC_SCATTERLIST_H */
diff --git a/include/asm-powerpc/smp.h b/include/asm-powerpc/smp.h
index 19102bfc14ca..505f35bacaa9 100644
--- a/include/asm-powerpc/smp.h
+++ b/include/asm-powerpc/smp.h
@@ -26,6 +26,7 @@
26#ifdef CONFIG_PPC64 26#ifdef CONFIG_PPC64
27#include <asm/paca.h> 27#include <asm/paca.h>
28#endif 28#endif
29#include <asm/percpu.h>
29 30
30extern int boot_cpuid; 31extern int boot_cpuid;
31 32
@@ -58,7 +59,7 @@ extern int smp_hw_index[];
58 (smp_hw_index[(cpu)] = (phys)) 59 (smp_hw_index[(cpu)] = (phys))
59#endif 60#endif
60 61
61extern cpumask_t cpu_sibling_map[NR_CPUS]; 62DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
62 63
63/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers. 64/* Since OpenPIC has only 4 IPIs, we use slightly different message numbers.
64 * 65 *
@@ -77,6 +78,7 @@ void smp_init_pSeries(void);
77void smp_init_cell(void); 78void smp_init_cell(void);
78void smp_init_celleb(void); 79void smp_init_celleb(void);
79void smp_setup_cpu_maps(void); 80void smp_setup_cpu_maps(void);
81void smp_setup_cpu_sibling_map(void);
80 82
81extern int __cpu_disable(void); 83extern int __cpu_disable(void);
82extern void __cpu_die(unsigned int cpu); 84extern void __cpu_die(unsigned int cpu);
diff --git a/include/asm-powerpc/topology.h b/include/asm-powerpc/topology.h
index 0ad21a849b5f..ca23b681ad05 100644
--- a/include/asm-powerpc/topology.h
+++ b/include/asm-powerpc/topology.h
@@ -108,7 +108,7 @@ static inline void sysfs_remove_device_from_node(struct sys_device *dev,
108#ifdef CONFIG_PPC64 108#ifdef CONFIG_PPC64
109#include <asm/smp.h> 109#include <asm/smp.h>
110 110
111#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu]) 111#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
112#endif 112#endif
113#endif 113#endif
114 114
diff --git a/include/asm-s390/kdebug.h b/include/asm-s390/kdebug.h
index 04418af08f85..40db27cd6e60 100644
--- a/include/asm-s390/kdebug.h
+++ b/include/asm-s390/kdebug.h
@@ -4,24 +4,9 @@
4/* 4/*
5 * Feb 2006 Ported to s390 <grundym@us.ibm.com> 5 * Feb 2006 Ported to s390 <grundym@us.ibm.com>
6 */ 6 */
7#include <linux/notifier.h>
8 7
9struct pt_regs; 8struct pt_regs;
10 9
11/*
12 * These are only here because kprobes.c wants them to implement a
13 * blatant layering violation. Will hopefully go away soon once all
14 * architectures are updated.
15 */
16static inline int register_page_fault_notifier(struct notifier_block *nb)
17{
18 return 0;
19}
20static inline int unregister_page_fault_notifier(struct notifier_block *nb)
21{
22 return 0;
23}
24
25enum die_val { 10enum die_val {
26 DIE_OOPS = 1, 11 DIE_OOPS = 1,
27 DIE_BPT, 12 DIE_BPT,
diff --git a/include/asm-s390/kprobes.h b/include/asm-s390/kprobes.h
index 340ba10446ea..948db3d0d05c 100644
--- a/include/asm-s390/kprobes.h
+++ b/include/asm-s390/kprobes.h
@@ -47,7 +47,7 @@ typedef u16 kprobe_opcode_t;
47 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) 47 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
48 48
49#define ARCH_SUPPORTS_KRETPROBES 49#define ARCH_SUPPORTS_KRETPROBES
50#define ARCH_INACTIVE_KPROBE_COUNT 0 50#define kretprobe_blacklist_size 0
51 51
52#define KPROBE_SWAP_INST 0x10 52#define KPROBE_SWAP_INST 0x10
53 53
diff --git a/include/asm-sh/kdebug.h b/include/asm-sh/kdebug.h
index 382cfc7deb73..49cd69051a88 100644
--- a/include/asm-sh/kdebug.h
+++ b/include/asm-sh/kdebug.h
@@ -1,8 +1,6 @@
1#ifndef __ASM_SH_KDEBUG_H 1#ifndef __ASM_SH_KDEBUG_H
2#define __ASM_SH_KDEBUG_H 2#define __ASM_SH_KDEBUG_H
3 3
4#include <linux/notifier.h>
5
6/* Grossly misnamed. */ 4/* Grossly misnamed. */
7enum die_val { 5enum die_val {
8 DIE_TRAP, 6 DIE_TRAP,
diff --git a/include/asm-sparc/scatterlist.h b/include/asm-sparc/scatterlist.h
index a4fcf9ac9649..4055af90ad7e 100644
--- a/include/asm-sparc/scatterlist.h
+++ b/include/asm-sparc/scatterlist.h
@@ -19,4 +19,6 @@ struct scatterlist {
19 19
20#define ISA_DMA_THRESHOLD (~0UL) 20#define ISA_DMA_THRESHOLD (~0UL)
21 21
22#define ARCH_HAS_SG_CHAIN
23
22#endif /* !(_SPARC_SCATTERLIST_H) */ 24#endif /* !(_SPARC_SCATTERLIST_H) */
diff --git a/include/asm-sparc64/kdebug.h b/include/asm-sparc64/kdebug.h
index 9974c7b0aebc..f905b773235a 100644
--- a/include/asm-sparc64/kdebug.h
+++ b/include/asm-sparc64/kdebug.h
@@ -1,26 +1,8 @@
1#ifndef _SPARC64_KDEBUG_H 1#ifndef _SPARC64_KDEBUG_H
2#define _SPARC64_KDEBUG_H 2#define _SPARC64_KDEBUG_H
3 3
4/* Nearly identical to x86_64/i386 code. */
5
6#include <linux/notifier.h>
7
8struct pt_regs; 4struct pt_regs;
9 5
10/*
11 * These are only here because kprobes.c wants them to implement a
12 * blatant layering violation. Will hopefully go away soon once all
13 * architectures are updated.
14 */
15static inline int register_page_fault_notifier(struct notifier_block *nb)
16{
17 return 0;
18}
19static inline int unregister_page_fault_notifier(struct notifier_block *nb)
20{
21 return 0;
22}
23
24extern void bad_trap(struct pt_regs *, long); 6extern void bad_trap(struct pt_regs *, long);
25 7
26/* Grossly misnamed. */ 8/* Grossly misnamed. */
diff --git a/include/asm-sparc64/kprobes.h b/include/asm-sparc64/kprobes.h
index 7f6774dca5f4..5020eaf67c29 100644
--- a/include/asm-sparc64/kprobes.h
+++ b/include/asm-sparc64/kprobes.h
@@ -10,8 +10,9 @@ typedef u32 kprobe_opcode_t;
10#define BREAKPOINT_INSTRUCTION_2 0x91d02071 /* ta 0x71 */ 10#define BREAKPOINT_INSTRUCTION_2 0x91d02071 /* ta 0x71 */
11#define MAX_INSN_SIZE 2 11#define MAX_INSN_SIZE 2
12 12
13#define kretprobe_blacklist_size 0
14
13#define arch_remove_kprobe(p) do {} while (0) 15#define arch_remove_kprobe(p) do {} while (0)
14#define ARCH_INACTIVE_KPROBE_COUNT 0
15 16
16#define flush_insn_slot(p) \ 17#define flush_insn_slot(p) \
17do { flushi(&(p)->ainsn.insn[0]); \ 18do { flushi(&(p)->ainsn.insn[0]); \
diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h
index 0393380d754a..3167ccff64f8 100644
--- a/include/asm-sparc64/pgtable.h
+++ b/include/asm-sparc64/pgtable.h
@@ -42,6 +42,9 @@
42#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL) 42#define HI_OBP_ADDRESS _AC(0x0000000100000000,UL)
43#define VMALLOC_START _AC(0x0000000100000000,UL) 43#define VMALLOC_START _AC(0x0000000100000000,UL)
44#define VMALLOC_END _AC(0x0000000200000000,UL) 44#define VMALLOC_END _AC(0x0000000200000000,UL)
45#define VMEMMAP_BASE _AC(0x0000000200000000,UL)
46
47#define vmemmap ((struct page *)VMEMMAP_BASE)
45 48
46/* XXX All of this needs to be rethought so we can take advantage 49/* XXX All of this needs to be rethought so we can take advantage
47 * XXX cheetah's full 64-bit virtual address space, ie. no more hole 50 * XXX cheetah's full 64-bit virtual address space, ie. no more hole
diff --git a/include/asm-sparc64/scatterlist.h b/include/asm-sparc64/scatterlist.h
index 048fdb40e81d..703c5bbe6c8c 100644
--- a/include/asm-sparc64/scatterlist.h
+++ b/include/asm-sparc64/scatterlist.h
@@ -20,4 +20,6 @@ struct scatterlist {
20 20
21#define ISA_DMA_THRESHOLD (~0UL) 21#define ISA_DMA_THRESHOLD (~0UL)
22 22
23#define ARCH_HAS_SG_CHAIN
24
23#endif /* !(_SPARC64_SCATTERLIST_H) */ 25#endif /* !(_SPARC64_SCATTERLIST_H) */
diff --git a/include/asm-sparc64/smp.h b/include/asm-sparc64/smp.h
index e8a96a31761b..42c09949526c 100644
--- a/include/asm-sparc64/smp.h
+++ b/include/asm-sparc64/smp.h
@@ -28,8 +28,9 @@
28 28
29#include <asm/bitops.h> 29#include <asm/bitops.h>
30#include <asm/atomic.h> 30#include <asm/atomic.h>
31#include <asm/percpu.h>
31 32
32extern cpumask_t cpu_sibling_map[NR_CPUS]; 33DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
33extern cpumask_t cpu_core_map[NR_CPUS]; 34extern cpumask_t cpu_core_map[NR_CPUS];
34extern int sparc64_multi_core; 35extern int sparc64_multi_core;
35 36
diff --git a/include/asm-sparc64/topology.h b/include/asm-sparc64/topology.h
index 290ac75f385b..c6b557034f68 100644
--- a/include/asm-sparc64/topology.h
+++ b/include/asm-sparc64/topology.h
@@ -5,7 +5,7 @@
5#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id) 5#define topology_physical_package_id(cpu) (cpu_data(cpu).proc_id)
6#define topology_core_id(cpu) (cpu_data(cpu).core_id) 6#define topology_core_id(cpu) (cpu_data(cpu).core_id)
7#define topology_core_siblings(cpu) (cpu_core_map[cpu]) 7#define topology_core_siblings(cpu) (cpu_core_map[cpu])
8#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu]) 8#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
9#define mc_capable() (sparc64_multi_core) 9#define mc_capable() (sparc64_multi_core)
10#define smt_capable() (sparc64_multi_core) 10#define smt_capable() (sparc64_multi_core)
11#endif /* CONFIG_SMP */ 11#endif /* CONFIG_SMP */
diff --git a/include/asm-um/a.out.h b/include/asm-um/a.out.h
index 78bc9eed26b2..9281dd8eb334 100644
--- a/include/asm-um/a.out.h
+++ b/include/asm-um/a.out.h
@@ -1,8 +1,12 @@
1/*
2 * Copyright (C) 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL
4 */
5
1#ifndef __UM_A_OUT_H 6#ifndef __UM_A_OUT_H
2#define __UM_A_OUT_H 7#define __UM_A_OUT_H
3 8
4#include "asm/arch/a.out.h" 9#include "asm/arch/a.out.h"
5#include "choose-mode.h"
6 10
7#undef STACK_TOP 11#undef STACK_TOP
8#undef STACK_TOP_MAX 12#undef STACK_TOP_MAX
@@ -13,10 +17,8 @@ extern unsigned long host_task_size;
13 17
14#define STACK_ROOM (stacksizelim) 18#define STACK_ROOM (stacksizelim)
15 19
16extern int honeypot; 20#define STACK_TOP task_size
17#define STACK_TOP \
18 CHOOSE_MODE((honeypot ? host_task_size : task_size), task_size)
19 21
20#define STACK_TOP_MAX STACK_TOP 22#define STACK_TOP_MAX STACK_TOP
21 23
22#endif 24#endif
diff --git a/include/asm-um/elf-i386.h b/include/asm-um/elf-i386.h
index 9bab712dc5c0..ca94a136dfe8 100644
--- a/include/asm-um/elf-i386.h
+++ b/include/asm-um/elf-i386.h
@@ -5,7 +5,8 @@
5#ifndef __UM_ELF_I386_H 5#ifndef __UM_ELF_I386_H
6#define __UM_ELF_I386_H 6#define __UM_ELF_I386_H
7 7
8#include <asm/user.h> 8#include <linux/sched.h>
9#include "skas.h"
9 10
10#define R_386_NONE 0 11#define R_386_NONE 0
11#define R_386_32 1 12#define R_386_32 1
@@ -75,6 +76,15 @@ typedef struct user_i387_struct elf_fpregset_t;
75 pr_reg[16] = PT_REGS_SS(regs); \ 76 pr_reg[16] = PT_REGS_SS(regs); \
76} while(0); 77} while(0);
77 78
79static inline int elf_core_copy_fpregs(struct task_struct *t,
80 elf_fpregset_t *fpu)
81{
82 int cpu = ((struct thread_info *) t->stack)->cpu;
83 return save_fp_registers(userspace_pid[cpu], (unsigned long *) fpu);
84}
85
86#define ELF_CORE_COPY_FPREGS(t, fpu) elf_core_copy_fpregs(t, fpu)
87
78extern long elf_aux_hwcap; 88extern long elf_aux_hwcap;
79#define ELF_HWCAP (elf_aux_hwcap) 89#define ELF_HWCAP (elf_aux_hwcap)
80 90
diff --git a/include/asm-um/elf-x86_64.h b/include/asm-um/elf-x86_64.h
index 857471c49dac..3c9d543eb61e 100644
--- a/include/asm-um/elf-x86_64.h
+++ b/include/asm-um/elf-x86_64.h
@@ -1,5 +1,6 @@
1/* 1/*
2 * Copyright 2003 PathScale, Inc. 2 * Copyright 2003 PathScale, Inc.
3 * Copyright (C) 2003 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * 4 *
4 * Licensed under the GPL 5 * Licensed under the GPL
5 */ 6 */
@@ -36,7 +37,7 @@ typedef unsigned long elf_greg_t;
36#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t)) 37#define ELF_NGREG (sizeof (struct user_regs_struct) / sizeof(elf_greg_t))
37typedef elf_greg_t elf_gregset_t[ELF_NGREG]; 38typedef elf_greg_t elf_gregset_t[ELF_NGREG];
38 39
39typedef struct { } elf_fpregset_t; 40typedef struct user_i387_struct elf_fpregset_t;
40 41
41/* 42/*
42 * This is used to ensure we don't load something for the wrong architecture. 43 * This is used to ensure we don't load something for the wrong architecture.
@@ -67,27 +68,27 @@ typedef struct { } elf_fpregset_t;
67} while (0) 68} while (0)
68 69
69#define ELF_CORE_COPY_REGS(pr_reg, regs) \ 70#define ELF_CORE_COPY_REGS(pr_reg, regs) \
70 (pr_reg)[0] = (regs)->regs.skas.regs[0]; \ 71 (pr_reg)[0] = (regs)->regs.gp[0]; \
71 (pr_reg)[1] = (regs)->regs.skas.regs[1]; \ 72 (pr_reg)[1] = (regs)->regs.gp[1]; \
72 (pr_reg)[2] = (regs)->regs.skas.regs[2]; \ 73 (pr_reg)[2] = (regs)->regs.gp[2]; \
73 (pr_reg)[3] = (regs)->regs.skas.regs[3]; \ 74 (pr_reg)[3] = (regs)->regs.gp[3]; \
74 (pr_reg)[4] = (regs)->regs.skas.regs[4]; \ 75 (pr_reg)[4] = (regs)->regs.gp[4]; \
75 (pr_reg)[5] = (regs)->regs.skas.regs[5]; \ 76 (pr_reg)[5] = (regs)->regs.gp[5]; \
76 (pr_reg)[6] = (regs)->regs.skas.regs[6]; \ 77 (pr_reg)[6] = (regs)->regs.gp[6]; \
77 (pr_reg)[7] = (regs)->regs.skas.regs[7]; \ 78 (pr_reg)[7] = (regs)->regs.gp[7]; \
78 (pr_reg)[8] = (regs)->regs.skas.regs[8]; \ 79 (pr_reg)[8] = (regs)->regs.gp[8]; \
79 (pr_reg)[9] = (regs)->regs.skas.regs[9]; \ 80 (pr_reg)[9] = (regs)->regs.gp[9]; \
80 (pr_reg)[10] = (regs)->regs.skas.regs[10]; \ 81 (pr_reg)[10] = (regs)->regs.gp[10]; \
81 (pr_reg)[11] = (regs)->regs.skas.regs[11]; \ 82 (pr_reg)[11] = (regs)->regs.gp[11]; \
82 (pr_reg)[12] = (regs)->regs.skas.regs[12]; \ 83 (pr_reg)[12] = (regs)->regs.gp[12]; \
83 (pr_reg)[13] = (regs)->regs.skas.regs[13]; \ 84 (pr_reg)[13] = (regs)->regs.gp[13]; \
84 (pr_reg)[14] = (regs)->regs.skas.regs[14]; \ 85 (pr_reg)[14] = (regs)->regs.gp[14]; \
85 (pr_reg)[15] = (regs)->regs.skas.regs[15]; \ 86 (pr_reg)[15] = (regs)->regs.gp[15]; \
86 (pr_reg)[16] = (regs)->regs.skas.regs[16]; \ 87 (pr_reg)[16] = (regs)->regs.gp[16]; \
87 (pr_reg)[17] = (regs)->regs.skas.regs[17]; \ 88 (pr_reg)[17] = (regs)->regs.gp[17]; \
88 (pr_reg)[18] = (regs)->regs.skas.regs[18]; \ 89 (pr_reg)[18] = (regs)->regs.gp[18]; \
89 (pr_reg)[19] = (regs)->regs.skas.regs[19]; \ 90 (pr_reg)[19] = (regs)->regs.gp[19]; \
90 (pr_reg)[20] = (regs)->regs.skas.regs[20]; \ 91 (pr_reg)[20] = (regs)->regs.gp[20]; \
91 (pr_reg)[21] = current->thread.arch.fs; \ 92 (pr_reg)[21] = current->thread.arch.fs; \
92 (pr_reg)[22] = 0; \ 93 (pr_reg)[22] = 0; \
93 (pr_reg)[23] = 0; \ 94 (pr_reg)[23] = 0; \
@@ -122,14 +123,3 @@ extern long elf_aux_hwcap;
122#define SET_PERSONALITY(ex, ibcs2) do ; while(0) 123#define SET_PERSONALITY(ex, ibcs2) do ; while(0)
123 124
124#endif 125#endif
125
126/*
127 * Overrides for Emacs so that we follow Linus's tabbing style.
128 * Emacs will notice this stuff at the end of the file and automatically
129 * adjust the settings for this buffer only. This must remain at the end
130 * of the file.
131 * ---------------------------------------------------------------------------
132 * Local variables:
133 * c-file-style: "linux"
134 * End:
135 */
diff --git a/include/asm-um/ldt.h b/include/asm-um/ldt.h
index 96f82a456ce6..b2553f3e87eb 100644
--- a/include/asm-um/ldt.h
+++ b/include/asm-um/ldt.h
@@ -11,11 +11,7 @@
11#include "asm/semaphore.h" 11#include "asm/semaphore.h"
12#include "asm/host_ldt.h" 12#include "asm/host_ldt.h"
13 13
14struct mmu_context_skas;
15extern void ldt_host_info(void); 14extern void ldt_host_info(void);
16extern long init_new_ldt(struct mmu_context_skas * to_mm,
17 struct mmu_context_skas * from_mm);
18extern void free_ldt(struct mmu_context_skas * mm);
19 15
20#define LDT_PAGES_MAX \ 16#define LDT_PAGES_MAX \
21 ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE) 17 ((LDT_ENTRIES * LDT_ENTRY_SIZE)/PAGE_SIZE)
diff --git a/include/asm-um/mmu_context.h b/include/asm-um/mmu_context.h
index 9aa4b44e8cc1..5f3b863aef9a 100644
--- a/include/asm-um/mmu_context.h
+++ b/include/asm-um/mmu_context.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -9,7 +9,6 @@
9#include <asm-generic/mm_hooks.h> 9#include <asm-generic/mm_hooks.h>
10 10
11#include "linux/sched.h" 11#include "linux/sched.h"
12#include "choose-mode.h"
13#include "um_mmu.h" 12#include "um_mmu.h"
14 13
15#define get_mmu_context(task) do ; while(0) 14#define get_mmu_context(task) do ; while(0)
@@ -30,8 +29,7 @@ static inline void activate_mm(struct mm_struct *old, struct mm_struct *new)
30 * possible. 29 * possible.
31 */ 30 */
32 if (old != new && (current->flags & PF_BORROWED_MM)) 31 if (old != new && (current->flags & PF_BORROWED_MM))
33 CHOOSE_MODE(force_flush_all(), 32 __switch_mm(&new->context.id);
34 switch_mm_skas(&new->context.skas.id));
35} 33}
36 34
37static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, 35static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
@@ -43,8 +41,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next,
43 cpu_clear(cpu, prev->cpu_vm_mask); 41 cpu_clear(cpu, prev->cpu_vm_mask);
44 cpu_set(cpu, next->cpu_vm_mask); 42 cpu_set(cpu, next->cpu_vm_mask);
45 if(next != &init_mm) 43 if(next != &init_mm)
46 CHOOSE_MODE((void) 0, 44 __switch_mm(&next->context.id);
47 switch_mm_skas(&next->context.skas.id));
48 } 45 }
49} 46}
50 47
@@ -53,38 +50,8 @@ static inline void enter_lazy_tlb(struct mm_struct *mm,
53{ 50{
54} 51}
55 52
56extern int init_new_context_skas(struct task_struct *task, 53extern int init_new_context(struct task_struct *task, struct mm_struct *mm);
57 struct mm_struct *mm);
58 54
59static inline int init_new_context_tt(struct task_struct *task, 55extern void destroy_context(struct mm_struct *mm);
60 struct mm_struct *mm)
61{
62 return(0);
63}
64
65static inline int init_new_context(struct task_struct *task,
66 struct mm_struct *mm)
67{
68 return(CHOOSE_MODE_PROC(init_new_context_tt, init_new_context_skas,
69 task, mm));
70}
71
72extern void destroy_context_skas(struct mm_struct *mm);
73
74static inline void destroy_context(struct mm_struct *mm)
75{
76 CHOOSE_MODE((void) 0, destroy_context_skas(mm));
77}
78 56
79#endif 57#endif
80
81/*
82 * Overrides for Emacs so that we follow Linus's tabbing style.
83 * Emacs will notice this stuff at the end of the file and automatically
84 * adjust the settings for this buffer only. This must remain at the end
85 * of the file.
86 * ---------------------------------------------------------------------------
87 * Local variables:
88 * c-file-style: "linux"
89 * End:
90 */
diff --git a/include/asm-um/page.h b/include/asm-um/page.h
index 8e310d81e5b4..4b424c75fca5 100644
--- a/include/asm-um/page.h
+++ b/include/asm-um/page.h
@@ -9,6 +9,7 @@
9 9
10struct page; 10struct page;
11 11
12#include <linux/types.h>
12#include <asm/vm-flags.h> 13#include <asm/vm-flags.h>
13 14
14/* PAGE_SHIFT determines the page size */ 15/* PAGE_SHIFT determines the page size */
diff --git a/include/asm-um/pgalloc.h b/include/asm-um/pgalloc.h
index 34ab268ef40e..14904876e8fb 100644
--- a/include/asm-um/pgalloc.h
+++ b/include/asm-um/pgalloc.h
@@ -42,7 +42,7 @@ static inline void pte_free(struct page *pte)
42 42
43#ifdef CONFIG_3_LEVEL_PGTABLES 43#ifdef CONFIG_3_LEVEL_PGTABLES
44 44
45extern __inline__ void pmd_free(pmd_t *pmd) 45static inline void pmd_free(pmd_t *pmd)
46{ 46{
47 free_page((unsigned long)pmd); 47 free_page((unsigned long)pmd);
48} 48}
diff --git a/include/asm-um/pgtable-3level.h b/include/asm-um/pgtable-3level.h
index ca0c2a92a112..aa82b88db805 100644
--- a/include/asm-um/pgtable-3level.h
+++ b/include/asm-um/pgtable-3level.h
@@ -69,7 +69,7 @@ static inline pmd_t *pmd_alloc_one(struct mm_struct *mm, unsigned long address)
69 return pmd; 69 return pmd;
70} 70}
71 71
72extern inline void pud_clear (pud_t *pud) 72static inline void pud_clear (pud_t *pud)
73{ 73{
74 set_pud(pud, __pud(0)); 74 set_pud(pud, __pud(0));
75} 75}
diff --git a/include/asm-um/processor-generic.h b/include/asm-um/processor-generic.h
index d99bbddffdb9..78c0599cc80c 100644
--- a/include/asm-um/processor-generic.h
+++ b/include/asm-um/processor-generic.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -11,44 +11,32 @@ struct pt_regs;
11struct task_struct; 11struct task_struct;
12 12
13#include "asm/ptrace.h" 13#include "asm/ptrace.h"
14#include "choose-mode.h"
15#include "registers.h" 14#include "registers.h"
16#include "sysdep/archsetjmp.h" 15#include "sysdep/archsetjmp.h"
17 16
18struct mm_struct; 17struct mm_struct;
19 18
20struct thread_struct { 19struct thread_struct {
21 /* This flag is set to 1 before calling do_fork (and analyzed in 20 struct task_struct *saved_task;
21 /*
22 * This flag is set to 1 before calling do_fork (and analyzed in
22 * copy_thread) to mark that we are begin called from userspace (fork / 23 * copy_thread) to mark that we are begin called from userspace (fork /
23 * vfork / clone), and reset to 0 after. It is left to 0 when called 24 * vfork / clone), and reset to 0 after. It is left to 0 when called
24 * from kernelspace (i.e. kernel_thread() or fork_idle(), as of 2.6.11). */ 25 * from kernelspace (i.e. kernel_thread() or fork_idle(),
25 struct task_struct *saved_task; 26 * as of 2.6.11).
27 */
26 int forking; 28 int forking;
27 int nsyscalls; 29 int nsyscalls;
28 struct pt_regs regs; 30 struct pt_regs regs;
29 int singlestep_syscall; 31 int singlestep_syscall;
30 void *fault_addr; 32 void *fault_addr;
31 void *fault_catcher; 33 jmp_buf *fault_catcher;
32 struct task_struct *prev_sched; 34 struct task_struct *prev_sched;
33 unsigned long temp_stack; 35 unsigned long temp_stack;
34 void *exec_buf; 36 jmp_buf *exec_buf;
35 struct arch_thread arch; 37 struct arch_thread arch;
36 union { 38 jmp_buf switch_buf;
37#ifdef CONFIG_MODE_TT 39 int mm_count;
38 struct {
39 int extern_pid;
40 int tracing;
41 int switch_pipe[2];
42 int vm_seq;
43 } tt;
44#endif
45#ifdef CONFIG_MODE_SKAS
46 struct {
47 jmp_buf switch_buf;
48 int mm_count;
49 } skas;
50#endif
51 } mode;
52 struct { 40 struct {
53 int op; 41 int op;
54 union { 42 union {
@@ -71,7 +59,7 @@ struct thread_struct {
71{ \ 59{ \
72 .forking = 0, \ 60 .forking = 0, \
73 .nsyscalls = 0, \ 61 .nsyscalls = 0, \
74 .regs = EMPTY_REGS, \ 62 .regs = EMPTY_REGS, \
75 .fault_addr = NULL, \ 63 .fault_addr = NULL, \
76 .prev_sched = NULL, \ 64 .prev_sched = NULL, \
77 .temp_stack = 0, \ 65 .temp_stack = 0, \
@@ -86,7 +74,10 @@ typedef struct {
86 74
87extern struct task_struct *alloc_task_struct(void); 75extern struct task_struct *alloc_task_struct(void);
88 76
89extern void release_thread(struct task_struct *); 77static inline void release_thread(struct task_struct *task)
78{
79}
80
90extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags); 81extern int kernel_thread(int (*fn)(void *), void * arg, unsigned long flags);
91 82
92static inline void prepare_to_copy(struct task_struct *tsk) 83static inline void prepare_to_copy(struct task_struct *tsk)
@@ -136,12 +127,7 @@ extern struct cpuinfo_um cpu_data[];
136#endif 127#endif
137 128
138 129
139#ifdef CONFIG_MODE_SKAS 130#define KSTK_REG(tsk, reg) get_thread_reg(reg, &tsk->thread.switch_buf)
140#define KSTK_REG(tsk, reg) \
141 get_thread_reg(reg, &tsk->thread.mode.skas.switch_buf)
142#else
143#define KSTK_REG(tsk, reg) (0xbadbabe)
144#endif
145#define get_wchan(p) (0) 131#define get_wchan(p) (0)
146 132
147#endif 133#endif
diff --git a/include/asm-um/processor-x86_64.h b/include/asm-um/processor-x86_64.h
index 31c2d4d685bd..d946bf2d334a 100644
--- a/include/asm-um/processor-x86_64.h
+++ b/include/asm-um/processor-x86_64.h
@@ -18,7 +18,7 @@ struct arch_thread {
18}; 18};
19 19
20/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */ 20/* REP NOP (PAUSE) is a good thing to insert into busy-wait loops. */
21extern inline void rep_nop(void) 21static inline void rep_nop(void)
22{ 22{
23 __asm__ __volatile__("rep;nop": : :"memory"); 23 __asm__ __volatile__("rep;nop": : :"memory");
24} 24}
diff --git a/include/asm-um/ptrace-generic.h b/include/asm-um/ptrace-generic.h
index 99c87c5ce994..6aefcd32fc61 100644
--- a/include/asm-um/ptrace-generic.h
+++ b/include/asm-um/ptrace-generic.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -9,10 +9,11 @@
9#ifndef __ASSEMBLY__ 9#ifndef __ASSEMBLY__
10 10
11#include "asm/arch/ptrace-abi.h" 11#include "asm/arch/ptrace-abi.h"
12#include <asm/user.h>
12#include "sysdep/ptrace.h" 13#include "sysdep/ptrace.h"
13 14
14struct pt_regs { 15struct pt_regs {
15 union uml_pt_regs regs; 16 struct uml_pt_regs regs;
16}; 17};
17 18
18#define EMPTY_REGS { .regs = EMPTY_UML_PT_REGS } 19#define EMPTY_REGS { .regs = EMPTY_UML_PT_REGS }
@@ -35,16 +36,18 @@ struct pt_regs {
35 36
36struct task_struct; 37struct task_struct;
37 38
39extern long subarch_ptrace(struct task_struct *child, long request, long addr,
40 long data);
38extern unsigned long getreg(struct task_struct *child, int regno); 41extern unsigned long getreg(struct task_struct *child, int regno);
39extern int putreg(struct task_struct *child, int regno, unsigned long value); 42extern int putreg(struct task_struct *child, int regno, unsigned long value);
40extern int get_fpregs(unsigned long buf, struct task_struct *child); 43extern int get_fpregs(struct user_i387_struct __user *buf,
41extern int set_fpregs(unsigned long buf, struct task_struct *child); 44 struct task_struct *child);
42extern int get_fpxregs(unsigned long buf, struct task_struct *child); 45extern int set_fpregs(struct user_i387_struct __user *buf,
43extern int set_fpxregs(unsigned long buf, struct task_struct *tsk); 46 struct task_struct *child);
44 47
45extern void show_regs(struct pt_regs *regs); 48extern void show_regs(struct pt_regs *regs);
46 49
47extern void send_sigtrap(struct task_struct *tsk, union uml_pt_regs *regs, 50extern void send_sigtrap(struct task_struct *tsk, struct uml_pt_regs *regs,
48 int error_code); 51 int error_code);
49 52
50extern int arch_copy_tls(struct task_struct *new); 53extern int arch_copy_tls(struct task_struct *new);
diff --git a/include/asm-um/ptrace-i386.h b/include/asm-um/ptrace-i386.h
index 6e2528bb0083..b2d24c5ea2c3 100644
--- a/include/asm-um/ptrace-i386.h
+++ b/include/asm-um/ptrace-i386.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2000, 2001, 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2000 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -9,10 +9,9 @@
9#define HOST_AUDIT_ARCH AUDIT_ARCH_I386 9#define HOST_AUDIT_ARCH AUDIT_ARCH_I386
10 10
11#include "linux/compiler.h" 11#include "linux/compiler.h"
12#include "sysdep/ptrace.h"
13#include "asm/ptrace-generic.h" 12#include "asm/ptrace-generic.h"
14#include "asm/host_ldt.h" 13#include <asm/user.h>
15#include "choose-mode.h" 14#include "sysdep/ptrace.h"
16 15
17#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs) 16#define PT_REGS_EAX(r) UPT_EAX(&(r)->regs)
18#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs) 17#define PT_REGS_EBX(r) UPT_EBX(&(r)->regs)
@@ -41,34 +40,21 @@
41 40
42#define user_mode(r) UPT_IS_USER(&(r)->regs) 41#define user_mode(r) UPT_IS_USER(&(r)->regs)
43 42
43/*
44 * Forward declaration to avoid including sysdep/tls.h, which causes a
45 * circular include, and compilation failures.
46 */
47struct user_desc;
48
49extern int get_fpxregs(struct user_fxsr_struct __user *buf,
50 struct task_struct *child);
51extern int set_fpxregs(struct user_fxsr_struct __user *buf,
52 struct task_struct *tsk);
53
44extern int ptrace_get_thread_area(struct task_struct *child, int idx, 54extern int ptrace_get_thread_area(struct task_struct *child, int idx,
45 struct user_desc __user *user_desc); 55 struct user_desc __user *user_desc);
46 56
47extern int ptrace_set_thread_area(struct task_struct *child, int idx, 57extern int ptrace_set_thread_area(struct task_struct *child, int idx,
48 struct user_desc __user *user_desc); 58 struct user_desc __user *user_desc);
49 59
50extern int do_set_thread_area_skas(struct user_desc *info);
51extern int do_get_thread_area_skas(struct user_desc *info);
52
53extern int do_set_thread_area_tt(struct user_desc *info);
54extern int do_get_thread_area_tt(struct user_desc *info);
55
56extern int arch_switch_tls_skas(struct task_struct *from, struct task_struct *to);
57extern int arch_switch_tls_tt(struct task_struct *from, struct task_struct *to);
58
59extern void arch_switch_to_tt(struct task_struct *from, struct task_struct *to);
60extern void arch_switch_to_skas(struct task_struct *from, struct task_struct *to);
61
62static inline int do_get_thread_area(struct user_desc *info)
63{
64 return CHOOSE_MODE_PROC(do_get_thread_area_tt, do_get_thread_area_skas, info);
65}
66
67static inline int do_set_thread_area(struct user_desc *info)
68{
69 return CHOOSE_MODE_PROC(do_set_thread_area_tt, do_set_thread_area_skas, info);
70}
71
72struct task_struct;
73
74#endif 60#endif
diff --git a/include/asm-um/ptrace-x86_64.h b/include/asm-um/ptrace-x86_64.h
index bf61d17de3f7..4c475350dcf0 100644
--- a/include/asm-um/ptrace-x86_64.h
+++ b/include/asm-um/ptrace-x86_64.h
@@ -76,15 +76,6 @@ static inline int ptrace_set_thread_area(struct task_struct *child, int idx,
76 return -ENOSYS; 76 return -ENOSYS;
77} 77}
78 78
79static inline void arch_switch_to_tt(struct task_struct *from, 79extern long arch_prctl(struct task_struct *task, int code,
80 struct task_struct *to) 80 unsigned long __user *addr);
81{
82}
83
84extern void arch_switch_to_skas(struct task_struct *from,
85 struct task_struct *to);
86
87extern long arch_prctl_skas(struct task_struct *task, int code,
88 unsigned long __user *addr);
89
90#endif 81#endif
diff --git a/include/asm-um/smp.h b/include/asm-um/smp.h
index 84f8cf29324e..f27a96313174 100644
--- a/include/asm-um/smp.h
+++ b/include/asm-um/smp.h
@@ -18,7 +18,7 @@ extern int hard_smp_processor_id(void);
18extern int ncpus; 18extern int ncpus;
19 19
20 20
21extern inline void smp_cpus_done(unsigned int maxcpus) 21static inline void smp_cpus_done(unsigned int maxcpus)
22{ 22{
23} 23}
24 24
diff --git a/include/asm-um/tlbflush.h b/include/asm-um/tlbflush.h
index e78c28c1f350..9d647c55350b 100644
--- a/include/asm-um/tlbflush.h
+++ b/include/asm-um/tlbflush.h
@@ -1,5 +1,5 @@
1/* 1/*
2 * Copyright (C) 2002 Jeff Dike (jdike@karaya.com) 2 * Copyright (C) 2002 - 2007 Jeff Dike (jdike@{addtoit,linux.intel}.com)
3 * Licensed under the GPL 3 * Licensed under the GPL
4 */ 4 */
5 5
@@ -7,7 +7,6 @@
7#define __UM_TLBFLUSH_H 7#define __UM_TLBFLUSH_H
8 8
9#include <linux/mm.h> 9#include <linux/mm.h>
10#include "choose-mode.h"
11 10
12/* 11/*
13 * TLB flushing: 12 * TLB flushing:
@@ -25,19 +24,7 @@ extern void flush_tlb_all(void);
25extern void flush_tlb_mm(struct mm_struct *mm); 24extern void flush_tlb_mm(struct mm_struct *mm);
26extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start, 25extern void flush_tlb_range(struct vm_area_struct *vma, unsigned long start,
27 unsigned long end); 26 unsigned long end);
28extern void flush_tlb_page_skas(struct vm_area_struct *vma, 27extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long address);
29 unsigned long address);
30
31static inline void flush_tlb_page(struct vm_area_struct *vma,
32 unsigned long address)
33{
34 address &= PAGE_MASK;
35
36 CHOOSE_MODE(flush_tlb_range(vma, address, address + PAGE_SIZE),
37 flush_tlb_page_skas(vma, address));
38}
39
40extern void flush_tlb_page(struct vm_area_struct *vma, unsigned long vmaddr);
41extern void flush_tlb_kernel_vm(void); 28extern void flush_tlb_kernel_vm(void);
42extern void flush_tlb_kernel_range(unsigned long start, unsigned long end); 29extern void flush_tlb_kernel_range(unsigned long start, unsigned long end);
43extern void __flush_tlb_one(unsigned long addr); 30extern void __flush_tlb_one(unsigned long addr);
diff --git a/include/asm-um/uaccess.h b/include/asm-um/uaccess.h
index 16c734af9193..077032d4fc47 100644
--- a/include/asm-um/uaccess.h
+++ b/include/asm-um/uaccess.h
@@ -80,7 +80,7 @@
80 __put_user(x, private_ptr) : -EFAULT); \ 80 __put_user(x, private_ptr) : -EFAULT); \
81}) 81})
82 82
83#define strlen_user(str) strnlen_user(str, ~0UL >> 1) 83#define strlen_user(str) strnlen_user(str, ~0U >> 1)
84 84
85struct exception_table_entry 85struct exception_table_entry
86{ 86{
diff --git a/include/asm-x86/cpufeature_32.h b/include/asm-x86/cpufeature_32.h
index 7b3aa28ebc6e..f17e688dfb05 100644
--- a/include/asm-x86/cpufeature_32.h
+++ b/include/asm-x86/cpufeature_32.h
@@ -92,6 +92,7 @@
92#define X86_FEATURE_CID (4*32+10) /* Context ID */ 92#define X86_FEATURE_CID (4*32+10) /* Context ID */
93#define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */ 93#define X86_FEATURE_CX16 (4*32+13) /* CMPXCHG16B */
94#define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */ 94#define X86_FEATURE_XTPR (4*32+14) /* Send Task Priority Messages */
95#define X86_FEATURE_DCA (4*32+18) /* Direct Cache Access */
95 96
96/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */ 97/* VIA/Cyrix/Centaur-defined CPU features, CPUID level 0xC0000001, word 5 */
97#define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */ 98#define X86_FEATURE_XSTORE (5*32+ 2) /* on-CPU RNG present (xstore insn) */
diff --git a/include/asm-x86/dma-mapping_32.h b/include/asm-x86/dma-mapping_32.h
index f1d72d177f68..6a2d26cb5da6 100644
--- a/include/asm-x86/dma-mapping_32.h
+++ b/include/asm-x86/dma-mapping_32.h
@@ -2,10 +2,10 @@
2#define _ASM_I386_DMA_MAPPING_H 2#define _ASM_I386_DMA_MAPPING_H
3 3
4#include <linux/mm.h> 4#include <linux/mm.h>
5#include <linux/scatterlist.h>
5 6
6#include <asm/cache.h> 7#include <asm/cache.h>
7#include <asm/io.h> 8#include <asm/io.h>
8#include <asm/scatterlist.h>
9#include <asm/bug.h> 9#include <asm/bug.h>
10 10
11#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f) 11#define dma_alloc_noncoherent(d, s, h, f) dma_alloc_coherent(d, s, h, f)
@@ -35,18 +35,19 @@ dma_unmap_single(struct device *dev, dma_addr_t dma_addr, size_t size,
35} 35}
36 36
37static inline int 37static inline int
38dma_map_sg(struct device *dev, struct scatterlist *sg, int nents, 38dma_map_sg(struct device *dev, struct scatterlist *sglist, int nents,
39 enum dma_data_direction direction) 39 enum dma_data_direction direction)
40{ 40{
41 struct scatterlist *sg;
41 int i; 42 int i;
42 43
43 BUG_ON(!valid_dma_direction(direction)); 44 BUG_ON(!valid_dma_direction(direction));
44 WARN_ON(nents == 0 || sg[0].length == 0); 45 WARN_ON(nents == 0 || sglist[0].length == 0);
45 46
46 for (i = 0; i < nents; i++ ) { 47 for_each_sg(sglist, sg, nents, i) {
47 BUG_ON(!sg[i].page); 48 BUG_ON(!sg->page);
48 49
49 sg[i].dma_address = page_to_phys(sg[i].page) + sg[i].offset; 50 sg->dma_address = page_to_phys(sg->page) + sg->offset;
50 } 51 }
51 52
52 flush_write_buffers(); 53 flush_write_buffers();
diff --git a/include/asm-x86/dma-mapping_64.h b/include/asm-x86/dma-mapping_64.h
index 6897e2a436e5..ecd0f6125ba3 100644
--- a/include/asm-x86/dma-mapping_64.h
+++ b/include/asm-x86/dma-mapping_64.h
@@ -6,8 +6,7 @@
6 * documentation. 6 * documentation.
7 */ 7 */
8 8
9 9#include <linux/scatterlist.h>
10#include <asm/scatterlist.h>
11#include <asm/io.h> 10#include <asm/io.h>
12#include <asm/swiotlb.h> 11#include <asm/swiotlb.h>
13 12
diff --git a/include/asm-x86/kdebug_32.h b/include/asm-x86/kdebug_32.h
index a185b5f73e7f..181d437eef4b 100644
--- a/include/asm-x86/kdebug_32.h
+++ b/include/asm-x86/kdebug_32.h
@@ -5,14 +5,9 @@
5 * Aug-05 2004 Ported by Prasanna S Panchamukhi <prasanna@in.ibm.com> 5 * Aug-05 2004 Ported by Prasanna S Panchamukhi <prasanna@in.ibm.com>
6 * from x86_64 architecture. 6 * from x86_64 architecture.
7 */ 7 */
8#include <linux/notifier.h>
9 8
10struct pt_regs; 9struct pt_regs;
11 10
12extern int register_page_fault_notifier(struct notifier_block *);
13extern int unregister_page_fault_notifier(struct notifier_block *);
14
15
16/* Grossly misnamed. */ 11/* Grossly misnamed. */
17enum die_val { 12enum die_val {
18 DIE_OOPS = 1, 13 DIE_OOPS = 1,
@@ -27,7 +22,6 @@ enum die_val {
27 DIE_GPF, 22 DIE_GPF,
28 DIE_CALL, 23 DIE_CALL,
29 DIE_NMI_IPI, 24 DIE_NMI_IPI,
30 DIE_PAGE_FAULT,
31}; 25};
32 26
33#endif 27#endif
diff --git a/include/asm-x86/kdebug_64.h b/include/asm-x86/kdebug_64.h
index d7e2bcf49e4f..df413e05375e 100644
--- a/include/asm-x86/kdebug_64.h
+++ b/include/asm-x86/kdebug_64.h
@@ -1,13 +1,10 @@
1#ifndef _X86_64_KDEBUG_H 1#ifndef _X86_64_KDEBUG_H
2#define _X86_64_KDEBUG_H 1 2#define _X86_64_KDEBUG_H 1
3 3
4#include <linux/notifier.h> 4#include <linux/compiler.h>
5 5
6struct pt_regs; 6struct pt_regs;
7 7
8extern int register_page_fault_notifier(struct notifier_block *);
9extern int unregister_page_fault_notifier(struct notifier_block *);
10
11/* Grossly misnamed. */ 8/* Grossly misnamed. */
12enum die_val { 9enum die_val {
13 DIE_OOPS = 1, 10 DIE_OOPS = 1,
@@ -22,7 +19,6 @@ enum die_val {
22 DIE_GPF, 19 DIE_GPF,
23 DIE_CALL, 20 DIE_CALL,
24 DIE_NMI_IPI, 21 DIE_NMI_IPI,
25 DIE_PAGE_FAULT,
26}; 22};
27 23
28extern void printk_address(unsigned long address); 24extern void printk_address(unsigned long address);
diff --git a/include/asm-x86/kprobes_32.h b/include/asm-x86/kprobes_32.h
index 06f7303c30ca..b772d5b38685 100644
--- a/include/asm-x86/kprobes_32.h
+++ b/include/asm-x86/kprobes_32.h
@@ -43,9 +43,10 @@ typedef u8 kprobe_opcode_t;
43 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) 43 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
44 44
45#define ARCH_SUPPORTS_KRETPROBES 45#define ARCH_SUPPORTS_KRETPROBES
46#define ARCH_INACTIVE_KPROBE_COUNT 0
47#define flush_insn_slot(p) do { } while (0) 46#define flush_insn_slot(p) do { } while (0)
48 47
48extern const int kretprobe_blacklist_size;
49
49void arch_remove_kprobe(struct kprobe *p); 50void arch_remove_kprobe(struct kprobe *p);
50void kretprobe_trampoline(void); 51void kretprobe_trampoline(void);
51 52
@@ -89,4 +90,5 @@ static inline void restore_interrupts(struct pt_regs *regs)
89 90
90extern int kprobe_exceptions_notify(struct notifier_block *self, 91extern int kprobe_exceptions_notify(struct notifier_block *self,
91 unsigned long val, void *data); 92 unsigned long val, void *data);
93extern int kprobe_fault_handler(struct pt_regs *regs, int trapnr);
92#endif /* _ASM_KPROBES_H */ 94#endif /* _ASM_KPROBES_H */
diff --git a/include/asm-x86/kprobes_64.h b/include/asm-x86/kprobes_64.h
index 7db825403e01..53f4d8507354 100644
--- a/include/asm-x86/kprobes_64.h
+++ b/include/asm-x86/kprobes_64.h
@@ -42,7 +42,7 @@ typedef u8 kprobe_opcode_t;
42 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR))) 42 : (((unsigned long)current_thread_info()) + THREAD_SIZE - (ADDR)))
43 43
44#define ARCH_SUPPORTS_KRETPROBES 44#define ARCH_SUPPORTS_KRETPROBES
45#define ARCH_INACTIVE_KPROBE_COUNT 1 45extern const int kretprobe_blacklist_size;
46 46
47void kretprobe_trampoline(void); 47void kretprobe_trampoline(void);
48extern void arch_remove_kprobe(struct kprobe *p); 48extern void arch_remove_kprobe(struct kprobe *p);
diff --git a/include/asm-x86/page_64.h b/include/asm-x86/page_64.h
index 88adf1afb0a2..c3b52bcb171e 100644
--- a/include/asm-x86/page_64.h
+++ b/include/asm-x86/page_64.h
@@ -134,6 +134,7 @@ extern unsigned long __phys_addr(unsigned long);
134 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC) 134 VM_READ | VM_WRITE | VM_MAYREAD | VM_MAYWRITE | VM_MAYEXEC)
135 135
136#define __HAVE_ARCH_GATE_AREA 1 136#define __HAVE_ARCH_GATE_AREA 1
137#define vmemmap ((struct page *)VMEMMAP_START)
137 138
138#include <asm-generic/memory_model.h> 139#include <asm-generic/memory_model.h>
139#include <asm-generic/page.h> 140#include <asm-generic/page.h>
diff --git a/include/asm-x86/pgtable_64.h b/include/asm-x86/pgtable_64.h
index 57dd6b3107ea..a79f5355e3b0 100644
--- a/include/asm-x86/pgtable_64.h
+++ b/include/asm-x86/pgtable_64.h
@@ -137,6 +137,7 @@ static inline pte_t ptep_get_and_clear_full(struct mm_struct *mm, unsigned long
137#define MAXMEM _AC(0x3fffffffffff, UL) 137#define MAXMEM _AC(0x3fffffffffff, UL)
138#define VMALLOC_START _AC(0xffffc20000000000, UL) 138#define VMALLOC_START _AC(0xffffc20000000000, UL)
139#define VMALLOC_END _AC(0xffffe1ffffffffff, UL) 139#define VMALLOC_END _AC(0xffffe1ffffffffff, UL)
140#define VMEMMAP_START _AC(0xffffe20000000000, UL)
140#define MODULES_VADDR _AC(0xffffffff88000000, UL) 141#define MODULES_VADDR _AC(0xffffffff88000000, UL)
141#define MODULES_END _AC(0xfffffffffff00000, UL) 142#define MODULES_END _AC(0xfffffffffff00000, UL)
142#define MODULES_LEN (MODULES_END - MODULES_VADDR) 143#define MODULES_LEN (MODULES_END - MODULES_VADDR)
diff --git a/include/asm-x86/scatterlist_32.h b/include/asm-x86/scatterlist_32.h
index d7e45a8f1aae..bd5164aa8f63 100644
--- a/include/asm-x86/scatterlist_32.h
+++ b/include/asm-x86/scatterlist_32.h
@@ -10,6 +10,8 @@ struct scatterlist {
10 unsigned int length; 10 unsigned int length;
11}; 11};
12 12
13#define ARCH_HAS_SG_CHAIN
14
13/* These macros should be used after a pci_map_sg call has been done 15/* These macros should be used after a pci_map_sg call has been done
14 * to get bus addresses of each of the SG entries and their lengths. 16 * to get bus addresses of each of the SG entries and their lengths.
15 * You should only work with the number of sg entries pci_map_sg 17 * You should only work with the number of sg entries pci_map_sg
diff --git a/include/asm-x86/scatterlist_64.h b/include/asm-x86/scatterlist_64.h
index eaf7ada27e14..ef3986ba4b79 100644
--- a/include/asm-x86/scatterlist_64.h
+++ b/include/asm-x86/scatterlist_64.h
@@ -11,6 +11,8 @@ struct scatterlist {
11 unsigned int dma_length; 11 unsigned int dma_length;
12}; 12};
13 13
14#define ARCH_HAS_SG_CHAIN
15
14#define ISA_DMA_THRESHOLD (0x00ffffff) 16#define ISA_DMA_THRESHOLD (0x00ffffff)
15 17
16/* These macros should be used after a pci_map_sg call has been done 18/* These macros should be used after a pci_map_sg call has been done
diff --git a/include/asm-x86/smp_32.h b/include/asm-x86/smp_32.h
index 1f73bde165b1..955dd7c8538f 100644
--- a/include/asm-x86/smp_32.h
+++ b/include/asm-x86/smp_32.h
@@ -30,8 +30,8 @@
30extern void smp_alloc_memory(void); 30extern void smp_alloc_memory(void);
31extern int pic_mode; 31extern int pic_mode;
32extern int smp_num_siblings; 32extern int smp_num_siblings;
33extern cpumask_t cpu_sibling_map[]; 33DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
34extern cpumask_t cpu_core_map[]; 34DECLARE_PER_CPU(cpumask_t, cpu_core_map);
35 35
36extern void (*mtrr_hook) (void); 36extern void (*mtrr_hook) (void);
37extern void zap_low_mappings (void); 37extern void zap_low_mappings (void);
diff --git a/include/asm-x86/smp_64.h b/include/asm-x86/smp_64.h
index 3f303d2365ed..f5bcee1c0927 100644
--- a/include/asm-x86/smp_64.h
+++ b/include/asm-x86/smp_64.h
@@ -38,8 +38,15 @@ extern void unlock_ipi_call_lock(void);
38extern int smp_num_siblings; 38extern int smp_num_siblings;
39extern void smp_send_reschedule(int cpu); 39extern void smp_send_reschedule(int cpu);
40 40
41extern cpumask_t cpu_sibling_map[NR_CPUS]; 41/*
42extern cpumask_t cpu_core_map[NR_CPUS]; 42 * cpu_sibling_map and cpu_core_map now live
43 * in the per cpu area
44 *
45 * extern cpumask_t cpu_sibling_map[NR_CPUS];
46 * extern cpumask_t cpu_core_map[NR_CPUS];
47 */
48DECLARE_PER_CPU(cpumask_t, cpu_sibling_map);
49DECLARE_PER_CPU(cpumask_t, cpu_core_map);
43extern u8 cpu_llc_id[NR_CPUS]; 50extern u8 cpu_llc_id[NR_CPUS];
44 51
45#define SMP_TRAMPOLINE_BASE 0x6000 52#define SMP_TRAMPOLINE_BASE 0x6000
diff --git a/include/asm-x86/topology_32.h b/include/asm-x86/topology_32.h
index 19b2dafd0c81..ae1074603c4b 100644
--- a/include/asm-x86/topology_32.h
+++ b/include/asm-x86/topology_32.h
@@ -30,8 +30,8 @@
30#ifdef CONFIG_X86_HT 30#ifdef CONFIG_X86_HT
31#define topology_physical_package_id(cpu) (cpu_data[cpu].phys_proc_id) 31#define topology_physical_package_id(cpu) (cpu_data[cpu].phys_proc_id)
32#define topology_core_id(cpu) (cpu_data[cpu].cpu_core_id) 32#define topology_core_id(cpu) (cpu_data[cpu].cpu_core_id)
33#define topology_core_siblings(cpu) (cpu_core_map[cpu]) 33#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu))
34#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu]) 34#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
35#endif 35#endif
36 36
37#ifdef CONFIG_NUMA 37#ifdef CONFIG_NUMA
diff --git a/include/asm-x86/topology_64.h b/include/asm-x86/topology_64.h
index 36e52fba7960..848c17f92226 100644
--- a/include/asm-x86/topology_64.h
+++ b/include/asm-x86/topology_64.h
@@ -58,8 +58,8 @@ extern int __node_distance(int, int);
58#ifdef CONFIG_SMP 58#ifdef CONFIG_SMP
59#define topology_physical_package_id(cpu) (cpu_data[cpu].phys_proc_id) 59#define topology_physical_package_id(cpu) (cpu_data[cpu].phys_proc_id)
60#define topology_core_id(cpu) (cpu_data[cpu].cpu_core_id) 60#define topology_core_id(cpu) (cpu_data[cpu].cpu_core_id)
61#define topology_core_siblings(cpu) (cpu_core_map[cpu]) 61#define topology_core_siblings(cpu) (per_cpu(cpu_core_map, cpu))
62#define topology_thread_siblings(cpu) (cpu_sibling_map[cpu]) 62#define topology_thread_siblings(cpu) (per_cpu(cpu_sibling_map, cpu))
63#define mc_capable() (boot_cpu_data.x86_max_cores > 1) 63#define mc_capable() (boot_cpu_data.x86_max_cores > 1)
64#define smt_capable() (smp_num_siblings > 1) 64#define smt_capable() (smp_num_siblings > 1)
65#endif 65#endif
diff --git a/include/linux/bio.h b/include/linux/bio.h
index 089a8bc55dd4..4da441337d6e 100644
--- a/include/linux/bio.h
+++ b/include/linux/bio.h
@@ -176,13 +176,28 @@ struct bio {
176#define bio_offset(bio) bio_iovec((bio))->bv_offset 176#define bio_offset(bio) bio_iovec((bio))->bv_offset
177#define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx) 177#define bio_segments(bio) ((bio)->bi_vcnt - (bio)->bi_idx)
178#define bio_sectors(bio) ((bio)->bi_size >> 9) 178#define bio_sectors(bio) ((bio)->bi_size >> 9)
179#define bio_cur_sectors(bio) (bio_iovec(bio)->bv_len >> 9)
180#define bio_data(bio) (page_address(bio_page((bio))) + bio_offset((bio)))
181#define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER)) 179#define bio_barrier(bio) ((bio)->bi_rw & (1 << BIO_RW_BARRIER))
182#define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC)) 180#define bio_sync(bio) ((bio)->bi_rw & (1 << BIO_RW_SYNC))
183#define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST)) 181#define bio_failfast(bio) ((bio)->bi_rw & (1 << BIO_RW_FAILFAST))
184#define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD)) 182#define bio_rw_ahead(bio) ((bio)->bi_rw & (1 << BIO_RW_AHEAD))
185#define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META)) 183#define bio_rw_meta(bio) ((bio)->bi_rw & (1 << BIO_RW_META))
184#define bio_empty_barrier(bio) (bio_barrier(bio) && !(bio)->bi_size)
185
186static inline unsigned int bio_cur_sectors(struct bio *bio)
187{
188 if (bio->bi_vcnt)
189 return bio_iovec(bio)->bv_len >> 9;
190
191 return 0;
192}
193
194static inline void *bio_data(struct bio *bio)
195{
196 if (bio->bi_vcnt)
197 return page_address(bio_page(bio)) + bio_offset(bio);
198
199 return NULL;
200}
186 201
187/* 202/*
188 * will die 203 * will die
diff --git a/include/linux/bitops.h b/include/linux/bitops.h
index 638165f571da..b9fb8ee3308b 100644
--- a/include/linux/bitops.h
+++ b/include/linux/bitops.h
@@ -8,6 +8,12 @@
8 */ 8 */
9#include <asm/bitops.h> 9#include <asm/bitops.h>
10 10
11#define for_each_bit(bit, addr, size) \
12 for ((bit) = find_first_bit((addr), (size)); \
13 (bit) < (size); \
14 (bit) = find_next_bit((addr), (size), (bit) + 1))
15
16
11static __inline__ int get_bitmask_order(unsigned int count) 17static __inline__ int get_bitmask_order(unsigned int count)
12{ 18{
13 int order; 19 int order;
diff --git a/include/linux/blkdev.h b/include/linux/blkdev.h
index 5ed888b04b29..bbf906a0b419 100644
--- a/include/linux/blkdev.h
+++ b/include/linux/blkdev.h
@@ -330,7 +330,6 @@ typedef void (unplug_fn) (struct request_queue *);
330 330
331struct bio_vec; 331struct bio_vec;
332typedef int (merge_bvec_fn) (struct request_queue *, struct bio *, struct bio_vec *); 332typedef int (merge_bvec_fn) (struct request_queue *, struct bio *, struct bio_vec *);
333typedef int (issue_flush_fn) (struct request_queue *, struct gendisk *, sector_t *);
334typedef void (prepare_flush_fn) (struct request_queue *, struct request *); 333typedef void (prepare_flush_fn) (struct request_queue *, struct request *);
335typedef void (softirq_done_fn)(struct request *); 334typedef void (softirq_done_fn)(struct request *);
336 335
@@ -368,7 +367,6 @@ struct request_queue
368 prep_rq_fn *prep_rq_fn; 367 prep_rq_fn *prep_rq_fn;
369 unplug_fn *unplug_fn; 368 unplug_fn *unplug_fn;
370 merge_bvec_fn *merge_bvec_fn; 369 merge_bvec_fn *merge_bvec_fn;
371 issue_flush_fn *issue_flush_fn;
372 prepare_flush_fn *prepare_flush_fn; 370 prepare_flush_fn *prepare_flush_fn;
373 softirq_done_fn *softirq_done_fn; 371 softirq_done_fn *softirq_done_fn;
374 372
@@ -540,6 +538,7 @@ enum {
540#define blk_barrier_rq(rq) ((rq)->cmd_flags & REQ_HARDBARRIER) 538#define blk_barrier_rq(rq) ((rq)->cmd_flags & REQ_HARDBARRIER)
541#define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA) 539#define blk_fua_rq(rq) ((rq)->cmd_flags & REQ_FUA)
542#define blk_bidi_rq(rq) ((rq)->next_rq != NULL) 540#define blk_bidi_rq(rq) ((rq)->next_rq != NULL)
541#define blk_empty_barrier(rq) (blk_barrier_rq(rq) && blk_fs_request(rq) && !(rq)->hard_nr_sectors)
543 542
544#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist) 543#define list_entry_rq(ptr) list_entry((ptr), struct request, queuelist)
545 544
@@ -729,7 +728,9 @@ static inline void blk_run_address_space(struct address_space *mapping)
729extern int end_that_request_first(struct request *, int, int); 728extern int end_that_request_first(struct request *, int, int);
730extern int end_that_request_chunk(struct request *, int, int); 729extern int end_that_request_chunk(struct request *, int, int);
731extern void end_that_request_last(struct request *, int); 730extern void end_that_request_last(struct request *, int);
732extern void end_request(struct request *req, int uptodate); 731extern void end_request(struct request *, int);
732extern void end_queued_request(struct request *, int);
733extern void end_dequeued_request(struct request *, int);
733extern void blk_complete_request(struct request *); 734extern void blk_complete_request(struct request *);
734 735
735/* 736/*
@@ -767,7 +768,6 @@ extern void blk_queue_dma_alignment(struct request_queue *, int);
767extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *); 768extern void blk_queue_softirq_done(struct request_queue *, softirq_done_fn *);
768extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev); 769extern struct backing_dev_info *blk_get_backing_dev_info(struct block_device *bdev);
769extern int blk_queue_ordered(struct request_queue *, unsigned, prepare_flush_fn *); 770extern int blk_queue_ordered(struct request_queue *, unsigned, prepare_flush_fn *);
770extern void blk_queue_issue_flush_fn(struct request_queue *, issue_flush_fn *);
771extern int blk_do_ordered(struct request_queue *, struct request **); 771extern int blk_do_ordered(struct request_queue *, struct request **);
772extern unsigned blk_ordered_cur_seq(struct request_queue *); 772extern unsigned blk_ordered_cur_seq(struct request_queue *);
773extern unsigned blk_ordered_req_seq(struct request *); 773extern unsigned blk_ordered_req_seq(struct request *);
diff --git a/include/linux/buffer_head.h b/include/linux/buffer_head.h
index 35cadad84b14..da0d83fbadc0 100644
--- a/include/linux/buffer_head.h
+++ b/include/linux/buffer_head.h
@@ -203,10 +203,20 @@ void block_invalidatepage(struct page *page, unsigned long offset);
203int block_write_full_page(struct page *page, get_block_t *get_block, 203int block_write_full_page(struct page *page, get_block_t *get_block,
204 struct writeback_control *wbc); 204 struct writeback_control *wbc);
205int block_read_full_page(struct page*, get_block_t*); 205int block_read_full_page(struct page*, get_block_t*);
206int block_write_begin(struct file *, struct address_space *,
207 loff_t, unsigned, unsigned,
208 struct page **, void **, get_block_t*);
209int block_write_end(struct file *, struct address_space *,
210 loff_t, unsigned, unsigned,
211 struct page *, void *);
212int generic_write_end(struct file *, struct address_space *,
213 loff_t, unsigned, unsigned,
214 struct page *, void *);
215void page_zero_new_buffers(struct page *page, unsigned from, unsigned to);
206int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*); 216int block_prepare_write(struct page*, unsigned, unsigned, get_block_t*);
207int cont_prepare_write(struct page*, unsigned, unsigned, get_block_t*, 217int cont_write_begin(struct file *, struct address_space *, loff_t,
208 loff_t *); 218 unsigned, unsigned, struct page **, void **,
209int generic_cont_expand(struct inode *inode, loff_t size); 219 get_block_t *, loff_t *);
210int generic_cont_expand_simple(struct inode *inode, loff_t size); 220int generic_cont_expand_simple(struct inode *inode, loff_t size);
211int block_commit_write(struct page *page, unsigned from, unsigned to); 221int block_commit_write(struct page *page, unsigned from, unsigned to);
212int block_page_mkwrite(struct vm_area_struct *vma, struct page *page, 222int block_page_mkwrite(struct vm_area_struct *vma, struct page *page,
@@ -216,9 +226,13 @@ sector_t generic_block_bmap(struct address_space *, sector_t, get_block_t *);
216int generic_commit_write(struct file *, struct page *, unsigned, unsigned); 226int generic_commit_write(struct file *, struct page *, unsigned, unsigned);
217int block_truncate_page(struct address_space *, loff_t, get_block_t *); 227int block_truncate_page(struct address_space *, loff_t, get_block_t *);
218int file_fsync(struct file *, struct dentry *, int); 228int file_fsync(struct file *, struct dentry *, int);
219int nobh_prepare_write(struct page*, unsigned, unsigned, get_block_t*); 229int nobh_write_begin(struct file *, struct address_space *,
220int nobh_commit_write(struct file *, struct page *, unsigned, unsigned); 230 loff_t, unsigned, unsigned,
221int nobh_truncate_page(struct address_space *, loff_t); 231 struct page **, void **, get_block_t*);
232int nobh_write_end(struct file *, struct address_space *,
233 loff_t, unsigned, unsigned,
234 struct page *, void *);
235int nobh_truncate_page(struct address_space *, loff_t, get_block_t *);
222int nobh_writepage(struct page *page, get_block_t *get_block, 236int nobh_writepage(struct page *page, get_block_t *get_block,
223 struct writeback_control *wbc); 237 struct writeback_control *wbc);
224 238
diff --git a/include/linux/connector.h b/include/linux/connector.h
index b62f823e90cf..13fc4541bf23 100644
--- a/include/linux/connector.h
+++ b/include/linux/connector.h
@@ -36,14 +36,15 @@
36#define CN_VAL_CIFS 0x1 36#define CN_VAL_CIFS 0x1
37#define CN_W1_IDX 0x3 /* w1 communication */ 37#define CN_W1_IDX 0x3 /* w1 communication */
38#define CN_W1_VAL 0x1 38#define CN_W1_VAL 0x1
39#define CN_IDX_V86D 0x4
40#define CN_VAL_V86D_UVESAFB 0x1
39 41
40 42#define CN_NETLINK_USERS 5
41#define CN_NETLINK_USERS 4
42 43
43/* 44/*
44 * Maximum connector's message size. 45 * Maximum connector's message size.
45 */ 46 */
46#define CONNECTOR_MAX_MSG_SIZE 1024 47#define CONNECTOR_MAX_MSG_SIZE 16384
47 48
48/* 49/*
49 * idx and val are unique identifiers which 50 * idx and val are unique identifiers which
diff --git a/include/linux/console.h b/include/linux/console.h
index 56a7bcda49cb..0a4542ddb73d 100644
--- a/include/linux/console.h
+++ b/include/linux/console.h
@@ -45,7 +45,8 @@ struct consw {
45 int (*con_font_get)(struct vc_data *, struct console_font *); 45 int (*con_font_get)(struct vc_data *, struct console_font *);
46 int (*con_font_default)(struct vc_data *, struct console_font *, char *); 46 int (*con_font_default)(struct vc_data *, struct console_font *, char *);
47 int (*con_font_copy)(struct vc_data *, int); 47 int (*con_font_copy)(struct vc_data *, int);
48 int (*con_resize)(struct vc_data *, unsigned int, unsigned int); 48 int (*con_resize)(struct vc_data *, unsigned int, unsigned int,
49 unsigned int);
49 int (*con_set_palette)(struct vc_data *, unsigned char *); 50 int (*con_set_palette)(struct vc_data *, unsigned char *);
50 int (*con_scrolldelta)(struct vc_data *, int); 51 int (*con_scrolldelta)(struct vc_data *, int);
51 int (*con_set_origin)(struct vc_data *); 52 int (*con_set_origin)(struct vc_data *);
diff --git a/include/linux/console_struct.h b/include/linux/console_struct.h
index dc77fed7b285..d71f7c0f931b 100644
--- a/include/linux/console_struct.h
+++ b/include/linux/console_struct.h
@@ -100,6 +100,7 @@ struct vc_data {
100 unsigned char vc_G1_charset; 100 unsigned char vc_G1_charset;
101 unsigned char vc_saved_G0; 101 unsigned char vc_saved_G0;
102 unsigned char vc_saved_G1; 102 unsigned char vc_saved_G1;
103 unsigned int vc_resize_user; /* resize request from user */
103 unsigned int vc_bell_pitch; /* Console bell pitch */ 104 unsigned int vc_bell_pitch; /* Console bell pitch */
104 unsigned int vc_bell_duration; /* Console bell duration */ 105 unsigned int vc_bell_duration; /* Console bell duration */
105 struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */ 106 struct vc_data **vc_display_fg; /* [!] Ptr to var holding fg console for this display */
diff --git a/include/linux/cpuset.h b/include/linux/cpuset.h
index 826b15e914e2..9e633ea103ce 100644
--- a/include/linux/cpuset.h
+++ b/include/linux/cpuset.h
@@ -93,7 +93,7 @@ static inline nodemask_t cpuset_mems_allowed(struct task_struct *p)
93 return node_possible_map; 93 return node_possible_map;
94} 94}
95 95
96#define cpuset_current_mems_allowed (node_online_map) 96#define cpuset_current_mems_allowed (node_states[N_HIGH_MEMORY])
97static inline void cpuset_init_current_mems_allowed(void) {} 97static inline void cpuset_init_current_mems_allowed(void) {}
98static inline void cpuset_update_task_memory_state(void) {} 98static inline void cpuset_update_task_memory_state(void) {}
99#define cpuset_nodes_subset_current_mems_allowed(nodes) (1) 99#define cpuset_nodes_subset_current_mems_allowed(nodes) (1)
diff --git a/include/linux/dca.h b/include/linux/dca.h
new file mode 100644
index 000000000000..83eaecc6f8ab
--- /dev/null
+++ b/include/linux/dca.h
@@ -0,0 +1,47 @@
1#ifndef DCA_H
2#define DCA_H
3/* DCA Provider API */
4
5/* DCA Notifier Interface */
6void dca_register_notify(struct notifier_block *nb);
7void dca_unregister_notify(struct notifier_block *nb);
8
9#define DCA_PROVIDER_ADD 0x0001
10#define DCA_PROVIDER_REMOVE 0x0002
11
12struct dca_provider {
13 struct dca_ops *ops;
14 struct class_device *cd;
15 int id;
16};
17
18struct dca_ops {
19 int (*add_requester) (struct dca_provider *, struct device *);
20 int (*remove_requester) (struct dca_provider *, struct device *);
21 u8 (*get_tag) (struct dca_provider *, int cpu);
22};
23
24struct dca_provider *alloc_dca_provider(struct dca_ops *ops, int priv_size);
25void free_dca_provider(struct dca_provider *dca);
26int register_dca_provider(struct dca_provider *dca, struct device *dev);
27void unregister_dca_provider(struct dca_provider *dca);
28
29static inline void *dca_priv(struct dca_provider *dca)
30{
31 return (void *)dca + sizeof(struct dca_provider);
32}
33
34/* Requester API */
35int dca_add_requester(struct device *dev);
36int dca_remove_requester(struct device *dev);
37u8 dca_get_tag(int cpu);
38
39/* internal stuff */
40int __init dca_sysfs_init(void);
41void __exit dca_sysfs_exit(void);
42int dca_sysfs_add_provider(struct dca_provider *dca, struct device *dev);
43void dca_sysfs_remove_provider(struct dca_provider *dca);
44int dca_sysfs_add_req(struct dca_provider *dca, struct device *dev, int slot);
45void dca_sysfs_remove_req(struct dca_provider *dca, int slot);
46
47#endif /* DCA_H */
diff --git a/include/linux/dma-mapping.h b/include/linux/dma-mapping.h
index 2dc21cbeb304..0ebfafbd338c 100644
--- a/include/linux/dma-mapping.h
+++ b/include/linux/dma-mapping.h
@@ -24,6 +24,8 @@ enum dma_data_direction {
24#define DMA_28BIT_MASK 0x000000000fffffffULL 24#define DMA_28BIT_MASK 0x000000000fffffffULL
25#define DMA_24BIT_MASK 0x0000000000ffffffULL 25#define DMA_24BIT_MASK 0x0000000000ffffffULL
26 26
27#define DMA_MASK_NONE 0x0ULL
28
27static inline int valid_dma_direction(int dma_direction) 29static inline int valid_dma_direction(int dma_direction)
28{ 30{
29 return ((dma_direction == DMA_BIDIRECTIONAL) || 31 return ((dma_direction == DMA_BIDIRECTIONAL) ||
@@ -31,6 +33,11 @@ static inline int valid_dma_direction(int dma_direction)
31 (dma_direction == DMA_FROM_DEVICE)); 33 (dma_direction == DMA_FROM_DEVICE));
32} 34}
33 35
36static inline int is_device_dma_capable(struct device *dev)
37{
38 return dev->dma_mask != NULL && *dev->dma_mask != DMA_MASK_NONE;
39}
40
34#ifdef CONFIG_HAS_DMA 41#ifdef CONFIG_HAS_DMA
35#include <asm/dma-mapping.h> 42#include <asm/dma-mapping.h>
36#else 43#else
diff --git a/include/linux/fb.h b/include/linux/fb.h
index cec54106aa87..58c57a33e5dd 100644
--- a/include/linux/fb.h
+++ b/include/linux/fb.h
@@ -180,6 +180,7 @@ struct fb_bitfield {
180}; 180};
181 181
182#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */ 182#define FB_NONSTD_HAM 1 /* Hold-And-Modify (HAM) */
183#define FB_NONSTD_REV_PIX_IN_B 2 /* order of pixels in each byte is reversed */
183 184
184#define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/ 185#define FB_ACTIVATE_NOW 0 /* set values immediately (or vbl)*/
185#define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */ 186#define FB_ACTIVATE_NXTOPEN 1 /* activate on next open */
@@ -206,6 +207,7 @@ struct fb_bitfield {
206#define FB_VMODE_NONINTERLACED 0 /* non interlaced */ 207#define FB_VMODE_NONINTERLACED 0 /* non interlaced */
207#define FB_VMODE_INTERLACED 1 /* interlaced */ 208#define FB_VMODE_INTERLACED 1 /* interlaced */
208#define FB_VMODE_DOUBLE 2 /* double scan */ 209#define FB_VMODE_DOUBLE 2 /* double scan */
210#define FB_VMODE_ODD_FLD_FIRST 4 /* interlaced: top line first */
209#define FB_VMODE_MASK 255 211#define FB_VMODE_MASK 255
210 212
211#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */ 213#define FB_VMODE_YWRAP 256 /* ywrap instead of panning */
@@ -1054,6 +1056,7 @@ struct fb_videomode {
1054 u32 flag; 1056 u32 flag;
1055}; 1057};
1056 1058
1059extern const char *fb_mode_option;
1057extern const struct fb_videomode vesa_modes[]; 1060extern const struct fb_videomode vesa_modes[];
1058 1061
1059struct fb_modelist { 1062struct fb_modelist {
diff --git a/include/linux/fs.h b/include/linux/fs.h
index 4a6a21077bae..f70d52c46617 100644
--- a/include/linux/fs.h
+++ b/include/linux/fs.h
@@ -381,7 +381,7 @@ struct iattr {
381 * trying again. The aop will be taking reasonable 381 * trying again. The aop will be taking reasonable
382 * precautions not to livelock. If the caller held a page 382 * precautions not to livelock. If the caller held a page
383 * reference, it should drop it before retrying. Returned 383 * reference, it should drop it before retrying. Returned
384 * by readpage(), prepare_write(), and commit_write(). 384 * by readpage().
385 * 385 *
386 * address_space_operation functions return these large constants to indicate 386 * address_space_operation functions return these large constants to indicate
387 * special semantics to the caller. These are much larger than the bytes in a 387 * special semantics to the caller. These are much larger than the bytes in a
@@ -394,6 +394,9 @@ enum positive_aop_returns {
394 AOP_TRUNCATED_PAGE = 0x80001, 394 AOP_TRUNCATED_PAGE = 0x80001,
395}; 395};
396 396
397#define AOP_FLAG_UNINTERRUPTIBLE 0x0001 /* will not do a short write */
398#define AOP_FLAG_CONT_EXPAND 0x0002 /* called from cont_expand */
399
397/* 400/*
398 * oh the beauties of C type declarations. 401 * oh the beauties of C type declarations.
399 */ 402 */
@@ -401,6 +404,39 @@ struct page;
401struct address_space; 404struct address_space;
402struct writeback_control; 405struct writeback_control;
403 406
407struct iov_iter {
408 const struct iovec *iov;
409 unsigned long nr_segs;
410 size_t iov_offset;
411 size_t count;
412};
413
414size_t iov_iter_copy_from_user_atomic(struct page *page,
415 struct iov_iter *i, unsigned long offset, size_t bytes);
416size_t iov_iter_copy_from_user(struct page *page,
417 struct iov_iter *i, unsigned long offset, size_t bytes);
418void iov_iter_advance(struct iov_iter *i, size_t bytes);
419int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes);
420size_t iov_iter_single_seg_count(struct iov_iter *i);
421
422static inline void iov_iter_init(struct iov_iter *i,
423 const struct iovec *iov, unsigned long nr_segs,
424 size_t count, size_t written)
425{
426 i->iov = iov;
427 i->nr_segs = nr_segs;
428 i->iov_offset = 0;
429 i->count = count + written;
430
431 iov_iter_advance(i, written);
432}
433
434static inline size_t iov_iter_count(struct iov_iter *i)
435{
436 return i->count;
437}
438
439
404struct address_space_operations { 440struct address_space_operations {
405 int (*writepage)(struct page *page, struct writeback_control *wbc); 441 int (*writepage)(struct page *page, struct writeback_control *wbc);
406 int (*readpage)(struct file *, struct page *); 442 int (*readpage)(struct file *, struct page *);
@@ -421,6 +457,14 @@ struct address_space_operations {
421 */ 457 */
422 int (*prepare_write)(struct file *, struct page *, unsigned, unsigned); 458 int (*prepare_write)(struct file *, struct page *, unsigned, unsigned);
423 int (*commit_write)(struct file *, struct page *, unsigned, unsigned); 459 int (*commit_write)(struct file *, struct page *, unsigned, unsigned);
460
461 int (*write_begin)(struct file *, struct address_space *mapping,
462 loff_t pos, unsigned len, unsigned flags,
463 struct page **pagep, void **fsdata);
464 int (*write_end)(struct file *, struct address_space *mapping,
465 loff_t pos, unsigned len, unsigned copied,
466 struct page *page, void *fsdata);
467
424 /* Unfortunately this kludge is needed for FIBMAP. Don't use it */ 468 /* Unfortunately this kludge is needed for FIBMAP. Don't use it */
425 sector_t (*bmap)(struct address_space *, sector_t); 469 sector_t (*bmap)(struct address_space *, sector_t);
426 void (*invalidatepage) (struct page *, unsigned long); 470 void (*invalidatepage) (struct page *, unsigned long);
@@ -435,6 +479,18 @@ struct address_space_operations {
435 int (*launder_page) (struct page *); 479 int (*launder_page) (struct page *);
436}; 480};
437 481
482/*
483 * pagecache_write_begin/pagecache_write_end must be used by general code
484 * to write into the pagecache.
485 */
486int pagecache_write_begin(struct file *, struct address_space *mapping,
487 loff_t pos, unsigned len, unsigned flags,
488 struct page **pagep, void **fsdata);
489
490int pagecache_write_end(struct file *, struct address_space *mapping,
491 loff_t pos, unsigned len, unsigned copied,
492 struct page *page, void *fsdata);
493
438struct backing_dev_info; 494struct backing_dev_info;
439struct address_space { 495struct address_space {
440 struct inode *host; /* owner: inode, block_device */ 496 struct inode *host; /* owner: inode, block_device */
@@ -697,16 +753,14 @@ struct fown_struct {
697 * Track a single file's readahead state 753 * Track a single file's readahead state
698 */ 754 */
699struct file_ra_state { 755struct file_ra_state {
700 pgoff_t start; /* where readahead started */ 756 pgoff_t start; /* where readahead started */
701 unsigned long size; /* # of readahead pages */ 757 unsigned int size; /* # of readahead pages */
702 unsigned long async_size; /* do asynchronous readahead when 758 unsigned int async_size; /* do asynchronous readahead when
703 there are only # of pages ahead */ 759 there are only # of pages ahead */
704 760
705 unsigned long ra_pages; /* Maximum readahead window */ 761 unsigned int ra_pages; /* Maximum readahead window */
706 unsigned long mmap_hit; /* Cache hit stat for mmap accesses */ 762 int mmap_miss; /* Cache miss stat for mmap accesses */
707 unsigned long mmap_miss; /* Cache miss stat for mmap accesses */ 763 loff_t prev_pos; /* Cache last read() position */
708 unsigned long prev_index; /* Cache last read() position */
709 unsigned int prev_offset; /* Offset where last read() ended in a page */
710}; 764};
711 765
712/* 766/*
@@ -1835,6 +1889,12 @@ extern int simple_prepare_write(struct file *file, struct page *page,
1835 unsigned offset, unsigned to); 1889 unsigned offset, unsigned to);
1836extern int simple_commit_write(struct file *file, struct page *page, 1890extern int simple_commit_write(struct file *file, struct page *page,
1837 unsigned offset, unsigned to); 1891 unsigned offset, unsigned to);
1892extern int simple_write_begin(struct file *file, struct address_space *mapping,
1893 loff_t pos, unsigned len, unsigned flags,
1894 struct page **pagep, void **fsdata);
1895extern int simple_write_end(struct file *file, struct address_space *mapping,
1896 loff_t pos, unsigned len, unsigned copied,
1897 struct page *page, void *fsdata);
1838 1898
1839extern struct dentry *simple_lookup(struct inode *, struct dentry *, struct nameidata *); 1899extern struct dentry *simple_lookup(struct inode *, struct dentry *, struct nameidata *);
1840extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *); 1900extern ssize_t generic_read_dir(struct file *, char __user *, size_t, loff_t *);
diff --git a/include/linux/gfp.h b/include/linux/gfp.h
index bc68dd9a6d41..7e93a9ae7064 100644
--- a/include/linux/gfp.h
+++ b/include/linux/gfp.h
@@ -48,18 +48,12 @@ struct vm_area_struct;
48#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */ 48#define __GFP_NOMEMALLOC ((__force gfp_t)0x10000u) /* Don't use emergency reserves */
49#define __GFP_HARDWALL ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */ 49#define __GFP_HARDWALL ((__force gfp_t)0x20000u) /* Enforce hardwall cpuset memory allocs */
50#define __GFP_THISNODE ((__force gfp_t)0x40000u)/* No fallback, no policies */ 50#define __GFP_THISNODE ((__force gfp_t)0x40000u)/* No fallback, no policies */
51#define __GFP_MOVABLE ((__force gfp_t)0x80000u) /* Page is movable */ 51#define __GFP_RECLAIMABLE ((__force gfp_t)0x80000u) /* Page is reclaimable */
52#define __GFP_MOVABLE ((__force gfp_t)0x100000u) /* Page is movable */
52 53
53#define __GFP_BITS_SHIFT 20 /* Room for 20 __GFP_FOO bits */ 54#define __GFP_BITS_SHIFT 21 /* Room for 21 __GFP_FOO bits */
54#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1)) 55#define __GFP_BITS_MASK ((__force gfp_t)((1 << __GFP_BITS_SHIFT) - 1))
55 56
56/* if you forget to add the bitmask here kernel will crash, period */
57#define GFP_LEVEL_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS| \
58 __GFP_COLD|__GFP_NOWARN|__GFP_REPEAT| \
59 __GFP_NOFAIL|__GFP_NORETRY|__GFP_COMP| \
60 __GFP_NOMEMALLOC|__GFP_HARDWALL|__GFP_THISNODE| \
61 __GFP_MOVABLE)
62
63/* This equals 0, but use constants in case they ever change */ 57/* This equals 0, but use constants in case they ever change */
64#define GFP_NOWAIT (GFP_ATOMIC & ~__GFP_HIGH) 58#define GFP_NOWAIT (GFP_ATOMIC & ~__GFP_HIGH)
65/* GFP_ATOMIC means both !wait (__GFP_WAIT not set) and use emergency pool */ 59/* GFP_ATOMIC means both !wait (__GFP_WAIT not set) and use emergency pool */
@@ -67,6 +61,8 @@ struct vm_area_struct;
67#define GFP_NOIO (__GFP_WAIT) 61#define GFP_NOIO (__GFP_WAIT)
68#define GFP_NOFS (__GFP_WAIT | __GFP_IO) 62#define GFP_NOFS (__GFP_WAIT | __GFP_IO)
69#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS) 63#define GFP_KERNEL (__GFP_WAIT | __GFP_IO | __GFP_FS)
64#define GFP_TEMPORARY (__GFP_WAIT | __GFP_IO | __GFP_FS | \
65 __GFP_RECLAIMABLE)
70#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL) 66#define GFP_USER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL)
71#define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \ 67#define GFP_HIGHUSER (__GFP_WAIT | __GFP_IO | __GFP_FS | __GFP_HARDWALL | \
72 __GFP_HIGHMEM) 68 __GFP_HIGHMEM)
@@ -86,6 +82,19 @@ struct vm_area_struct;
86#define GFP_THISNODE ((__force gfp_t)0) 82#define GFP_THISNODE ((__force gfp_t)0)
87#endif 83#endif
88 84
85/* This mask makes up all the page movable related flags */
86#define GFP_MOVABLE_MASK (__GFP_RECLAIMABLE|__GFP_MOVABLE)
87
88/* Control page allocator reclaim behavior */
89#define GFP_RECLAIM_MASK (__GFP_WAIT|__GFP_HIGH|__GFP_IO|__GFP_FS|\
90 __GFP_NOWARN|__GFP_REPEAT|__GFP_NOFAIL|\
91 __GFP_NORETRY|__GFP_NOMEMALLOC)
92
93/* Control allocation constraints */
94#define GFP_CONSTRAINT_MASK (__GFP_HARDWALL|__GFP_THISNODE)
95
96/* Do not use these with a slab allocator */
97#define GFP_SLAB_BUG_MASK (__GFP_DMA32|__GFP_HIGHMEM|~__GFP_BITS_MASK)
89 98
90/* Flag - indicates that the buffer will be suitable for DMA. Ignored on some 99/* Flag - indicates that the buffer will be suitable for DMA. Ignored on some
91 platforms, used as appropriate on others */ 100 platforms, used as appropriate on others */
@@ -95,25 +104,50 @@ struct vm_area_struct;
95/* 4GB DMA on some platforms */ 104/* 4GB DMA on some platforms */
96#define GFP_DMA32 __GFP_DMA32 105#define GFP_DMA32 __GFP_DMA32
97 106
107/* Convert GFP flags to their corresponding migrate type */
108static inline int allocflags_to_migratetype(gfp_t gfp_flags)
109{
110 WARN_ON((gfp_flags & GFP_MOVABLE_MASK) == GFP_MOVABLE_MASK);
111
112 if (unlikely(page_group_by_mobility_disabled))
113 return MIGRATE_UNMOVABLE;
114
115 /* Group based on mobility */
116 return (((gfp_flags & __GFP_MOVABLE) != 0) << 1) |
117 ((gfp_flags & __GFP_RECLAIMABLE) != 0);
118}
98 119
99static inline enum zone_type gfp_zone(gfp_t flags) 120static inline enum zone_type gfp_zone(gfp_t flags)
100{ 121{
122 int base = 0;
123
124#ifdef CONFIG_NUMA
125 if (flags & __GFP_THISNODE)
126 base = MAX_NR_ZONES;
127#endif
128
101#ifdef CONFIG_ZONE_DMA 129#ifdef CONFIG_ZONE_DMA
102 if (flags & __GFP_DMA) 130 if (flags & __GFP_DMA)
103 return ZONE_DMA; 131 return base + ZONE_DMA;
104#endif 132#endif
105#ifdef CONFIG_ZONE_DMA32 133#ifdef CONFIG_ZONE_DMA32
106 if (flags & __GFP_DMA32) 134 if (flags & __GFP_DMA32)
107 return ZONE_DMA32; 135 return base + ZONE_DMA32;
108#endif 136#endif
109 if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) == 137 if ((flags & (__GFP_HIGHMEM | __GFP_MOVABLE)) ==
110 (__GFP_HIGHMEM | __GFP_MOVABLE)) 138 (__GFP_HIGHMEM | __GFP_MOVABLE))
111 return ZONE_MOVABLE; 139 return base + ZONE_MOVABLE;
112#ifdef CONFIG_HIGHMEM 140#ifdef CONFIG_HIGHMEM
113 if (flags & __GFP_HIGHMEM) 141 if (flags & __GFP_HIGHMEM)
114 return ZONE_HIGHMEM; 142 return base + ZONE_HIGHMEM;
115#endif 143#endif
116 return ZONE_NORMAL; 144 return base + ZONE_NORMAL;
145}
146
147static inline gfp_t set_migrateflags(gfp_t gfp, gfp_t migrate_flags)
148{
149 BUG_ON((gfp & GFP_MOVABLE_MASK) == GFP_MOVABLE_MASK);
150 return (gfp & ~(GFP_MOVABLE_MASK)) | migrate_flags;
117} 151}
118 152
119/* 153/*
diff --git a/include/linux/hugetlb.h b/include/linux/hugetlb.h
index 3a19b032c0eb..ea0f50bfbe03 100644
--- a/include/linux/hugetlb.h
+++ b/include/linux/hugetlb.h
@@ -33,6 +33,7 @@ void hugetlb_unreserve_pages(struct inode *inode, long offset, long freed);
33 33
34extern unsigned long max_huge_pages; 34extern unsigned long max_huge_pages;
35extern unsigned long hugepages_treat_as_movable; 35extern unsigned long hugepages_treat_as_movable;
36extern int hugetlb_dynamic_pool;
36extern const unsigned long hugetlb_zero, hugetlb_infinity; 37extern const unsigned long hugetlb_zero, hugetlb_infinity;
37extern int sysctl_hugetlb_shm_group; 38extern int sysctl_hugetlb_shm_group;
38 39
diff --git a/include/linux/i2o.h b/include/linux/i2o.h
index 9752307d16ba..7da5b98d90e6 100644
--- a/include/linux/i2o.h
+++ b/include/linux/i2o.h
@@ -32,6 +32,7 @@
32#include <linux/workqueue.h> /* work_struct */ 32#include <linux/workqueue.h> /* work_struct */
33#include <linux/mempool.h> 33#include <linux/mempool.h>
34#include <linux/mutex.h> 34#include <linux/mutex.h>
35#include <linux/scatterlist.h>
35 36
36#include <asm/io.h> 37#include <asm/io.h>
37#include <asm/semaphore.h> /* Needed for MUTEX init macros */ 38#include <asm/semaphore.h> /* Needed for MUTEX init macros */
@@ -837,7 +838,7 @@ static inline int i2o_dma_map_sg(struct i2o_controller *c,
837 if ((sizeof(dma_addr_t) > 4) && c->pae_support) 838 if ((sizeof(dma_addr_t) > 4) && c->pae_support)
838 *mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg))); 839 *mptr++ = cpu_to_le32(i2o_dma_high(sg_dma_address(sg)));
839#endif 840#endif
840 sg++; 841 sg = sg_next(sg);
841 } 842 }
842 *sg_ptr = mptr; 843 *sg_ptr = mptr;
843 844
diff --git a/include/linux/ide.h b/include/linux/ide.h
index 02a27e8cbad2..30a1931466a6 100644
--- a/include/linux/ide.h
+++ b/include/linux/ide.h
@@ -772,7 +772,7 @@ typedef struct hwif_s {
772 772
773 unsigned int nsect; 773 unsigned int nsect;
774 unsigned int nleft; 774 unsigned int nleft;
775 unsigned int cursg; 775 struct scatterlist *cursg;
776 unsigned int cursg_ofs; 776 unsigned int cursg_ofs;
777 777
778 int rqsize; /* max sectors per request */ 778 int rqsize; /* max sectors per request */
@@ -1093,11 +1093,6 @@ extern ide_startstop_t ide_do_reset (ide_drive_t *);
1093extern void ide_init_drive_cmd (struct request *rq); 1093extern void ide_init_drive_cmd (struct request *rq);
1094 1094
1095/* 1095/*
1096 * this function returns error location sector offset in case of a write error
1097 */
1098extern u64 ide_get_error_location(ide_drive_t *, char *);
1099
1100/*
1101 * "action" parameter type for ide_do_drive_cmd() below. 1096 * "action" parameter type for ide_do_drive_cmd() below.
1102 */ 1097 */
1103typedef enum { 1098typedef enum {
diff --git a/include/linux/init.h b/include/linux/init.h
index f8d9d0b5cffc..9b7a2ba8237e 100644
--- a/include/linux/init.h
+++ b/include/linux/init.h
@@ -67,8 +67,10 @@
67 67
68/* For assembly routines */ 68/* For assembly routines */
69#define __INIT .section ".init.text","ax" 69#define __INIT .section ".init.text","ax"
70#define __INIT_REFOK .section ".text.init.refok","ax"
70#define __FINIT .previous 71#define __FINIT .previous
71#define __INITDATA .section ".init.data","aw" 72#define __INITDATA .section ".init.data","aw"
73#define __INITDATA_REFOK .section ".data.init.refok","aw"
72 74
73#ifndef __ASSEMBLY__ 75#ifndef __ASSEMBLY__
74/* 76/*
diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
index 5523f19d88d2..8e5f289052a2 100644
--- a/include/linux/interrupt.h
+++ b/include/linux/interrupt.h
@@ -205,6 +205,15 @@ static inline int disable_irq_wake(unsigned int irq)
205 enable_irq(irq) 205 enable_irq(irq)
206# endif 206# endif
207 207
208static inline int enable_irq_wake(unsigned int irq)
209{
210 return 0;
211}
212
213static inline int disable_irq_wake(unsigned int irq)
214{
215 return 0;
216}
208#endif /* CONFIG_GENERIC_HARDIRQS */ 217#endif /* CONFIG_GENERIC_HARDIRQS */
209 218
210#ifndef __ARCH_SET_SOFTIRQ_PENDING 219#ifndef __ARCH_SET_SOFTIRQ_PENDING
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 71ea92319241..6187a8567bc7 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -110,9 +110,6 @@ extern int allocate_resource(struct resource *root, struct resource *new,
110int adjust_resource(struct resource *res, resource_size_t start, 110int adjust_resource(struct resource *res, resource_size_t start,
111 resource_size_t size); 111 resource_size_t size);
112 112
113/* get registered SYSTEM_RAM resources in specified area */
114extern int find_next_system_ram(struct resource *res);
115
116/* Convenience shorthand with allocation */ 113/* Convenience shorthand with allocation */
117#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name)) 114#define request_region(start,n,name) __request_region(&ioport_resource, (start), (n), (name))
118#define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name)) 115#define request_mem_region(start,n,name) __request_region(&iomem_resource, (start), (n), (name))
diff --git a/include/linux/isdn.h b/include/linux/isdn.h
index d5dda4b643ac..d0ecc8eebfbf 100644
--- a/include/linux/isdn.h
+++ b/include/linux/isdn.h
@@ -167,6 +167,7 @@ typedef struct {
167#include <linux/etherdevice.h> 167#include <linux/etherdevice.h>
168#include <linux/skbuff.h> 168#include <linux/skbuff.h>
169#include <linux/tcp.h> 169#include <linux/tcp.h>
170#include <linux/mutex.h>
170 171
171#define ISDN_TTY_MAJOR 43 172#define ISDN_TTY_MAJOR 43
172#define ISDN_TTYAUX_MAJOR 44 173#define ISDN_TTYAUX_MAJOR 44
@@ -616,7 +617,7 @@ typedef struct isdn_devt {
616 int v110emu[ISDN_MAX_CHANNELS]; /* V.110 emulator-mode 0=none */ 617 int v110emu[ISDN_MAX_CHANNELS]; /* V.110 emulator-mode 0=none */
617 atomic_t v110use[ISDN_MAX_CHANNELS]; /* Usage-Semaphore for stream */ 618 atomic_t v110use[ISDN_MAX_CHANNELS]; /* Usage-Semaphore for stream */
618 isdn_v110_stream *v110[ISDN_MAX_CHANNELS]; /* V.110 private data */ 619 isdn_v110_stream *v110[ISDN_MAX_CHANNELS]; /* V.110 private data */
619 struct semaphore sem; /* serialize list access*/ 620 struct mutex mtx; /* serialize list access*/
620 unsigned long global_features; 621 unsigned long global_features;
621} isdn_dev; 622} isdn_dev;
622 623
diff --git a/include/linux/jbd.h b/include/linux/jbd.h
index 700a93b79189..72f522372924 100644
--- a/include/linux/jbd.h
+++ b/include/linux/jbd.h
@@ -372,6 +372,7 @@ struct jbd_revoke_table_s;
372 * @h_sync: flag for sync-on-close 372 * @h_sync: flag for sync-on-close
373 * @h_jdata: flag to force data journaling 373 * @h_jdata: flag to force data journaling
374 * @h_aborted: flag indicating fatal error on handle 374 * @h_aborted: flag indicating fatal error on handle
375 * @h_lockdep_map: lockdep info for debugging lock problems
375 **/ 376 **/
376 377
377/* Docbook can't yet cope with the bit fields, but will leave the documentation 378/* Docbook can't yet cope with the bit fields, but will leave the documentation
diff --git a/include/linux/jiffies.h b/include/linux/jiffies.h
index e757a74b9d17..8b080024bbc1 100644
--- a/include/linux/jiffies.h
+++ b/include/linux/jiffies.h
@@ -148,6 +148,8 @@ static inline u64 get_jiffies_64(void)
148 */ 148 */
149#define MAX_JIFFY_OFFSET ((LONG_MAX >> 1)-1) 149#define MAX_JIFFY_OFFSET ((LONG_MAX >> 1)-1)
150 150
151extern unsigned long preset_lpj;
152
151/* 153/*
152 * We want to do realistic conversions of time so we need to use the same 154 * We want to do realistic conversions of time so we need to use the same
153 * values the update wall clock code uses as the jiffies size. This value 155 * values the update wall clock code uses as the jiffies size. This value
diff --git a/include/linux/kernel.h b/include/linux/kernel.h
index d9725a28a265..5fdbc814c2eb 100644
--- a/include/linux/kernel.h
+++ b/include/linux/kernel.h
@@ -35,6 +35,7 @@ extern const char linux_proc_banner[];
35#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1) 35#define ALIGN(x,a) __ALIGN_MASK(x,(typeof(x))(a)-1)
36#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask)) 36#define __ALIGN_MASK(x,mask) (((x)+(mask))&~(mask))
37#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a))) 37#define PTR_ALIGN(p, a) ((typeof(p))ALIGN((unsigned long)(p), (a)))
38#define IS_ALIGNED(x,a) (((x) % ((typeof(x))(a))) == 0)
38 39
39#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr)) 40#define ARRAY_SIZE(arr) (sizeof(arr) / sizeof((arr)[0]) + __must_be_array(arr))
40 41
diff --git a/include/linux/kprobes.h b/include/linux/kprobes.h
index 51464d12a4e5..81891581e89b 100644
--- a/include/linux/kprobes.h
+++ b/include/linux/kprobes.h
@@ -166,6 +166,12 @@ struct kretprobe_instance {
166 struct task_struct *task; 166 struct task_struct *task;
167}; 167};
168 168
169struct kretprobe_blackpoint {
170 const char *name;
171 void *addr;
172};
173extern struct kretprobe_blackpoint kretprobe_blacklist[];
174
169static inline void kretprobe_assert(struct kretprobe_instance *ri, 175static inline void kretprobe_assert(struct kretprobe_instance *ri,
170 unsigned long orig_ret_address, unsigned long trampoline_address) 176 unsigned long orig_ret_address, unsigned long trampoline_address)
171{ 177{
diff --git a/include/linux/libata.h b/include/linux/libata.h
index 229a9ff9f924..377e6d4d9be3 100644
--- a/include/linux/libata.h
+++ b/include/linux/libata.h
@@ -29,7 +29,7 @@
29#include <linux/delay.h> 29#include <linux/delay.h>
30#include <linux/interrupt.h> 30#include <linux/interrupt.h>
31#include <linux/dma-mapping.h> 31#include <linux/dma-mapping.h>
32#include <asm/scatterlist.h> 32#include <linux/scatterlist.h>
33#include <linux/io.h> 33#include <linux/io.h>
34#include <linux/ata.h> 34#include <linux/ata.h>
35#include <linux/workqueue.h> 35#include <linux/workqueue.h>
@@ -416,6 +416,7 @@ struct ata_queued_cmd {
416 unsigned long flags; /* ATA_QCFLAG_xxx */ 416 unsigned long flags; /* ATA_QCFLAG_xxx */
417 unsigned int tag; 417 unsigned int tag;
418 unsigned int n_elem; 418 unsigned int n_elem;
419 unsigned int n_iter;
419 unsigned int orig_n_elem; 420 unsigned int orig_n_elem;
420 421
421 int dma_dir; 422 int dma_dir;
@@ -426,7 +427,7 @@ struct ata_queued_cmd {
426 unsigned int nbytes; 427 unsigned int nbytes;
427 unsigned int curbytes; 428 unsigned int curbytes;
428 429
429 unsigned int cursg; 430 struct scatterlist *cursg;
430 unsigned int cursg_ofs; 431 unsigned int cursg_ofs;
431 432
432 struct scatterlist sgent; 433 struct scatterlist sgent;
@@ -1043,7 +1044,7 @@ ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
1043 return 1; 1044 return 1;
1044 if (qc->pad_len) 1045 if (qc->pad_len)
1045 return 0; 1046 return 0;
1046 if (((sg - qc->__sg) + 1) == qc->n_elem) 1047 if (qc->n_iter == qc->n_elem)
1047 return 1; 1048 return 1;
1048 return 0; 1049 return 0;
1049} 1050}
@@ -1051,6 +1052,7 @@ ata_sg_is_last(struct scatterlist *sg, struct ata_queued_cmd *qc)
1051static inline struct scatterlist * 1052static inline struct scatterlist *
1052ata_qc_first_sg(struct ata_queued_cmd *qc) 1053ata_qc_first_sg(struct ata_queued_cmd *qc)
1053{ 1054{
1055 qc->n_iter = 0;
1054 if (qc->n_elem) 1056 if (qc->n_elem)
1055 return qc->__sg; 1057 return qc->__sg;
1056 if (qc->pad_len) 1058 if (qc->pad_len)
@@ -1063,8 +1065,8 @@ ata_qc_next_sg(struct scatterlist *sg, struct ata_queued_cmd *qc)
1063{ 1065{
1064 if (sg == &qc->pad_sgent) 1066 if (sg == &qc->pad_sgent)
1065 return NULL; 1067 return NULL;
1066 if (++sg - qc->__sg < qc->n_elem) 1068 if (++qc->n_iter < qc->n_elem)
1067 return sg; 1069 return sg_next(sg);
1068 if (qc->pad_len) 1070 if (qc->pad_len)
1069 return &qc->pad_sgent; 1071 return &qc->pad_sgent;
1070 return NULL; 1072 return NULL;
@@ -1309,9 +1311,11 @@ static inline void ata_qc_reinit(struct ata_queued_cmd *qc)
1309 qc->dma_dir = DMA_NONE; 1311 qc->dma_dir = DMA_NONE;
1310 qc->__sg = NULL; 1312 qc->__sg = NULL;
1311 qc->flags = 0; 1313 qc->flags = 0;
1312 qc->cursg = qc->cursg_ofs = 0; 1314 qc->cursg = NULL;
1315 qc->cursg_ofs = 0;
1313 qc->nbytes = qc->curbytes = 0; 1316 qc->nbytes = qc->curbytes = 0;
1314 qc->n_elem = 0; 1317 qc->n_elem = 0;
1318 qc->n_iter = 0;
1315 qc->err_mask = 0; 1319 qc->err_mask = 0;
1316 qc->pad_len = 0; 1320 qc->pad_len = 0;
1317 qc->sect_size = ATA_SECT_SIZE; 1321 qc->sect_size = ATA_SECT_SIZE;
diff --git a/include/linux/memory_hotplug.h b/include/linux/memory_hotplug.h
index 7b54666cea8e..8fee7a45736b 100644
--- a/include/linux/memory_hotplug.h
+++ b/include/linux/memory_hotplug.h
@@ -3,7 +3,6 @@
3 3
4#include <linux/mmzone.h> 4#include <linux/mmzone.h>
5#include <linux/spinlock.h> 5#include <linux/spinlock.h>
6#include <linux/mmzone.h>
7#include <linux/notifier.h> 6#include <linux/notifier.h>
8 7
9struct page; 8struct page;
@@ -59,11 +58,21 @@ extern int add_one_highpage(struct page *page, int pfn, int bad_ppro);
59extern void online_page(struct page *page); 58extern void online_page(struct page *page);
60/* VM interface that may be used by firmware interface */ 59/* VM interface that may be used by firmware interface */
61extern int online_pages(unsigned long, unsigned long); 60extern int online_pages(unsigned long, unsigned long);
61extern void __offline_isolated_pages(unsigned long, unsigned long);
62extern int offline_pages(unsigned long, unsigned long, unsigned long);
62 63
63/* reasonably generic interface to expand the physical pages in a zone */ 64/* reasonably generic interface to expand the physical pages in a zone */
64extern int __add_pages(struct zone *zone, unsigned long start_pfn, 65extern int __add_pages(struct zone *zone, unsigned long start_pfn,
65 unsigned long nr_pages); 66 unsigned long nr_pages);
66 67
68/*
69 * Walk thorugh all memory which is registered as resource.
70 * arg is (start_pfn, nr_pages, private_arg_pointer)
71 */
72extern int walk_memory_resource(unsigned long start_pfn,
73 unsigned long nr_pages, void *arg,
74 int (*func)(unsigned long, unsigned long, void *));
75
67#ifdef CONFIG_NUMA 76#ifdef CONFIG_NUMA
68extern int memory_add_physaddr_to_nid(u64 start); 77extern int memory_add_physaddr_to_nid(u64 start);
69#else 78#else
@@ -161,13 +170,6 @@ static inline int mhp_notimplemented(const char *func)
161} 170}
162 171
163#endif /* ! CONFIG_MEMORY_HOTPLUG */ 172#endif /* ! CONFIG_MEMORY_HOTPLUG */
164static inline int __remove_pages(struct zone *zone, unsigned long start_pfn,
165 unsigned long nr_pages)
166{
167 printk(KERN_WARNING "%s() called, not yet supported\n", __FUNCTION__);
168 dump_stack();
169 return -ENOSYS;
170}
171 173
172extern int add_memory(int nid, u64 start, u64 size); 174extern int add_memory(int nid, u64 start, u64 size);
173extern int arch_add_memory(int nid, u64 start, u64 size); 175extern int arch_add_memory(int nid, u64 start, u64 size);
diff --git a/include/linux/mempolicy.h b/include/linux/mempolicy.h
index a020eb2d4e2a..38c04d61ee06 100644
--- a/include/linux/mempolicy.h
+++ b/include/linux/mempolicy.h
@@ -19,6 +19,7 @@
19/* Flags for get_mem_policy */ 19/* Flags for get_mem_policy */
20#define MPOL_F_NODE (1<<0) /* return next IL mode instead of node mask */ 20#define MPOL_F_NODE (1<<0) /* return next IL mode instead of node mask */
21#define MPOL_F_ADDR (1<<1) /* look up vma using address */ 21#define MPOL_F_ADDR (1<<1) /* look up vma using address */
22#define MPOL_F_MEMS_ALLOWED (1<<2) /* return allowed memories */
22 23
23/* Flags for mbind */ 24/* Flags for mbind */
24#define MPOL_MF_STRICT (1<<0) /* Verify existing pages in the mapping */ 25#define MPOL_MF_STRICT (1<<0) /* Verify existing pages in the mapping */
@@ -143,7 +144,6 @@ struct mempolicy *mpol_shared_policy_lookup(struct shared_policy *sp,
143 144
144extern void numa_default_policy(void); 145extern void numa_default_policy(void);
145extern void numa_policy_init(void); 146extern void numa_policy_init(void);
146extern void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *new);
147extern void mpol_rebind_task(struct task_struct *tsk, 147extern void mpol_rebind_task(struct task_struct *tsk,
148 const nodemask_t *new); 148 const nodemask_t *new);
149extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new); 149extern void mpol_rebind_mm(struct mm_struct *mm, nodemask_t *new);
@@ -235,11 +235,6 @@ static inline void numa_default_policy(void)
235{ 235{
236} 236}
237 237
238static inline void mpol_rebind_policy(struct mempolicy *pol,
239 const nodemask_t *new)
240{
241}
242
243static inline void mpol_rebind_task(struct task_struct *tsk, 238static inline void mpol_rebind_task(struct task_struct *tsk,
244 const nodemask_t *new) 239 const nodemask_t *new)
245{ 240{
diff --git a/include/linux/mm.h b/include/linux/mm.h
index 1692dd6cb915..7e87e1b1662e 100644
--- a/include/linux/mm.h
+++ b/include/linux/mm.h
@@ -50,69 +50,6 @@ extern int sysctl_legacy_va_layout;
50 * mmap() functions). 50 * mmap() functions).
51 */ 51 */
52 52
53/*
54 * This struct defines a memory VMM memory area. There is one of these
55 * per VM-area/task. A VM area is any part of the process virtual memory
56 * space that has a special rule for the page-fault handlers (ie a shared
57 * library, the executable area etc).
58 */
59struct vm_area_struct {
60 struct mm_struct * vm_mm; /* The address space we belong to. */
61 unsigned long vm_start; /* Our start address within vm_mm. */
62 unsigned long vm_end; /* The first byte after our end address
63 within vm_mm. */
64
65 /* linked list of VM areas per task, sorted by address */
66 struct vm_area_struct *vm_next;
67
68 pgprot_t vm_page_prot; /* Access permissions of this VMA. */
69 unsigned long vm_flags; /* Flags, listed below. */
70
71 struct rb_node vm_rb;
72
73 /*
74 * For areas with an address space and backing store,
75 * linkage into the address_space->i_mmap prio tree, or
76 * linkage to the list of like vmas hanging off its node, or
77 * linkage of vma in the address_space->i_mmap_nonlinear list.
78 */
79 union {
80 struct {
81 struct list_head list;
82 void *parent; /* aligns with prio_tree_node parent */
83 struct vm_area_struct *head;
84 } vm_set;
85
86 struct raw_prio_tree_node prio_tree_node;
87 } shared;
88
89 /*
90 * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
91 * list, after a COW of one of the file pages. A MAP_SHARED vma
92 * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack
93 * or brk vma (with NULL file) can only be in an anon_vma list.
94 */
95 struct list_head anon_vma_node; /* Serialized by anon_vma->lock */
96 struct anon_vma *anon_vma; /* Serialized by page_table_lock */
97
98 /* Function pointers to deal with this struct. */
99 struct vm_operations_struct * vm_ops;
100
101 /* Information about our backing store: */
102 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
103 units, *not* PAGE_CACHE_SIZE */
104 struct file * vm_file; /* File we map to (can be NULL). */
105 void * vm_private_data; /* was vm_pte (shared mem) */
106 unsigned long vm_truncate_count;/* truncate_count or restart_addr */
107
108#ifndef CONFIG_MMU
109 atomic_t vm_usage; /* refcount (VMAs shared if !MMU) */
110#endif
111#ifdef CONFIG_NUMA
112 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
113#endif
114};
115
116extern struct kmem_cache *vm_area_cachep; 53extern struct kmem_cache *vm_area_cachep;
117 54
118/* 55/*
@@ -631,10 +568,6 @@ static inline struct address_space *page_mapping(struct page *page)
631 VM_BUG_ON(PageSlab(page)); 568 VM_BUG_ON(PageSlab(page));
632 if (unlikely(PageSwapCache(page))) 569 if (unlikely(PageSwapCache(page)))
633 mapping = &swapper_space; 570 mapping = &swapper_space;
634#ifdef CONFIG_SLUB
635 else if (unlikely(PageSlab(page)))
636 mapping = NULL;
637#endif
638 else if (unlikely((unsigned long)mapping & PAGE_MAPPING_ANON)) 571 else if (unlikely((unsigned long)mapping & PAGE_MAPPING_ANON))
639 mapping = NULL; 572 mapping = NULL;
640 return mapping; 573 return mapping;
@@ -715,9 +648,6 @@ static inline int page_mapped(struct page *page)
715extern void show_free_areas(void); 648extern void show_free_areas(void);
716 649
717#ifdef CONFIG_SHMEM 650#ifdef CONFIG_SHMEM
718int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new);
719struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
720 unsigned long addr);
721int shmem_lock(struct file *file, int lock, struct user_struct *user); 651int shmem_lock(struct file *file, int lock, struct user_struct *user);
722#else 652#else
723static inline int shmem_lock(struct file *file, int lock, 653static inline int shmem_lock(struct file *file, int lock,
@@ -725,18 +655,6 @@ static inline int shmem_lock(struct file *file, int lock,
725{ 655{
726 return 0; 656 return 0;
727} 657}
728
729static inline int shmem_set_policy(struct vm_area_struct *vma,
730 struct mempolicy *new)
731{
732 return 0;
733}
734
735static inline struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
736 unsigned long addr)
737{
738 return NULL;
739}
740#endif 658#endif
741struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags); 659struct file *shmem_file_setup(char *name, loff_t size, unsigned long flags);
742 660
@@ -779,8 +697,6 @@ void free_pgtables(struct mmu_gather **tlb, struct vm_area_struct *start_vma,
779 unsigned long floor, unsigned long ceiling); 697 unsigned long floor, unsigned long ceiling);
780int copy_page_range(struct mm_struct *dst, struct mm_struct *src, 698int copy_page_range(struct mm_struct *dst, struct mm_struct *src,
781 struct vm_area_struct *vma); 699 struct vm_area_struct *vma);
782int zeromap_page_range(struct vm_area_struct *vma, unsigned long from,
783 unsigned long size, pgprot_t prot);
784void unmap_mapping_range(struct address_space *mapping, 700void unmap_mapping_range(struct address_space *mapping,
785 loff_t const holebegin, loff_t const holelen, int even_cows); 701 loff_t const holebegin, loff_t const holelen, int even_cows);
786 702
@@ -1106,8 +1022,6 @@ int write_one_page(struct page *page, int wait);
1106/* readahead.c */ 1022/* readahead.c */
1107#define VM_MAX_READAHEAD 128 /* kbytes */ 1023#define VM_MAX_READAHEAD 128 /* kbytes */
1108#define VM_MIN_READAHEAD 16 /* kbytes (includes current page) */ 1024#define VM_MIN_READAHEAD 16 /* kbytes (includes current page) */
1109#define VM_MAX_CACHE_HIT 256 /* max pages in a row in cache before
1110 * turning readahead off */
1111 1025
1112int do_page_cache_readahead(struct address_space *mapping, struct file *filp, 1026int do_page_cache_readahead(struct address_space *mapping, struct file *filp,
1113 pgoff_t offset, unsigned long nr_to_read); 1027 pgoff_t offset, unsigned long nr_to_read);
@@ -1218,5 +1132,16 @@ extern int randomize_va_space;
1218 1132
1219const char * arch_vma_name(struct vm_area_struct *vma); 1133const char * arch_vma_name(struct vm_area_struct *vma);
1220 1134
1135struct page *sparse_mem_map_populate(unsigned long pnum, int nid);
1136pgd_t *vmemmap_pgd_populate(unsigned long addr, int node);
1137pud_t *vmemmap_pud_populate(pgd_t *pgd, unsigned long addr, int node);
1138pmd_t *vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node);
1139pte_t *vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node);
1140void *vmemmap_alloc_block(unsigned long size, int node);
1141void vmemmap_verify(pte_t *, int, unsigned long, unsigned long);
1142int vmemmap_populate_basepages(struct page *start_page,
1143 unsigned long pages, int node);
1144int vmemmap_populate(struct page *start_page, unsigned long pages, int node);
1145
1221#endif /* __KERNEL__ */ 1146#endif /* __KERNEL__ */
1222#endif /* _LINUX_MM_H */ 1147#endif /* _LINUX_MM_H */
diff --git a/include/linux/mm_types.h b/include/linux/mm_types.h
index d5bb1796e12b..877667918452 100644
--- a/include/linux/mm_types.h
+++ b/include/linux/mm_types.h
@@ -1,13 +1,26 @@
1#ifndef _LINUX_MM_TYPES_H 1#ifndef _LINUX_MM_TYPES_H
2#define _LINUX_MM_TYPES_H 2#define _LINUX_MM_TYPES_H
3 3
4#include <linux/auxvec.h> /* For AT_VECTOR_SIZE */
4#include <linux/types.h> 5#include <linux/types.h>
5#include <linux/threads.h> 6#include <linux/threads.h>
6#include <linux/list.h> 7#include <linux/list.h>
7#include <linux/spinlock.h> 8#include <linux/spinlock.h>
9#include <linux/prio_tree.h>
10#include <linux/rbtree.h>
11#include <linux/rwsem.h>
12#include <linux/completion.h>
13#include <asm/page.h>
14#include <asm/mmu.h>
8 15
9struct address_space; 16struct address_space;
10 17
18#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
19typedef atomic_long_t mm_counter_t;
20#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
21typedef unsigned long mm_counter_t;
22#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
23
11/* 24/*
12 * Each physical page in the system has a struct page associated with 25 * Each physical page in the system has a struct page associated with
13 * it to keep track of whatever it is we are using the page for at the 26 * it to keep track of whatever it is we are using the page for at the
@@ -24,10 +37,7 @@ struct page {
24 * to show when page is mapped 37 * to show when page is mapped
25 * & limit reverse map searches. 38 * & limit reverse map searches.
26 */ 39 */
27 struct { /* SLUB uses */ 40 unsigned int inuse; /* SLUB: Nr of objects */
28 short unsigned int inuse;
29 short unsigned int offset;
30 };
31 }; 41 };
32 union { 42 union {
33 struct { 43 struct {
@@ -49,13 +59,8 @@ struct page {
49#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS 59#if NR_CPUS >= CONFIG_SPLIT_PTLOCK_CPUS
50 spinlock_t ptl; 60 spinlock_t ptl;
51#endif 61#endif
52 struct { /* SLUB uses */ 62 struct kmem_cache *slab; /* SLUB: Pointer to slab */
53 void **lockless_freelist; 63 struct page *first_page; /* Compound tail pages */
54 struct kmem_cache *slab; /* Pointer to slab */
55 };
56 struct {
57 struct page *first_page; /* Compound pages */
58 };
59 }; 64 };
60 union { 65 union {
61 pgoff_t index; /* Our offset within mapping. */ 66 pgoff_t index; /* Our offset within mapping. */
@@ -80,4 +85,135 @@ struct page {
80#endif /* WANT_PAGE_VIRTUAL */ 85#endif /* WANT_PAGE_VIRTUAL */
81}; 86};
82 87
88/*
89 * This struct defines a memory VMM memory area. There is one of these
90 * per VM-area/task. A VM area is any part of the process virtual memory
91 * space that has a special rule for the page-fault handlers (ie a shared
92 * library, the executable area etc).
93 */
94struct vm_area_struct {
95 struct mm_struct * vm_mm; /* The address space we belong to. */
96 unsigned long vm_start; /* Our start address within vm_mm. */
97 unsigned long vm_end; /* The first byte after our end address
98 within vm_mm. */
99
100 /* linked list of VM areas per task, sorted by address */
101 struct vm_area_struct *vm_next;
102
103 pgprot_t vm_page_prot; /* Access permissions of this VMA. */
104 unsigned long vm_flags; /* Flags, listed below. */
105
106 struct rb_node vm_rb;
107
108 /*
109 * For areas with an address space and backing store,
110 * linkage into the address_space->i_mmap prio tree, or
111 * linkage to the list of like vmas hanging off its node, or
112 * linkage of vma in the address_space->i_mmap_nonlinear list.
113 */
114 union {
115 struct {
116 struct list_head list;
117 void *parent; /* aligns with prio_tree_node parent */
118 struct vm_area_struct *head;
119 } vm_set;
120
121 struct raw_prio_tree_node prio_tree_node;
122 } shared;
123
124 /*
125 * A file's MAP_PRIVATE vma can be in both i_mmap tree and anon_vma
126 * list, after a COW of one of the file pages. A MAP_SHARED vma
127 * can only be in the i_mmap tree. An anonymous MAP_PRIVATE, stack
128 * or brk vma (with NULL file) can only be in an anon_vma list.
129 */
130 struct list_head anon_vma_node; /* Serialized by anon_vma->lock */
131 struct anon_vma *anon_vma; /* Serialized by page_table_lock */
132
133 /* Function pointers to deal with this struct. */
134 struct vm_operations_struct * vm_ops;
135
136 /* Information about our backing store: */
137 unsigned long vm_pgoff; /* Offset (within vm_file) in PAGE_SIZE
138 units, *not* PAGE_CACHE_SIZE */
139 struct file * vm_file; /* File we map to (can be NULL). */
140 void * vm_private_data; /* was vm_pte (shared mem) */
141 unsigned long vm_truncate_count;/* truncate_count or restart_addr */
142
143#ifndef CONFIG_MMU
144 atomic_t vm_usage; /* refcount (VMAs shared if !MMU) */
145#endif
146#ifdef CONFIG_NUMA
147 struct mempolicy *vm_policy; /* NUMA policy for the VMA */
148#endif
149};
150
151struct mm_struct {
152 struct vm_area_struct * mmap; /* list of VMAs */
153 struct rb_root mm_rb;
154 struct vm_area_struct * mmap_cache; /* last find_vma result */
155 unsigned long (*get_unmapped_area) (struct file *filp,
156 unsigned long addr, unsigned long len,
157 unsigned long pgoff, unsigned long flags);
158 void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
159 unsigned long mmap_base; /* base of mmap area */
160 unsigned long task_size; /* size of task vm space */
161 unsigned long cached_hole_size; /* if non-zero, the largest hole below free_area_cache */
162 unsigned long free_area_cache; /* first hole of size cached_hole_size or larger */
163 pgd_t * pgd;
164 atomic_t mm_users; /* How many users with user space? */
165 atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
166 int map_count; /* number of VMAs */
167 struct rw_semaphore mmap_sem;
168 spinlock_t page_table_lock; /* Protects page tables and some counters */
169
170 struct list_head mmlist; /* List of maybe swapped mm's. These are globally strung
171 * together off init_mm.mmlist, and are protected
172 * by mmlist_lock
173 */
174
175 /* Special counters, in some configurations protected by the
176 * page_table_lock, in other configurations by being atomic.
177 */
178 mm_counter_t _file_rss;
179 mm_counter_t _anon_rss;
180
181 unsigned long hiwater_rss; /* High-watermark of RSS usage */
182 unsigned long hiwater_vm; /* High-water virtual memory usage */
183
184 unsigned long total_vm, locked_vm, shared_vm, exec_vm;
185 unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;
186 unsigned long start_code, end_code, start_data, end_data;
187 unsigned long start_brk, brk, start_stack;
188 unsigned long arg_start, arg_end, env_start, env_end;
189
190 unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
191
192 cpumask_t cpu_vm_mask;
193
194 /* Architecture-specific MM context */
195 mm_context_t context;
196
197 /* Swap token stuff */
198 /*
199 * Last value of global fault stamp as seen by this process.
200 * In other words, this value gives an indication of how long
201 * it has been since this task got the token.
202 * Look at mm/thrash.c
203 */
204 unsigned int faultstamp;
205 unsigned int token_priority;
206 unsigned int last_interval;
207
208 unsigned long flags; /* Must use atomic bitops to access the bits */
209
210 /* coredumping support */
211 int core_waiters;
212 struct completion *core_startup_done, core_done;
213
214 /* aio bits */
215 rwlock_t ioctx_list_lock;
216 struct kioctx *ioctx_list;
217};
218
83#endif /* _LINUX_MM_TYPES_H */ 219#endif /* _LINUX_MM_TYPES_H */
diff --git a/include/linux/mmzone.h b/include/linux/mmzone.h
index 4e5627379b09..f4bfe824834f 100644
--- a/include/linux/mmzone.h
+++ b/include/linux/mmzone.h
@@ -13,6 +13,7 @@
13#include <linux/init.h> 13#include <linux/init.h>
14#include <linux/seqlock.h> 14#include <linux/seqlock.h>
15#include <linux/nodemask.h> 15#include <linux/nodemask.h>
16#include <linux/pageblock-flags.h>
16#include <asm/atomic.h> 17#include <asm/atomic.h>
17#include <asm/page.h> 18#include <asm/page.h>
18 19
@@ -32,8 +33,29 @@
32 */ 33 */
33#define PAGE_ALLOC_COSTLY_ORDER 3 34#define PAGE_ALLOC_COSTLY_ORDER 3
34 35
36#define MIGRATE_UNMOVABLE 0
37#define MIGRATE_RECLAIMABLE 1
38#define MIGRATE_MOVABLE 2
39#define MIGRATE_RESERVE 3
40#define MIGRATE_ISOLATE 4 /* can't allocate from here */
41#define MIGRATE_TYPES 5
42
43#define for_each_migratetype_order(order, type) \
44 for (order = 0; order < MAX_ORDER; order++) \
45 for (type = 0; type < MIGRATE_TYPES; type++)
46
47extern int page_group_by_mobility_disabled;
48
49static inline int get_pageblock_migratetype(struct page *page)
50{
51 if (unlikely(page_group_by_mobility_disabled))
52 return MIGRATE_UNMOVABLE;
53
54 return get_pageblock_flags_group(page, PB_migrate, PB_migrate_end);
55}
56
35struct free_area { 57struct free_area {
36 struct list_head free_list; 58 struct list_head free_list[MIGRATE_TYPES];
37 unsigned long nr_free; 59 unsigned long nr_free;
38}; 60};
39 61
@@ -222,6 +244,14 @@ struct zone {
222#endif 244#endif
223 struct free_area free_area[MAX_ORDER]; 245 struct free_area free_area[MAX_ORDER];
224 246
247#ifndef CONFIG_SPARSEMEM
248 /*
249 * Flags for a pageblock_nr_pages block. See pageblock-flags.h.
250 * In SPARSEMEM, this map is stored in struct mem_section
251 */
252 unsigned long *pageblock_flags;
253#endif /* CONFIG_SPARSEMEM */
254
225 255
226 ZONE_PADDING(_pad1_) 256 ZONE_PADDING(_pad1_)
227 257
@@ -324,6 +354,17 @@ struct zone {
324#define MAX_ZONES_PER_ZONELIST (MAX_NUMNODES * MAX_NR_ZONES) 354#define MAX_ZONES_PER_ZONELIST (MAX_NUMNODES * MAX_NR_ZONES)
325 355
326#ifdef CONFIG_NUMA 356#ifdef CONFIG_NUMA
357
358/*
359 * The NUMA zonelists are doubled becausse we need zonelists that restrict the
360 * allocations to a single node for GFP_THISNODE.
361 *
362 * [0 .. MAX_NR_ZONES -1] : Zonelists with fallback
363 * [MAZ_NR_ZONES ... MAZ_ZONELISTS -1] : No fallback (GFP_THISNODE)
364 */
365#define MAX_ZONELISTS (2 * MAX_NR_ZONES)
366
367
327/* 368/*
328 * We cache key information from each zonelist for smaller cache 369 * We cache key information from each zonelist for smaller cache
329 * footprint when scanning for free pages in get_page_from_freelist(). 370 * footprint when scanning for free pages in get_page_from_freelist().
@@ -389,6 +430,7 @@ struct zonelist_cache {
389 unsigned long last_full_zap; /* when last zap'd (jiffies) */ 430 unsigned long last_full_zap; /* when last zap'd (jiffies) */
390}; 431};
391#else 432#else
433#define MAX_ZONELISTS MAX_NR_ZONES
392struct zonelist_cache; 434struct zonelist_cache;
393#endif 435#endif
394 436
@@ -455,7 +497,7 @@ extern struct page *mem_map;
455struct bootmem_data; 497struct bootmem_data;
456typedef struct pglist_data { 498typedef struct pglist_data {
457 struct zone node_zones[MAX_NR_ZONES]; 499 struct zone node_zones[MAX_NR_ZONES];
458 struct zonelist node_zonelists[MAX_NR_ZONES]; 500 struct zonelist node_zonelists[MAX_ZONELISTS];
459 int nr_zones; 501 int nr_zones;
460#ifdef CONFIG_FLAT_NODE_MEM_MAP 502#ifdef CONFIG_FLAT_NODE_MEM_MAP
461 struct page *node_mem_map; 503 struct page *node_mem_map;
@@ -708,6 +750,9 @@ extern struct zone *next_zone(struct zone *zone);
708#define PAGES_PER_SECTION (1UL << PFN_SECTION_SHIFT) 750#define PAGES_PER_SECTION (1UL << PFN_SECTION_SHIFT)
709#define PAGE_SECTION_MASK (~(PAGES_PER_SECTION-1)) 751#define PAGE_SECTION_MASK (~(PAGES_PER_SECTION-1))
710 752
753#define SECTION_BLOCKFLAGS_BITS \
754 ((1UL << (PFN_SECTION_SHIFT - pageblock_order)) * NR_PAGEBLOCK_BITS)
755
711#if (MAX_ORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS 756#if (MAX_ORDER - 1 + PAGE_SHIFT) > SECTION_SIZE_BITS
712#error Allocator MAX_ORDER exceeds SECTION_SIZE 757#error Allocator MAX_ORDER exceeds SECTION_SIZE
713#endif 758#endif
@@ -727,6 +772,9 @@ struct mem_section {
727 * before using it wrong. 772 * before using it wrong.
728 */ 773 */
729 unsigned long section_mem_map; 774 unsigned long section_mem_map;
775
776 /* See declaration of similar field in struct zone */
777 unsigned long *pageblock_flags;
730}; 778};
731 779
732#ifdef CONFIG_SPARSEMEM_EXTREME 780#ifdef CONFIG_SPARSEMEM_EXTREME
@@ -771,12 +819,17 @@ static inline struct page *__section_mem_map_addr(struct mem_section *section)
771 return (struct page *)map; 819 return (struct page *)map;
772} 820}
773 821
774static inline int valid_section(struct mem_section *section) 822static inline int present_section(struct mem_section *section)
775{ 823{
776 return (section && (section->section_mem_map & SECTION_MARKED_PRESENT)); 824 return (section && (section->section_mem_map & SECTION_MARKED_PRESENT));
777} 825}
778 826
779static inline int section_has_mem_map(struct mem_section *section) 827static inline int present_section_nr(unsigned long nr)
828{
829 return present_section(__nr_to_section(nr));
830}
831
832static inline int valid_section(struct mem_section *section)
780{ 833{
781 return (section && (section->section_mem_map & SECTION_HAS_MEM_MAP)); 834 return (section && (section->section_mem_map & SECTION_HAS_MEM_MAP));
782} 835}
@@ -798,6 +851,13 @@ static inline int pfn_valid(unsigned long pfn)
798 return valid_section(__nr_to_section(pfn_to_section_nr(pfn))); 851 return valid_section(__nr_to_section(pfn_to_section_nr(pfn)));
799} 852}
800 853
854static inline int pfn_present(unsigned long pfn)
855{
856 if (pfn_to_section_nr(pfn) >= NR_MEM_SECTIONS)
857 return 0;
858 return present_section(__nr_to_section(pfn_to_section_nr(pfn)));
859}
860
801/* 861/*
802 * These are _only_ used during initialisation, therefore they 862 * These are _only_ used during initialisation, therefore they
803 * can use __initdata ... They could have names to indicate 863 * can use __initdata ... They could have names to indicate
diff --git a/include/linux/nfsd/export.h b/include/linux/nfsd/export.h
index 5cd192469096..bcb7abafbca9 100644
--- a/include/linux/nfsd/export.h
+++ b/include/linux/nfsd/export.h
@@ -127,17 +127,9 @@ void nfsd_export_shutdown(void);
127void nfsd_export_flush(void); 127void nfsd_export_flush(void);
128void exp_readlock(void); 128void exp_readlock(void);
129void exp_readunlock(void); 129void exp_readunlock(void);
130struct svc_export * exp_get_by_name(struct auth_domain *clp,
131 struct vfsmount *mnt,
132 struct dentry *dentry,
133 struct cache_req *reqp);
134struct svc_export * rqst_exp_get_by_name(struct svc_rqst *, 130struct svc_export * rqst_exp_get_by_name(struct svc_rqst *,
135 struct vfsmount *, 131 struct vfsmount *,
136 struct dentry *); 132 struct dentry *);
137struct svc_export * exp_parent(struct auth_domain *clp,
138 struct vfsmount *mnt,
139 struct dentry *dentry,
140 struct cache_req *reqp);
141struct svc_export * rqst_exp_parent(struct svc_rqst *, 133struct svc_export * rqst_exp_parent(struct svc_rqst *,
142 struct vfsmount *mnt, 134 struct vfsmount *mnt,
143 struct dentry *dentry); 135 struct dentry *dentry);
@@ -157,9 +149,6 @@ static inline void exp_get(struct svc_export *exp)
157{ 149{
158 cache_get(&exp->h); 150 cache_get(&exp->h);
159} 151}
160extern struct svc_export *
161exp_find(struct auth_domain *clp, int fsid_type, u32 *fsidv,
162 struct cache_req *reqp);
163struct svc_export * rqst_exp_find(struct svc_rqst *, int, u32 *); 152struct svc_export * rqst_exp_find(struct svc_rqst *, int, u32 *);
164 153
165#endif /* __KERNEL__ */ 154#endif /* __KERNEL__ */
diff --git a/include/linux/nodemask.h b/include/linux/nodemask.h
index 52c54a5720f3..905e18f4b412 100644
--- a/include/linux/nodemask.h
+++ b/include/linux/nodemask.h
@@ -338,31 +338,88 @@ static inline void __nodes_remap(nodemask_t *dstp, const nodemask_t *srcp,
338#endif /* MAX_NUMNODES */ 338#endif /* MAX_NUMNODES */
339 339
340/* 340/*
341 * Bitmasks that are kept for all the nodes.
342 */
343enum node_states {
344 N_POSSIBLE, /* The node could become online at some point */
345 N_ONLINE, /* The node is online */
346 N_NORMAL_MEMORY, /* The node has regular memory */
347#ifdef CONFIG_HIGHMEM
348 N_HIGH_MEMORY, /* The node has regular or high memory */
349#else
350 N_HIGH_MEMORY = N_NORMAL_MEMORY,
351#endif
352 N_CPU, /* The node has one or more cpus */
353 NR_NODE_STATES
354};
355
356/*
341 * The following particular system nodemasks and operations 357 * The following particular system nodemasks and operations
342 * on them manage all possible and online nodes. 358 * on them manage all possible and online nodes.
343 */ 359 */
344 360
345extern nodemask_t node_online_map; 361extern nodemask_t node_states[NR_NODE_STATES];
346extern nodemask_t node_possible_map;
347 362
348#if MAX_NUMNODES > 1 363#if MAX_NUMNODES > 1
349#define num_online_nodes() nodes_weight(node_online_map) 364static inline int node_state(int node, enum node_states state)
350#define num_possible_nodes() nodes_weight(node_possible_map) 365{
351#define node_online(node) node_isset((node), node_online_map) 366 return node_isset(node, node_states[state]);
352#define node_possible(node) node_isset((node), node_possible_map) 367}
353#define first_online_node first_node(node_online_map) 368
354#define next_online_node(nid) next_node((nid), node_online_map) 369static inline void node_set_state(int node, enum node_states state)
370{
371 __node_set(node, &node_states[state]);
372}
373
374static inline void node_clear_state(int node, enum node_states state)
375{
376 __node_clear(node, &node_states[state]);
377}
378
379static inline int num_node_state(enum node_states state)
380{
381 return nodes_weight(node_states[state]);
382}
383
384#define for_each_node_state(__node, __state) \
385 for_each_node_mask((__node), node_states[__state])
386
387#define first_online_node first_node(node_states[N_ONLINE])
388#define next_online_node(nid) next_node((nid), node_states[N_ONLINE])
389
355extern int nr_node_ids; 390extern int nr_node_ids;
356#else 391#else
357#define num_online_nodes() 1 392
358#define num_possible_nodes() 1 393static inline int node_state(int node, enum node_states state)
359#define node_online(node) ((node) == 0) 394{
360#define node_possible(node) ((node) == 0) 395 return node == 0;
396}
397
398static inline void node_set_state(int node, enum node_states state)
399{
400}
401
402static inline void node_clear_state(int node, enum node_states state)
403{
404}
405
406static inline int num_node_state(enum node_states state)
407{
408 return 1;
409}
410
411#define for_each_node_state(node, __state) \
412 for ( (node) = 0; (node) == 0; (node) = 1)
413
361#define first_online_node 0 414#define first_online_node 0
362#define next_online_node(nid) (MAX_NUMNODES) 415#define next_online_node(nid) (MAX_NUMNODES)
363#define nr_node_ids 1 416#define nr_node_ids 1
417
364#endif 418#endif
365 419
420#define node_online_map node_states[N_ONLINE]
421#define node_possible_map node_states[N_POSSIBLE]
422
366#define any_online_node(mask) \ 423#define any_online_node(mask) \
367({ \ 424({ \
368 int node; \ 425 int node; \
@@ -372,10 +429,15 @@ extern int nr_node_ids;
372 node; \ 429 node; \
373}) 430})
374 431
375#define node_set_online(node) set_bit((node), node_online_map.bits) 432#define num_online_nodes() num_node_state(N_ONLINE)
376#define node_set_offline(node) clear_bit((node), node_online_map.bits) 433#define num_possible_nodes() num_node_state(N_POSSIBLE)
434#define node_online(node) node_state((node), N_ONLINE)
435#define node_possible(node) node_state((node), N_POSSIBLE)
436
437#define node_set_online(node) node_set_state((node), N_ONLINE)
438#define node_set_offline(node) node_clear_state((node), N_ONLINE)
377 439
378#define for_each_node(node) for_each_node_mask((node), node_possible_map) 440#define for_each_node(node) for_each_node_state(node, N_POSSIBLE)
379#define for_each_online_node(node) for_each_node_mask((node), node_online_map) 441#define for_each_online_node(node) for_each_node_state(node, N_ONLINE)
380 442
381#endif /* __LINUX_NODEMASK_H */ 443#endif /* __LINUX_NODEMASK_H */
diff --git a/include/linux/page-isolation.h b/include/linux/page-isolation.h
new file mode 100644
index 000000000000..051c1b1ede4e
--- /dev/null
+++ b/include/linux/page-isolation.h
@@ -0,0 +1,37 @@
1#ifndef __LINUX_PAGEISOLATION_H
2#define __LINUX_PAGEISOLATION_H
3
4/*
5 * Changes migrate type in [start_pfn, end_pfn) to be MIGRATE_ISOLATE.
6 * If specified range includes migrate types other than MOVABLE,
7 * this will fail with -EBUSY.
8 *
9 * For isolating all pages in the range finally, the caller have to
10 * free all pages in the range. test_page_isolated() can be used for
11 * test it.
12 */
13extern int
14start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn);
15
16/*
17 * Changes MIGRATE_ISOLATE to MIGRATE_MOVABLE.
18 * target range is [start_pfn, end_pfn)
19 */
20extern int
21undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn);
22
23/*
24 * test all pages in [start_pfn, end_pfn)are isolated or not.
25 */
26extern int
27test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn);
28
29/*
30 * Internal funcs.Changes pageblock's migrate type.
31 * Please use make_pagetype_isolated()/make_pagetype_movable().
32 */
33extern int set_migratetype_isolate(struct page *page);
34extern void unset_migratetype_isolate(struct page *page);
35
36
37#endif
diff --git a/include/linux/pageblock-flags.h b/include/linux/pageblock-flags.h
new file mode 100644
index 000000000000..e875905f7b12
--- /dev/null
+++ b/include/linux/pageblock-flags.h
@@ -0,0 +1,75 @@
1/*
2 * Macros for manipulating and testing flags related to a
3 * pageblock_nr_pages number of pages.
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of the GNU General Public License as published by
7 * the Free Software Foundation version 2 of the License
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
17 *
18 * Copyright (C) IBM Corporation, 2006
19 *
20 * Original author, Mel Gorman
21 * Major cleanups and reduction of bit operations, Andy Whitcroft
22 */
23#ifndef PAGEBLOCK_FLAGS_H
24#define PAGEBLOCK_FLAGS_H
25
26#include <linux/types.h>
27
28/* Macro to aid the definition of ranges of bits */
29#define PB_range(name, required_bits) \
30 name, name ## _end = (name + required_bits) - 1
31
32/* Bit indices that affect a whole block of pages */
33enum pageblock_bits {
34 PB_range(PB_migrate, 3), /* 3 bits required for migrate types */
35 NR_PAGEBLOCK_BITS
36};
37
38#ifdef CONFIG_HUGETLB_PAGE
39
40#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
41
42/* Huge page sizes are variable */
43extern int pageblock_order;
44
45#else /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
46
47/* Huge pages are a constant size */
48#define pageblock_order HUGETLB_PAGE_ORDER
49
50#endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
51
52#else /* CONFIG_HUGETLB_PAGE */
53
54/* If huge pages are not used, group by MAX_ORDER_NR_PAGES */
55#define pageblock_order (MAX_ORDER-1)
56
57#endif /* CONFIG_HUGETLB_PAGE */
58
59#define pageblock_nr_pages (1UL << pageblock_order)
60
61/* Forward declaration */
62struct page;
63
64/* Declarations for getting and setting flags. See mm/page_alloc.c */
65unsigned long get_pageblock_flags_group(struct page *page,
66 int start_bitidx, int end_bitidx);
67void set_pageblock_flags_group(struct page *page, unsigned long flags,
68 int start_bitidx, int end_bitidx);
69
70#define get_pageblock_flags(page) \
71 get_pageblock_flags_group(page, 0, NR_PAGEBLOCK_BITS-1)
72#define set_pageblock_flags(page) \
73 set_pageblock_flags_group(page, 0, NR_PAGEBLOCK_BITS-1)
74
75#endif /* PAGEBLOCK_FLAGS_H */
diff --git a/include/linux/pagemap.h b/include/linux/pagemap.h
index 8a83537d6978..db8a410ae9e1 100644
--- a/include/linux/pagemap.h
+++ b/include/linux/pagemap.h
@@ -84,11 +84,11 @@ static inline struct page *page_cache_alloc_cold(struct address_space *x)
84typedef int filler_t(void *, struct page *); 84typedef int filler_t(void *, struct page *);
85 85
86extern struct page * find_get_page(struct address_space *mapping, 86extern struct page * find_get_page(struct address_space *mapping,
87 unsigned long index); 87 pgoff_t index);
88extern struct page * find_lock_page(struct address_space *mapping, 88extern struct page * find_lock_page(struct address_space *mapping,
89 unsigned long index); 89 pgoff_t index);
90extern struct page * find_or_create_page(struct address_space *mapping, 90extern struct page * find_or_create_page(struct address_space *mapping,
91 unsigned long index, gfp_t gfp_mask); 91 pgoff_t index, gfp_t gfp_mask);
92unsigned find_get_pages(struct address_space *mapping, pgoff_t start, 92unsigned find_get_pages(struct address_space *mapping, pgoff_t start,
93 unsigned int nr_pages, struct page **pages); 93 unsigned int nr_pages, struct page **pages);
94unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start, 94unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
@@ -96,44 +96,47 @@ unsigned find_get_pages_contig(struct address_space *mapping, pgoff_t start,
96unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index, 96unsigned find_get_pages_tag(struct address_space *mapping, pgoff_t *index,
97 int tag, unsigned int nr_pages, struct page **pages); 97 int tag, unsigned int nr_pages, struct page **pages);
98 98
99struct page *__grab_cache_page(struct address_space *mapping, pgoff_t index);
100
99/* 101/*
100 * Returns locked page at given index in given cache, creating it if needed. 102 * Returns locked page at given index in given cache, creating it if needed.
101 */ 103 */
102static inline struct page *grab_cache_page(struct address_space *mapping, unsigned long index) 104static inline struct page *grab_cache_page(struct address_space *mapping,
105 pgoff_t index)
103{ 106{
104 return find_or_create_page(mapping, index, mapping_gfp_mask(mapping)); 107 return find_or_create_page(mapping, index, mapping_gfp_mask(mapping));
105} 108}
106 109
107extern struct page * grab_cache_page_nowait(struct address_space *mapping, 110extern struct page * grab_cache_page_nowait(struct address_space *mapping,
108 unsigned long index); 111 pgoff_t index);
109extern struct page * read_cache_page_async(struct address_space *mapping, 112extern struct page * read_cache_page_async(struct address_space *mapping,
110 unsigned long index, filler_t *filler, 113 pgoff_t index, filler_t *filler,
111 void *data); 114 void *data);
112extern struct page * read_cache_page(struct address_space *mapping, 115extern struct page * read_cache_page(struct address_space *mapping,
113 unsigned long index, filler_t *filler, 116 pgoff_t index, filler_t *filler,
114 void *data); 117 void *data);
115extern int read_cache_pages(struct address_space *mapping, 118extern int read_cache_pages(struct address_space *mapping,
116 struct list_head *pages, filler_t *filler, void *data); 119 struct list_head *pages, filler_t *filler, void *data);
117 120
118static inline struct page *read_mapping_page_async( 121static inline struct page *read_mapping_page_async(
119 struct address_space *mapping, 122 struct address_space *mapping,
120 unsigned long index, void *data) 123 pgoff_t index, void *data)
121{ 124{
122 filler_t *filler = (filler_t *)mapping->a_ops->readpage; 125 filler_t *filler = (filler_t *)mapping->a_ops->readpage;
123 return read_cache_page_async(mapping, index, filler, data); 126 return read_cache_page_async(mapping, index, filler, data);
124} 127}
125 128
126static inline struct page *read_mapping_page(struct address_space *mapping, 129static inline struct page *read_mapping_page(struct address_space *mapping,
127 unsigned long index, void *data) 130 pgoff_t index, void *data)
128{ 131{
129 filler_t *filler = (filler_t *)mapping->a_ops->readpage; 132 filler_t *filler = (filler_t *)mapping->a_ops->readpage;
130 return read_cache_page(mapping, index, filler, data); 133 return read_cache_page(mapping, index, filler, data);
131} 134}
132 135
133int add_to_page_cache(struct page *page, struct address_space *mapping, 136int add_to_page_cache(struct page *page, struct address_space *mapping,
134 unsigned long index, gfp_t gfp_mask); 137 pgoff_t index, gfp_t gfp_mask);
135int add_to_page_cache_lru(struct page *page, struct address_space *mapping, 138int add_to_page_cache_lru(struct page *page, struct address_space *mapping,
136 unsigned long index, gfp_t gfp_mask); 139 pgoff_t index, gfp_t gfp_mask);
137extern void remove_from_page_cache(struct page *page); 140extern void remove_from_page_cache(struct page *page);
138extern void __remove_from_page_cache(struct page *page); 141extern void __remove_from_page_cache(struct page *page);
139 142
@@ -218,6 +221,9 @@ static inline int fault_in_pages_writeable(char __user *uaddr, int size)
218{ 221{
219 int ret; 222 int ret;
220 223
224 if (unlikely(size == 0))
225 return 0;
226
221 /* 227 /*
222 * Writing zeroes into userspace here is OK, because we know that if 228 * Writing zeroes into userspace here is OK, because we know that if
223 * the zero gets there, we'll be overwriting it. 229 * the zero gets there, we'll be overwriting it.
@@ -237,19 +243,23 @@ static inline int fault_in_pages_writeable(char __user *uaddr, int size)
237 return ret; 243 return ret;
238} 244}
239 245
240static inline void fault_in_pages_readable(const char __user *uaddr, int size) 246static inline int fault_in_pages_readable(const char __user *uaddr, int size)
241{ 247{
242 volatile char c; 248 volatile char c;
243 int ret; 249 int ret;
244 250
251 if (unlikely(size == 0))
252 return 0;
253
245 ret = __get_user(c, uaddr); 254 ret = __get_user(c, uaddr);
246 if (ret == 0) { 255 if (ret == 0) {
247 const char __user *end = uaddr + size - 1; 256 const char __user *end = uaddr + size - 1;
248 257
249 if (((unsigned long)uaddr & PAGE_MASK) != 258 if (((unsigned long)uaddr & PAGE_MASK) !=
250 ((unsigned long)end & PAGE_MASK)) 259 ((unsigned long)end & PAGE_MASK))
251 __get_user(c, end); 260 ret = __get_user(c, end);
252 } 261 }
262 return ret;
253} 263}
254 264
255#endif /* _LINUX_PAGEMAP_H */ 265#endif /* _LINUX_PAGEMAP_H */
diff --git a/include/linux/pci_ids.h b/include/linux/pci_ids.h
index 2c49561f9b45..df948b44edad 100644
--- a/include/linux/pci_ids.h
+++ b/include/linux/pci_ids.h
@@ -1995,6 +1995,8 @@
1995#define PCI_VENDOR_ID_TOPIC 0x151f 1995#define PCI_VENDOR_ID_TOPIC 0x151f
1996#define PCI_DEVICE_ID_TOPIC_TP560 0x0000 1996#define PCI_DEVICE_ID_TOPIC_TP560 0x0000
1997 1997
1998#define PCI_VENDOR_ID_MAINPINE 0x1522
1999#define PCI_DEVICE_ID_MAINPINE_PBRIDGE 0x0100
1998#define PCI_VENDOR_ID_ENE 0x1524 2000#define PCI_VENDOR_ID_ENE 0x1524
1999#define PCI_DEVICE_ID_ENE_CB712_SD 0x0550 2001#define PCI_DEVICE_ID_ENE_CB712_SD 0x0550
2000#define PCI_DEVICE_ID_ENE_CB712_SD_2 0x0551 2002#define PCI_DEVICE_ID_ENE_CB712_SD_2 0x0551
@@ -2324,6 +2326,8 @@
2324#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599 2326#define PCI_DEVICE_ID_INTEL_MCH_PC 0x3599
2325#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a 2327#define PCI_DEVICE_ID_INTEL_MCH_PC1 0x359a
2326#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e 2328#define PCI_DEVICE_ID_INTEL_E7525_MCH 0x359e
2329#define PCI_DEVICE_ID_INTEL_IOAT_CNB 0x360b
2330#define PCI_DEVICE_ID_INTEL_IOAT_SCNB 0x65ff
2327#define PCI_DEVICE_ID_INTEL_TOLAPAI_0 0x5031 2331#define PCI_DEVICE_ID_INTEL_TOLAPAI_0 0x5031
2328#define PCI_DEVICE_ID_INTEL_TOLAPAI_1 0x5032 2332#define PCI_DEVICE_ID_INTEL_TOLAPAI_1 0x5032
2329#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000 2333#define PCI_DEVICE_ID_INTEL_82371SB_0 0x7000
diff --git a/include/linux/radix-tree.h b/include/linux/radix-tree.h
index f9e77d2ee320..b6116b4445c7 100644
--- a/include/linux/radix-tree.h
+++ b/include/linux/radix-tree.h
@@ -26,28 +26,31 @@
26#include <linux/rcupdate.h> 26#include <linux/rcupdate.h>
27 27
28/* 28/*
29 * A direct pointer (root->rnode pointing directly to a data item, 29 * An indirect pointer (root->rnode pointing to a radix_tree_node, rather
30 * rather than another radix_tree_node) is signalled by the low bit 30 * than a data item) is signalled by the low bit set in the root->rnode
31 * set in the root->rnode pointer. 31 * pointer.
32 * 32 *
33 * In this case root->height is also NULL, but the direct pointer tests are 33 * In this case root->height is > 0, but the indirect pointer tests are
34 * needed for RCU lookups when root->height is unreliable. 34 * needed for RCU lookups (because root->height is unreliable). The only
35 * time callers need worry about this is when doing a lookup_slot under
36 * RCU.
35 */ 37 */
36#define RADIX_TREE_DIRECT_PTR 1 38#define RADIX_TREE_INDIRECT_PTR 1
39#define RADIX_TREE_RETRY ((void *)-1UL)
37 40
38static inline void *radix_tree_ptr_to_direct(void *ptr) 41static inline void *radix_tree_ptr_to_indirect(void *ptr)
39{ 42{
40 return (void *)((unsigned long)ptr | RADIX_TREE_DIRECT_PTR); 43 return (void *)((unsigned long)ptr | RADIX_TREE_INDIRECT_PTR);
41} 44}
42 45
43static inline void *radix_tree_direct_to_ptr(void *ptr) 46static inline void *radix_tree_indirect_to_ptr(void *ptr)
44{ 47{
45 return (void *)((unsigned long)ptr & ~RADIX_TREE_DIRECT_PTR); 48 return (void *)((unsigned long)ptr & ~RADIX_TREE_INDIRECT_PTR);
46} 49}
47 50
48static inline int radix_tree_is_direct_ptr(void *ptr) 51static inline int radix_tree_is_indirect_ptr(void *ptr)
49{ 52{
50 return (int)((unsigned long)ptr & RADIX_TREE_DIRECT_PTR); 53 return (int)((unsigned long)ptr & RADIX_TREE_INDIRECT_PTR);
51} 54}
52 55
53/*** radix-tree API starts here ***/ 56/*** radix-tree API starts here ***/
@@ -130,7 +133,10 @@ do { \
130 */ 133 */
131static inline void *radix_tree_deref_slot(void **pslot) 134static inline void *radix_tree_deref_slot(void **pslot)
132{ 135{
133 return radix_tree_direct_to_ptr(*pslot); 136 void *ret = *pslot;
137 if (unlikely(radix_tree_is_indirect_ptr(ret)))
138 ret = RADIX_TREE_RETRY;
139 return ret;
134} 140}
135/** 141/**
136 * radix_tree_replace_slot - replace item in a slot 142 * radix_tree_replace_slot - replace item in a slot
@@ -142,10 +148,8 @@ static inline void *radix_tree_deref_slot(void **pslot)
142 */ 148 */
143static inline void radix_tree_replace_slot(void **pslot, void *item) 149static inline void radix_tree_replace_slot(void **pslot, void *item)
144{ 150{
145 BUG_ON(radix_tree_is_direct_ptr(item)); 151 BUG_ON(radix_tree_is_indirect_ptr(item));
146 rcu_assign_pointer(*pslot, 152 rcu_assign_pointer(*pslot, item);
147 (void *)((unsigned long)item |
148 ((unsigned long)*pslot & RADIX_TREE_DIRECT_PTR)));
149} 153}
150 154
151int radix_tree_insert(struct radix_tree_root *, unsigned long, void *); 155int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
@@ -155,6 +159,8 @@ void *radix_tree_delete(struct radix_tree_root *, unsigned long);
155unsigned int 159unsigned int
156radix_tree_gang_lookup(struct radix_tree_root *root, void **results, 160radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
157 unsigned long first_index, unsigned int max_items); 161 unsigned long first_index, unsigned int max_items);
162unsigned long radix_tree_next_hole(struct radix_tree_root *root,
163 unsigned long index, unsigned long max_scan);
158int radix_tree_preload(gfp_t gfp_mask); 164int radix_tree_preload(gfp_t gfp_mask);
159void radix_tree_init(void); 165void radix_tree_init(void);
160void *radix_tree_tag_set(struct radix_tree_root *root, 166void *radix_tree_tag_set(struct radix_tree_root *root,
diff --git a/include/linux/scatterlist.h b/include/linux/scatterlist.h
index 4efbd9c445f5..2dc7464cce52 100644
--- a/include/linux/scatterlist.h
+++ b/include/linux/scatterlist.h
@@ -20,4 +20,88 @@ static inline void sg_init_one(struct scatterlist *sg, const void *buf,
20 sg_set_buf(sg, buf, buflen); 20 sg_set_buf(sg, buf, buflen);
21} 21}
22 22
23/*
24 * We overload the LSB of the page pointer to indicate whether it's
25 * a valid sg entry, or whether it points to the start of a new scatterlist.
26 * Those low bits are there for everyone! (thanks mason :-)
27 */
28#define sg_is_chain(sg) ((unsigned long) (sg)->page & 0x01)
29#define sg_chain_ptr(sg) \
30 ((struct scatterlist *) ((unsigned long) (sg)->page & ~0x01))
31
32/**
33 * sg_next - return the next scatterlist entry in a list
34 * @sg: The current sg entry
35 *
36 * Usually the next entry will be @sg@ + 1, but if this sg element is part
37 * of a chained scatterlist, it could jump to the start of a new
38 * scatterlist array.
39 *
40 * Note that the caller must ensure that there are further entries after
41 * the current entry, this function will NOT return NULL for an end-of-list.
42 *
43 */
44static inline struct scatterlist *sg_next(struct scatterlist *sg)
45{
46 sg++;
47
48 if (unlikely(sg_is_chain(sg)))
49 sg = sg_chain_ptr(sg);
50
51 return sg;
52}
53
54/*
55 * Loop over each sg element, following the pointer to a new list if necessary
56 */
57#define for_each_sg(sglist, sg, nr, __i) \
58 for (__i = 0, sg = (sglist); __i < (nr); __i++, sg = sg_next(sg))
59
60/**
61 * sg_last - return the last scatterlist entry in a list
62 * @sgl: First entry in the scatterlist
63 * @nents: Number of entries in the scatterlist
64 *
65 * Should only be used casually, it (currently) scan the entire list
66 * to get the last entry.
67 *
68 * Note that the @sgl@ pointer passed in need not be the first one,
69 * the important bit is that @nents@ denotes the number of entries that
70 * exist from @sgl@.
71 *
72 */
73static inline struct scatterlist *sg_last(struct scatterlist *sgl,
74 unsigned int nents)
75{
76#ifndef ARCH_HAS_SG_CHAIN
77 struct scatterlist *ret = &sgl[nents - 1];
78#else
79 struct scatterlist *sg, *ret = NULL;
80 int i;
81
82 for_each_sg(sgl, sg, nents, i)
83 ret = sg;
84
85#endif
86 return ret;
87}
88
89/**
90 * sg_chain - Chain two sglists together
91 * @prv: First scatterlist
92 * @prv_nents: Number of entries in prv
93 * @sgl: Second scatterlist
94 *
95 * Links @prv@ and @sgl@ together, to form a longer scatterlist.
96 *
97 */
98static inline void sg_chain(struct scatterlist *prv, unsigned int prv_nents,
99 struct scatterlist *sgl)
100{
101#ifndef ARCH_HAS_SG_CHAIN
102 BUG();
103#endif
104 prv[prv_nents - 1].page = (struct page *) ((unsigned long) sgl | 0x01);
105}
106
23#endif /* _LINUX_SCATTERLIST_H */ 107#endif /* _LINUX_SCATTERLIST_H */
diff --git a/include/linux/sched.h b/include/linux/sched.h
index 228e0a8ce248..592e3a55f818 100644
--- a/include/linux/sched.h
+++ b/include/linux/sched.h
@@ -1,8 +1,6 @@
1#ifndef _LINUX_SCHED_H 1#ifndef _LINUX_SCHED_H
2#define _LINUX_SCHED_H 2#define _LINUX_SCHED_H
3 3
4#include <linux/auxvec.h> /* For AT_VECTOR_SIZE */
5
6/* 4/*
7 * cloning flags: 5 * cloning flags:
8 */ 6 */
@@ -58,12 +56,12 @@ struct sched_param {
58#include <linux/cpumask.h> 56#include <linux/cpumask.h>
59#include <linux/errno.h> 57#include <linux/errno.h>
60#include <linux/nodemask.h> 58#include <linux/nodemask.h>
59#include <linux/mm_types.h>
61 60
62#include <asm/system.h> 61#include <asm/system.h>
63#include <asm/semaphore.h> 62#include <asm/semaphore.h>
64#include <asm/page.h> 63#include <asm/page.h>
65#include <asm/ptrace.h> 64#include <asm/ptrace.h>
66#include <asm/mmu.h>
67#include <asm/cputime.h> 65#include <asm/cputime.h>
68 66
69#include <linux/smp.h> 67#include <linux/smp.h>
@@ -319,7 +317,6 @@ extern void arch_unmap_area_topdown(struct mm_struct *, unsigned long);
319#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member) 317#define add_mm_counter(mm, member, value) atomic_long_add(value, &(mm)->_##member)
320#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member) 318#define inc_mm_counter(mm, member) atomic_long_inc(&(mm)->_##member)
321#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member) 319#define dec_mm_counter(mm, member) atomic_long_dec(&(mm)->_##member)
322typedef atomic_long_t mm_counter_t;
323 320
324#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ 321#else /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
325/* 322/*
@@ -331,7 +328,6 @@ typedef atomic_long_t mm_counter_t;
331#define add_mm_counter(mm, member, value) (mm)->_##member += (value) 328#define add_mm_counter(mm, member, value) (mm)->_##member += (value)
332#define inc_mm_counter(mm, member) (mm)->_##member++ 329#define inc_mm_counter(mm, member) (mm)->_##member++
333#define dec_mm_counter(mm, member) (mm)->_##member-- 330#define dec_mm_counter(mm, member) (mm)->_##member--
334typedef unsigned long mm_counter_t;
335 331
336#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */ 332#endif /* NR_CPUS < CONFIG_SPLIT_PTLOCK_CPUS */
337 333
@@ -368,74 +364,6 @@ extern int get_dumpable(struct mm_struct *mm);
368#define MMF_DUMP_FILTER_DEFAULT \ 364#define MMF_DUMP_FILTER_DEFAULT \
369 ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED)) 365 ((1 << MMF_DUMP_ANON_PRIVATE) | (1 << MMF_DUMP_ANON_SHARED))
370 366
371struct mm_struct {
372 struct vm_area_struct * mmap; /* list of VMAs */
373 struct rb_root mm_rb;
374 struct vm_area_struct * mmap_cache; /* last find_vma result */
375 unsigned long (*get_unmapped_area) (struct file *filp,
376 unsigned long addr, unsigned long len,
377 unsigned long pgoff, unsigned long flags);
378 void (*unmap_area) (struct mm_struct *mm, unsigned long addr);
379 unsigned long mmap_base; /* base of mmap area */
380 unsigned long task_size; /* size of task vm space */
381 unsigned long cached_hole_size; /* if non-zero, the largest hole below free_area_cache */
382 unsigned long free_area_cache; /* first hole of size cached_hole_size or larger */
383 pgd_t * pgd;
384 atomic_t mm_users; /* How many users with user space? */
385 atomic_t mm_count; /* How many references to "struct mm_struct" (users count as 1) */
386 int map_count; /* number of VMAs */
387 struct rw_semaphore mmap_sem;
388 spinlock_t page_table_lock; /* Protects page tables and some counters */
389
390 struct list_head mmlist; /* List of maybe swapped mm's. These are globally strung
391 * together off init_mm.mmlist, and are protected
392 * by mmlist_lock
393 */
394
395 /* Special counters, in some configurations protected by the
396 * page_table_lock, in other configurations by being atomic.
397 */
398 mm_counter_t _file_rss;
399 mm_counter_t _anon_rss;
400
401 unsigned long hiwater_rss; /* High-watermark of RSS usage */
402 unsigned long hiwater_vm; /* High-water virtual memory usage */
403
404 unsigned long total_vm, locked_vm, shared_vm, exec_vm;
405 unsigned long stack_vm, reserved_vm, def_flags, nr_ptes;
406 unsigned long start_code, end_code, start_data, end_data;
407 unsigned long start_brk, brk, start_stack;
408 unsigned long arg_start, arg_end, env_start, env_end;
409
410 unsigned long saved_auxv[AT_VECTOR_SIZE]; /* for /proc/PID/auxv */
411
412 cpumask_t cpu_vm_mask;
413
414 /* Architecture-specific MM context */
415 mm_context_t context;
416
417 /* Swap token stuff */
418 /*
419 * Last value of global fault stamp as seen by this process.
420 * In other words, this value gives an indication of how long
421 * it has been since this task got the token.
422 * Look at mm/thrash.c
423 */
424 unsigned int faultstamp;
425 unsigned int token_priority;
426 unsigned int last_interval;
427
428 unsigned long flags; /* Must use atomic bitops to access the bits */
429
430 /* coredumping support */
431 int core_waiters;
432 struct completion *core_startup_done, core_done;
433
434 /* aio bits */
435 rwlock_t ioctx_list_lock;
436 struct kioctx *ioctx_list;
437};
438
439struct sighand_struct { 367struct sighand_struct {
440 atomic_t count; 368 atomic_t count;
441 struct k_sigaction action[_NSIG]; 369 struct k_sigaction action[_NSIG];
@@ -801,9 +729,6 @@ struct sched_domain {
801#endif 729#endif
802}; 730};
803 731
804extern int partition_sched_domains(cpumask_t *partition1,
805 cpumask_t *partition2);
806
807#endif /* CONFIG_SMP */ 732#endif /* CONFIG_SMP */
808 733
809/* 734/*
diff --git a/include/linux/selection.h b/include/linux/selection.h
index f9457861937c..8cdaa1151d2e 100644
--- a/include/linux/selection.h
+++ b/include/linux/selection.h
@@ -13,6 +13,7 @@
13struct tty_struct; 13struct tty_struct;
14 14
15extern struct vc_data *sel_cons; 15extern struct vc_data *sel_cons;
16struct tty_struct;
16 17
17extern void clear_selection(void); 18extern void clear_selection(void);
18extern int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty); 19extern int set_selection(const struct tiocl_selection __user *sel, struct tty_struct *tty);
diff --git a/include/linux/serial_core.h b/include/linux/serial_core.h
index 09d17b06bf02..4db77249281c 100644
--- a/include/linux/serial_core.h
+++ b/include/linux/serial_core.h
@@ -291,7 +291,8 @@ struct uart_port {
291 resource_size_t mapbase; /* for ioremap */ 291 resource_size_t mapbase; /* for ioremap */
292 struct device *dev; /* parent device */ 292 struct device *dev; /* parent device */
293 unsigned char hub6; /* this should be in the 8250 driver */ 293 unsigned char hub6; /* this should be in the 8250 driver */
294 unsigned char unused[3]; 294 unsigned char suspended;
295 unsigned char unused[2];
295 void *private_data; /* generic platform data pointer */ 296 void *private_data; /* generic platform data pointer */
296}; 297};
297 298
diff --git a/include/linux/slab.h b/include/linux/slab.h
index d859354b9e51..3a5bad3ad126 100644
--- a/include/linux/slab.h
+++ b/include/linux/slab.h
@@ -24,12 +24,14 @@
24#define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */ 24#define SLAB_HWCACHE_ALIGN 0x00002000UL /* Align objs on cache lines */
25#define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */ 25#define SLAB_CACHE_DMA 0x00004000UL /* Use GFP_DMA memory */
26#define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */ 26#define SLAB_STORE_USER 0x00010000UL /* DEBUG: Store the last owner for bug hunting */
27#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */
28#define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */ 27#define SLAB_PANIC 0x00040000UL /* Panic if kmem_cache_create() fails */
29#define SLAB_DESTROY_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */ 28#define SLAB_DESTROY_BY_RCU 0x00080000UL /* Defer freeing slabs to RCU */
30#define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */ 29#define SLAB_MEM_SPREAD 0x00100000UL /* Spread some memory over cpuset */
31#define SLAB_TRACE 0x00200000UL /* Trace allocations and frees */ 30#define SLAB_TRACE 0x00200000UL /* Trace allocations and frees */
32 31
32/* The following flags affect the page allocator grouping pages by mobility */
33#define SLAB_RECLAIM_ACCOUNT 0x00020000UL /* Objects are reclaimable */
34#define SLAB_TEMPORARY SLAB_RECLAIM_ACCOUNT /* Objects are short-lived */
33/* 35/*
34 * ZERO_SIZE_PTR will be returned for zero sized kmalloc requests. 36 * ZERO_SIZE_PTR will be returned for zero sized kmalloc requests.
35 * 37 *
diff --git a/include/linux/slub_def.h b/include/linux/slub_def.h
index 74962077f632..d65159d1d4f5 100644
--- a/include/linux/slub_def.h
+++ b/include/linux/slub_def.h
@@ -11,6 +11,14 @@
11#include <linux/workqueue.h> 11#include <linux/workqueue.h>
12#include <linux/kobject.h> 12#include <linux/kobject.h>
13 13
14struct kmem_cache_cpu {
15 void **freelist;
16 struct page *page;
17 int node;
18 unsigned int offset;
19 unsigned int objsize;
20};
21
14struct kmem_cache_node { 22struct kmem_cache_node {
15 spinlock_t list_lock; /* Protect partial list and nr_partial */ 23 spinlock_t list_lock; /* Protect partial list and nr_partial */
16 unsigned long nr_partial; 24 unsigned long nr_partial;
@@ -54,7 +62,11 @@ struct kmem_cache {
54 int defrag_ratio; 62 int defrag_ratio;
55 struct kmem_cache_node *node[MAX_NUMNODES]; 63 struct kmem_cache_node *node[MAX_NUMNODES];
56#endif 64#endif
57 struct page *cpu_slab[NR_CPUS]; 65#ifdef CONFIG_SMP
66 struct kmem_cache_cpu *cpu_slab[NR_CPUS];
67#else
68 struct kmem_cache_cpu cpu_slab;
69#endif
58}; 70};
59 71
60/* 72/*
@@ -72,7 +84,7 @@ struct kmem_cache {
72 * We keep the general caches in an array of slab caches that are used for 84 * We keep the general caches in an array of slab caches that are used for
73 * 2^x bytes of allocations. 85 * 2^x bytes of allocations.
74 */ 86 */
75extern struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_HIGH + 1]; 87extern struct kmem_cache kmalloc_caches[PAGE_SHIFT];
76 88
77/* 89/*
78 * Sorry that the following has to be that ugly but some versions of GCC 90 * Sorry that the following has to be that ugly but some versions of GCC
@@ -83,9 +95,6 @@ static __always_inline int kmalloc_index(size_t size)
83 if (!size) 95 if (!size)
84 return 0; 96 return 0;
85 97
86 if (size > KMALLOC_MAX_SIZE)
87 return -1;
88
89 if (size <= KMALLOC_MIN_SIZE) 98 if (size <= KMALLOC_MIN_SIZE)
90 return KMALLOC_SHIFT_LOW; 99 return KMALLOC_SHIFT_LOW;
91 100
@@ -102,6 +111,10 @@ static __always_inline int kmalloc_index(size_t size)
102 if (size <= 512) return 9; 111 if (size <= 512) return 9;
103 if (size <= 1024) return 10; 112 if (size <= 1024) return 10;
104 if (size <= 2 * 1024) return 11; 113 if (size <= 2 * 1024) return 11;
114/*
115 * The following is only needed to support architectures with a larger page
116 * size than 4k.
117 */
105 if (size <= 4 * 1024) return 12; 118 if (size <= 4 * 1024) return 12;
106 if (size <= 8 * 1024) return 13; 119 if (size <= 8 * 1024) return 13;
107 if (size <= 16 * 1024) return 14; 120 if (size <= 16 * 1024) return 14;
@@ -109,13 +122,9 @@ static __always_inline int kmalloc_index(size_t size)
109 if (size <= 64 * 1024) return 16; 122 if (size <= 64 * 1024) return 16;
110 if (size <= 128 * 1024) return 17; 123 if (size <= 128 * 1024) return 17;
111 if (size <= 256 * 1024) return 18; 124 if (size <= 256 * 1024) return 18;
112 if (size <= 512 * 1024) return 19; 125 if (size <= 512 * 1024) return 19;
113 if (size <= 1024 * 1024) return 20; 126 if (size <= 1024 * 1024) return 20;
114 if (size <= 2 * 1024 * 1024) return 21; 127 if (size <= 2 * 1024 * 1024) return 21;
115 if (size <= 4 * 1024 * 1024) return 22;
116 if (size <= 8 * 1024 * 1024) return 23;
117 if (size <= 16 * 1024 * 1024) return 24;
118 if (size <= 32 * 1024 * 1024) return 25;
119 return -1; 128 return -1;
120 129
121/* 130/*
@@ -140,19 +149,6 @@ static __always_inline struct kmem_cache *kmalloc_slab(size_t size)
140 if (index == 0) 149 if (index == 0)
141 return NULL; 150 return NULL;
142 151
143 /*
144 * This function only gets expanded if __builtin_constant_p(size), so
145 * testing it here shouldn't be needed. But some versions of gcc need
146 * help.
147 */
148 if (__builtin_constant_p(size) && index < 0) {
149 /*
150 * Generate a link failure. Would be great if we could
151 * do something to stop the compile here.
152 */
153 extern void __kmalloc_size_too_large(void);
154 __kmalloc_size_too_large();
155 }
156 return &kmalloc_caches[index]; 152 return &kmalloc_caches[index];
157} 153}
158 154
@@ -168,15 +164,21 @@ void *__kmalloc(size_t size, gfp_t flags);
168 164
169static __always_inline void *kmalloc(size_t size, gfp_t flags) 165static __always_inline void *kmalloc(size_t size, gfp_t flags)
170{ 166{
171 if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) { 167 if (__builtin_constant_p(size)) {
172 struct kmem_cache *s = kmalloc_slab(size); 168 if (size > PAGE_SIZE / 2)
169 return (void *)__get_free_pages(flags | __GFP_COMP,
170 get_order(size));
173 171
174 if (!s) 172 if (!(flags & SLUB_DMA)) {
175 return ZERO_SIZE_PTR; 173 struct kmem_cache *s = kmalloc_slab(size);
176 174
177 return kmem_cache_alloc(s, flags); 175 if (!s)
178 } else 176 return ZERO_SIZE_PTR;
179 return __kmalloc(size, flags); 177
178 return kmem_cache_alloc(s, flags);
179 }
180 }
181 return __kmalloc(size, flags);
180} 182}
181 183
182#ifdef CONFIG_NUMA 184#ifdef CONFIG_NUMA
@@ -185,15 +187,16 @@ void *kmem_cache_alloc_node(struct kmem_cache *, gfp_t flags, int node);
185 187
186static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node) 188static __always_inline void *kmalloc_node(size_t size, gfp_t flags, int node)
187{ 189{
188 if (__builtin_constant_p(size) && !(flags & SLUB_DMA)) { 190 if (__builtin_constant_p(size) &&
189 struct kmem_cache *s = kmalloc_slab(size); 191 size <= PAGE_SIZE / 2 && !(flags & SLUB_DMA)) {
192 struct kmem_cache *s = kmalloc_slab(size);
190 193
191 if (!s) 194 if (!s)
192 return ZERO_SIZE_PTR; 195 return ZERO_SIZE_PTR;
193 196
194 return kmem_cache_alloc_node(s, flags, node); 197 return kmem_cache_alloc_node(s, flags, node);
195 } else 198 }
196 return __kmalloc_node(size, flags, node); 199 return __kmalloc_node(size, flags, node);
197} 200}
198#endif 201#endif
199 202
diff --git a/include/linux/sm501-regs.h b/include/linux/sm501-regs.h
index 014e73b31fc0..df7620dd8f31 100644
--- a/include/linux/sm501-regs.h
+++ b/include/linux/sm501-regs.h
@@ -15,6 +15,24 @@
15 15
16/* config 1 */ 16/* config 1 */
17#define SM501_SYSTEM_CONTROL (0x000000) 17#define SM501_SYSTEM_CONTROL (0x000000)
18
19#define SM501_SYSCTRL_PANEL_TRISTATE (1<<0)
20#define SM501_SYSCTRL_MEM_TRISTATE (1<<1)
21#define SM501_SYSCTRL_CRT_TRISTATE (1<<2)
22
23#define SM501_SYSCTRL_PCI_SLAVE_BURST_MASK (3<<4)
24#define SM501_SYSCTRL_PCI_SLAVE_BURST_1 (0<<4)
25#define SM501_SYSCTRL_PCI_SLAVE_BURST_2 (1<<4)
26#define SM501_SYSCTRL_PCI_SLAVE_BURST_4 (2<<4)
27#define SM501_SYSCTRL_PCI_SLAVE_BURST_8 (3<<4)
28
29#define SM501_SYSCTRL_PCI_CLOCK_RUN_EN (1<<6)
30#define SM501_SYSCTRL_PCI_RETRY_DISABLE (1<<7)
31#define SM501_SYSCTRL_PCI_SUBSYS_LOCK (1<<11)
32#define SM501_SYSCTRL_PCI_BURST_READ_EN (1<<15)
33
34/* miscellaneous control */
35
18#define SM501_MISC_CONTROL (0x000004) 36#define SM501_MISC_CONTROL (0x000004)
19 37
20#define SM501_MISC_BUS_SH (0x0) 38#define SM501_MISC_BUS_SH (0x0)
diff --git a/include/linux/spi/spi.h b/include/linux/spi/spi.h
index 002a3cddbdd5..387e428f1cdf 100644
--- a/include/linux/spi/spi.h
+++ b/include/linux/spi/spi.h
@@ -195,7 +195,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
195 195
196/** 196/**
197 * struct spi_master - interface to SPI master controller 197 * struct spi_master - interface to SPI master controller
198 * @cdev: class interface to this driver 198 * @dev: device interface to this driver
199 * @bus_num: board-specific (and often SOC-specific) identifier for a 199 * @bus_num: board-specific (and often SOC-specific) identifier for a
200 * given SPI controller. 200 * given SPI controller.
201 * @num_chipselect: chipselects are used to distinguish individual 201 * @num_chipselect: chipselects are used to distinguish individual
@@ -222,7 +222,7 @@ static inline void spi_unregister_driver(struct spi_driver *sdrv)
222 * message's completion function when the transaction completes. 222 * message's completion function when the transaction completes.
223 */ 223 */
224struct spi_master { 224struct spi_master {
225 struct class_device cdev; 225 struct device dev;
226 226
227 /* other than negative (== assign one dynamically), bus_num is fully 227 /* other than negative (== assign one dynamically), bus_num is fully
228 * board-specific. usually that simplifies to being SOC-specific. 228 * board-specific. usually that simplifies to being SOC-specific.
@@ -268,17 +268,17 @@ struct spi_master {
268 268
269static inline void *spi_master_get_devdata(struct spi_master *master) 269static inline void *spi_master_get_devdata(struct spi_master *master)
270{ 270{
271 return class_get_devdata(&master->cdev); 271 return dev_get_drvdata(&master->dev);
272} 272}
273 273
274static inline void spi_master_set_devdata(struct spi_master *master, void *data) 274static inline void spi_master_set_devdata(struct spi_master *master, void *data)
275{ 275{
276 class_set_devdata(&master->cdev, data); 276 dev_set_drvdata(&master->dev, data);
277} 277}
278 278
279static inline struct spi_master *spi_master_get(struct spi_master *master) 279static inline struct spi_master *spi_master_get(struct spi_master *master)
280{ 280{
281 if (!master || !class_device_get(&master->cdev)) 281 if (!master || !get_device(&master->dev))
282 return NULL; 282 return NULL;
283 return master; 283 return master;
284} 284}
@@ -286,7 +286,7 @@ static inline struct spi_master *spi_master_get(struct spi_master *master)
286static inline void spi_master_put(struct spi_master *master) 286static inline void spi_master_put(struct spi_master *master)
287{ 287{
288 if (master) 288 if (master)
289 class_device_put(&master->cdev); 289 put_device(&master->dev);
290} 290}
291 291
292 292
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 46705e91573d..c1527c2ef3cb 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -481,7 +481,7 @@ static inline void *get_gadget_data (struct usb_gadget *gadget)
481 481
482/** 482/**
483 * gadget_is_dualspeed - return true iff the hardware handles high speed 483 * gadget_is_dualspeed - return true iff the hardware handles high speed
484 * @gadget: controller that might support both high and full speeds 484 * @g: controller that might support both high and full speeds
485 */ 485 */
486static inline int gadget_is_dualspeed(struct usb_gadget *g) 486static inline int gadget_is_dualspeed(struct usb_gadget *g)
487{ 487{
@@ -497,7 +497,7 @@ static inline int gadget_is_dualspeed(struct usb_gadget *g)
497 497
498/** 498/**
499 * gadget_is_otg - return true iff the hardware is OTG-ready 499 * gadget_is_otg - return true iff the hardware is OTG-ready
500 * @gadget: controller that might have a Mini-AB connector 500 * @g: controller that might have a Mini-AB connector
501 * 501 *
502 * This is a runtime test, since kernels with a USB-OTG stack sometimes 502 * This is a runtime test, since kernels with a USB-OTG stack sometimes
503 * run on boards which only have a Mini-B (or Mini-A) connector. 503 * run on boards which only have a Mini-B (or Mini-A) connector.
diff --git a/include/pcmcia/ds.h b/include/pcmcia/ds.h
index 90ef552c42dd..f047a1fd64f8 100644
--- a/include/pcmcia/ds.h
+++ b/include/pcmcia/ds.h
@@ -184,6 +184,7 @@ struct pcmcia_device {
184 184
185 char * prod_id[4]; 185 char * prod_id[4];
186 186
187 u64 dma_mask;
187 struct device dev; 188 struct device dev;
188 189
189#ifdef CONFIG_PCMCIA_IOCTL 190#ifdef CONFIG_PCMCIA_IOCTL
diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h
index 9f8f80ab0c8b..702fcfeb37f1 100644
--- a/include/scsi/scsi.h
+++ b/include/scsi/scsi.h
@@ -11,13 +11,6 @@
11#include <linux/types.h> 11#include <linux/types.h>
12 12
13/* 13/*
14 * The maximum sg list length SCSI can cope with
15 * (currently must be a power of 2 between 32 and 256)
16 */
17#define SCSI_MAX_PHYS_SEGMENTS MAX_PHYS_SEGMENTS
18
19
20/*
21 * SCSI command lengths 14 * SCSI command lengths
22 */ 15 */
23 16
diff --git a/include/scsi/scsi_cmnd.h b/include/scsi/scsi_cmnd.h
index 65ab5145a09b..3f47e522a1ec 100644
--- a/include/scsi/scsi_cmnd.h
+++ b/include/scsi/scsi_cmnd.h
@@ -5,6 +5,7 @@
5#include <linux/list.h> 5#include <linux/list.h>
6#include <linux/types.h> 6#include <linux/types.h>
7#include <linux/timer.h> 7#include <linux/timer.h>
8#include <linux/scatterlist.h>
8 9
9struct request; 10struct request;
10struct scatterlist; 11struct scatterlist;
@@ -68,7 +69,7 @@ struct scsi_cmnd {
68 69
69 /* These elements define the operation we ultimately want to perform */ 70 /* These elements define the operation we ultimately want to perform */
70 unsigned short use_sg; /* Number of pieces of scatter-gather */ 71 unsigned short use_sg; /* Number of pieces of scatter-gather */
71 unsigned short sglist_len; /* size of malloc'd scatter-gather list */ 72 unsigned short __use_sg;
72 73
73 unsigned underflow; /* Return error if less than 74 unsigned underflow; /* Return error if less than
74 this amount is transferred */ 75 this amount is transferred */
@@ -128,7 +129,7 @@ extern void *scsi_kmap_atomic_sg(struct scatterlist *sg, int sg_count,
128extern void scsi_kunmap_atomic_sg(void *virt); 129extern void scsi_kunmap_atomic_sg(void *virt);
129 130
130extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t); 131extern struct scatterlist *scsi_alloc_sgtable(struct scsi_cmnd *, gfp_t);
131extern void scsi_free_sgtable(struct scatterlist *, int); 132extern void scsi_free_sgtable(struct scsi_cmnd *);
132 133
133extern int scsi_dma_map(struct scsi_cmnd *cmd); 134extern int scsi_dma_map(struct scsi_cmnd *cmd);
134extern void scsi_dma_unmap(struct scsi_cmnd *cmd); 135extern void scsi_dma_unmap(struct scsi_cmnd *cmd);
@@ -148,6 +149,6 @@ static inline int scsi_get_resid(struct scsi_cmnd *cmd)
148} 149}
149 150
150#define scsi_for_each_sg(cmd, sg, nseg, __i) \ 151#define scsi_for_each_sg(cmd, sg, nseg, __i) \
151 for (__i = 0, sg = scsi_sglist(cmd); __i < (nseg); __i++, (sg)++) 152 for_each_sg(scsi_sglist(cmd), sg, nseg, __i)
152 153
153#endif /* _SCSI_SCSI_CMND_H */ 154#endif /* _SCSI_SCSI_CMND_H */
diff --git a/include/scsi/scsi_host.h b/include/scsi/scsi_host.h
index 7d210cd6c38d..0fd4746ee39d 100644
--- a/include/scsi/scsi_host.h
+++ b/include/scsi/scsi_host.h
@@ -39,6 +39,9 @@ struct blk_queue_tags;
39#define DISABLE_CLUSTERING 0 39#define DISABLE_CLUSTERING 0
40#define ENABLE_CLUSTERING 1 40#define ENABLE_CLUSTERING 1
41 41
42#define DISABLE_SG_CHAINING 0
43#define ENABLE_SG_CHAINING 1
44
42enum scsi_eh_timer_return { 45enum scsi_eh_timer_return {
43 EH_NOT_HANDLED, 46 EH_NOT_HANDLED,
44 EH_HANDLED, 47 EH_HANDLED,
@@ -443,6 +446,15 @@ struct scsi_host_template {
443 unsigned ordered_tag:1; 446 unsigned ordered_tag:1;
444 447
445 /* 448 /*
449 * true if the low-level driver can support sg chaining. this
450 * will be removed eventually when all the drivers are
451 * converted to support sg chaining.
452 *
453 * Status: OBSOLETE
454 */
455 unsigned use_sg_chaining:1;
456
457 /*
446 * Countdown for host blocking with no commands outstanding 458 * Countdown for host blocking with no commands outstanding
447 */ 459 */
448 unsigned int max_host_blocked; 460 unsigned int max_host_blocked;
@@ -586,6 +598,7 @@ struct Scsi_Host {
586 unsigned unchecked_isa_dma:1; 598 unsigned unchecked_isa_dma:1;
587 unsigned use_clustering:1; 599 unsigned use_clustering:1;
588 unsigned use_blk_tcq:1; 600 unsigned use_blk_tcq:1;
601 unsigned use_sg_chaining:1;
589 602
590 /* 603 /*
591 * Host has requested that no further requests come through for the 604 * Host has requested that no further requests come through for the
diff --git a/include/video/Kbuild b/include/video/Kbuild
index a14f9c045b8c..53a6c7310e61 100644
--- a/include/video/Kbuild
+++ b/include/video/Kbuild
@@ -1 +1 @@
unifdef-y += sisfb.h unifdef-y += sisfb.h uvesafb.h
diff --git a/include/video/mbxfb.h b/include/video/mbxfb.h
index 20b9002712ef..ea18961fc5e7 100644
--- a/include/video/mbxfb.h
+++ b/include/video/mbxfb.h
@@ -29,18 +29,18 @@ struct mbxfb_platform_data {
29}; 29};
30 30
31/* planar */ 31/* planar */
32#define MBXFB_FMT_YUV12 0 32#define MBXFB_FMT_YUV16 0
33#define MBXFB_FMT_YUV12 1
33 34
34/* packed */ 35/* packed */
35#define MBXFB_FMT_UY0VY1 1 36#define MBXFB_FMT_UY0VY1 2
36#define MBXFB_FMT_VY0UY1 2 37#define MBXFB_FMT_VY0UY1 3
37#define MBXFB_FMT_Y0UY1V 3 38#define MBXFB_FMT_Y0UY1V 4
38#define MBXFB_FMT_Y0VY1U 4 39#define MBXFB_FMT_Y0VY1U 5
39struct mbxfb_overlaySetup { 40struct mbxfb_overlaySetup {
40 __u32 enable; 41 __u32 enable;
41 __u32 x, y; 42 __u32 x, y;
42 __u32 width, height; 43 __u32 width, height;
43 __u32 alpha;
44 __u32 fmt; 44 __u32 fmt;
45 __u32 mem_offset; 45 __u32 mem_offset;
46 __u32 scaled_width; 46 __u32 scaled_width;
@@ -54,6 +54,45 @@ struct mbxfb_overlaySetup {
54 __u16 UV_stride; 54 __u16 UV_stride;
55}; 55};
56 56
57#define MBXFB_IOCX_OVERLAY _IOWR(0xF4, 0x00,struct mbxfb_overlaySetup) 57#define MBXFB_ALPHABLEND_NONE 0
58#define MBXFB_ALPHABLEND_GLOBAL 1
59#define MBXFB_ALPHABLEND_PIXEL 2
60
61#define MBXFB_COLORKEY_DISABLED 0
62#define MBXFB_COLORKEY_PREVIOUS 1
63#define MBXFB_COLORKEY_CURRENT 2
64struct mbxfb_alphaCtl {
65 __u8 overlay_blend_mode;
66 __u8 overlay_colorkey_mode;
67 __u8 overlay_global_alpha;
68 __u32 overlay_colorkey;
69 __u32 overlay_colorkey_mask;
70
71 __u8 graphics_blend_mode;
72 __u8 graphics_colorkey_mode;
73 __u8 graphics_global_alpha;
74 __u32 graphics_colorkey;
75 __u32 graphics_colorkey_mask;
76};
77
78#define MBXFB_PLANE_GRAPHICS 0
79#define MBXFB_PLANE_VIDEO 1
80struct mbxfb_planeorder {
81 __u8 bottom;
82 __u8 top;
83};
84
85struct mbxfb_reg {
86 __u32 addr; /* offset from 0x03fe 0000 */
87 __u32 val; /* value */
88 __u32 mask; /* which bits to touch (for write) */
89};
90
91#define MBXFB_IOCX_OVERLAY _IOWR(0xF4, 0x00,struct mbxfb_overlaySetup)
92#define MBXFB_IOCG_ALPHA _IOR(0xF4, 0x01,struct mbxfb_alphaCtl)
93#define MBXFB_IOCS_ALPHA _IOW(0xF4, 0x02,struct mbxfb_alphaCtl)
94#define MBXFB_IOCS_PLANEORDER _IOR(0xF4, 0x03,struct mbxfb_planeorder)
95#define MBXFB_IOCS_REG _IOW(0xF4, 0x04,struct mbxfb_reg)
96#define MBXFB_IOCX_REG _IOWR(0xF4, 0x05,struct mbxfb_reg)
58 97
59#endif /* __MBX_FB_H */ 98#endif /* __MBX_FB_H */
diff --git a/include/video/permedia2.h b/include/video/permedia2.h
index 9e49c9571ec3..9ce9adbfda2b 100644
--- a/include/video/permedia2.h
+++ b/include/video/permedia2.h
@@ -58,7 +58,14 @@
58#define PM2R_RD_PALETTE_DATA 0x4008 58#define PM2R_RD_PALETTE_DATA 0x4008
59#define PM2R_RD_PIXEL_MASK 0x4010 59#define PM2R_RD_PIXEL_MASK 0x4010
60#define PM2R_RD_PALETTE_READ_ADDRESS 0x4018 60#define PM2R_RD_PALETTE_READ_ADDRESS 0x4018
61#define PM2R_RD_CURSOR_COLOR_ADDRESS 0x4020
62#define PM2R_RD_CURSOR_COLOR_DATA 0x4028
61#define PM2R_RD_INDEXED_DATA 0x4050 63#define PM2R_RD_INDEXED_DATA 0x4050
64#define PM2R_RD_CURSOR_DATA 0x4058
65#define PM2R_RD_CURSOR_X_LSB 0x4060
66#define PM2R_RD_CURSOR_X_MSB 0x4068
67#define PM2R_RD_CURSOR_Y_LSB 0x4070
68#define PM2R_RD_CURSOR_Y_MSB 0x4078
62 69
63#define PM2R_START_X_DOM 0x8000 70#define PM2R_START_X_DOM 0x8000
64#define PM2R_D_X_DOM 0x8008 71#define PM2R_D_X_DOM 0x8008
@@ -68,11 +75,14 @@
68#define PM2R_D_Y 0x8028 75#define PM2R_D_Y 0x8028
69#define PM2R_COUNT 0x8030 76#define PM2R_COUNT 0x8030
70#define PM2R_RENDER 0x8038 77#define PM2R_RENDER 0x8038
78#define PM2R_BIT_MASK_PATTERN 0x8068
71#define PM2R_RASTERIZER_MODE 0x80a0 79#define PM2R_RASTERIZER_MODE 0x80a0
72#define PM2R_RECTANGLE_ORIGIN 0x80d0 80#define PM2R_RECTANGLE_ORIGIN 0x80d0
73#define PM2R_RECTANGLE_SIZE 0x80d8 81#define PM2R_RECTANGLE_SIZE 0x80d8
74#define PM2R_PACKED_DATA_LIMITS 0x8150 82#define PM2R_PACKED_DATA_LIMITS 0x8150
75#define PM2R_SCISSOR_MODE 0x8180 83#define PM2R_SCISSOR_MODE 0x8180
84#define PM2R_SCISSOR_MIN_XY 0x8188
85#define PM2R_SCISSOR_MAX_XY 0x8190
76#define PM2R_SCREEN_SIZE 0x8198 86#define PM2R_SCREEN_SIZE 0x8198
77#define PM2R_AREA_STIPPLE_MODE 0x81a0 87#define PM2R_AREA_STIPPLE_MODE 0x81a0
78#define PM2R_WINDOW_ORIGIN 0x81c8 88#define PM2R_WINDOW_ORIGIN 0x81c8
@@ -83,7 +93,9 @@
83#define PM2R_TEXEL_LUT_MODE 0x8678 93#define PM2R_TEXEL_LUT_MODE 0x8678
84#define PM2R_TEXTURE_COLOR_MODE 0x8680 94#define PM2R_TEXTURE_COLOR_MODE 0x8680
85#define PM2R_FOG_MODE 0x8690 95#define PM2R_FOG_MODE 0x8690
96#define PM2R_TEXEL0 0x8760
86#define PM2R_COLOR_DDA_MODE 0x87e0 97#define PM2R_COLOR_DDA_MODE 0x87e0
98#define PM2R_CONSTANT_COLOR 0x87e8
87#define PM2R_ALPHA_BLEND_MODE 0x8810 99#define PM2R_ALPHA_BLEND_MODE 0x8810
88#define PM2R_DITHER_MODE 0x8818 100#define PM2R_DITHER_MODE 0x8818
89#define PM2R_FB_SOFT_WRITE_MASK 0x8820 101#define PM2R_FB_SOFT_WRITE_MASK 0x8820
@@ -148,6 +160,7 @@
148#define PM2VI_RD_CURSOR_Y_HIGH 0x00A 160#define PM2VI_RD_CURSOR_Y_HIGH 0x00A
149#define PM2VI_RD_CURSOR_X_HOT 0x00B 161#define PM2VI_RD_CURSOR_X_HOT 0x00B
150#define PM2VI_RD_CURSOR_Y_HOT 0x00C 162#define PM2VI_RD_CURSOR_Y_HOT 0x00C
163#define PM2VI_RD_OVERLAY_KEY 0x00D
151#define PM2VI_RD_CLK0_PRESCALE 0x201 164#define PM2VI_RD_CLK0_PRESCALE 0x201
152#define PM2VI_RD_CLK0_FEEDBACK 0x202 165#define PM2VI_RD_CLK0_FEEDBACK 0x202
153#define PM2VI_RD_CLK0_POSTSCALE 0x203 166#define PM2VI_RD_CLK0_POSTSCALE 0x203
@@ -169,6 +182,8 @@
169#define PM2F_RENDER_TRAPEZOID (1L<<6) 182#define PM2F_RENDER_TRAPEZOID (1L<<6)
170#define PM2F_RENDER_POINT (2L<<6) 183#define PM2F_RENDER_POINT (2L<<6)
171#define PM2F_RENDER_RECTANGLE (3L<<6) 184#define PM2F_RENDER_RECTANGLE (3L<<6)
185#define PM2F_RENDER_SYNC_ON_BIT_MASK (1L<<11)
186#define PM2F_RENDER_TEXTURE_ENABLE (1L<<13)
172#define PM2F_SYNCHRONIZATION (1L<<10) 187#define PM2F_SYNCHRONIZATION (1L<<10)
173#define PM2F_PLL_LOCKED 0x10 188#define PM2F_PLL_LOCKED 0x10
174#define PM2F_BEING_RESET (1L<<31) 189#define PM2F_BEING_RESET (1L<<31)
@@ -224,6 +239,8 @@
224#define PM2F_APERTURE_STANDARD 0 239#define PM2F_APERTURE_STANDARD 0
225#define PM2F_APERTURE_BYTESWAP 1 240#define PM2F_APERTURE_BYTESWAP 1
226#define PM2F_APERTURE_HALFWORDSWAP 2 241#define PM2F_APERTURE_HALFWORDSWAP 2
242#define PM2F_CURSORMODE_CURSOR_ENABLE (1 << 0)
243#define PM2F_CURSORMODE_TYPE_X (1 << 4)
227 244
228typedef enum { 245typedef enum {
229 PM2_TYPE_PERMEDIA2, 246 PM2_TYPE_PERMEDIA2,
diff --git a/include/video/pm3fb.h b/include/video/pm3fb.h
index d52e45a1e9b8..2b85134fe96f 100644
--- a/include/video/pm3fb.h
+++ b/include/video/pm3fb.h
@@ -1,6 +1,6 @@
1/* 1/*
2 * linux/drivers/video/pm3fb.h -- 3DLabs Permedia3 frame buffer device 2 * linux/drivers/video/pm3fb.h -- 3DLabs Permedia3 frame buffer device
3 * 3 *
4 * Copyright (C) 2001 Romain Dolbeau <dolbeau@irisa.fr> 4 * Copyright (C) 2001 Romain Dolbeau <dolbeau@irisa.fr>
5 * Copyright (C) 2001 Sven Luther, <luther@dpt-info.u-strasbg.fr> 5 * Copyright (C) 2001 Sven Luther, <luther@dpt-info.u-strasbg.fr>
6 * 6 *
@@ -51,37 +51,36 @@
51* GLINT Permedia3 Region 0 Bypass Controls * 51* GLINT Permedia3 Region 0 Bypass Controls *
52***********************************************/ 52***********************************************/
53#define PM3ByAperture1Mode 0x0300 53#define PM3ByAperture1Mode 0x0300
54 #define PM3ByApertureMode_BYTESWAP_ABCD (0<<0) 54 #define PM3ByApertureMode_BYTESWAP_ABCD (0 << 0)
55 #define PM3ByApertureMode_BYTESWAP_BADC (1<<0) 55 #define PM3ByApertureMode_BYTESWAP_BADC (1 << 0)
56 #define PM3ByApertureMode_BYTESWAP_CDAB (2<<0) 56 #define PM3ByApertureMode_BYTESWAP_CDAB (2 << 0)
57 #define PM3ByApertureMode_BYTESWAP_DCBA (3<<0) 57 #define PM3ByApertureMode_BYTESWAP_DCBA (3 << 0)
58 #define PM3ByApertureMode_PATCH_DISABLE (0<<2) 58 #define PM3ByApertureMode_PATCH_ENABLE (1 << 2)
59 #define PM3ByApertureMode_PATCH_ENABLE (1<<2) 59 #define PM3ByApertureMode_FORMAT_RAW (0 << 3)
60 #define PM3ByApertureMode_FORMAT_RAW (0<<3) 60 #define PM3ByApertureMode_FORMAT_YUYV (1 << 3)
61 #define PM3ByApertureMode_FORMAT_YUYV (1<<3) 61 #define PM3ByApertureMode_FORMAT_UYVY (2 << 3)
62 #define PM3ByApertureMode_FORMAT_UYVY (2<<3) 62 #define PM3ByApertureMode_PIXELSIZE_8BIT (0 << 5)
63 #define PM3ByApertureMode_PIXELSIZE_8BIT (0<<5) 63 #define PM3ByApertureMode_PIXELSIZE_16BIT (1 << 5)
64 #define PM3ByApertureMode_PIXELSIZE_16BIT (1<<5) 64 #define PM3ByApertureMode_PIXELSIZE_32BIT (2 << 5)
65 #define PM3ByApertureMode_PIXELSIZE_32BIT (2<<5) 65 #define PM3ByApertureMode_PIXELSIZE_MASK (3 << 5)
66 #define PM3ByApertureMode_PIXELSIZE_MASK (3<<5) 66 #define PM3ByApertureMode_EFFECTIVE_STRIDE_1024 (0 << 7)
67 #define PM3ByApertureMode_EFFECTIVE_STRIDE_1024 (0<<7) 67 #define PM3ByApertureMode_EFFECTIVE_STRIDE_2048 (1 << 7)
68 #define PM3ByApertureMode_EFFECTIVE_STRIDE_2048 (1<<7) 68 #define PM3ByApertureMode_EFFECTIVE_STRIDE_4096 (2 << 7)
69 #define PM3ByApertureMode_EFFECTIVE_STRIDE_4096 (2<<7) 69 #define PM3ByApertureMode_EFFECTIVE_STRIDE_8192 (3 << 7)
70 #define PM3ByApertureMode_EFFECTIVE_STRIDE_8192 (3<<7) 70 #define PM3ByApertureMode_PATCH_OFFSET_X(off) (((off) & 0x7f) << 9)
71 #define PM3ByApertureMode_PATCH_OFFSET_X(off) (((off)&7f)<<9) 71 #define PM3ByApertureMode_PATCH_OFFSET_Y(off) (((off) & 0x7f) << 16)
72 #define PM3ByApertureMode_PATCH_OFFSET_Y(off) (((off)&7f)<<16) 72 #define PM3ByApertureMode_FRAMEBUFFER (0 << 21)
73 #define PM3ByApertureMode_FRAMEBUFFER (0<<21) 73 #define PM3ByApertureMode_LOCALBUFFER (1 << 21)
74 #define PM3ByApertureMode_LOCALBUFFER (1<<21) 74 #define PM3ByApertureMode_DOUBLE_WRITE_OFF (0 << 22)
75 #define PM3ByApertureMode_DOUBLE_WRITE_OFF (0<<22) 75 #define PM3ByApertureMode_DOUBLE_WRITE_1MB (1 << 22)
76 #define PM3ByApertureMode_DOUBLE_WRITE_1MB (1<<22) 76 #define PM3ByApertureMode_DOUBLE_WRITE_2MB (2 << 22)
77 #define PM3ByApertureMode_DOUBLE_WRITE_2MB (2<<22) 77 #define PM3ByApertureMode_DOUBLE_WRITE_4MB (3 << 22)
78 #define PM3ByApertureMode_DOUBLE_WRITE_4MB (3<<22) 78 #define PM3ByApertureMode_DOUBLE_WRITE_8MB (4 << 22)
79 #define PM3ByApertureMode_DOUBLE_WRITE_8MB (4<<22) 79 #define PM3ByApertureMode_DOUBLE_WRITE_16MB (5 << 22)
80 #define PM3ByApertureMode_DOUBLE_WRITE_16MB (5<<22) 80 #define PM3ByApertureMode_DOUBLE_WRITE_32MB (6 << 22)
81 #define PM3ByApertureMode_DOUBLE_WRITE_32MB (6<<22)
82 81
83#define PM3ByAperture2Mode 0x0328 82#define PM3ByAperture2Mode 0x0328
84 83
85/********************************************** 84/**********************************************
86* GLINT Permedia3 Memory Control (0x1000) * 85* GLINT Permedia3 Memory Control (0x1000) *
87***********************************************/ 86***********************************************/
@@ -89,7 +88,7 @@
89#define PM3MemBypassWriteMask 0x1008 88#define PM3MemBypassWriteMask 0x1008
90#define PM3MemScratch 0x1010 89#define PM3MemScratch 0x1010
91#define PM3LocalMemCaps 0x1018 90#define PM3LocalMemCaps 0x1018
92 #define PM3LocalMemCaps_NoWriteMask (1 << 28) 91 #define PM3LocalMemCaps_NoWriteMask (1 << 28)
93#define PM3LocalMemTimings 0x1020 92#define PM3LocalMemTimings 0x1020
94#define PM3LocalMemControl 0x1028 93#define PM3LocalMemControl 0x1028
95#define PM3LocalMemRefresh 0x1030 94#define PM3LocalMemRefresh 0x1030
@@ -112,45 +111,41 @@
112#define PM3VsStart 0x3048 111#define PM3VsStart 0x3048
113#define PM3VsEnd 0x3050 112#define PM3VsEnd 0x3050
114#define PM3VideoControl 0x3058 113#define PM3VideoControl 0x3058
115 #define PM3VideoControl_DISABLE (0<<0) 114 #define PM3VideoControl_ENABLE (1 << 0)
116 #define PM3VideoControl_ENABLE (1<<0) 115 #define PM3VideoControl_BLANK_ACTIVE_HIGH (0 << 1)
117 #define PM3VideoControl_BLANK_ACTIVE_HIGH (0<<1) 116 #define PM3VideoControl_BLANK_ACTIVE_LOW (1 << 1)
118 #define PM3VideoControl_BLANK_ACTIVE_LOW (1<<1) 117 #define PM3VideoControl_LINE_DOUBLE_OFF (0 << 2)
119 #define PM3VideoControl_LINE_DOUBLE_OFF (0<<2) 118 #define PM3VideoControl_LINE_DOUBLE_ON (1 << 2)
120 #define PM3VideoControl_LINE_DOUBLE_ON (1<<2) 119 #define PM3VideoControl_HSYNC_FORCE_HIGH (0 << 3)
121 #define PM3VideoControl_HSYNC_FORCE_HIGH (0<<3) 120 #define PM3VideoControl_HSYNC_ACTIVE_HIGH (1 << 3)
122 #define PM3VideoControl_HSYNC_ACTIVE_HIGH (1<<3) 121 #define PM3VideoControl_HSYNC_FORCE_LOW (2 << 3)
123 #define PM3VideoControl_HSYNC_FORCE_LOW (2<<3) 122 #define PM3VideoControl_HSYNC_ACTIVE_LOW (3 << 3)
124 #define PM3VideoControl_HSYNC_ACTIVE_LOW (3<<3) 123 #define PM3VideoControl_HSYNC_MASK (3 << 3)
125 #define PM3VideoControl_HSYNC_MASK (3<<3) 124 #define PM3VideoControl_VSYNC_FORCE_HIGH (0 << 5)
126 #define PM3VideoControl_VSYNC_FORCE_HIGH (0<<5) 125 #define PM3VideoControl_VSYNC_ACTIVE_HIGH (1 << 5)
127 #define PM3VideoControl_VSYNC_ACTIVE_HIGH (1<<5) 126 #define PM3VideoControl_VSYNC_FORCE_LOW (2 << 5)
128 #define PM3VideoControl_VSYNC_FORCE_LOW (2<<5) 127 #define PM3VideoControl_VSYNC_ACTIVE_LOW (3 << 5)
129 #define PM3VideoControl_VSYNC_ACTIVE_LOW (3<<5) 128 #define PM3VideoControl_VSYNC_MASK (3 << 5)
130 #define PM3VideoControl_VSYNC_MASK (3<<5) 129 #define PM3VideoControl_BYTE_DOUBLE_OFF (0 << 7)
131 #define PM3VideoControl_BYTE_DOUBLE_OFF (0<<7) 130 #define PM3VideoControl_BYTE_DOUBLE_ON (1 << 7)
132 #define PM3VideoControl_BYTE_DOUBLE_ON (1<<7) 131 #define PM3VideoControl_BUFFER_SWAP_SYNCON_FRAMEBLANK (0 << 9)
133 #define PM3VideoControl_BUFFER_SWAP_SYNCON_FRAMEBLANK (0<<9) 132 #define PM3VideoControl_BUFFER_SWAP_FREE_RUNNING (1 << 9)
134 #define PM3VideoControl_BUFFER_SWAP_FREE_RUNNING (1<<9) 133 #define PM3VideoControl_BUFFER_SWAP_LIMITETO_FRAMERATE (2 << 9)
135 #define PM3VideoControl_BUFFER_SWAP_LIMITETO_FRAMERATE (2<<9) 134 #define PM3VideoControl_STEREO_ENABLE (1 << 11)
136 #define PM3VideoControl_STEREO_DISABLE (0<<11) 135 #define PM3VideoControl_RIGHT_EYE_ACTIVE_HIGH (0 << 12)
137 #define PM3VideoControl_STEREO_ENABLE (1<<11) 136 #define PM3VideoControl_RIGHT_EYE_ACTIVE_LOW (1 << 12)
138 #define PM3VideoControl_RIGHT_EYE_ACTIVE_HIGH (0<<12) 137 #define PM3VideoControl_VIDEO_EXT_LOW (0 << 14)
139 #define PM3VideoControl_RIGHT_EYE_ACTIVE_LOW (1<<12) 138 #define PM3VideoControl_VIDEO_EXT_HIGH (1 << 14)
140 #define PM3VideoControl_VIDEO_EXT_LOW (0<<14) 139 #define PM3VideoControl_SYNC_MODE_INDEPENDENT (0 << 16)
141 #define PM3VideoControl_VIDEO_EXT_HIGH (1<<14) 140 #define PM3VideoControl_SYNC_MODE_SYNCTO_VSA (1 << 16)
142 #define PM3VideoControl_SYNC_MODE_INDEPENDENT (0<<16) 141 #define PM3VideoControl_SYNC_MODE_SYNCTO_VSB (2 << 16)
143 #define PM3VideoControl_SYNC_MODE_SYNCTO_VSA (1<<16) 142 #define PM3VideoControl_PATCH_ENABLE (1 << 18)
144 #define PM3VideoControl_SYNC_MODE_SYNCTO_VSB (2<<16) 143 #define PM3VideoControl_PIXELSIZE_8BIT (0 << 19)
145 #define PM3VideoControl_PATCH_DISABLE (0<<18) 144 #define PM3VideoControl_PIXELSIZE_16BIT (1 << 19)
146 #define PM3VideoControl_PATCH_ENABLE (1<<18) 145 #define PM3VideoControl_PIXELSIZE_32BIT (2 << 19)
147 #define PM3VideoControl_PIXELSIZE_8BIT (0<<19) 146 #define PM3VideoControl_DISPLAY_ENABLE (1 << 21)
148 #define PM3VideoControl_PIXELSIZE_16BIT (1<<19) 147 #define PM3VideoControl_PATCH_OFFSET_X(off) (((off) & 0x3f) << 22)
149 #define PM3VideoControl_PIXELSIZE_32BIT (2<<19) 148 #define PM3VideoControl_PATCH_OFFSET_Y(off) (((off) & 0x3f) << 28)
150 #define PM3VideoControl_DISPLAY_DISABLE (0<<21)
151 #define PM3VideoControl_DISPLAY_ENABLE (1<<21)
152 #define PM3VideoControl_PATCH_OFFSET_X(off) (((off)&0x3f)<<22)
153 #define PM3VideoControl_PATCH_OFFSET_Y(off) (((off)&0x3f)<<28)
154#define PM3InterruptLine 0x3060 149#define PM3InterruptLine 0x3060
155#define PM3DisplayData 0x3068 150#define PM3DisplayData 0x3068
156#define PM3VerticalLineCount 0x3070 151#define PM3VerticalLineCount 0x3070
@@ -159,80 +154,93 @@
159#define PM3MiscControl 0x3088 154#define PM3MiscControl 0x3088
160 155
161#define PM3VideoOverlayUpdate 0x3100 156#define PM3VideoOverlayUpdate 0x3100
162 #define PM3VideoOverlayUpdate_DISABLE (0<<0) 157 #define PM3VideoOverlayUpdate_ENABLE (1 << 0)
163 #define PM3VideoOverlayUpdate_ENABLE (1<<0)
164#define PM3VideoOverlayMode 0x3108 158#define PM3VideoOverlayMode 0x3108
165 #define PM3VideoOverlayMode_DISABLE (0<<0) 159 #define PM3VideoOverlayMode_ENABLE (1 << 0)
166 #define PM3VideoOverlayMode_ENABLE (1<<0) 160 #define PM3VideoOverlayMode_BUFFERSYNC_MANUAL (0 << 1)
167 #define PM3VideoOverlayMode_BUFFERSYNC_MANUAL (0<<1) 161 #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMA (1 << 1)
168 #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMA (1<<1) 162 #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMB (2 << 1)
169 #define PM3VideoOverlayMode_BUFFERSYNC_VIDEOSTREAMB (2<<1) 163 #define PM3VideoOverlayMode_FIELDPOLARITY_NORMAL (0 << 4)
170 #define PM3VideoOverlayMode_FIELDPOLARITY_NORMAL (0<<4) 164 #define PM3VideoOverlayMode_FIELDPOLARITY_INVERT (1 << 4)
171 #define PM3VideoOverlayMode_FIELDPOLARITY_INVERT (1<<4) 165 #define PM3VideoOverlayMode_PIXELSIZE_8BIT (0 << 5)
172 #define PM3VideoOverlayMode_PIXELSIZE_8BIT (0<<5) 166 #define PM3VideoOverlayMode_PIXELSIZE_16BIT (1 << 5)
173 #define PM3VideoOverlayMode_PIXELSIZE_16BIT (1<<5) 167 #define PM3VideoOverlayMode_PIXELSIZE_32BIT (2 << 5)
174 #define PM3VideoOverlayMode_PIXELSIZE_32BIT (2<<5) 168 #define PM3VideoOverlayMode_COLORFORMAT_RGB8888 \
175 #define PM3VideoOverlayMode_COLORFORMAT_RGB8888 ((0<<7)|(1<<12)|(2<<5)) 169 ((0 << 7)|(1 << 12)|(2 << 5))
176 #define PM3VideoOverlayMode_COLORFORMAT_RGB4444 ((1<<7)|(1<<12)|(1<<5)) 170 #define PM3VideoOverlayMode_COLORFORMAT_RGB4444 \
177 #define PM3VideoOverlayMode_COLORFORMAT_RGB5551 ((2<<7)|(1<<12)|(1<<5)) 171 ((1 << 7)|(1 << 12)|(1 << 5))
178 #define PM3VideoOverlayMode_COLORFORMAT_RGB565 ((3<<7)|(1<<12)|(1<<5)) 172 #define PM3VideoOverlayMode_COLORFORMAT_RGB5551 \
179 #define PM3VideoOverlayMode_COLORFORMAT_RGB332 ((4<<7)|(1<<12)|(0<<5)) 173 ((2 << 7)|(1 << 12)|(1 << 5))
180 #define PM3VideoOverlayMode_COLORFORMAT_BGR8888 ((0<<7)|(2<<5)) 174 #define PM3VideoOverlayMode_COLORFORMAT_RGB565 \
181 #define PM3VideoOverlayMode_COLORFORMAT_BGR4444 ((1<<7)|(1<<5)) 175 ((3 << 7)|(1 << 12)|(1 << 5))
182 #define PM3VideoOverlayMode_COLORFORMAT_BGR5551 ((2<<7)|(1<<5)) 176 #define PM3VideoOverlayMode_COLORFORMAT_RGB332 \
183 #define PM3VideoOverlayMode_COLORFORMAT_BGR565 ((3<<7)|(1<<5)) 177 ((4 << 7)|(1 << 12)|(0 << 5))
184 #define PM3VideoOverlayMode_COLORFORMAT_BGR332 ((4<<7)|(0<<5)) 178 #define PM3VideoOverlayMode_COLORFORMAT_BGR8888 \
185 #define PM3VideoOverlayMode_COLORFORMAT_CI8 ((5<<7)|(1<<12)|(0<<5)) 179 ((0 << 7)|(2 << 5))
186 #define PM3VideoOverlayMode_COLORFORMAT_VUY444 ((2<<10)|(1<<12)|(2<<5)) 180 #define PM3VideoOverlayMode_COLORFORMAT_BGR4444 \
187 #define PM3VideoOverlayMode_COLORFORMAT_YUV444 ((2<<10)|(2<<5)) 181 ((1 << 7)|(1 << 5))
188 #define PM3VideoOverlayMode_COLORFORMAT_VUY422 ((1<<10)|(1<<12)|(1<<5)) 182 #define PM3VideoOverlayMode_COLORFORMAT_BGR5551 \
189 #define PM3VideoOverlayMode_COLORFORMAT_YUV422 ((1<<10)|(1<<5)) 183 ((2 << 7)|(1 << 5))
190 #define PM3VideoOverlayMode_COLORORDER_BGR (0<<12) 184 #define PM3VideoOverlayMode_COLORFORMAT_BGR565 \
191 #define PM3VideoOverlayMode_COLORORDER_RGB (1<<12) 185 ((3 << 7)|(1 << 5))
192 #define PM3VideoOverlayMode_LINEARCOLOREXT_OFF (0<<13) 186 #define PM3VideoOverlayMode_COLORFORMAT_BGR332 \
193 #define PM3VideoOverlayMode_LINEARCOLOREXT_ON (1<<13) 187 ((4 << 7)|(0 << 5))
194 #define PM3VideoOverlayMode_FILTER_MASK (3<<14) 188 #define PM3VideoOverlayMode_COLORFORMAT_CI8 \
195 #define PM3VideoOverlayMode_FILTER_OFF (0<<14) 189 ((5 << 7)|(1 << 12)|(0 << 5))
196 #define PM3VideoOverlayMode_FILTER_FULL (1<<14) 190 #define PM3VideoOverlayMode_COLORFORMAT_VUY444 \
197 #define PM3VideoOverlayMode_FILTER_PARTIAL (2<<14) 191 ((2 << 10)|(1 << 12)|(2 << 5))
198 #define PM3VideoOverlayMode_DEINTERLACE_OFF (0<<16) 192 #define PM3VideoOverlayMode_COLORFORMAT_YUV444 \
199 #define PM3VideoOverlayMode_DEINTERLACE_BOB (1<<16) 193 ((2 << 10)|(2 << 5))
200 #define PM3VideoOverlayMode_PATCHMODE_OFF (0<<18) 194 #define PM3VideoOverlayMode_COLORFORMAT_VUY422 \
201 #define PM3VideoOverlayMode_PATCHMODE_ON (1<<18) 195 ((1 << 10)|(1 << 12)|(1 << 5))
202 #define PM3VideoOverlayMode_FLIP_VIDEO (0<<20) 196 #define PM3VideoOverlayMode_COLORFORMAT_YUV422 \
203 #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMA (1<<20) 197 ((1 << 10)|(1 << 5))
204 #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMB (2<<20) 198 #define PM3VideoOverlayMode_COLORORDER_BGR (0 << 12)
205 #define PM3VideoOverlayMode_MIRROR_MASK (3<<23) 199 #define PM3VideoOverlayMode_COLORORDER_RGB (1 << 12)
206 #define PM3VideoOverlayMode_MIRRORX_OFF (0<<23) 200 #define PM3VideoOverlayMode_LINEARCOLOREXT_OFF (0 << 13)
207 #define PM3VideoOverlayMode_MIRRORX_ON (1<<23) 201 #define PM3VideoOverlayMode_LINEARCOLOREXT_ON (1 << 13)
208 #define PM3VideoOverlayMode_MIRRORY_OFF (0<<24) 202 #define PM3VideoOverlayMode_FILTER_MASK (3 << 14)
209 #define PM3VideoOverlayMode_MIRRORY_ON (1<<24) 203 #define PM3VideoOverlayMode_FILTER_OFF (0 << 14)
204 #define PM3VideoOverlayMode_FILTER_FULL (1 << 14)
205 #define PM3VideoOverlayMode_FILTER_PARTIAL (2 << 14)
206 #define PM3VideoOverlayMode_DEINTERLACE_OFF (0 << 16)
207 #define PM3VideoOverlayMode_DEINTERLACE_BOB (1 << 16)
208 #define PM3VideoOverlayMode_PATCHMODE_OFF (0 << 18)
209 #define PM3VideoOverlayMode_PATCHMODE_ON (1 << 18)
210 #define PM3VideoOverlayMode_FLIP_VIDEO (0 << 20)
211 #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMA (1 << 20)
212 #define PM3VideoOverlayMode_FLIP_VIDEOSTREAMB (2 << 20)
213 #define PM3VideoOverlayMode_MIRROR_MASK (3 << 23)
214 #define PM3VideoOverlayMode_MIRRORX_OFF (0 << 23)
215 #define PM3VideoOverlayMode_MIRRORX_ON (1 << 23)
216 #define PM3VideoOverlayMode_MIRRORY_OFF (0 << 24)
217 #define PM3VideoOverlayMode_MIRRORY_ON (1 << 24)
210#define PM3VideoOverlayFifoControl 0x3110 218#define PM3VideoOverlayFifoControl 0x3110
211#define PM3VideoOverlayIndex 0x3118 219#define PM3VideoOverlayIndex 0x3118
212#define PM3VideoOverlayBase0 0x3120 220#define PM3VideoOverlayBase0 0x3120
213#define PM3VideoOverlayBase1 0x3128 221#define PM3VideoOverlayBase1 0x3128
214#define PM3VideoOverlayBase2 0x3130 222#define PM3VideoOverlayBase2 0x3130
215#define PM3VideoOverlayStride 0x3138 223#define PM3VideoOverlayStride 0x3138
216 #define PM3VideoOverlayStride_STRIDE(s) (((s)&0xfff)<<0) 224 #define PM3VideoOverlayStride_STRIDE(s) (((s) & 0xfff) << 0)
217#define PM3VideoOverlayWidth 0x3140 225#define PM3VideoOverlayWidth 0x3140
218 #define PM3VideoOverlayWidth_WIDTH(w) (((w)&0xfff)<<0) 226 #define PM3VideoOverlayWidth_WIDTH(w) (((w) & 0xfff) << 0)
219#define PM3VideoOverlayHeight 0x3148 227#define PM3VideoOverlayHeight 0x3148
220 #define PM3VideoOverlayHeight_HEIGHT(h) (((h)&0xfff)<<0) 228 #define PM3VideoOverlayHeight_HEIGHT(h) (((h) & 0xfff) << 0)
221#define PM3VideoOverlayOrigin 0x3150 229#define PM3VideoOverlayOrigin 0x3150
222 #define PM3VideoOverlayOrigin_XORIGIN(x) (((x)&0xfff)<<0) 230 #define PM3VideoOverlayOrigin_XORIGIN(x) (((x) & 0xfff) << 0)
223 #define PM3VideoOverlayOrigin_YORIGIN(y) (((y)&0xfff)<<16) 231 #define PM3VideoOverlayOrigin_YORIGIN(y) (((y) & 0xfff) << 16)
224#define PM3VideoOverlayShrinkXDelta 0x3158 232#define PM3VideoOverlayShrinkXDelta 0x3158
225 #define PM3VideoOverlayShrinkXDelta_NONE (1<<16) 233 #define PM3VideoOverlayShrinkXDelta_NONE (1 << 16)
226 #define PM3VideoOverlayShrinkXDelta_DELTA(s,d) \ 234 #define PM3VideoOverlayShrinkXDelta_DELTA(s,d) \
227 ((((s)<<16)/(d))&0x0ffffff0) 235 ((((s) << 16)/(d)) & 0x0ffffff0)
228#define PM3VideoOverlayZoomXDelta 0x3160 236#define PM3VideoOverlayZoomXDelta 0x3160
229 #define PM3VideoOverlayZoomXDelta_NONE (1<<16) 237 #define PM3VideoOverlayZoomXDelta_NONE (1 << 16)
230 #define PM3VideoOverlayZoomXDelta_DELTA(s,d) \ 238 #define PM3VideoOverlayZoomXDelta_DELTA(s,d) \
231 ((((s)<<16)/(d))&0x0001fff0) 239 ((((s) << 16)/(d)) & 0x0001fff0)
232#define PM3VideoOverlayYDelta 0x3168 240#define PM3VideoOverlayYDelta 0x3168
233 #define PM3VideoOverlayYDelta_NONE (1<<16) 241 #define PM3VideoOverlayYDelta_NONE (1 << 16)
234 #define PM3VideoOverlayYDelta_DELTA(s,d) \ 242 #define PM3VideoOverlayYDelta_DELTA(s,d) \
235 ((((s)<<16)/(d))&0x0ffffff0) 243 ((((s) << 16)/(d)) & 0x0ffffff0)
236#define PM3VideoOverlayFieldOffset 0x3170 244#define PM3VideoOverlayFieldOffset 0x3170
237#define PM3VideoOverlayStatus 0x3178 245#define PM3VideoOverlayStatus 0x3178
238 246
@@ -249,102 +257,82 @@
249#define PM3RD_IndexHigh 0x4028 257#define PM3RD_IndexHigh 0x4028
250#define PM3RD_IndexedData 0x4030 258#define PM3RD_IndexedData 0x4030
251#define PM3RD_IndexControl 0x4038 259#define PM3RD_IndexControl 0x4038
252 #define PM3RD_IndexControl_AUTOINCREMENT_ENABLE (1<<0) 260 #define PM3RD_IndexControl_AUTOINCREMENT_ENABLE (1 << 0)
253 #define PM3RD_IndexControl_AUTOINCREMENT_DISABLE (0<<0)
254 261
255/* Indirect Registers */ 262/* Indirect Registers */
256#define PM3RD_MiscControl 0x000 263#define PM3RD_MiscControl 0x000
257 #define PM3RD_MiscControl_HIGHCOLOR_RES_DISABLE (0<<0) 264 #define PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE (1 << 0)
258 #define PM3RD_MiscControl_HIGHCOLOR_RES_ENABLE (1<<0) 265 #define PM3RD_MiscControl_PIXELDOUBLE_ENABLE (1 << 1)
259 #define PM3RD_MiscControl_PIXELDOUBLE_DISABLE (0<<1) 266 #define PM3RD_MiscControl_LASTREAD_ADDR_ENABLE (1 << 2)
260 #define PM3RD_MiscControl_PIXELDOUBLE_ENABLE (1<<1) 267 #define PM3RD_MiscControl_DIRECTCOLOR_ENABLE (1 << 3)
261 #define PM3RD_MiscControl_LASTREAD_ADDR_DISABLE (0<<2) 268 #define PM3RD_MiscControl_OVERLAY_ENABLE (1 << 4)
262 #define PM3RD_MiscControl_LASTREAD_ADDR_ENABLE (1<<2) 269 #define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_ENABLE (1 << 5)
263 #define PM3RD_MiscControl_DIRECTCOLOR_DISABLE (0<<3) 270 #define PM3RD_MiscControl_VSB_OUTPUT_ENABLE (1 << 6)
264 #define PM3RD_MiscControl_DIRECTCOLOR_ENABLE (1<<3) 271 #define PM3RD_MiscControl_STEREODOUBLE_BUFFER_ENABLE (1 << 7)
265 #define PM3RD_MiscControl_OVERLAY_DISABLE (0<<4)
266 #define PM3RD_MiscControl_OVERLAY_ENABLE (1<<4)
267 #define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_DISABLE (0<<5)
268 #define PM3RD_MiscControl_PIXELDOUBLE_BUFFER_ENABLE (1<<5)
269 #define PM3RD_MiscControl_VSB_OUTPUT_DISABLE (0<<6)
270 #define PM3RD_MiscControl_VSB_OUTPUT_ENABLE (1<<6)
271 #define PM3RD_MiscControl_STEREODOUBLE_BUFFER_DISABLE (0<<7)
272 #define PM3RD_MiscControl_STEREODOUBLE_BUFFER_ENABLE (1<<7)
273#define PM3RD_SyncControl 0x001 272#define PM3RD_SyncControl 0x001
274 #define PM3RD_SyncControl_HSYNC_ACTIVE_LOW (0<<0) 273 #define PM3RD_SyncControl_HSYNC_ACTIVE_LOW (0 << 0)
275 #define PM3RD_SyncControl_HSYNC_ACTIVE_HIGH (1<<0) 274 #define PM3RD_SyncControl_HSYNC_ACTIVE_HIGH (1 << 0)
276 #define PM3RD_SyncControl_HSYNC_FORCE_ACTIVE (3<<0) 275 #define PM3RD_SyncControl_HSYNC_FORCE_ACTIVE (3 << 0)
277 #define PM3RD_SyncControl_HSYNC_FORCE_INACTIVE (4<<0) 276 #define PM3RD_SyncControl_HSYNC_FORCE_INACTIVE (4 << 0)
278 #define PM3RD_SyncControl_HSYNC_TRI_STATE (2<<0) 277 #define PM3RD_SyncControl_HSYNC_TRI_STATE (2 << 0)
279 #define PM3RD_SyncControl_VSYNC_ACTIVE_LOW (0<<3) 278 #define PM3RD_SyncControl_VSYNC_ACTIVE_LOW (0 << 3)
280 #define PM3RD_SyncControl_VSYNC_ACTIVE_HIGH (1<<3) 279 #define PM3RD_SyncControl_VSYNC_ACTIVE_HIGH (1 << 3)
281 #define PM3RD_SyncControl_VSYNC_TRI_STATE (2<<3) 280 #define PM3RD_SyncControl_VSYNC_TRI_STATE (2 << 3)
282 #define PM3RD_SyncControl_VSYNC_FORCE_ACTIVE (3<<3) 281 #define PM3RD_SyncControl_VSYNC_FORCE_ACTIVE (3 << 3)
283 #define PM3RD_SyncControl_VSYNC_FORCE_INACTIVE (4<<3) 282 #define PM3RD_SyncControl_VSYNC_FORCE_INACTIVE (4 << 3)
284 #define PM3RD_SyncControl_HSYNC_OVERRIDE_SETBY_HSYNC (0<<6) 283 #define PM3RD_SyncControl_HSYNC_OVERRIDE_SETBY_HSYNC (0 << 6)
285 #define PM3RD_SyncControl_HSYNC_OVERRIDE_FORCE_HIGH (1<<6) 284 #define PM3RD_SyncControl_HSYNC_OVERRIDE_FORCE_HIGH (1 << 6)
286 #define PM3RD_SyncControl_VSYNC_OVERRIDE_SETBY_VSYNC (0<<7) 285 #define PM3RD_SyncControl_VSYNC_OVERRIDE_SETBY_VSYNC (0 << 7)
287 #define PM3RD_SyncControl_VSYNC_OVERRIDE_FORCE_HIGH (1<<7) 286 #define PM3RD_SyncControl_VSYNC_OVERRIDE_FORCE_HIGH (1 << 7)
288#define PM3RD_DACControl 0x002 287#define PM3RD_DACControl 0x002
289 #define PM3RD_DACControl_DAC_POWER_ON (0<<0) 288 #define PM3RD_DACControl_DAC_POWER_ON (0 << 0)
290 #define PM3RD_DACControl_DAC_POWER_OFF (1<<0) 289 #define PM3RD_DACControl_DAC_POWER_OFF (1 << 0)
291 #define PM3RD_DACControl_SYNC_ON_GREEN_DISABLE (0<<3) 290 #define PM3RD_DACControl_SYNC_ON_GREEN_ENABLE (1 << 3)
292 #define PM3RD_DACControl_SYNC_ON_GREEN_ENABLE (1<<3) 291 #define PM3RD_DACControl_BLANK_RED_DAC_ENABLE (1 << 4)
293 #define PM3RD_DACControl_BLANK_RED_DAC_DISABLE (0<<4) 292 #define PM3RD_DACControl_BLANK_GREEN_DAC_ENABLE (1 << 5)
294 #define PM3RD_DACControl_BLANK_RED_DAC_ENABLE (1<<4) 293 #define PM3RD_DACControl_BLANK_BLUE_DAC_ENABLE (1 << 6)
295 #define PM3RD_DACControl_BLANK_GREEN_DAC_DISABLE (0<<5) 294 #define PM3RD_DACControl_BLANK_PEDESTAL_ENABLE (1 << 7)
296 #define PM3RD_DACControl_BLANK_GREEN_DAC_ENABLE (1<<5)
297 #define PM3RD_DACControl_BLANK_BLUE_DAC_DISABLE (0<<6)
298 #define PM3RD_DACControl_BLANK_BLUE_DAC_ENABLE (1<<6)
299 #define PM3RD_DACControl_BLANK_PEDESTAL_DISABLE (0<<7)
300 #define PM3RD_DACControl_BLANK_PEDESTAL_ENABLE (1<<7)
301#define PM3RD_PixelSize 0x003 295#define PM3RD_PixelSize 0x003
302 #define PM3RD_PixelSize_24_BIT_PIXELS (4<<0) 296 #define PM3RD_PixelSize_24_BIT_PIXELS (4 << 0)
303 #define PM3RD_PixelSize_32_BIT_PIXELS (2<<0) 297 #define PM3RD_PixelSize_32_BIT_PIXELS (2 << 0)
304 #define PM3RD_PixelSize_16_BIT_PIXELS (1<<0) 298 #define PM3RD_PixelSize_16_BIT_PIXELS (1 << 0)
305 #define PM3RD_PixelSize_8_BIT_PIXELS (0<<0) 299 #define PM3RD_PixelSize_8_BIT_PIXELS (0 << 0)
306#define PM3RD_ColorFormat 0x004 300#define PM3RD_ColorFormat 0x004
307 #define PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE (1<<6) 301 #define PM3RD_ColorFormat_LINEAR_COLOR_EXT_ENABLE (1 << 6)
308 #define PM3RD_ColorFormat_LINEAR_COLOR_EXT_DISABLE (0<<6) 302 #define PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW (1 << 5)
309 #define PM3RD_ColorFormat_COLOR_ORDER_BLUE_LOW (1<<5) 303 #define PM3RD_ColorFormat_COLOR_ORDER_RED_LOW (0 << 5)
310 #define PM3RD_ColorFormat_COLOR_ORDER_RED_LOW (0<<5) 304 #define PM3RD_ColorFormat_COLOR_FORMAT_MASK (0x1f << 0)
311 #define PM3RD_ColorFormat_COLOR_FORMAT_MASK (0x1f<<0) 305 #define PM3RD_ColorFormat_8888_COLOR (0 << 0)
312 #define PM3RD_ColorFormat_8888_COLOR (0<<0) 306 #define PM3RD_ColorFormat_5551_FRONT_COLOR (1 << 0)
313 #define PM3RD_ColorFormat_5551_FRONT_COLOR (1<<0) 307 #define PM3RD_ColorFormat_4444_COLOR (2 << 0)
314 #define PM3RD_ColorFormat_4444_COLOR (2<<0) 308 #define PM3RD_ColorFormat_332_FRONT_COLOR (5 << 0)
315 #define PM3RD_ColorFormat_332_FRONT_COLOR (5<<0) 309 #define PM3RD_ColorFormat_332_BACK_COLOR (6 << 0)
316 #define PM3RD_ColorFormat_332_BACK_COLOR (6<<0) 310 #define PM3RD_ColorFormat_2321_FRONT_COLOR (9 << 0)
317 #define PM3RD_ColorFormat_2321_FRONT_COLOR (9<<0) 311 #define PM3RD_ColorFormat_2321_BACK_COLOR (10 << 0)
318 #define PM3RD_ColorFormat_2321_BACK_COLOR (10<<0) 312 #define PM3RD_ColorFormat_232_FRONTOFF_COLOR (11 << 0)
319 #define PM3RD_ColorFormat_232_FRONTOFF_COLOR (11<<0) 313 #define PM3RD_ColorFormat_232_BACKOFF_COLOR (12 << 0)
320 #define PM3RD_ColorFormat_232_BACKOFF_COLOR (12<<0) 314 #define PM3RD_ColorFormat_5551_BACK_COLOR (13 << 0)
321 #define PM3RD_ColorFormat_5551_BACK_COLOR (13<<0) 315 #define PM3RD_ColorFormat_CI8_COLOR (14 << 0)
322 #define PM3RD_ColorFormat_CI8_COLOR (14<<0) 316 #define PM3RD_ColorFormat_565_FRONT_COLOR (16 << 0)
323 #define PM3RD_ColorFormat_565_FRONT_COLOR (16<<0) 317 #define PM3RD_ColorFormat_565_BACK_COLOR (17 << 0)
324 #define PM3RD_ColorFormat_565_BACK_COLOR (17<<0)
325#define PM3RD_CursorMode 0x005 318#define PM3RD_CursorMode 0x005
326 #define PM3RD_CursorMode_CURSOR_DISABLE (0<<0) 319 #define PM3RD_CursorMode_CURSOR_ENABLE (1 << 0)
327 #define PM3RD_CursorMode_CURSOR_ENABLE (1<<0) 320 #define PM3RD_CursorMode_FORMAT_64x64_2BPE_P0123 (0 << 2)
328 #define PM3RD_CursorMode_FORMAT_64x64_2BPE_P0123 (0<<2) 321 #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P0 (1 << 2)
329 #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P0 (1<<2) 322 #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P1 (2 << 2)
330 #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P1 (2<<2) 323 #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P2 (3 << 2)
331 #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P2 (3<<2) 324 #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P3 (4 << 2)
332 #define PM3RD_CursorMode_FORMAT_32x32_2BPE_P3 (4<<2) 325 #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P01 (5 << 2)
333 #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P01 (5<<2) 326 #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P23 (6 << 2)
334 #define PM3RD_CursorMode_FORMAT_32x32_4BPE_P23 (6<<2) 327 #define PM3RD_CursorMode_TYPE_MS (0 << 4)
335 #define PM3RD_CursorMode_TYPE_MS (0<<4) 328 #define PM3RD_CursorMode_TYPE_X (1 << 4)
336 #define PM3RD_CursorMode_TYPE_X (1<<4) 329 #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_ENABLE (1 << 6)
337 #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_DISABLE (0<<6) 330 #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_3_COLOR (2 << 6)
338 #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_ENABLE (1<<6) 331 #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_15_COLOR (3 << 6)
339 #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_3_COLOR (2<<6)
340 #define PM3RD_CursorMode_REVERSE_PIXEL_ORDER_15_COLOR (3<<6)
341#define PM3RD_CursorControl 0x006 332#define PM3RD_CursorControl 0x006
342 #define PM3RD_CursorControl_DOUBLE_X_DISABLED (0<<0) 333 #define PM3RD_CursorControl_DOUBLE_X_ENABLED (1 << 0)
343 #define PM3RD_CursorControl_DOUBLE_X_ENABLED (1<<0) 334 #define PM3RD_CursorControl_DOUBLE_Y_ENABLED (1 << 1)
344 #define PM3RD_CursorControl_DOUBLE_Y_DISABLED (0<<1) 335 #define PM3RD_CursorControl_READBACK_POS_ENABLED (1 << 2)
345 #define PM3RD_CursorControl_DOUBLE_Y_ENABLED (1<<1)
346 #define PM3RD_CursorControl_READBACK_POS_DISABLED (0<<2)
347 #define PM3RD_CursorControl_READBACK_POS_ENABLED (1<<2)
348 336
349#define PM3RD_CursorXLow 0x007 337#define PM3RD_CursorXLow 0x007
350#define PM3RD_CursorXHigh 0x008 338#define PM3RD_CursorXHigh 0x008
@@ -354,17 +342,13 @@
354#define PM3RD_CursorHotSpotY 0x00c 342#define PM3RD_CursorHotSpotY 0x00c
355#define PM3RD_OverlayKey 0x00d 343#define PM3RD_OverlayKey 0x00d
356#define PM3RD_Pan 0x00e 344#define PM3RD_Pan 0x00e
357 #define PM3RD_Pan_DISABLE (0<<0) 345 #define PM3RD_Pan_ENABLE (1 << 0)
358 #define PM3RD_Pan_ENABLE (1<<0) 346 #define PM3RD_Pan_GATE_ENABLE (1 << 1)
359 #define PM3RD_Pan_GATE_DISABLE (0<<1)
360 #define PM3RD_Pan_GATE_ENABLE (1<<1)
361#define PM3RD_Sense 0x00f 347#define PM3RD_Sense 0x00f
362 348
363#define PM3RD_CheckControl 0x018 349#define PM3RD_CheckControl 0x018
364 #define PM3RD_CheckControl_PIXEL_DISABLED (0<<0) 350 #define PM3RD_CheckControl_PIXEL_ENABLED (1 << 0)
365 #define PM3RD_CheckControl_PIXEL_ENABLED (1<<0) 351 #define PM3RD_CheckControl_LUT_ENABLED (1 << 1)
366 #define PM3RD_CheckControl_LUT_DISABLED (0<<1)
367 #define PM3RD_CheckControl_LUT_ENABLED (1<<1)
368#define PM3RD_CheckPixelRed 0x019 352#define PM3RD_CheckPixelRed 0x019
369#define PM3RD_CheckPixelGreen 0x01a 353#define PM3RD_CheckPixelGreen 0x01a
370#define PM3RD_CheckPixelBlue 0x01b 354#define PM3RD_CheckPixelBlue 0x01b
@@ -374,19 +358,17 @@
374#define PM3RD_Scratch 0x01f 358#define PM3RD_Scratch 0x01f
375 359
376#define PM3RD_VideoOverlayControl 0x020 360#define PM3RD_VideoOverlayControl 0x020
377 #define PM3RD_VideoOverlayControl_DISABLE (0<<0) 361 #define PM3RD_VideoOverlayControl_ENABLE (1 << 0)
378 #define PM3RD_VideoOverlayControl_ENABLE (1<<0) 362 #define PM3RD_VideoOverlayControl_MODE_MASK (3 << 1)
379 #define PM3RD_VideoOverlayControl_MODE_MASK (3<<1) 363 #define PM3RD_VideoOverlayControl_MODE_MAINKEY (0 << 1)
380 #define PM3RD_VideoOverlayControl_MODE_MAINKEY (0<<1) 364 #define PM3RD_VideoOverlayControl_MODE_OVERLAYKEY (1 << 1)
381 #define PM3RD_VideoOverlayControl_MODE_OVERLAYKEY (1<<1) 365 #define PM3RD_VideoOverlayControl_MODE_ALWAYS (2 << 1)
382 #define PM3RD_VideoOverlayControl_MODE_ALWAYS (2<<1) 366 #define PM3RD_VideoOverlayControl_MODE_BLEND (3 << 1)
383 #define PM3RD_VideoOverlayControl_MODE_BLEND (3<<1) 367 #define PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED (1 << 3)
384 #define PM3RD_VideoOverlayControl_DIRECTCOLOR_DISABLED (0<<3) 368 #define PM3RD_VideoOverlayControl_BLENDSRC_MAIN (0 << 4)
385 #define PM3RD_VideoOverlayControl_DIRECTCOLOR_ENABLED (1<<3) 369 #define PM3RD_VideoOverlayControl_BLENDSRC_REGISTER (1 << 4)
386 #define PM3RD_VideoOverlayControl_BLENDSRC_MAIN (0<<4) 370 #define PM3RD_VideoOverlayControl_KEY_COLOR (0 << 5)
387 #define PM3RD_VideoOverlayControl_BLENDSRC_REGISTER (1<<4) 371 #define PM3RD_VideoOverlayControl_KEY_ALPHA (1 << 5)
388 #define PM3RD_VideoOverlayControl_KEY_COLOR (0<<5)
389 #define PM3RD_VideoOverlayControl_KEY_ALPHA (1<<5)
390#define PM3RD_VideoOverlayXStartLow 0x021 372#define PM3RD_VideoOverlayXStartLow 0x021
391#define PM3RD_VideoOverlayXStartHigh 0x022 373#define PM3RD_VideoOverlayXStartHigh 0x022
392#define PM3RD_VideoOverlayYStartLow 0x023 374#define PM3RD_VideoOverlayYStartLow 0x023
@@ -399,10 +381,10 @@
399#define PM3RD_VideoOverlayKeyG 0x02a 381#define PM3RD_VideoOverlayKeyG 0x02a
400#define PM3RD_VideoOverlayKeyB 0x02b 382#define PM3RD_VideoOverlayKeyB 0x02b
401#define PM3RD_VideoOverlayBlend 0x02c 383#define PM3RD_VideoOverlayBlend 0x02c
402 #define PM3RD_VideoOverlayBlend_FACTOR_0_PERCENT (0<<6) 384 #define PM3RD_VideoOverlayBlend_FACTOR_0_PERCENT (0 << 6)
403 #define PM3RD_VideoOverlayBlend_FACTOR_25_PERCENT (1<<6) 385 #define PM3RD_VideoOverlayBlend_FACTOR_25_PERCENT (1 << 6)
404 #define PM3RD_VideoOverlayBlend_FACTOR_75_PERCENT (2<<6) 386 #define PM3RD_VideoOverlayBlend_FACTOR_75_PERCENT (2 << 6)
405 #define PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT (3<<6) 387 #define PM3RD_VideoOverlayBlend_FACTOR_100_PERCENT (3 << 6)
406 388
407#define PM3RD_DClkSetup1 0x1f0 389#define PM3RD_DClkSetup1 0x1f0
408#define PM3RD_DClkSetup2 0x1f1 390#define PM3RD_DClkSetup2 0x1f1
@@ -410,21 +392,20 @@
410#define PM3RD_KClkSetup2 0x1f3 392#define PM3RD_KClkSetup2 0x1f3
411 393
412#define PM3RD_DClkControl 0x200 394#define PM3RD_DClkControl 0x200
413 #define PM3RD_DClkControl_SOURCE_PLL (0<<4) 395 #define PM3RD_DClkControl_SOURCE_PLL (0 << 4)
414 #define PM3RD_DClkControl_SOURCE_VSA (1<<4) 396 #define PM3RD_DClkControl_SOURCE_VSA (1 << 4)
415 #define PM3RD_DClkControl_SOURCE_VSB (2<<4) 397 #define PM3RD_DClkControl_SOURCE_VSB (2 << 4)
416 #define PM3RD_DClkControl_SOURCE_EXT (3<<4) 398 #define PM3RD_DClkControl_SOURCE_EXT (3 << 4)
417 #define PM3RD_DClkControl_STATE_RUN (2<<2) 399 #define PM3RD_DClkControl_STATE_RUN (2 << 2)
418 #define PM3RD_DClkControl_STATE_HIGH (1<<2) 400 #define PM3RD_DClkControl_STATE_HIGH (1 << 2)
419 #define PM3RD_DClkControl_STATE_LOW (0<<2) 401 #define PM3RD_DClkControl_STATE_LOW (0 << 2)
420 #define PM3RD_DClkControl_LOCKED (1<<1) 402 #define PM3RD_DClkControl_LOCKED (1 << 1)
421 #define PM3RD_DClkControl_NOT_LOCKED (0<<1) 403 #define PM3RD_DClkControl_NOT_LOCKED (0 << 1)
422 #define PM3RD_DClkControl_ENABLE (1<<0) 404 #define PM3RD_DClkControl_ENABLE (1 << 0)
423 #define PM3RD_DClkControl_DISABLE (0<<0)
424#define PM3RD_DClk0PreScale 0x201 405#define PM3RD_DClk0PreScale 0x201
425#define PM3RD_DClk0FeedbackScale 0x202 406#define PM3RD_DClk0FeedbackScale 0x202
426#define PM3RD_DClk0PostScale 0x203 407#define PM3RD_DClk0PostScale 0x203
427 #define PM3_REF_CLOCK 14318 408 #define PM3_REF_CLOCK 14318
428#define PM3RD_DClk1PreScale 0x204 409#define PM3RD_DClk1PreScale 0x204
429#define PM3RD_DClk1FeedbackScale 0x205 410#define PM3RD_DClk1FeedbackScale 0x205
430#define PM3RD_DClk1PostScale 0x206 411#define PM3RD_DClk1PostScale 0x206
@@ -435,59 +416,56 @@
435#define PM3RD_DClk3FeedbackScale 0x20b 416#define PM3RD_DClk3FeedbackScale 0x20b
436#define PM3RD_DClk3PostScale 0x20c 417#define PM3RD_DClk3PostScale 0x20c
437#define PM3RD_KClkControl 0x20d 418#define PM3RD_KClkControl 0x20d
438 #define PM3RD_KClkControl_DISABLE (0<<0) 419 #define PM3RD_KClkControl_ENABLE (1 << 0)
439 #define PM3RD_KClkControl_ENABLE (1<<0) 420 #define PM3RD_KClkControl_NOT_LOCKED (0 << 1)
440 #define PM3RD_KClkControl_NOT_LOCKED (0<<1) 421 #define PM3RD_KClkControl_LOCKED (1 << 1)
441 #define PM3RD_KClkControl_LOCKED (1<<1) 422 #define PM3RD_KClkControl_STATE_LOW (0 << 2)
442 #define PM3RD_KClkControl_STATE_LOW (0<<2) 423 #define PM3RD_KClkControl_STATE_HIGH (1 << 2)
443 #define PM3RD_KClkControl_STATE_HIGH (1<<2) 424 #define PM3RD_KClkControl_STATE_RUN (2 << 2)
444 #define PM3RD_KClkControl_STATE_RUN (2<<2) 425 #define PM3RD_KClkControl_STATE_LOW_POWER (3 << 2)
445 #define PM3RD_KClkControl_STATE_LOW_POWER (3<<2) 426 #define PM3RD_KClkControl_SOURCE_PCLK (0 << 4)
446 #define PM3RD_KClkControl_SOURCE_PCLK (0<<4) 427 #define PM3RD_KClkControl_SOURCE_HALF_PCLK (1 << 4)
447 #define PM3RD_KClkControl_SOURCE_HALF_PCLK (1<<4) 428 #define PM3RD_KClkControl_SOURCE_PLL (2 << 4)
448 #define PM3RD_KClkControl_SOURCE_PLL (2<<4)
449#define PM3RD_KClkPreScale 0x20e 429#define PM3RD_KClkPreScale 0x20e
450#define PM3RD_KClkFeedbackScale 0x20f 430#define PM3RD_KClkFeedbackScale 0x20f
451#define PM3RD_KClkPostScale 0x210 431#define PM3RD_KClkPostScale 0x210
452#define PM3RD_MClkControl 0x211 432#define PM3RD_MClkControl 0x211
453 #define PM3RD_MClkControl_DISABLE (0<<0) 433 #define PM3RD_MClkControl_ENABLE (1 << 0)
454 #define PM3RD_MClkControl_ENABLE (1<<0) 434 #define PM3RD_MClkControl_NOT_LOCKED (0 << 1)
455 #define PM3RD_MClkControl_NOT_LOCKED (0<<1) 435 #define PM3RD_MClkControl_LOCKED (1 << 1)
456 #define PM3RD_MClkControl_LOCKED (1<<1) 436 #define PM3RD_MClkControl_STATE_LOW (0 << 2)
457 #define PM3RD_MClkControl_STATE_LOW (0<<2) 437 #define PM3RD_MClkControl_STATE_HIGH (1 << 2)
458 #define PM3RD_MClkControl_STATE_HIGH (1<<2) 438 #define PM3RD_MClkControl_STATE_RUN (2 << 2)
459 #define PM3RD_MClkControl_STATE_RUN (2<<2) 439 #define PM3RD_MClkControl_STATE_LOW_POWER (3 << 2)
460 #define PM3RD_MClkControl_STATE_LOW_POWER (3<<2) 440 #define PM3RD_MClkControl_SOURCE_PCLK (0 << 4)
461 #define PM3RD_MClkControl_SOURCE_PCLK (0<<4) 441 #define PM3RD_MClkControl_SOURCE_HALF_PCLK (1 << 4)
462 #define PM3RD_MClkControl_SOURCE_HALF_PCLK (1<<4) 442 #define PM3RD_MClkControl_SOURCE_HALF_EXT (3 << 4)
463 #define PM3RD_MClkControl_SOURCE_HALF_EXT (3<<4) 443 #define PM3RD_MClkControl_SOURCE_EXT (4 << 4)
464 #define PM3RD_MClkControl_SOURCE_EXT (4<<4) 444 #define PM3RD_MClkControl_SOURCE_HALF_KCLK (5 << 4)
465 #define PM3RD_MClkControl_SOURCE_HALF_KCLK (5<<4) 445 #define PM3RD_MClkControl_SOURCE_KCLK (6 << 4)
466 #define PM3RD_MClkControl_SOURCE_KCLK (6<<4)
467#define PM3RD_MClkPreScale 0x212 446#define PM3RD_MClkPreScale 0x212
468#define PM3RD_MClkFeedbackScale 0x213 447#define PM3RD_MClkFeedbackScale 0x213
469#define PM3RD_MClkPostScale 0x214 448#define PM3RD_MClkPostScale 0x214
470#define PM3RD_SClkControl 0x215 449#define PM3RD_SClkControl 0x215
471 #define PM3RD_SClkControl_DISABLE (0<<0) 450 #define PM3RD_SClkControl_ENABLE (1 << 0)
472 #define PM3RD_SClkControl_ENABLE (1<<0) 451 #define PM3RD_SClkControl_NOT_LOCKED (0 << 1)
473 #define PM3RD_SClkControl_NOT_LOCKED (0<<1) 452 #define PM3RD_SClkControl_LOCKED (1 << 1)
474 #define PM3RD_SClkControl_LOCKED (1<<1) 453 #define PM3RD_SClkControl_STATE_LOW (0 << 2)
475 #define PM3RD_SClkControl_STATE_LOW (0<<2) 454 #define PM3RD_SClkControl_STATE_HIGH (1 << 2)
476 #define PM3RD_SClkControl_STATE_HIGH (1<<2) 455 #define PM3RD_SClkControl_STATE_RUN (2 << 2)
477 #define PM3RD_SClkControl_STATE_RUN (2<<2) 456 #define PM3RD_SClkControl_STATE_LOW_POWER (3 << 2)
478 #define PM3RD_SClkControl_STATE_LOW_POWER (3<<2) 457 #define PM3RD_SClkControl_SOURCE_PCLK (0 << 4)
479 #define PM3RD_SClkControl_SOURCE_PCLK (0<<4) 458 #define PM3RD_SClkControl_SOURCE_HALF_PCLK (1 << 4)
480 #define PM3RD_SClkControl_SOURCE_HALF_PCLK (1<<4) 459 #define PM3RD_SClkControl_SOURCE_HALF_EXT (3 << 4)
481 #define PM3RD_SClkControl_SOURCE_HALF_EXT (3<<4) 460 #define PM3RD_SClkControl_SOURCE_EXT (4 << 4)
482 #define PM3RD_SClkControl_SOURCE_EXT (4<<4) 461 #define PM3RD_SClkControl_SOURCE_HALF_KCLK (5 << 4)
483 #define PM3RD_SClkControl_SOURCE_HALF_KCLK (5<<4) 462 #define PM3RD_SClkControl_SOURCE_KCLK (6 << 4)
484 #define PM3RD_SClkControl_SOURCE_KCLK (6<<4)
485#define PM3RD_SClkPreScale 0x216 463#define PM3RD_SClkPreScale 0x216
486#define PM3RD_SClkFeedbackScale 0x217 464#define PM3RD_SClkFeedbackScale 0x217
487#define PM3RD_SClkPostScale 0x218 465#define PM3RD_SClkPostScale 0x218
488 466
489#define PM3RD_CursorPalette(p) (0x303+(p)) 467#define PM3RD_CursorPalette(p) (0x303 + (p))
490#define PM3RD_CursorPattern(p) (0x400+(p)) 468#define PM3RD_CursorPattern(p) (0x400 + (p))
491/****************************************************** 469/******************************************************
492* GLINT Permedia3 Video Streaming Registers (0x5000) * 470* GLINT Permedia3 Video Streaming Registers (0x5000) *
493*******************************************************/ 471*******************************************************/
@@ -521,10 +499,10 @@
521#define PM3ColorDDAModeOr 0xabe8 499#define PM3ColorDDAModeOr 0xabe8
522#define PM3CommandInterrupt 0xa990 500#define PM3CommandInterrupt 0xa990
523#define PM3ConstantColorDDA 0xafb0 501#define PM3ConstantColorDDA 0xafb0
524 #define PM3ConstantColorDDA_R(r) ((r)&0xff) 502 #define PM3ConstantColorDDA_R(r) ((r) & 0xff)
525 #define PM3ConstantColorDDA_G(g) (((g)&0xff)<<8) 503 #define PM3ConstantColorDDA_G(g) (((g) & 0xff) << 8)
526 #define PM3ConstantColorDDA_B(b) (((b)&0xff)<<16) 504 #define PM3ConstantColorDDA_B(b) (((b) & 0xff) << 16)
527 #define PM3ConstantColorDDA_A(a) (((a)&0xff)<<24) 505 #define PM3ConstantColorDDA_A(a) (((a) & 0xff) << 24)
528#define PM3ContextData 0x8dd0 506#define PM3ContextData 0x8dd0
529#define PM3ContextDump 0x8dc0 507#define PM3ContextDump 0x8dc0
530#define PM3ContextRestore 0x8dc8 508#define PM3ContextRestore 0x8dc8
@@ -568,59 +546,59 @@
568#define PM3FBDestReadBufferOffset1 0xaea8 546#define PM3FBDestReadBufferOffset1 0xaea8
569#define PM3FBDestReadBufferOffset2 0xaeb0 547#define PM3FBDestReadBufferOffset2 0xaeb0
570#define PM3FBDestReadBufferOffset3 0xaeb8 548#define PM3FBDestReadBufferOffset3 0xaeb8
571 #define PM3FBDestReadBufferOffset_XOffset(x) ((x)&0xffff) 549 #define PM3FBDestReadBufferOffset_XOffset(x) ((x) & 0xffff)
572 #define PM3FBDestReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) 550 #define PM3FBDestReadBufferOffset_YOffset(y) (((y) & 0xffff) << 16)
573#define PM3FBDestReadBufferWidth0 0xaec0 551#define PM3FBDestReadBufferWidth0 0xaec0
574#define PM3FBDestReadBufferWidth1 0xaec8 552#define PM3FBDestReadBufferWidth1 0xaec8
575#define PM3FBDestReadBufferWidth2 0xaed0 553#define PM3FBDestReadBufferWidth2 0xaed0
576#define PM3FBDestReadBufferWidth3 0xaed8 554#define PM3FBDestReadBufferWidth3 0xaed8
577 #define PM3FBDestReadBufferWidth_Width(w) ((w)&0x0fff) 555 #define PM3FBDestReadBufferWidth_Width(w) ((w) & 0x0fff)
578 556
579#define PM3FBDestReadEnables 0xaee8 557#define PM3FBDestReadEnables 0xaee8
580#define PM3FBDestReadEnablesAnd 0xad20 558#define PM3FBDestReadEnablesAnd 0xad20
581#define PM3FBDestReadEnablesOr 0xad28 559#define PM3FBDestReadEnablesOr 0xad28
582 #define PM3FBDestReadEnables_E(e) ((e)&0xff) 560 #define PM3FBDestReadEnables_E(e) ((e) & 0xff)
583 #define PM3FBDestReadEnables_E0 1<<0 561 #define PM3FBDestReadEnables_E0 (1 << 0)
584 #define PM3FBDestReadEnables_E1 1<<1 562 #define PM3FBDestReadEnables_E1 (1 << 1)
585 #define PM3FBDestReadEnables_E2 1<<2 563 #define PM3FBDestReadEnables_E2 (1 << 2)
586 #define PM3FBDestReadEnables_E3 1<<3 564 #define PM3FBDestReadEnables_E3 (1 << 3)
587 #define PM3FBDestReadEnables_E4 1<<4 565 #define PM3FBDestReadEnables_E4 (1 << 4)
588 #define PM3FBDestReadEnables_E5 1<<5 566 #define PM3FBDestReadEnables_E5 (1 << 5)
589 #define PM3FBDestReadEnables_E6 1<<6 567 #define PM3FBDestReadEnables_E6 (1 << 6)
590 #define PM3FBDestReadEnables_E7 1<<7 568 #define PM3FBDestReadEnables_E7 (1 << 7)
591 #define PM3FBDestReadEnables_R(r) (((r)&0xff)<<8) 569 #define PM3FBDestReadEnables_R(r) (((r) & 0xff) << 8)
592 #define PM3FBDestReadEnables_R0 1<<8 570 #define PM3FBDestReadEnables_R0 (1 << 8)
593 #define PM3FBDestReadEnables_R1 1<<9 571 #define PM3FBDestReadEnables_R1 (1 << 9)
594 #define PM3FBDestReadEnables_R2 1<<10 572 #define PM3FBDestReadEnables_R2 (1 << 10)
595 #define PM3FBDestReadEnables_R3 1<<11 573 #define PM3FBDestReadEnables_R3 (1 << 11)
596 #define PM3FBDestReadEnables_R4 1<<12 574 #define PM3FBDestReadEnables_R4 (1 << 12)
597 #define PM3FBDestReadEnables_R5 1<<13 575 #define PM3FBDestReadEnables_R5 (1 << 13)
598 #define PM3FBDestReadEnables_R6 1<<14 576 #define PM3FBDestReadEnables_R6 (1 << 14)
599 #define PM3FBDestReadEnables_R7 1<<15 577 #define PM3FBDestReadEnables_R7 (1 << 15)
600 #define PM3FBDestReadEnables_ReferenceAlpha(a) (((a)&0xff)<<24) 578 #define PM3FBDestReadEnables_ReferenceAlpha(a) (((a) & 0xff) << 24)
601 579
602#define PM3FBDestReadMode 0xaee0 580#define PM3FBDestReadMode 0xaee0
603#define PM3FBDestReadModeAnd 0xac90 581#define PM3FBDestReadModeAnd 0xac90
604#define PM3FBDestReadModeOr 0xac98 582#define PM3FBDestReadModeOr 0xac98
605 #define PM3FBDestReadMode_ReadDisable 0<<0 583 #define PM3FBDestReadMode_ReadDisable (0 << 0)
606 #define PM3FBDestReadMode_ReadEnable 1<<0 584 #define PM3FBDestReadMode_ReadEnable (1 << 0)
607 #define PM3FBDestReadMode_StripePitch(sp) (((sp)&0x7)<<2) 585 #define PM3FBDestReadMode_StripePitch(sp) (((sp) & 0x7) << 2)
608 #define PM3FBDestReadMode_StripeHeight(sh) (((sh)&0x7)<<7) 586 #define PM3FBDestReadMode_StripeHeight(sh) (((sh) & 0x7) << 7)
609 #define PM3FBDestReadMode_Enable0 1<<8 587 #define PM3FBDestReadMode_Enable0 (1 << 8)
610 #define PM3FBDestReadMode_Enable1 1<<9 588 #define PM3FBDestReadMode_Enable1 (1 << 9)
611 #define PM3FBDestReadMode_Enable2 1<<10 589 #define PM3FBDestReadMode_Enable2 (1 << 10)
612 #define PM3FBDestReadMode_Enable3 1<<11 590 #define PM3FBDestReadMode_Enable3 (1 << 11)
613 #define PM3FBDestReadMode_Layout0(l) (((l)&0x3)<<12) 591 #define PM3FBDestReadMode_Layout0(l) (((l) & 0x3) << 12)
614 #define PM3FBDestReadMode_Layout1(l) (((l)&0x3)<<14) 592 #define PM3FBDestReadMode_Layout1(l) (((l) & 0x3) << 14)
615 #define PM3FBDestReadMode_Layout2(l) (((l)&0x3)<<16) 593 #define PM3FBDestReadMode_Layout2(l) (((l) & 0x3) << 16)
616 #define PM3FBDestReadMode_Layout3(l) (((l)&0x3)<<18) 594 #define PM3FBDestReadMode_Layout3(l) (((l) & 0x3) << 18)
617 #define PM3FBDestReadMode_Origin0 1<<20 595 #define PM3FBDestReadMode_Origin0 (1 << 20)
618 #define PM3FBDestReadMode_Origin1 1<<21 596 #define PM3FBDestReadMode_Origin1 (1 << 21)
619 #define PM3FBDestReadMode_Origin2 1<<22 597 #define PM3FBDestReadMode_Origin2 (1 << 22)
620 #define PM3FBDestReadMode_Origin3 1<<23 598 #define PM3FBDestReadMode_Origin3 (1 << 23)
621 #define PM3FBDestReadMode_Blocking 1<<24 599 #define PM3FBDestReadMode_Blocking (1 << 24)
622 #define PM3FBDestReadMode_UseReadEnabled 1<<26 600 #define PM3FBDestReadMode_UseReadEnabled (1 << 26)
623 #define PM3FBDestReadMode_AlphaFiltering 1<<27 601 #define PM3FBDestReadMode_AlphaFiltering (1 << 27)
624 602
625#define PM3FBHardwareWriteMask 0x8ac0 603#define PM3FBHardwareWriteMask 0x8ac0
626#define PM3FBSoftwareWriteMask 0x8820 604#define PM3FBSoftwareWriteMask 0x8820
@@ -628,65 +606,65 @@
628#define PM3FBSourceData 0x8aa8 606#define PM3FBSourceData 0x8aa8
629#define PM3FBSourceReadBufferAddr 0xaf08 607#define PM3FBSourceReadBufferAddr 0xaf08
630#define PM3FBSourceReadBufferOffset 0xaf10 608#define PM3FBSourceReadBufferOffset 0xaf10
631 #define PM3FBSourceReadBufferOffset_XOffset(x) ((x)&0xffff) 609 #define PM3FBSourceReadBufferOffset_XOffset(x) ((x) & 0xffff)
632 #define PM3FBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) 610 #define PM3FBSourceReadBufferOffset_YOffset(y) (((y) & 0xffff) << 16)
633#define PM3FBSourceReadBufferWidth 0xaf18 611#define PM3FBSourceReadBufferWidth 0xaf18
634 #define PM3FBSourceReadBufferWidth_Width(w) ((w)&0x0fff) 612 #define PM3FBSourceReadBufferWidth_Width(w) ((w) & 0x0fff)
635#define PM3FBSourceReadMode 0xaf00 613#define PM3FBSourceReadMode 0xaf00
636#define PM3FBSourceReadModeAnd 0xaca0 614#define PM3FBSourceReadModeAnd 0xaca0
637#define PM3FBSourceReadModeOr 0xaca8 615#define PM3FBSourceReadModeOr 0xaca8
638 #define PM3FBSourceReadMode_ReadDisable (0<<0) 616 #define PM3FBSourceReadMode_ReadDisable (0 << 0)
639 #define PM3FBSourceReadMode_ReadEnable (1<<0) 617 #define PM3FBSourceReadMode_ReadEnable (1 << 0)
640 #define PM3FBSourceReadMode_StripePitch(sp) (((sp)&0x7)<<2) 618 #define PM3FBSourceReadMode_StripePitch(sp) (((sp) & 0x7) << 2)
641 #define PM3FBSourceReadMode_StripeHeight(sh) (((sh)&0x7)<<7) 619 #define PM3FBSourceReadMode_StripeHeight(sh) (((sh) & 0x7) << 7)
642 #define PM3FBSourceReadMode_Layout(l) (((l)&0x3)<<8) 620 #define PM3FBSourceReadMode_Layout(l) (((l) & 0x3) << 8)
643 #define PM3FBSourceReadMode_Origin 1<<10 621 #define PM3FBSourceReadMode_Origin (1 << 10)
644 #define PM3FBSourceReadMode_Blocking 1<<11 622 #define PM3FBSourceReadMode_Blocking (1 << 11)
645 #define PM3FBSourceReadMode_UserTexelCoord 1<<13 623 #define PM3FBSourceReadMode_UserTexelCoord (1 << 13)
646 #define PM3FBSourceReadMode_WrapXEnable 1<<14 624 #define PM3FBSourceReadMode_WrapXEnable (1 << 14)
647 #define PM3FBSourceReadMode_WrapYEnable 1<<15 625 #define PM3FBSourceReadMode_WrapYEnable (1 << 15)
648 #define PM3FBSourceReadMode_WrapX(w) (((w)&0xf)<<16) 626 #define PM3FBSourceReadMode_WrapX(w) (((w) & 0xf) << 16)
649 #define PM3FBSourceReadMode_WrapY(w) (((w)&0xf)<<20) 627 #define PM3FBSourceReadMode_WrapY(w) (((w) & 0xf) << 20)
650 #define PM3FBSourceReadMode_ExternalSourceData 1<<24 628 #define PM3FBSourceReadMode_ExternalSourceData (1 << 24)
651#define PM3FBWriteBufferAddr0 0xb000 629#define PM3FBWriteBufferAddr0 0xb000
652#define PM3FBWriteBufferAddr1 0xb008 630#define PM3FBWriteBufferAddr1 0xb008
653#define PM3FBWriteBufferAddr2 0xb010 631#define PM3FBWriteBufferAddr2 0xb010
654#define PM3FBWriteBufferAddr3 0xb018 632#define PM3FBWriteBufferAddr3 0xb018
655 633
656#define PM3FBWriteBufferOffset0 0xb020 634#define PM3FBWriteBufferOffset0 0xb020
657#define PM3FBWriteBufferOffset1 0xb028 635#define PM3FBWriteBufferOffset1 0xb028
658#define PM3FBWriteBufferOffset2 0xb030 636#define PM3FBWriteBufferOffset2 0xb030
659#define PM3FBWriteBufferOffset3 0xb038 637#define PM3FBWriteBufferOffset3 0xb038
660 #define PM3FBWriteBufferOffset_XOffset(x) ((x)&0xffff) 638 #define PM3FBWriteBufferOffset_XOffset(x) ((x) & 0xffff)
661 #define PM3FBWriteBufferOffset_YOffset(y) (((y)&0xffff)<<16) 639 #define PM3FBWriteBufferOffset_YOffset(y) (((y) & 0xffff) << 16)
662 640
663#define PM3FBWriteBufferWidth0 0xb040 641#define PM3FBWriteBufferWidth0 0xb040
664#define PM3FBWriteBufferWidth1 0xb048 642#define PM3FBWriteBufferWidth1 0xb048
665#define PM3FBWriteBufferWidth2 0xb050 643#define PM3FBWriteBufferWidth2 0xb050
666#define PM3FBWriteBufferWidth3 0xb058 644#define PM3FBWriteBufferWidth3 0xb058
667 #define PM3FBWriteBufferWidth_Width(w) ((w)&0x0fff) 645 #define PM3FBWriteBufferWidth_Width(w) ((w) & 0x0fff)
668 646
669#define PM3FBWriteMode 0x8ab8 647#define PM3FBWriteMode 0x8ab8
670#define PM3FBWriteModeAnd 0xacf0 648#define PM3FBWriteModeAnd 0xacf0
671#define PM3FBWriteModeOr 0xacf8 649#define PM3FBWriteModeOr 0xacf8
672 #define PM3FBWriteMode_WriteDisable 0<<0 650 #define PM3FBWriteMode_WriteDisable (0 << 0)
673 #define PM3FBWriteMode_WriteEnable 1<<0 651 #define PM3FBWriteMode_WriteEnable (1 << 0)
674 #define PM3FBWriteMode_Replicate 1<<4 652 #define PM3FBWriteMode_Replicate (1 << 4)
675 #define PM3FBWriteMode_OpaqueSpan 1<<5 653 #define PM3FBWriteMode_OpaqueSpan (1 << 5)
676 #define PM3FBWriteMode_StripePitch(p) (((p)&0x7)<<6) 654 #define PM3FBWriteMode_StripePitch(p) (((p) & 0x7) << 6)
677 #define PM3FBWriteMode_StripeHeight(h) (((h)&0x7)<<9) 655 #define PM3FBWriteMode_StripeHeight(h) (((h) & 0x7) << 9)
678 #define PM3FBWriteMode_Enable0 1<<12 656 #define PM3FBWriteMode_Enable0 (1 << 12)
679 #define PM3FBWriteMode_Enable1 1<<13 657 #define PM3FBWriteMode_Enable1 (1 << 13)
680 #define PM3FBWriteMode_Enable2 1<<14 658 #define PM3FBWriteMode_Enable2 (1 << 14)
681 #define PM3FBWriteMode_Enable3 1<<15 659 #define PM3FBWriteMode_Enable3 (1 << 15)
682 #define PM3FBWriteMode_Layout0(l) (((l)&0x3)<<16) 660 #define PM3FBWriteMode_Layout0(l) (((l) & 0x3) << 16)
683 #define PM3FBWriteMode_Layout1(l) (((l)&0x3)<<18) 661 #define PM3FBWriteMode_Layout1(l) (((l) & 0x3) << 18)
684 #define PM3FBWriteMode_Layout2(l) (((l)&0x3)<<20) 662 #define PM3FBWriteMode_Layout2(l) (((l) & 0x3) << 20)
685 #define PM3FBWriteMode_Layout3(l) (((l)&0x3)<<22) 663 #define PM3FBWriteMode_Layout3(l) (((l) & 0x3) << 22)
686 #define PM3FBWriteMode_Origin0 1<<24 664 #define PM3FBWriteMode_Origin0 (1 << 24)
687 #define PM3FBWriteMode_Origin1 1<<25 665 #define PM3FBWriteMode_Origin1 (1 << 25)
688 #define PM3FBWriteMode_Origin2 1<<26 666 #define PM3FBWriteMode_Origin2 (1 << 26)
689 #define PM3FBWriteMode_Origin3 1<<27 667 #define PM3FBWriteMode_Origin3 (1 << 27)
690#define PM3ForegroundColor 0xb0c0 668#define PM3ForegroundColor 0xb0c0
691/* ... */ 669/* ... */
692#define PM3GIDMode 0xb538 670#define PM3GIDMode 0xb538
@@ -701,55 +679,55 @@
701#define PM3LBDestReadMode 0xb500 679#define PM3LBDestReadMode 0xb500
702#define PM3LBDestReadModeAnd 0xb580 680#define PM3LBDestReadModeAnd 0xb580
703#define PM3LBDestReadModeOr 0xb588 681#define PM3LBDestReadModeOr 0xb588
704 #define PM3LBDestReadMode_Disable 0<<0 682 #define PM3LBDestReadMode_Disable (0 << 0)
705 #define PM3LBDestReadMode_Enable 1<<0 683 #define PM3LBDestReadMode_Enable (1 << 0)
706 #define PM3LBDestReadMode_StripePitch(p) (((p)&0x7)<<2) 684 #define PM3LBDestReadMode_StripePitch(p) (((p) & 0x7) << 2)
707 #define PM3LBDestReadMode_StripeHeight(h) (((h)&0x7)<<5) 685 #define PM3LBDestReadMode_StripeHeight(h) (((h) & 0x7) << 5)
708 #define PM3LBDestReadMode_Layout 1<<8 686 #define PM3LBDestReadMode_Layout (1 << 8)
709 #define PM3LBDestReadMode_Origin 1<<9 687 #define PM3LBDestReadMode_Origin (1 << 9)
710 #define PM3LBDestReadMode_UserReadEnables 1<<10 688 #define PM3LBDestReadMode_UserReadEnables (1 << 10)
711 #define PM3LBDestReadMode_Packed16 1<<11 689 #define PM3LBDestReadMode_Packed16 (1 << 11)
712 #define PM3LBDestReadMode_Width(w) (((w)&0xfff)<<12) 690 #define PM3LBDestReadMode_Width(w) (((w) & 0xfff) << 12)
713#define PM3LBReadFormat 0x8888 691#define PM3LBReadFormat 0x8888
714 #define PM3LBReadFormat_DepthWidth(w) (((w)&0x3)<<0) 692 #define PM3LBReadFormat_DepthWidth(w) (((w) & 0x3) << 0)
715 #define PM3LBReadFormat_StencilWidth(w) (((w)&0xf)<<2) 693 #define PM3LBReadFormat_StencilWidth(w) (((w) & 0xf) << 2)
716 #define PM3LBReadFormat_StencilPosition(p) (((p)&0x1f)<<6) 694 #define PM3LBReadFormat_StencilPosition(p) (((p) & 0x1f) << 6)
717 #define PM3LBReadFormat_FCPWidth(w) (((w)&0xf)<<11) 695 #define PM3LBReadFormat_FCPWidth(w) (((w) & 0xf) << 11)
718 #define PM3LBReadFormat_FCPPosition(p) (((p)&0x1f)<<15) 696 #define PM3LBReadFormat_FCPPosition(p) (((p) & 0x1f) << 15)
719 #define PM3LBReadFormat_GIDWidth(w) (((w)&0x7)<<20) 697 #define PM3LBReadFormat_GIDWidth(w) (((w) & 0x7) << 20)
720 #define PM3LBReadFormat_GIDPosition(p) (((p)&0x1f)<<23) 698 #define PM3LBReadFormat_GIDPosition(p) (((p) & 0x1f) << 23)
721#define PM3LBSourceReadBufferAddr 0xb528 699#define PM3LBSourceReadBufferAddr 0xb528
722#define PM3LBSourceReadBufferOffset 0xb530 700#define PM3LBSourceReadBufferOffset 0xb530
723#define PM3LBSourceReadMode 0xb520 701#define PM3LBSourceReadMode 0xb520
724#define PM3LBSourceReadModeAnd 0xb5a0 702#define PM3LBSourceReadModeAnd 0xb5a0
725#define PM3LBSourceReadModeOr 0xb5a8 703#define PM3LBSourceReadModeOr 0xb5a8
726 #define PM3LBSourceReadMode_Enable 1<<0 704 #define PM3LBSourceReadMode_Enable (1 << 0)
727 #define PM3LBSourceReadMode_StripePitch(p) (((p)&0x7)<<2) 705 #define PM3LBSourceReadMode_StripePitch(p) (((p) & 0x7) << 2)
728 #define PM3LBSourceReadMode_StripeHeight(h) (((h)&0x7)<<5) 706 #define PM3LBSourceReadMode_StripeHeight(h) (((h) & 0x7) << 5)
729 #define PM3LBSourceReadMode_Layout 1<<8 707 #define PM3LBSourceReadMode_Layout (1 << 8)
730 #define PM3LBSourceReadMode_Origin 1<<9 708 #define PM3LBSourceReadMode_Origin (1 << 9)
731 #define PM3LBSourceReadMode_Packed16 1<<10 709 #define PM3LBSourceReadMode_Packed16 (1 << 10)
732 #define PM3LBSourceReadMode_Width(w) (((w)&0xfff)<<11) 710 #define PM3LBSourceReadMode_Width(w) (((w) & 0xfff) << 11)
733#define PM3LBStencil 0x88a8 711#define PM3LBStencil 0x88a8
734#define PM3LBWriteBufferAddr 0xb540 712#define PM3LBWriteBufferAddr 0xb540
735#define PM3LBWriteBufferOffset 0xb548 713#define PM3LBWriteBufferOffset 0xb548
736#define PM3LBWriteFormat 0x88c8 714#define PM3LBWriteFormat 0x88c8
737 #define PM3LBWriteFormat_DepthWidth(w) (((w)&0x3)<<0) 715 #define PM3LBWriteFormat_DepthWidth(w) (((w) & 0x3) << 0)
738 #define PM3LBWriteFormat_StencilWidth(w) (((w)&0xf)<<2) 716 #define PM3LBWriteFormat_StencilWidth(w) (((w) & 0xf) << 2)
739 #define PM3LBWriteFormat_StencilPosition(p) (((p)&0x1f)<<6) 717 #define PM3LBWriteFormat_StencilPosition(p) (((p) & 0x1f) << 6)
740 #define PM3LBWriteFormat_GIDWidth(w) (((w)&0x7)<<20) 718 #define PM3LBWriteFormat_GIDWidth(w) (((w) & 0x7) << 20)
741 #define PM3LBWriteFormat_GIDPosition(p) (((p)&0x1f)<<23) 719 #define PM3LBWriteFormat_GIDPosition(p) (((p) & 0x1f) << 23)
742#define PM3LBWriteMode 0x88c0 720#define PM3LBWriteMode 0x88c0
743#define PM3LBWriteModeAnd 0xac80 721#define PM3LBWriteModeAnd 0xac80
744#define PM3LBWriteModeOr 0xac88 722#define PM3LBWriteModeOr 0xac88
745 #define PM3LBWriteMode_WriteDisable 0<<0 723 #define PM3LBWriteMode_WriteDisable (0 << 0)
746 #define PM3LBWriteMode_WriteEnable 1<<0 724 #define PM3LBWriteMode_WriteEnable (1 << 0)
747 #define PM3LBWriteMode_StripePitch(p) (((p)&0x7)<<3) 725 #define PM3LBWriteMode_StripePitch(p) (((p) & 0x7) << 3)
748 #define PM3LBWriteMode_StripeHeight(h) (((h)&0x7)<<6) 726 #define PM3LBWriteMode_StripeHeight(h) (((h) & 0x7) << 6)
749 #define PM3LBWriteMode_Layout 1<<9 727 #define PM3LBWriteMode_Layout (1 << 9)
750 #define PM3LBWriteMode_Origin 1<<10 728 #define PM3LBWriteMode_Origin (1 << 10)
751 #define PM3LBWriteMode_Packed16 1<<11 729 #define PM3LBWriteMode_Packed16 (1 << 11)
752 #define PM3LBWriteMode_Width(w) (((w)&0xfff)<<12) 730 #define PM3LBWriteMode_Width(w) (((w) & 0xfff) << 12)
753/* ... */ 731/* ... */
754#define PM3LineStippleMode 0x81a8 732#define PM3LineStippleMode 0x81a8
755#define PM3LineStippleModeAnd 0xabc0 733#define PM3LineStippleModeAnd 0xabc0
@@ -759,19 +737,16 @@
759#define PM3LogicalOpMode 0x8828 737#define PM3LogicalOpMode 0x8828
760#define PM3LogicalOpModeAnd 0xace0 738#define PM3LogicalOpModeAnd 0xace0
761#define PM3LogicalOpModeOr 0xace8 739#define PM3LogicalOpModeOr 0xace8
762 #define PM3LogicalOpMode_Disable (0<<0) 740 #define PM3LogicalOpMode_Disable (0 << 0)
763 #define PM3LogicalOpMode_Enable (1<<0) 741 #define PM3LogicalOpMode_Enable (1 << 0)
764 #define PM3LogicalOpMode_LogicOp(op) (((op)&0xf)<<1) 742 #define PM3LogicalOpMode_LogicOp(op) (((op) & 0xf) << 1)
765 #define PM3LogicalOpMode_UseConstantWriteData_Disable (0<<5) 743 #define PM3LogicalOpMode_UseConstantWriteData_Disable (0 << 5)
766 #define PM3LogicalOpMode_UseConstantWriteData_Enable (1<<5) 744 #define PM3LogicalOpMode_UseConstantWriteData_Enable (1 << 5)
767 #define PM3LogicalOpMode_Background_Disable (0<<6) 745 #define PM3LogicalOpMode_Background_Disable (0 << 6)
768 #define PM3LogicalOpMode_Background_Enable (1<<6) 746 #define PM3LogicalOpMode_Background_Enable (1 << 6)
769 #define PM3LogicalOpMode_Background_LogicOp(op) (((op)&0xf)<<7) 747 #define PM3LogicalOpMode_Background_LogicOp(op) (((op) & 0xf) << 7)
770 #define PM3LogicalOpMode_UseConstantSource_Disable (0<<11) 748 #define PM3LogicalOpMode_UseConstantSource_Disable (0 << 11)
771 #define PM3LogicalOpMode_UseConstantSource_Enable (1<<11) 749 #define PM3LogicalOpMode_UseConstantSource_Enable (1 << 11)
772
773/* ... */
774#define PM3LUT 0x8e80
775/* ... */ 750/* ... */
776#define PM3LUT 0x8e80 751#define PM3LUT 0x8e80
777#define PM3LUTAddress 0x84d0 752#define PM3LUTAddress 0x84d0
@@ -783,75 +758,74 @@
783#define PM3LUTTransfer 0x84d8 758#define PM3LUTTransfer 0x84d8
784/* ... */ 759/* ... */
785#define PM3PixelSize 0x80c0 760#define PM3PixelSize 0x80c0
786 #define PM3PixelSize_GLOBAL_32BIT (0<<0) 761 #define PM3PixelSize_GLOBAL_32BIT (0 << 0)
787 #define PM3PixelSize_GLOBAL_16BIT (1<<0) 762 #define PM3PixelSize_GLOBAL_16BIT (1 << 0)
788 #define PM3PixelSize_GLOBAL_8BIT (2<<0) 763 #define PM3PixelSize_GLOBAL_8BIT (2 << 0)
789 #define PM3PixelSize_RASTERIZER_32BIT (0<<2) 764 #define PM3PixelSize_RASTERIZER_32BIT (0 << 2)
790 #define PM3PixelSize_RASTERIZER_16BIT (1<<2) 765 #define PM3PixelSize_RASTERIZER_16BIT (1 << 2)
791 #define PM3PixelSize_RASTERIZER_8BIT (2<<2) 766 #define PM3PixelSize_RASTERIZER_8BIT (2 << 2)
792 #define PM3PixelSize_SCISSOR_AND_STIPPLE_32BIT (0<<4) 767 #define PM3PixelSize_SCISSOR_AND_STIPPLE_32BIT (0 << 4)
793 #define PM3PixelSize_SCISSOR_AND_STIPPLE_16BIT (1<<4) 768 #define PM3PixelSize_SCISSOR_AND_STIPPLE_16BIT (1 << 4)
794 #define PM3PixelSize_SCISSOR_AND_STIPPLE_8BIT (2<<4) 769 #define PM3PixelSize_SCISSOR_AND_STIPPLE_8BIT (2 << 4)
795 #define PM3PixelSize_TEXTURE_32BIT (0<<6) 770 #define PM3PixelSize_TEXTURE_32BIT (0 << 6)
796 #define PM3PixelSize_TEXTURE_16BIT (1<<6) 771 #define PM3PixelSize_TEXTURE_16BIT (1 << 6)
797 #define PM3PixelSize_TEXTURE_8BIT (2<<6) 772 #define PM3PixelSize_TEXTURE_8BIT (2 << 6)
798 #define PM3PixelSize_LUT_32BIT (0<<8) 773 #define PM3PixelSize_LUT_32BIT (0 << 8)
799 #define PM3PixelSize_LUT_16BIT (1<<8) 774 #define PM3PixelSize_LUT_16BIT (1 << 8)
800 #define PM3PixelSize_LUT_8BIT (2<<8) 775 #define PM3PixelSize_LUT_8BIT (2 << 8)
801 #define PM3PixelSize_FRAMEBUFFER_32BIT (0<<10) 776 #define PM3PixelSize_FRAMEBUFFER_32BIT (0 << 10)
802 #define PM3PixelSize_FRAMEBUFFER_16BIT (1<<10) 777 #define PM3PixelSize_FRAMEBUFFER_16BIT (1 << 10)
803 #define PM3PixelSize_FRAMEBUFFER_8BIT (2<<10) 778 #define PM3PixelSize_FRAMEBUFFER_8BIT (2 << 10)
804 #define PM3PixelSize_LOGICAL_OP_32BIT (0<<12) 779 #define PM3PixelSize_LOGICAL_OP_32BIT (0 << 12)
805 #define PM3PixelSize_LOGICAL_OP_16BIT (1<<12) 780 #define PM3PixelSize_LOGICAL_OP_16BIT (1 << 12)
806 #define PM3PixelSize_LOGICAL_OP_8BIT (2<<12) 781 #define PM3PixelSize_LOGICAL_OP_8BIT (2 << 12)
807 #define PM3PixelSize_LOCALBUFFER_32BIT (0<<14) 782 #define PM3PixelSize_LOCALBUFFER_32BIT (0 << 14)
808 #define PM3PixelSize_LOCALBUFFER_16BIT (1<<14) 783 #define PM3PixelSize_LOCALBUFFER_16BIT (1 << 14)
809 #define PM3PixelSize_LOCALBUFFER_8BIT (2<<14) 784 #define PM3PixelSize_LOCALBUFFER_8BIT (2 << 14)
810 #define PM3PixelSize_SETUP_32BIT (0<<16) 785 #define PM3PixelSize_SETUP_32BIT (0 << 16)
811 #define PM3PixelSize_SETUP_16BIT (1<<16) 786 #define PM3PixelSize_SETUP_16BIT (1 << 16)
812 #define PM3PixelSize_SETUP_8BIT (2<<16) 787 #define PM3PixelSize_SETUP_8BIT (2 << 16)
813 #define PM3PixelSize_GLOBAL (0<<31) 788 #define PM3PixelSize_GLOBAL (0 << 31)
814 #define PM3PixelSize_INDIVIDUAL (1<<31) 789 #define PM3PixelSize_INDIVIDUAL (1 << 31)
815/* ... */ 790/* ... */
816#define PM3Render 0x8038 791#define PM3Render 0x8038
817 #define PM3Render_AreaStipple_Disable (0<<0) 792 #define PM3Render_AreaStipple_Disable (0 << 0)
818 #define PM3Render_AreaStipple_Enable (1<<0) 793 #define PM3Render_AreaStipple_Enable (1 << 0)
819 #define PM3Render_LineStipple_Disable (0<<1) 794 #define PM3Render_LineStipple_Disable (0 << 1)
820 #define PM3Render_LineStipple_Enable (1<<1) 795 #define PM3Render_LineStipple_Enable (1 << 1)
821 #define PM3Render_ResetLine_Disable (0<<2) 796 #define PM3Render_ResetLine_Disable (0 << 2)
822 #define PM3Render_ResetLine_Enable (1<<2) 797 #define PM3Render_ResetLine_Enable (1 << 2)
823 #define PM3Render_FastFill_Disable (0<<3) 798 #define PM3Render_FastFill_Disable (0 << 3)
824 #define PM3Render_FastFill_Enable (1<<3) 799 #define PM3Render_FastFill_Enable (1 << 3)
825 #define PM3Render_Primitive_Line (0<<6) 800 #define PM3Render_Primitive_Line (0 << 6)
826 #define PM3Render_Primitive_Trapezoid (1<<6) 801 #define PM3Render_Primitive_Trapezoid (1 << 6)
827 #define PM3Render_Primitive_Point (2<<6) 802 #define PM3Render_Primitive_Point (2 << 6)
828 #define PM3Render_Antialias_Disable (0<<8) 803 #define PM3Render_Antialias_Disable (0 << 8)
829 #define PM3Render_Antialias_Enable (1<<8) 804 #define PM3Render_Antialias_Enable (1 << 8)
830 #define PM3Render_Antialias_SubPixelRes_4x4 (0<<9) 805 #define PM3Render_Antialias_SubPixelRes_4x4 (0 << 9)
831 #define PM3Render_Antialias_SubPixelRes_8x8 (1<<9) 806 #define PM3Render_Antialias_SubPixelRes_8x8 (1 << 9)
832 #define PM3Render_UsePointTable_Disable (0<<10) 807 #define PM3Render_UsePointTable_Disable (0 << 10)
833 #define PM3Render_UsePointTable_Enable (1<<10) 808 #define PM3Render_UsePointTable_Enable (1 << 10)
834 #define PM3Render_SyncOnbitMask_Disable (0<<11) 809 #define PM3Render_SyncOnbitMask_Disable (0 << 11)
835 #define PM3Render_SyncOnBitMask_Enable (1<<11) 810 #define PM3Render_SyncOnBitMask_Enable (1 << 11)
836 #define PM3Render_SyncOnHostData_Disable (0<<12) 811 #define PM3Render_SyncOnHostData_Disable (0 << 12)
837 #define PM3Render_SyncOnHostData_Enable (1<<12) 812 #define PM3Render_SyncOnHostData_Enable (1 << 12)
838 #define PM3Render_Texture_Disable (0<<13) 813 #define PM3Render_Texture_Disable (0 << 13)
839 #define PM3Render_Texture_Enable (1<<13) 814 #define PM3Render_Texture_Enable (1 << 13)
840 #define PM3Render_Fog_Disable (0<<14) 815 #define PM3Render_Fog_Disable (0 << 14)
841 #define PM3Render_Fog_Enable (1<<14) 816 #define PM3Render_Fog_Enable (1 << 14)
842 #define PM3Render_Coverage_Disable (0<<15) 817 #define PM3Render_Coverage_Disable (0 << 15)
843 #define PM3Render_Coverage_Enable (1<<15) 818 #define PM3Render_Coverage_Enable (1 << 15)
844 #define PM3Render_SubPixelCorrection_Disable (0<<16) 819 #define PM3Render_SubPixelCorrection_Disable (0 << 16)
845 #define PM3Render_SubPixelCorrection_Enable (1<<16) 820 #define PM3Render_SubPixelCorrection_Enable (1 << 16)
846 #define PM3Render_SpanOperation_Disable (0<<18) 821 #define PM3Render_SpanOperation_Disable (0 << 18)
847 #define PM3Render_SpanOperation_Enable (1<<18) 822 #define PM3Render_SpanOperation_Enable (1 << 18)
848 #define PM3Render_FBSourceRead_Disable (0<<27) 823 #define PM3Render_FBSourceRead_Disable (0 << 27)
849 #define PM3Render_FBSourceRead_Enable (1<<27) 824 #define PM3Render_FBSourceRead_Enable (1 << 27)
850#define PM3RasterizerMode 0x80a0 825#define PM3RasterizerMode 0x80a0
851#define PM3RasterizerModeAnd 0xaba0 826#define PM3RasterizerModeAnd 0xaba0
852#define PM3RasterizerModeOr 0xabb8 827#define PM3RasterizerModeOr 0xaba8
853#define PM3RectangleHeight 0x94e0 828#define PM3RectangleHeight 0x94e0
854#define PM3Render 0x8038
855#define PM3RepeatLine 0x9328 829#define PM3RepeatLine 0x9328
856#define PM3ResetPickResult 0x8c20 830#define PM3ResetPickResult 0x8c20
857#define PM3RLEMask 0x8c48 831#define PM3RLEMask 0x8c48
@@ -918,31 +892,31 @@
918#define PM3TextureIndexMode1And 0xb3d0 892#define PM3TextureIndexMode1And 0xb3d0
919#define PM3TextureIndexMode1Or 0xb3d8 893#define PM3TextureIndexMode1Or 0xb3d8
920/* ... */ 894/* ... */
921#define PM3TextureMapSize 0xb428 895#define PM3TextureMapSize 0xb428
922#define PM3TextureMapWidth0 0x8580 896#define PM3TextureMapWidth0 0x8580
923#define PM3TextureMapWidth1 0x8588 897#define PM3TextureMapWidth1 0x8588
924 #define PM3TextureMapWidth_Width(w) ((w&0xfff)<<0) 898 #define PM3TextureMapWidth_Width(w) (((w) & 0xfff) << 0)
925 #define PM3TextureMapWidth_BorderLayout (1<<12) 899 #define PM3TextureMapWidth_BorderLayout (1 << 12)
926 #define PM3TextureMapWidth_Layout_Linear (0<<13) 900 #define PM3TextureMapWidth_Layout_Linear (0 << 13)
927 #define PM3TextureMapWidth_Layout_Patch64 (1<<13) 901 #define PM3TextureMapWidth_Layout_Patch64 (1 << 13)
928 #define PM3TextureMapWidth_Layout_Patch32_2 (2<<13) 902 #define PM3TextureMapWidth_Layout_Patch32_2 (2 << 13)
929 #define PM3TextureMapWidth_Layout_Patch2 (3<<13) 903 #define PM3TextureMapWidth_Layout_Patch2 (3 << 13)
930 #define PM3TextureMapWidth_HostTexture (1<<15) 904 #define PM3TextureMapWidth_HostTexture (1 << 15)
931#define PM3TextureReadMode0 0xb400 905#define PM3TextureReadMode0 0xb400
932#define PM3TextureReadMode0And 0xac30 906#define PM3TextureReadMode0And 0xac30
933#define PM3TextureReadMode0Or 0xac38 907#define PM3TextureReadMode0Or 0xac38
934#define PM3TextureReadMode1 0xb408 908#define PM3TextureReadMode1 0xb408
935#define PM3TextureReadMode1And 0xad40 909#define PM3TextureReadMode1And 0xad40
936#define PM3TextureReadMode1Or 0xad48 910#define PM3TextureReadMode1Or 0xad48
937/* ... */ 911/* ... */
938#define PM3WaitForCompletion 0x80b8 912#define PM3WaitForCompletion 0x80b8
939#define PM3Window 0x8980 913#define PM3Window 0x8980
940 #define PM3Window_ForceLBUpdate 1<<3 914 #define PM3Window_ForceLBUpdate (1 << 3)
941 #define PM3Window_LBUpdateSource 1<<4 915 #define PM3Window_LBUpdateSource (1 << 4)
942 #define PM3Window_FrameCount(c) (((c)&0xff)<<9) 916 #define PM3Window_FrameCount(c) (((c) & 0xff) << 9)
943 #define PM3Window_StencilFCP 1<<17 917 #define PM3Window_StencilFCP (1 << 17)
944 #define PM3Window_DepthFCP 1<<18 918 #define PM3Window_DepthFCP (1 << 18)
945 #define PM3Window_OverrideWriteFiltering 1<<19 919 #define PM3Window_OverrideWriteFiltering (1 << 19)
946#define PM3WindowAnd 0xab80 920#define PM3WindowAnd 0xab80
947#define PM3WindowOr 0xab88 921#define PM3WindowOr 0xab88
948#define PM3WindowOrigin 0x81c8 922#define PM3WindowOrigin 0x81c8
@@ -957,169 +931,131 @@
957 931
958 932
959/********************************************** 933/**********************************************
960* GLINT Permedia3 2D setup Unit * 934* GLINT Permedia3 2D setup Unit *
961***********************************************/ 935***********************************************/
962#define PM3Config2D 0xb618 936#define PM3Config2D 0xb618
963 #define PM3Config2D_OpaqueSpan 1<<0 937 #define PM3Config2D_OpaqueSpan (1 << 0)
964 #define PM3Config2D_MultiRXBlit 1<<1 938 #define PM3Config2D_MultiRXBlit (1 << 1)
965 #define PM3Config2D_UserScissorEnable 1<<2 939 #define PM3Config2D_UserScissorEnable (1 << 2)
966 #define PM3Config2D_FBDestReadEnable 1<<3 940 #define PM3Config2D_FBDestReadEnable (1 << 3)
967 #define PM3Config2D_AlphaBlendEnable 1<<4 941 #define PM3Config2D_AlphaBlendEnable (1 << 4)
968 #define PM3Config2D_DitherEnable 1<<5 942 #define PM3Config2D_DitherEnable (1 << 5)
969 #define PM3Config2D_ForegroundROPEnable 1<<6 943 #define PM3Config2D_ForegroundROPEnable (1 << 6)
970 #define PM3Config2D_ForegroundROP(rop) (((rop)&0xf)<<7) 944 #define PM3Config2D_ForegroundROP(rop) (((rop) & 0xf) << 7)
971 #define PM3Config2D_BackgroundROPEnable 1<<11 945 #define PM3Config2D_BackgroundROPEnable (1 << 11)
972 #define PM3Config2D_BackgroundROP(rop) (((rop)&0xf)<<12) 946 #define PM3Config2D_BackgroundROP(rop) (((rop) & 0xf) << 12)
973 #define PM3Config2D_UseConstantSource 1<<16 947 #define PM3Config2D_UseConstantSource (1 << 16)
974 #define PM3Config2D_FBWriteEnable 1<<17 948 #define PM3Config2D_FBWriteEnable (1 << 17)
975 #define PM3Config2D_Blocking 1<<18 949 #define PM3Config2D_Blocking (1 << 18)
976 #define PM3Config2D_ExternalSourceData 1<<19 950 #define PM3Config2D_ExternalSourceData (1 << 19)
977 #define PM3Config2D_LUTModeEnable 1<<20 951 #define PM3Config2D_LUTModeEnable (1 << 20)
978#define PM3DownloadGlyphwidth 0xb658 952#define PM3DownloadGlyphwidth 0xb658
979 #define PM3DownloadGlyphwidth_GlyphWidth(gw) ((gw)&0xffff) 953 #define PM3DownloadGlyphwidth_GlyphWidth(gw) ((gw) & 0xffff)
980#define PM3DownloadTarget 0xb650 954#define PM3DownloadTarget 0xb650
981 #define PM3DownloadTarget_TagName(tag) ((tag)&0x1fff) 955 #define PM3DownloadTarget_TagName(tag) ((tag) & 0x1fff)
982#define PM3GlyphData 0xb660 956#define PM3GlyphData 0xb660
983#define PM3GlyphPosition 0xb608 957#define PM3GlyphPosition 0xb608
984 #define PM3GlyphPosition_XOffset(x) ((x)&0xffff) 958 #define PM3GlyphPosition_XOffset(x) ((x) & 0xffff)
985 #define PM3GlyphPosition_YOffset(y) (((y)&0xffff)<<16) 959 #define PM3GlyphPosition_YOffset(y) (((y) & 0xffff) << 16)
986#define PM3Packed4Pixels 0xb668 960#define PM3Packed4Pixels 0xb668
987#define PM3Packed8Pixels 0xb630 961#define PM3Packed8Pixels 0xb630
988#define PM3Packed16Pixels 0xb638 962#define PM3Packed16Pixels 0xb638
989#define PM3RectanglePosition 0xb600 963#define PM3RectanglePosition 0xb600
990 #define PM3RectanglePosition_XOffset(x) ((x)&0xffff) 964 #define PM3RectanglePosition_XOffset(x) ((x) & 0xffff)
991 #define PM3RectanglePosition_YOffset(y) (((y)&0xffff)<<16) 965 #define PM3RectanglePosition_YOffset(y) (((y) & 0xffff) << 16)
992#define PM3Render2D 0xb640 966#define PM3Render2D 0xb640
993 #define PM3Render2D_Width(w) ((w)&0x0fff) 967 #define PM3Render2D_Width(w) ((w) & 0x0fff)
994 #define PM3Render2D_Operation_Normal 0<<12 968 #define PM3Render2D_Operation_Normal (0 << 12)
995 #define PM3Render2D_Operation_SyncOnHostData 1<<12 969 #define PM3Render2D_Operation_SyncOnHostData (1 << 12)
996 #define PM3Render2D_Operation_SyncOnBitMask 2<<12 970 #define PM3Render2D_Operation_SyncOnBitMask (2 << 12)
997 #define PM3Render2D_Operation_PatchOrderRendering 3<<12 971 #define PM3Render2D_Operation_PatchOrderRendering (3 << 12)
998 #define PM3Render2D_FBSourceReadEnable 1<<14 972 #define PM3Render2D_FBSourceReadEnable (1 << 14)
999 #define PM3Render2D_SpanOperation 1<<15 973 #define PM3Render2D_SpanOperation (1 << 15)
1000 #define PM3Render2D_Height(h) (((h)&0x0fff)<<16) 974 #define PM3Render2D_Height(h) (((h) & 0x0fff) << 16)
1001 #define PM3Render2D_XPositive 1<<28 975 #define PM3Render2D_XPositive (1 << 28)
1002 #define PM3Render2D_YPositive 1<<29 976 #define PM3Render2D_YPositive (1 << 29)
1003 #define PM3Render2D_AreaStippleEnable 1<<30 977 #define PM3Render2D_AreaStippleEnable (1 << 30)
1004 #define PM3Render2D_TextureEnable 1<<31 978 #define PM3Render2D_TextureEnable (1 << 31)
1005#define PM3Render2DGlyph 0xb648 979#define PM3Render2DGlyph 0xb648
1006 #define PM3Render2DGlyph_Width(w) ((w)&0x7f) 980 #define PM3Render2DGlyph_Width(w) ((w) & 0x7f)
1007 #define PM3Render2DGlyph_Height(h) (((h)&0x7f)<<7) 981 #define PM3Render2DGlyph_Height(h) (((h) & 0x7f) << 7)
1008 #define PM3Render2DGlyph_XOffset(x) (((x)&0x1ff)<<14) 982 #define PM3Render2DGlyph_XOffset(x) (((x) & 0x1ff) << 14)
1009 #define PM3Render2DGlyph_YOffset(y) (((y)&0x1ff)<<23) 983 #define PM3Render2DGlyph_YOffset(y) (((y) & 0x1ff) << 23)
1010#define PM3RenderPatchOffset 0xb610 984#define PM3RenderPatchOffset 0xb610
1011 #define PM3RenderPatchOffset_XOffset(x) ((x)&0xffff) 985 #define PM3RenderPatchOffset_XOffset(x) ((x) & 0xffff)
1012 #define PM3RenderPatchOffset_YOffset(y) (((y)&0xffff)<<16) 986 #define PM3RenderPatchOffset_YOffset(y) (((y) & 0xffff) << 16)
1013#define PM3RLCount 0xb678 987#define PM3RLCount 0xb678
1014 #define PM3RLCount_Count(c) ((c)&0x0fff) 988 #define PM3RLCount_Count(c) ((c) & 0x0fff)
1015#define PM3RLData 0xb670 989#define PM3RLData 0xb670
1016 990
1017/********************************************** 991/**********************************************
1018* GLINT Permedia3 Alias Register * 992* GLINT Permedia3 Alias Register *
1019***********************************************/ 993***********************************************/
1020#define PM3FillBackgroundColor 0x8330 994#define PM3FillBackgroundColor 0x8330
1021#define PM3FillConfig2D0 0x8338 995#define PM3FillConfig2D0 0x8338
1022#define PM3FillConfig2D1 0x8360 996#define PM3FillConfig2D1 0x8360
1023 #define PM3FillConfig2D_OpaqueSpan 1<<0 997 #define PM3FillConfig2D_OpaqueSpan (1 << 0)
1024 #define PM3FillConfig2D_MultiRXBlit 1<<1 998 #define PM3FillConfig2D_MultiRXBlit (1 << 1)
1025 #define PM3FillConfig2D_UserScissorEnable 1<<2 999 #define PM3FillConfig2D_UserScissorEnable (1 << 2)
1026 #define PM3FillConfig2D_FBDestReadEnable 1<<3 1000 #define PM3FillConfig2D_FBDestReadEnable (1 << 3)
1027 #define PM3FillConfig2D_AlphaBlendEnable 1<<4 1001 #define PM3FillConfig2D_AlphaBlendEnable (1 << 4)
1028 #define PM3FillConfig2D_DitherEnable 1<<5 1002 #define PM3FillConfig2D_DitherEnable (1 << 5)
1029 #define PM3FillConfig2D_ForegroundROPEnable 1<<6 1003 #define PM3FillConfig2D_ForegroundROPEnable (1 << 6)
1030 #define PM3FillConfig2D_ForegroundROP(rop) (((rop)&0xf)<<7) 1004 #define PM3FillConfig2D_ForegroundROP(rop) (((rop) & 0xf) << 7)
1031 #define PM3FillConfig2D_BackgroundROPEnable 1<<11 1005 #define PM3FillConfig2D_BackgroundROPEnable (1 << 11)
1032 #define PM3FillConfig2D_BackgroundROP(rop) (((rop)&0xf)<<12) 1006 #define PM3FillConfig2D_BackgroundROP(rop) (((rop) & 0xf) << 12)
1033 #define PM3FillConfig2D_UseConstantSource 1<<16 1007 #define PM3FillConfig2D_UseConstantSource (1 << 16)
1034 #define PM3FillConfig2D_FBWriteEnable 1<<17 1008 #define PM3FillConfig2D_FBWriteEnable (1 << 17)
1035 #define PM3FillConfig2D_Blocking 1<<18 1009 #define PM3FillConfig2D_Blocking (1 << 18)
1036 #define PM3FillConfig2D_ExternalSourceData 1<<19 1010 #define PM3FillConfig2D_ExternalSourceData (1 << 19)
1037 #define PM3FillConfig2D_LUTModeEnable 1<<20 1011 #define PM3FillConfig2D_LUTModeEnable (1 << 20)
1038#define PM3FillFBDestReadBufferAddr 0x8310 1012#define PM3FillFBDestReadBufferAddr 0x8310
1039#define PM3FillFBSourceReadBufferAddr 0x8308 1013#define PM3FillFBSourceReadBufferAddr 0x8308
1040#define PM3FillFBSourceReadBufferOffset 0x8340 1014#define PM3FillFBSourceReadBufferOffset 0x8340
1041 #define PM3FillFBSourceReadBufferOffset_XOffset(x) ((x)&0xffff) 1015 #define PM3FillFBSourceReadBufferOffset_XOffset(x) ((x) & 0xffff)
1042 #define PM3FillFBSourceReadBufferOffset_YOffset(y) (((y)&0xffff)<<16) 1016 #define PM3FillFBSourceReadBufferOffset_YOffset(y) \
1043#define PM3FillFBWriteBufferAddr 0x8300 1017 (((y) & 0xffff) << 16)
1044#define PM3FillForegroundColor0 0x8328 1018#define PM3FillFBWriteBufferAddr 0x8300
1045#define PM3FillForegroundColor1 0x8358 1019#define PM3FillForegroundColor0 0x8328
1046#define PM3FillGlyphPosition 0x8368 1020#define PM3FillForegroundColor1 0x8358
1047 #define PM3FillGlyphPosition_XOffset(x) ((x)&0xffff) 1021#define PM3FillGlyphPosition 0x8368
1048 #define PM3FillGlyphPosition_YOffset(y) (((y)&0xffff)<<16) 1022 #define PM3FillGlyphPosition_XOffset(x) ((x) & 0xffff)
1049#define PM3FillRectanglePosition 0x8348 1023 #define PM3FillGlyphPosition_YOffset(y) (((y) & 0xffff) << 16)
1050 #define PM3FillRectanglePosition_XOffset(x) ((x)&0xffff) 1024#define PM3FillRectanglePosition 0x8348
1051 #define PM3FillRectanglePosition_YOffset(y) (((y)&0xffff)<<16) 1025 #define PM3FillRectanglePosition_XOffset(x) ((x) & 0xffff)
1026 #define PM3FillRectanglePosition_YOffset(y) (((y) & 0xffff) << 16)
1052 1027
1053#define PM3_REGS_SIZE 0x10000
1054#define PM3_MAX_PIXCLOCK 300000
1055/* a few more useful registers & regs value... */ 1028/* a few more useful registers & regs value... */
1056#define PM3Sync 0x8c40 1029#define PM3Sync 0x8c40
1057 #define PM3Sync_Tag 0x188 1030 #define PM3Sync_Tag 0x188
1058#define PM3FilterMode 0x8c00 1031#define PM3FilterMode 0x8c00
1059 #define PM3FilterModeSync 0x400 1032 #define PM3FilterModeSync 0x400
1060#define PM3OutputFifo 0x2000 1033#define PM3OutputFifo 0x2000
1061#define PM3StatisticMode 0x8c08 1034#define PM3StatisticMode 0x8c08
1062#define PM3AreaStippleMode 0x81a0 1035#define PM3AreaStippleMode 0x81a0
1063 #define AreaStipplePattern0 (0x8200) 1036#define AreaStipplePattern_indexed(i) (0x8200 + ((i) * 0x8))
1064 #define AreaStipplePattern1 (0x8208)
1065 #define AreaStipplePattern2 (0x8210)
1066 #define AreaStipplePattern3 (0x8218)
1067 #define AreaStipplePattern4 (0x8220)
1068 #define AreaStipplePattern5 (0x8228)
1069 #define AreaStipplePattern6 (0x8230)
1070 #define AreaStipplePattern7 (0x8238)
1071 #define AreaStipplePattern8 (0x8240)
1072 #define AreaStipplePattern9 (0x8248)
1073 #define AreaStipplePattern10 (0x8250)
1074 #define AreaStipplePattern11 (0x8258)
1075 #define AreaStipplePattern12 (0x8260)
1076 #define AreaStipplePattern13 (0x8268)
1077 #define AreaStipplePattern14 (0x8270)
1078 #define AreaStipplePattern15 (0x8278)
1079 #define AreaStipplePattern16 (0x8280)
1080 #define AreaStipplePattern17 (0x8288)
1081 #define AreaStipplePattern18 (0x8290)
1082 #define AreaStipplePattern19 (0x8298)
1083 #define AreaStipplePattern20 (0x82a0)
1084 #define AreaStipplePattern21 (0x82a8)
1085 #define AreaStipplePattern22 (0x82b0)
1086 #define AreaStipplePattern23 (0x82b8)
1087 #define AreaStipplePattern24 (0x82c0)
1088 #define AreaStipplePattern25 (0x82c8)
1089 #define AreaStipplePattern26 (0x82d0)
1090 #define AreaStipplePattern27 (0x82d8)
1091 #define AreaStipplePattern28 (0x82eo)
1092 #define AreaStipplePattern29 (0x82e8)
1093 #define AreaStipplePattern30 (0x82f0)
1094 #define AreaStipplePattern31 (0x82f8)
1095 #define AreaStipplePattern_indexed(i) (0x8200 + ((i) * 0x8))
1096 1037
1097#define PM3DepthMode 0x89a0 1038#define PM3DepthMode 0x89a0
1098#define PM3StencilMode 0x8988 1039#define PM3StencilMode 0x8988
1099#define PM3StencilData 0x8990 1040#define PM3StencilData 0x8990
1100#define PM3TextureReadMode 0x8670 1041#define PM3TextureReadMode 0x8670
1101#define PM3FogMode 0x8690 1042#define PM3FogMode 0x8690
1102#define PM3ChromaTestMode 0x8f18 1043#define PM3ChromaTestMode 0x8f18
1103#define PM3YUVMode 0x8f00 1044#define PM3YUVMode 0x8f00
1104#define PM3BitMaskPattern 0x8068 1045#define PM3BitMaskPattern 0x8068
1105 1046
1106/* ***************************** */ 1047/* ***************************** */
1107/* ***** pm3fb IOCTL const ***** */ 1048/* ***** pm3fb IOCTL const ***** */
1108/* ***************************** */ 1049/* ***************************** */
1109/* debug-only IOCTL */ 1050#define PM3FBIO_RESETCHIP 0x504D33FF /* 'PM3\377' */
1110#define PM3FBIO_CLEARMEMORY 0x504D3300 /* 'PM3\000' */
1111#define PM3FBIO_CLEARCMAP 0x504D3301 /* 'PM3\001' */
1112/* common use IOCTL */
1113#define PM3FBIO_RESETCHIP 0x504D33FF /* 'PM3\377' */
1114 1051
1115/* ***************************************** */ 1052/* ***************************************** */
1116/* ***** pm3fb useful define and macro ***** */ 1053/* ***** pm3fb useful define and macro ***** */
1117/* ***************************************** */ 1054/* ***************************************** */
1118 1055
1119/* max size of options */ 1056/* fifo size in chip */
1120#define PM3_OPTIONS_SIZE 256 1057#define PM3_FIFO_SIZE 120
1121 1058#define PM3_REGS_SIZE 0x10000
1122/* max size of font name */ 1059#define PM3_MAX_PIXCLOCK 300000
1123#define PM3_FONTNAME_SIZE 40
1124 1060
1125#endif /* PM3FB_H */ 1061#endif /* PM3FB_H */
diff --git a/include/video/tdfx.h b/include/video/tdfx.h
index c1cc94ba3fdd..05b63c2a5abc 100644
--- a/include/video/tdfx.h
+++ b/include/video/tdfx.h
@@ -2,140 +2,140 @@
2#define _TDFX_H 2#define _TDFX_H
3 3
4/* membase0 register offsets */ 4/* membase0 register offsets */
5#define STATUS 0x00 5#define STATUS 0x00
6#define PCIINIT0 0x04 6#define PCIINIT0 0x04
7#define SIPMONITOR 0x08 7#define SIPMONITOR 0x08
8#define LFBMEMORYCONFIG 0x0c 8#define LFBMEMORYCONFIG 0x0c
9#define MISCINIT0 0x10 9#define MISCINIT0 0x10
10#define MISCINIT1 0x14 10#define MISCINIT1 0x14
11#define DRAMINIT0 0x18 11#define DRAMINIT0 0x18
12#define DRAMINIT1 0x1c 12#define DRAMINIT1 0x1c
13#define AGPINIT 0x20 13#define AGPINIT 0x20
14#define TMUGBEINIT 0x24 14#define TMUGBEINIT 0x24
15#define VGAINIT0 0x28 15#define VGAINIT0 0x28
16#define VGAINIT1 0x2c 16#define VGAINIT1 0x2c
17#define DRAMCOMMAND 0x30 17#define DRAMCOMMAND 0x30
18#define DRAMDATA 0x34 18#define DRAMDATA 0x34
19/* reserved 0x38 */ 19/* reserved 0x38 */
20/* reserved 0x3c */ 20/* reserved 0x3c */
21#define PLLCTRL0 0x40 21#define PLLCTRL0 0x40
22#define PLLCTRL1 0x44 22#define PLLCTRL1 0x44
23#define PLLCTRL2 0x48 23#define PLLCTRL2 0x48
24#define DACMODE 0x4c 24#define DACMODE 0x4c
25#define DACADDR 0x50 25#define DACADDR 0x50
26#define DACDATA 0x54 26#define DACDATA 0x54
27#define RGBMAXDELTA 0x58 27#define RGBMAXDELTA 0x58
28#define VIDPROCCFG 0x5c 28#define VIDPROCCFG 0x5c
29#define HWCURPATADDR 0x60 29#define HWCURPATADDR 0x60
30#define HWCURLOC 0x64 30#define HWCURLOC 0x64
31#define HWCURC0 0x68 31#define HWCURC0 0x68
32#define HWCURC1 0x6c 32#define HWCURC1 0x6c
33#define VIDINFORMAT 0x70 33#define VIDINFORMAT 0x70
34#define VIDINSTATUS 0x74 34#define VIDINSTATUS 0x74
35#define VIDSERPARPORT 0x78 35#define VIDSERPARPORT 0x78
36#define VIDINXDELTA 0x7c 36#define VIDINXDELTA 0x7c
37#define VIDININITERR 0x80 37#define VIDININITERR 0x80
38#define VIDINYDELTA 0x84 38#define VIDINYDELTA 0x84
39#define VIDPIXBUFTHOLD 0x88 39#define VIDPIXBUFTHOLD 0x88
40#define VIDCHRMIN 0x8c 40#define VIDCHRMIN 0x8c
41#define VIDCHRMAX 0x90 41#define VIDCHRMAX 0x90
42#define VIDCURLIN 0x94 42#define VIDCURLIN 0x94
43#define VIDSCREENSIZE 0x98 43#define VIDSCREENSIZE 0x98
44#define VIDOVRSTARTCRD 0x9c 44#define VIDOVRSTARTCRD 0x9c
45#define VIDOVRENDCRD 0xa0 45#define VIDOVRENDCRD 0xa0
46#define VIDOVRDUDX 0xa4 46#define VIDOVRDUDX 0xa4
47#define VIDOVRDUDXOFF 0xa8 47#define VIDOVRDUDXOFF 0xa8
48#define VIDOVRDVDY 0xac 48#define VIDOVRDVDY 0xac
49/* ... */ 49/* ... */
50#define VIDOVRDVDYOFF 0xe0 50#define VIDOVRDVDYOFF 0xe0
51#define VIDDESKSTART 0xe4 51#define VIDDESKSTART 0xe4
52#define VIDDESKSTRIDE 0xe8 52#define VIDDESKSTRIDE 0xe8
53#define VIDINADDR0 0xec 53#define VIDINADDR0 0xec
54#define VIDINADDR1 0xf0 54#define VIDINADDR1 0xf0
55#define VIDINADDR2 0xf4 55#define VIDINADDR2 0xf4
56#define VIDINSTRIDE 0xf8 56#define VIDINSTRIDE 0xf8
57#define VIDCUROVRSTART 0xfc 57#define VIDCUROVRSTART 0xfc
58 58
59#define INTCTRL (0x00100000 + 0x04) 59#define INTCTRL (0x00100000 + 0x04)
60#define CLIP0MIN (0x00100000 + 0x08) 60#define CLIP0MIN (0x00100000 + 0x08)
61#define CLIP0MAX (0x00100000 + 0x0c) 61#define CLIP0MAX (0x00100000 + 0x0c)
62#define DSTBASE (0x00100000 + 0x10) 62#define DSTBASE (0x00100000 + 0x10)
63#define DSTFORMAT (0x00100000 + 0x14) 63#define DSTFORMAT (0x00100000 + 0x14)
64#define SRCBASE (0x00100000 + 0x34) 64#define SRCBASE (0x00100000 + 0x34)
65#define COMMANDEXTRA_2D (0x00100000 + 0x38) 65#define COMMANDEXTRA_2D (0x00100000 + 0x38)
66#define CLIP1MIN (0x00100000 + 0x4c) 66#define CLIP1MIN (0x00100000 + 0x4c)
67#define CLIP1MAX (0x00100000 + 0x50) 67#define CLIP1MAX (0x00100000 + 0x50)
68#define SRCFORMAT (0x00100000 + 0x54) 68#define SRCFORMAT (0x00100000 + 0x54)
69#define SRCSIZE (0x00100000 + 0x58) 69#define SRCSIZE (0x00100000 + 0x58)
70#define SRCXY (0x00100000 + 0x5c) 70#define SRCXY (0x00100000 + 0x5c)
71#define COLORBACK (0x00100000 + 0x60) 71#define COLORBACK (0x00100000 + 0x60)
72#define COLORFORE (0x00100000 + 0x64) 72#define COLORFORE (0x00100000 + 0x64)
73#define DSTSIZE (0x00100000 + 0x68) 73#define DSTSIZE (0x00100000 + 0x68)
74#define DSTXY (0x00100000 + 0x6c) 74#define DSTXY (0x00100000 + 0x6c)
75#define COMMAND_2D (0x00100000 + 0x70) 75#define COMMAND_2D (0x00100000 + 0x70)
76#define LAUNCH_2D (0x00100000 + 0x80) 76#define LAUNCH_2D (0x00100000 + 0x80)
77 77
78#define COMMAND_3D (0x00200000 + 0x120) 78#define COMMAND_3D (0x00200000 + 0x120)
79 79
80/* register bitfields (not all, only as needed) */ 80/* register bitfields (not all, only as needed) */
81 81
82#define BIT(x) (1UL << (x)) 82#define BIT(x) (1UL << (x))
83 83
84/* COMMAND_2D reg. values */ 84/* COMMAND_2D reg. values */
85#define TDFX_ROP_COPY 0xcc // src 85#define TDFX_ROP_COPY 0xcc /* src */
86#define TDFX_ROP_INVERT 0x55 // NOT dst 86#define TDFX_ROP_INVERT 0x55 /* NOT dst */
87#define TDFX_ROP_XOR 0x66 // src XOR dst 87#define TDFX_ROP_XOR 0x66 /* src XOR dst */
88 88
89#define AUTOINC_DSTX BIT(10) 89#define AUTOINC_DSTX BIT(10)
90#define AUTOINC_DSTY BIT(11) 90#define AUTOINC_DSTY BIT(11)
91#define COMMAND_2D_FILLRECT 0x05 91#define COMMAND_2D_FILLRECT 0x05
92#define COMMAND_2D_S2S_BITBLT 0x01 // screen to screen 92#define COMMAND_2D_S2S_BITBLT 0x01 /* screen to screen */
93#define COMMAND_2D_H2S_BITBLT 0x03 // host to screen 93#define COMMAND_2D_H2S_BITBLT 0x03 /* host to screen */
94 94
95#define COMMAND_3D_NOP 0x00 95#define COMMAND_3D_NOP 0x00
96#define STATUS_RETRACE BIT(6) 96#define STATUS_RETRACE BIT(6)
97#define STATUS_BUSY BIT(9) 97#define STATUS_BUSY BIT(9)
98#define MISCINIT1_CLUT_INV BIT(0) 98#define MISCINIT1_CLUT_INV BIT(0)
99#define MISCINIT1_2DBLOCK_DIS BIT(15) 99#define MISCINIT1_2DBLOCK_DIS BIT(15)
100#define DRAMINIT0_SGRAM_NUM BIT(26) 100#define DRAMINIT0_SGRAM_NUM BIT(26)
101#define DRAMINIT0_SGRAM_TYPE BIT(27) 101#define DRAMINIT0_SGRAM_TYPE BIT(27)
102#define DRAMINIT0_SGRAM_TYPE_MASK (BIT(27)|BIT(28)|BIT(29)) 102#define DRAMINIT0_SGRAM_TYPE_MASK (BIT(27) | BIT(28) | BIT(29))
103#define DRAMINIT0_SGRAM_TYPE_SHIFT 27 103#define DRAMINIT0_SGRAM_TYPE_SHIFT 27
104#define DRAMINIT1_MEM_SDRAM BIT(30) 104#define DRAMINIT1_MEM_SDRAM BIT(30)
105#define VGAINIT0_VGA_DISABLE BIT(0) 105#define VGAINIT0_VGA_DISABLE BIT(0)
106#define VGAINIT0_EXT_TIMING BIT(1) 106#define VGAINIT0_EXT_TIMING BIT(1)
107#define VGAINIT0_8BIT_DAC BIT(2) 107#define VGAINIT0_8BIT_DAC BIT(2)
108#define VGAINIT0_EXT_ENABLE BIT(6) 108#define VGAINIT0_EXT_ENABLE BIT(6)
109#define VGAINIT0_WAKEUP_3C3 BIT(8) 109#define VGAINIT0_WAKEUP_3C3 BIT(8)
110#define VGAINIT0_LEGACY_DISABLE BIT(9) 110#define VGAINIT0_LEGACY_DISABLE BIT(9)
111#define VGAINIT0_ALT_READBACK BIT(10) 111#define VGAINIT0_ALT_READBACK BIT(10)
112#define VGAINIT0_FAST_BLINK BIT(11) 112#define VGAINIT0_FAST_BLINK BIT(11)
113#define VGAINIT0_EXTSHIFTOUT BIT(12) 113#define VGAINIT0_EXTSHIFTOUT BIT(12)
114#define VGAINIT0_DECODE_3C6 BIT(13) 114#define VGAINIT0_DECODE_3C6 BIT(13)
115#define VGAINIT0_SGRAM_HBLANK_DISABLE BIT(22) 115#define VGAINIT0_SGRAM_HBLANK_DISABLE BIT(22)
116#define VGAINIT1_MASK 0x1fffff 116#define VGAINIT1_MASK 0x1fffff
117#define VIDCFG_VIDPROC_ENABLE BIT(0) 117#define VIDCFG_VIDPROC_ENABLE BIT(0)
118#define VIDCFG_CURS_X11 BIT(1) 118#define VIDCFG_CURS_X11 BIT(1)
119#define VIDCFG_INTERLACE BIT(3) 119#define VIDCFG_INTERLACE BIT(3)
120#define VIDCFG_HALF_MODE BIT(4) 120#define VIDCFG_HALF_MODE BIT(4)
121#define VIDCFG_DESK_ENABLE BIT(7) 121#define VIDCFG_DESK_ENABLE BIT(7)
122#define VIDCFG_CLUT_BYPASS BIT(10) 122#define VIDCFG_CLUT_BYPASS BIT(10)
123#define VIDCFG_2X BIT(26) 123#define VIDCFG_2X BIT(26)
124#define VIDCFG_HWCURSOR_ENABLE BIT(27) 124#define VIDCFG_HWCURSOR_ENABLE BIT(27)
125#define VIDCFG_PIXFMT_SHIFT 18 125#define VIDCFG_PIXFMT_SHIFT 18
126#define DACMODE_2X BIT(0) 126#define DACMODE_2X BIT(0)
127 127
128/* VGA rubbish, need to change this for multihead support */ 128/* VGA rubbish, need to change this for multihead support */
129#define MISC_W 0x3c2 129#define MISC_W 0x3c2
130#define MISC_R 0x3cc 130#define MISC_R 0x3cc
131#define SEQ_I 0x3c4 131#define SEQ_I 0x3c4
132#define SEQ_D 0x3c5 132#define SEQ_D 0x3c5
133#define CRT_I 0x3d4 133#define CRT_I 0x3d4
134#define CRT_D 0x3d5 134#define CRT_D 0x3d5
135#define ATT_IW 0x3c0 135#define ATT_IW 0x3c0
136#define IS1_R 0x3da 136#define IS1_R 0x3da
137#define GRA_I 0x3ce 137#define GRA_I 0x3ce
138#define GRA_D 0x3cf 138#define GRA_D 0x3cf
139 139
140#ifdef __KERNEL__ 140#ifdef __KERNEL__
141 141
@@ -143,9 +143,9 @@ struct banshee_reg {
143 /* VGA rubbish */ 143 /* VGA rubbish */
144 unsigned char att[21]; 144 unsigned char att[21];
145 unsigned char crt[25]; 145 unsigned char crt[25];
146 unsigned char gra[ 9]; 146 unsigned char gra[9];
147 unsigned char misc[1]; 147 unsigned char misc[1];
148 unsigned char seq[ 5]; 148 unsigned char seq[5];
149 149
150 /* Banshee extensions */ 150 /* Banshee extensions */
151 unsigned char ext[2]; 151 unsigned char ext[2];
@@ -167,8 +167,6 @@ struct banshee_reg {
167 unsigned long clip0max; 167 unsigned long clip0max;
168 unsigned long clip1min; 168 unsigned long clip1min;
169 unsigned long clip1max; 169 unsigned long clip1max;
170 unsigned long srcbase;
171 unsigned long dstbase;
172 unsigned long miscinit0; 170 unsigned long miscinit0;
173}; 171};
174 172
@@ -177,18 +175,10 @@ struct tdfx_par {
177 u32 palette[16]; 175 u32 palette[16];
178 void __iomem *regbase_virt; 176 void __iomem *regbase_virt;
179 unsigned long iobase; 177 unsigned long iobase;
180 u32 baseline; 178 int mtrr_handle;
181
182 struct {
183 int w,u,d;
184 unsigned long enable,disable;
185 struct timer_list timer;
186 } hwcursor;
187
188 spinlock_t DAClock;
189}; 179};
190 180
191#endif /* __KERNEL__ */ 181#endif /* __KERNEL__ */
192 182
193#endif /* _TDFX_H */ 183#endif /* _TDFX_H */
194 184
diff --git a/include/video/uvesafb.h b/include/video/uvesafb.h
new file mode 100644
index 000000000000..95bcef193954
--- /dev/null
+++ b/include/video/uvesafb.h
@@ -0,0 +1,193 @@
1#ifndef _UVESAFB_H
2#define _UVESAFB_H
3
4struct v86_regs {
5 __u32 ebx;
6 __u32 ecx;
7 __u32 edx;
8 __u32 esi;
9 __u32 edi;
10 __u32 ebp;
11 __u32 eax;
12 __u32 eip;
13 __u32 eflags;
14 __u32 esp;
15 __u16 cs;
16 __u16 ss;
17 __u16 es;
18 __u16 ds;
19 __u16 fs;
20 __u16 gs;
21};
22
23/* Task flags */
24#define TF_VBEIB 0x01
25#define TF_BUF_ESDI 0x02
26#define TF_BUF_ESBX 0x04
27#define TF_BUF_RET 0x08
28#define TF_EXIT 0x10
29
30struct uvesafb_task {
31 __u8 flags;
32 int buf_len;
33 struct v86_regs regs;
34};
35
36/* Constants for the capabilities field
37 * in vbe_ib */
38#define VBE_CAP_CAN_SWITCH_DAC 0x01
39#define VBE_CAP_VGACOMPAT 0x02
40
41/* The VBE Info Block */
42struct vbe_ib {
43 char vbe_signature[4];
44 __u16 vbe_version;
45 __u32 oem_string_ptr;
46 __u32 capabilities;
47 __u32 mode_list_ptr;
48 __u16 total_memory;
49 __u16 oem_software_rev;
50 __u32 oem_vendor_name_ptr;
51 __u32 oem_product_name_ptr;
52 __u32 oem_product_rev_ptr;
53 __u8 reserved[222];
54 char oem_data[256];
55 char misc_data[512];
56} __attribute__ ((packed));
57
58#ifdef __KERNEL__
59
60/* VBE CRTC Info Block */
61struct vbe_crtc_ib {
62 u16 horiz_total;
63 u16 horiz_start;
64 u16 horiz_end;
65 u16 vert_total;
66 u16 vert_start;
67 u16 vert_end;
68 u8 flags;
69 u32 pixel_clock;
70 u16 refresh_rate;
71 u8 reserved[40];
72} __attribute__ ((packed));
73
74#define VBE_MODE_VGACOMPAT 0x20
75#define VBE_MODE_COLOR 0x08
76#define VBE_MODE_SUPPORTEDHW 0x01
77#define VBE_MODE_GRAPHICS 0x10
78#define VBE_MODE_LFB 0x80
79
80#define VBE_MODE_MASK (VBE_MODE_COLOR | VBE_MODE_SUPPORTEDHW | \
81 VBE_MODE_GRAPHICS | VBE_MODE_LFB)
82
83/* VBE Mode Info Block */
84struct vbe_mode_ib {
85 /* for all VBE revisions */
86 u16 mode_attr;
87 u8 winA_attr;
88 u8 winB_attr;
89 u16 win_granularity;
90 u16 win_size;
91 u16 winA_seg;
92 u16 winB_seg;
93 u32 win_func_ptr;
94 u16 bytes_per_scan_line;
95
96 /* for VBE 1.2+ */
97 u16 x_res;
98 u16 y_res;
99 u8 x_char_size;
100 u8 y_char_size;
101 u8 planes;
102 u8 bits_per_pixel;
103 u8 banks;
104 u8 memory_model;
105 u8 bank_size;
106 u8 image_pages;
107 u8 reserved1;
108
109 /* Direct color fields for direct/6 and YUV/7 memory models. */
110 /* Offsets are bit positions of lsb in the mask. */
111 u8 red_len;
112 u8 red_off;
113 u8 green_len;
114 u8 green_off;
115 u8 blue_len;
116 u8 blue_off;
117 u8 rsvd_len;
118 u8 rsvd_off;
119 u8 direct_color_info; /* direct color mode attributes */
120
121 /* for VBE 2.0+ */
122 u32 phys_base_ptr;
123 u8 reserved2[6];
124
125 /* for VBE 3.0+ */
126 u16 lin_bytes_per_scan_line;
127 u8 bnk_image_pages;
128 u8 lin_image_pages;
129 u8 lin_red_len;
130 u8 lin_red_off;
131 u8 lin_green_len;
132 u8 lin_green_off;
133 u8 lin_blue_len;
134 u8 lin_blue_off;
135 u8 lin_rsvd_len;
136 u8 lin_rsvd_off;
137 u32 max_pixel_clock;
138 u16 mode_id;
139 u8 depth;
140} __attribute__ ((packed));
141
142#define UVESAFB_DEFAULT_MODE "640x480-16"
143
144/* How long to wait for a reply from userspace [ms] */
145#define UVESAFB_TIMEOUT 5000
146
147/* Max number of concurrent tasks */
148#define UVESAFB_TASKS_MAX 16
149
150#define dac_reg (0x3c8)
151#define dac_val (0x3c9)
152
153struct uvesafb_pal_entry {
154 u_char blue, green, red, pad;
155} __attribute__ ((packed));
156
157struct uvesafb_ktask {
158 struct uvesafb_task t;
159 void *buf;
160 struct completion *done;
161 u32 ack;
162};
163
164static int uvesafb_exec(struct uvesafb_ktask *tsk);
165
166#define UVESAFB_EXACT_RES 1
167#define UVESAFB_EXACT_DEPTH 2
168
169struct uvesafb_par {
170 struct vbe_ib vbe_ib; /* VBE Info Block */
171 struct vbe_mode_ib *vbe_modes; /* list of supported VBE modes */
172 int vbe_modes_cnt;
173
174 u8 nocrtc;
175 u8 ypan; /* 0 - nothing, 1 - ypan, 2 - ywrap */
176 u8 pmi_setpal; /* PMI for palette changes */
177 u16 *pmi_base; /* protected mode interface location */
178 void *pmi_start;
179 void *pmi_pal;
180 u8 *vbe_state_orig; /*
181 * original hardware state, before the
182 * driver was loaded
183 */
184 u8 *vbe_state_saved; /* state saved by fb_save_state */
185 int vbe_state_size;
186 atomic_t ref_count;
187
188 int mode_idx;
189 struct vbe_crtc_ib crtc;
190};
191
192#endif /* __KERNEL__ */
193#endif /* _UVESAFB_H */
diff --git a/init/calibrate.c b/init/calibrate.c
index 40ff3b404895..2d3d73bd4ce1 100644
--- a/init/calibrate.c
+++ b/init/calibrate.c
@@ -10,7 +10,7 @@
10 10
11#include <asm/timex.h> 11#include <asm/timex.h>
12 12
13static unsigned long preset_lpj; 13unsigned long preset_lpj;
14static int __init lpj_setup(char *str) 14static int __init lpj_setup(char *str)
15{ 15{
16 preset_lpj = simple_strtoul(str,NULL,0); 16 preset_lpj = simple_strtoul(str,NULL,0);
diff --git a/kernel/cpuset.c b/kernel/cpuset.c
index 57e6448b171e..0864f4097930 100644
--- a/kernel/cpuset.c
+++ b/kernel/cpuset.c
@@ -581,26 +581,28 @@ static void guarantee_online_cpus(const struct cpuset *cs, cpumask_t *pmask)
581 581
582/* 582/*
583 * Return in *pmask the portion of a cpusets's mems_allowed that 583 * Return in *pmask the portion of a cpusets's mems_allowed that
584 * are online. If none are online, walk up the cpuset hierarchy 584 * are online, with memory. If none are online with memory, walk
585 * until we find one that does have some online mems. If we get 585 * up the cpuset hierarchy until we find one that does have some
586 * all the way to the top and still haven't found any online mems, 586 * online mems. If we get all the way to the top and still haven't
587 * return node_online_map. 587 * found any online mems, return node_states[N_HIGH_MEMORY].
588 * 588 *
589 * One way or another, we guarantee to return some non-empty subset 589 * One way or another, we guarantee to return some non-empty subset
590 * of node_online_map. 590 * of node_states[N_HIGH_MEMORY].
591 * 591 *
592 * Call with callback_mutex held. 592 * Call with callback_mutex held.
593 */ 593 */
594 594
595static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask) 595static void guarantee_online_mems(const struct cpuset *cs, nodemask_t *pmask)
596{ 596{
597 while (cs && !nodes_intersects(cs->mems_allowed, node_online_map)) 597 while (cs && !nodes_intersects(cs->mems_allowed,
598 node_states[N_HIGH_MEMORY]))
598 cs = cs->parent; 599 cs = cs->parent;
599 if (cs) 600 if (cs)
600 nodes_and(*pmask, cs->mems_allowed, node_online_map); 601 nodes_and(*pmask, cs->mems_allowed,
602 node_states[N_HIGH_MEMORY]);
601 else 603 else
602 *pmask = node_online_map; 604 *pmask = node_states[N_HIGH_MEMORY];
603 BUG_ON(!nodes_intersects(*pmask, node_online_map)); 605 BUG_ON(!nodes_intersects(*pmask, node_states[N_HIGH_MEMORY]));
604} 606}
605 607
606/** 608/**
@@ -753,68 +755,13 @@ static int validate_change(const struct cpuset *cur, const struct cpuset *trial)
753} 755}
754 756
755/* 757/*
756 * For a given cpuset cur, partition the system as follows
757 * a. All cpus in the parent cpuset's cpus_allowed that are not part of any
758 * exclusive child cpusets
759 * b. All cpus in the current cpuset's cpus_allowed that are not part of any
760 * exclusive child cpusets
761 * Build these two partitions by calling partition_sched_domains
762 *
763 * Call with manage_mutex held. May nest a call to the
764 * lock_cpu_hotplug()/unlock_cpu_hotplug() pair.
765 * Must not be called holding callback_mutex, because we must
766 * not call lock_cpu_hotplug() while holding callback_mutex.
767 */
768
769static void update_cpu_domains(struct cpuset *cur)
770{
771 struct cpuset *c, *par = cur->parent;
772 cpumask_t pspan, cspan;
773
774 if (par == NULL || cpus_empty(cur->cpus_allowed))
775 return;
776
777 /*
778 * Get all cpus from parent's cpus_allowed not part of exclusive
779 * children
780 */
781 pspan = par->cpus_allowed;
782 list_for_each_entry(c, &par->children, sibling) {
783 if (is_cpu_exclusive(c))
784 cpus_andnot(pspan, pspan, c->cpus_allowed);
785 }
786 if (!is_cpu_exclusive(cur)) {
787 cpus_or(pspan, pspan, cur->cpus_allowed);
788 if (cpus_equal(pspan, cur->cpus_allowed))
789 return;
790 cspan = CPU_MASK_NONE;
791 } else {
792 if (cpus_empty(pspan))
793 return;
794 cspan = cur->cpus_allowed;
795 /*
796 * Get all cpus from current cpuset's cpus_allowed not part
797 * of exclusive children
798 */
799 list_for_each_entry(c, &cur->children, sibling) {
800 if (is_cpu_exclusive(c))
801 cpus_andnot(cspan, cspan, c->cpus_allowed);
802 }
803 }
804
805 lock_cpu_hotplug();
806 partition_sched_domains(&pspan, &cspan);
807 unlock_cpu_hotplug();
808}
809
810/*
811 * Call with manage_mutex held. May take callback_mutex during call. 758 * Call with manage_mutex held. May take callback_mutex during call.
812 */ 759 */
813 760
814static int update_cpumask(struct cpuset *cs, char *buf) 761static int update_cpumask(struct cpuset *cs, char *buf)
815{ 762{
816 struct cpuset trialcs; 763 struct cpuset trialcs;
817 int retval, cpus_unchanged; 764 int retval;
818 765
819 /* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */ 766 /* top_cpuset.cpus_allowed tracks cpu_online_map; it's read-only */
820 if (cs == &top_cpuset) 767 if (cs == &top_cpuset)
@@ -841,12 +788,9 @@ static int update_cpumask(struct cpuset *cs, char *buf)
841 retval = validate_change(cs, &trialcs); 788 retval = validate_change(cs, &trialcs);
842 if (retval < 0) 789 if (retval < 0)
843 return retval; 790 return retval;
844 cpus_unchanged = cpus_equal(cs->cpus_allowed, trialcs.cpus_allowed);
845 mutex_lock(&callback_mutex); 791 mutex_lock(&callback_mutex);
846 cs->cpus_allowed = trialcs.cpus_allowed; 792 cs->cpus_allowed = trialcs.cpus_allowed;
847 mutex_unlock(&callback_mutex); 793 mutex_unlock(&callback_mutex);
848 if (is_cpu_exclusive(cs) && !cpus_unchanged)
849 update_cpu_domains(cs);
850 return 0; 794 return 0;
851} 795}
852 796
@@ -924,7 +868,10 @@ static int update_nodemask(struct cpuset *cs, char *buf)
924 int fudge; 868 int fudge;
925 int retval; 869 int retval;
926 870
927 /* top_cpuset.mems_allowed tracks node_online_map; it's read-only */ 871 /*
872 * top_cpuset.mems_allowed tracks node_stats[N_HIGH_MEMORY];
873 * it's read-only
874 */
928 if (cs == &top_cpuset) 875 if (cs == &top_cpuset)
929 return -EACCES; 876 return -EACCES;
930 877
@@ -941,8 +888,21 @@ static int update_nodemask(struct cpuset *cs, char *buf)
941 retval = nodelist_parse(buf, trialcs.mems_allowed); 888 retval = nodelist_parse(buf, trialcs.mems_allowed);
942 if (retval < 0) 889 if (retval < 0)
943 goto done; 890 goto done;
891 if (!nodes_intersects(trialcs.mems_allowed,
892 node_states[N_HIGH_MEMORY])) {
893 /*
894 * error if only memoryless nodes specified.
895 */
896 retval = -ENOSPC;
897 goto done;
898 }
944 } 899 }
945 nodes_and(trialcs.mems_allowed, trialcs.mems_allowed, node_online_map); 900 /*
901 * Exclude memoryless nodes. We know that trialcs.mems_allowed
902 * contains at least one node with memory.
903 */
904 nodes_and(trialcs.mems_allowed, trialcs.mems_allowed,
905 node_states[N_HIGH_MEMORY]);
946 oldmem = cs->mems_allowed; 906 oldmem = cs->mems_allowed;
947 if (nodes_equal(oldmem, trialcs.mems_allowed)) { 907 if (nodes_equal(oldmem, trialcs.mems_allowed)) {
948 retval = 0; /* Too easy - nothing to do */ 908 retval = 0; /* Too easy - nothing to do */
@@ -1067,7 +1027,7 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
1067{ 1027{
1068 int turning_on; 1028 int turning_on;
1069 struct cpuset trialcs; 1029 struct cpuset trialcs;
1070 int err, cpu_exclusive_changed; 1030 int err;
1071 1031
1072 turning_on = (simple_strtoul(buf, NULL, 10) != 0); 1032 turning_on = (simple_strtoul(buf, NULL, 10) != 0);
1073 1033
@@ -1080,14 +1040,10 @@ static int update_flag(cpuset_flagbits_t bit, struct cpuset *cs, char *buf)
1080 err = validate_change(cs, &trialcs); 1040 err = validate_change(cs, &trialcs);
1081 if (err < 0) 1041 if (err < 0)
1082 return err; 1042 return err;
1083 cpu_exclusive_changed =
1084 (is_cpu_exclusive(cs) != is_cpu_exclusive(&trialcs));
1085 mutex_lock(&callback_mutex); 1043 mutex_lock(&callback_mutex);
1086 cs->flags = trialcs.flags; 1044 cs->flags = trialcs.flags;
1087 mutex_unlock(&callback_mutex); 1045 mutex_unlock(&callback_mutex);
1088 1046
1089 if (cpu_exclusive_changed)
1090 update_cpu_domains(cs);
1091 return 0; 1047 return 0;
1092} 1048}
1093 1049
@@ -1445,7 +1401,7 @@ static ssize_t cpuset_common_file_read(struct file *file, char __user *buf,
1445 ssize_t retval = 0; 1401 ssize_t retval = 0;
1446 char *s; 1402 char *s;
1447 1403
1448 if (!(page = (char *)__get_free_page(GFP_KERNEL))) 1404 if (!(page = (char *)__get_free_page(GFP_TEMPORARY)))
1449 return -ENOMEM; 1405 return -ENOMEM;
1450 1406
1451 s = page; 1407 s = page;
@@ -1947,17 +1903,6 @@ static int cpuset_mkdir(struct inode *dir, struct dentry *dentry, int mode)
1947 return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR); 1903 return cpuset_create(c_parent, dentry->d_name.name, mode | S_IFDIR);
1948} 1904}
1949 1905
1950/*
1951 * Locking note on the strange update_flag() call below:
1952 *
1953 * If the cpuset being removed is marked cpu_exclusive, then simulate
1954 * turning cpu_exclusive off, which will call update_cpu_domains().
1955 * The lock_cpu_hotplug() call in update_cpu_domains() must not be
1956 * made while holding callback_mutex. Elsewhere the kernel nests
1957 * callback_mutex inside lock_cpu_hotplug() calls. So the reverse
1958 * nesting would risk an ABBA deadlock.
1959 */
1960
1961static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry) 1906static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
1962{ 1907{
1963 struct cpuset *cs = dentry->d_fsdata; 1908 struct cpuset *cs = dentry->d_fsdata;
@@ -1977,13 +1922,6 @@ static int cpuset_rmdir(struct inode *unused_dir, struct dentry *dentry)
1977 mutex_unlock(&manage_mutex); 1922 mutex_unlock(&manage_mutex);
1978 return -EBUSY; 1923 return -EBUSY;
1979 } 1924 }
1980 if (is_cpu_exclusive(cs)) {
1981 int retval = update_flag(CS_CPU_EXCLUSIVE, cs, "0");
1982 if (retval < 0) {
1983 mutex_unlock(&manage_mutex);
1984 return retval;
1985 }
1986 }
1987 parent = cs->parent; 1925 parent = cs->parent;
1988 mutex_lock(&callback_mutex); 1926 mutex_lock(&callback_mutex);
1989 set_bit(CS_REMOVED, &cs->flags); 1927 set_bit(CS_REMOVED, &cs->flags);
@@ -2098,8 +2036,9 @@ static void guarantee_online_cpus_mems_in_subtree(const struct cpuset *cur)
2098 2036
2099/* 2037/*
2100 * The cpus_allowed and mems_allowed nodemasks in the top_cpuset track 2038 * The cpus_allowed and mems_allowed nodemasks in the top_cpuset track
2101 * cpu_online_map and node_online_map. Force the top cpuset to track 2039 * cpu_online_map and node_states[N_HIGH_MEMORY]. Force the top cpuset to
2102 * whats online after any CPU or memory node hotplug or unplug event. 2040 * track what's online after any CPU or memory node hotplug or unplug
2041 * event.
2103 * 2042 *
2104 * To ensure that we don't remove a CPU or node from the top cpuset 2043 * To ensure that we don't remove a CPU or node from the top cpuset
2105 * that is currently in use by a child cpuset (which would violate 2044 * that is currently in use by a child cpuset (which would violate
@@ -2119,7 +2058,7 @@ static void common_cpu_mem_hotplug_unplug(void)
2119 2058
2120 guarantee_online_cpus_mems_in_subtree(&top_cpuset); 2059 guarantee_online_cpus_mems_in_subtree(&top_cpuset);
2121 top_cpuset.cpus_allowed = cpu_online_map; 2060 top_cpuset.cpus_allowed = cpu_online_map;
2122 top_cpuset.mems_allowed = node_online_map; 2061 top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
2123 2062
2124 mutex_unlock(&callback_mutex); 2063 mutex_unlock(&callback_mutex);
2125 mutex_unlock(&manage_mutex); 2064 mutex_unlock(&manage_mutex);
@@ -2147,8 +2086,9 @@ static int cpuset_handle_cpuhp(struct notifier_block *nb,
2147 2086
2148#ifdef CONFIG_MEMORY_HOTPLUG 2087#ifdef CONFIG_MEMORY_HOTPLUG
2149/* 2088/*
2150 * Keep top_cpuset.mems_allowed tracking node_online_map. 2089 * Keep top_cpuset.mems_allowed tracking node_states[N_HIGH_MEMORY].
2151 * Call this routine anytime after you change node_online_map. 2090 * Call this routine anytime after you change
2091 * node_states[N_HIGH_MEMORY].
2152 * See also the previous routine cpuset_handle_cpuhp(). 2092 * See also the previous routine cpuset_handle_cpuhp().
2153 */ 2093 */
2154 2094
@@ -2167,7 +2107,7 @@ void cpuset_track_online_nodes(void)
2167void __init cpuset_init_smp(void) 2107void __init cpuset_init_smp(void)
2168{ 2108{
2169 top_cpuset.cpus_allowed = cpu_online_map; 2109 top_cpuset.cpus_allowed = cpu_online_map;
2170 top_cpuset.mems_allowed = node_online_map; 2110 top_cpuset.mems_allowed = node_states[N_HIGH_MEMORY];
2171 2111
2172 hotcpu_notifier(cpuset_handle_cpuhp, 0); 2112 hotcpu_notifier(cpuset_handle_cpuhp, 0);
2173} 2113}
@@ -2309,7 +2249,7 @@ void cpuset_init_current_mems_allowed(void)
2309 * 2249 *
2310 * Description: Returns the nodemask_t mems_allowed of the cpuset 2250 * Description: Returns the nodemask_t mems_allowed of the cpuset
2311 * attached to the specified @tsk. Guaranteed to return some non-empty 2251 * attached to the specified @tsk. Guaranteed to return some non-empty
2312 * subset of node_online_map, even if this means going outside the 2252 * subset of node_states[N_HIGH_MEMORY], even if this means going outside the
2313 * tasks cpuset. 2253 * tasks cpuset.
2314 **/ 2254 **/
2315 2255
diff --git a/kernel/kprobes.c b/kernel/kprobes.c
index 4b8a4493c541..e3a5d817ac9b 100644
--- a/kernel/kprobes.c
+++ b/kernel/kprobes.c
@@ -64,7 +64,6 @@
64 64
65static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE]; 65static struct hlist_head kprobe_table[KPROBE_TABLE_SIZE];
66static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE]; 66static struct hlist_head kretprobe_inst_table[KPROBE_TABLE_SIZE];
67static atomic_t kprobe_count;
68 67
69/* NOTE: change this value only with kprobe_mutex held */ 68/* NOTE: change this value only with kprobe_mutex held */
70static bool kprobe_enabled; 69static bool kprobe_enabled;
@@ -73,11 +72,6 @@ DEFINE_MUTEX(kprobe_mutex); /* Protects kprobe_table */
73DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */ 72DEFINE_SPINLOCK(kretprobe_lock); /* Protects kretprobe_inst_table */
74static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL; 73static DEFINE_PER_CPU(struct kprobe *, kprobe_instance) = NULL;
75 74
76static struct notifier_block kprobe_page_fault_nb = {
77 .notifier_call = kprobe_exceptions_notify,
78 .priority = 0x7fffffff /* we need to notified first */
79};
80
81#ifdef __ARCH_WANT_KPROBES_INSN_SLOT 75#ifdef __ARCH_WANT_KPROBES_INSN_SLOT
82/* 76/*
83 * kprobe->ainsn.insn points to the copy of the instruction to be 77 * kprobe->ainsn.insn points to the copy of the instruction to be
@@ -556,8 +550,6 @@ static int __kprobes __register_kprobe(struct kprobe *p,
556 old_p = get_kprobe(p->addr); 550 old_p = get_kprobe(p->addr);
557 if (old_p) { 551 if (old_p) {
558 ret = register_aggr_kprobe(old_p, p); 552 ret = register_aggr_kprobe(old_p, p);
559 if (!ret)
560 atomic_inc(&kprobe_count);
561 goto out; 553 goto out;
562 } 554 }
563 555
@@ -569,13 +561,9 @@ static int __kprobes __register_kprobe(struct kprobe *p,
569 hlist_add_head_rcu(&p->hlist, 561 hlist_add_head_rcu(&p->hlist,
570 &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]); 562 &kprobe_table[hash_ptr(p->addr, KPROBE_HASH_BITS)]);
571 563
572 if (kprobe_enabled) { 564 if (kprobe_enabled)
573 if (atomic_add_return(1, &kprobe_count) == \
574 (ARCH_INACTIVE_KPROBE_COUNT + 1))
575 register_page_fault_notifier(&kprobe_page_fault_nb);
576
577 arch_arm_kprobe(p); 565 arch_arm_kprobe(p);
578 } 566
579out: 567out:
580 mutex_unlock(&kprobe_mutex); 568 mutex_unlock(&kprobe_mutex);
581 569
@@ -658,16 +646,6 @@ valid_p:
658 } 646 }
659 mutex_unlock(&kprobe_mutex); 647 mutex_unlock(&kprobe_mutex);
660 } 648 }
661
662 /* Call unregister_page_fault_notifier()
663 * if no probes are active
664 */
665 mutex_lock(&kprobe_mutex);
666 if (atomic_add_return(-1, &kprobe_count) == \
667 ARCH_INACTIVE_KPROBE_COUNT)
668 unregister_page_fault_notifier(&kprobe_page_fault_nb);
669 mutex_unlock(&kprobe_mutex);
670 return;
671} 649}
672 650
673static struct notifier_block kprobe_exceptions_nb = { 651static struct notifier_block kprobe_exceptions_nb = {
@@ -738,6 +716,18 @@ int __kprobes register_kretprobe(struct kretprobe *rp)
738 int ret = 0; 716 int ret = 0;
739 struct kretprobe_instance *inst; 717 struct kretprobe_instance *inst;
740 int i; 718 int i;
719 void *addr = rp->kp.addr;
720
721 if (kretprobe_blacklist_size) {
722 if (addr == NULL)
723 kprobe_lookup_name(rp->kp.symbol_name, addr);
724 addr += rp->kp.offset;
725
726 for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
727 if (kretprobe_blacklist[i].addr == addr)
728 return -EINVAL;
729 }
730 }
741 731
742 rp->kp.pre_handler = pre_handler_kretprobe; 732 rp->kp.pre_handler = pre_handler_kretprobe;
743 rp->kp.post_handler = NULL; 733 rp->kp.post_handler = NULL;
@@ -815,7 +805,17 @@ static int __init init_kprobes(void)
815 INIT_HLIST_HEAD(&kprobe_table[i]); 805 INIT_HLIST_HEAD(&kprobe_table[i]);
816 INIT_HLIST_HEAD(&kretprobe_inst_table[i]); 806 INIT_HLIST_HEAD(&kretprobe_inst_table[i]);
817 } 807 }
818 atomic_set(&kprobe_count, 0); 808
809 if (kretprobe_blacklist_size) {
810 /* lookup the function address from its name */
811 for (i = 0; kretprobe_blacklist[i].name != NULL; i++) {
812 kprobe_lookup_name(kretprobe_blacklist[i].name,
813 kretprobe_blacklist[i].addr);
814 if (!kretprobe_blacklist[i].addr)
815 printk("kretprobe: lookup failed: %s\n",
816 kretprobe_blacklist[i].name);
817 }
818 }
819 819
820 /* By default, kprobes are enabled */ 820 /* By default, kprobes are enabled */
821 kprobe_enabled = true; 821 kprobe_enabled = true;
@@ -921,13 +921,6 @@ static void __kprobes enable_all_kprobes(void)
921 if (kprobe_enabled) 921 if (kprobe_enabled)
922 goto already_enabled; 922 goto already_enabled;
923 923
924 /*
925 * Re-register the page fault notifier only if there are any
926 * active probes at the time of enabling kprobes globally
927 */
928 if (atomic_read(&kprobe_count) > ARCH_INACTIVE_KPROBE_COUNT)
929 register_page_fault_notifier(&kprobe_page_fault_nb);
930
931 for (i = 0; i < KPROBE_TABLE_SIZE; i++) { 924 for (i = 0; i < KPROBE_TABLE_SIZE; i++) {
932 head = &kprobe_table[i]; 925 head = &kprobe_table[i];
933 hlist_for_each_entry_rcu(p, node, head, hlist) 926 hlist_for_each_entry_rcu(p, node, head, hlist)
@@ -968,10 +961,7 @@ static void __kprobes disable_all_kprobes(void)
968 mutex_unlock(&kprobe_mutex); 961 mutex_unlock(&kprobe_mutex);
969 /* Allow all currently running kprobes to complete */ 962 /* Allow all currently running kprobes to complete */
970 synchronize_sched(); 963 synchronize_sched();
971 964 return;
972 mutex_lock(&kprobe_mutex);
973 /* Unconditionally unregister the page_fault notifier */
974 unregister_page_fault_notifier(&kprobe_page_fault_nb);
975 965
976already_disabled: 966already_disabled:
977 mutex_unlock(&kprobe_mutex); 967 mutex_unlock(&kprobe_mutex);
diff --git a/kernel/printk.c b/kernel/printk.c
index 8451dfc31d25..b2b5c3a22a36 100644
--- a/kernel/printk.c
+++ b/kernel/printk.c
@@ -22,6 +22,8 @@
22#include <linux/tty_driver.h> 22#include <linux/tty_driver.h>
23#include <linux/console.h> 23#include <linux/console.h>
24#include <linux/init.h> 24#include <linux/init.h>
25#include <linux/jiffies.h>
26#include <linux/nmi.h>
25#include <linux/module.h> 27#include <linux/module.h>
26#include <linux/moduleparam.h> 28#include <linux/moduleparam.h>
27#include <linux/interrupt.h> /* For in_interrupt() */ 29#include <linux/interrupt.h> /* For in_interrupt() */
@@ -162,6 +164,61 @@ out:
162 164
163__setup("log_buf_len=", log_buf_len_setup); 165__setup("log_buf_len=", log_buf_len_setup);
164 166
167#ifdef CONFIG_BOOT_PRINTK_DELAY
168
169static unsigned int boot_delay; /* msecs delay after each printk during bootup */
170static unsigned long long printk_delay_msec; /* per msec, based on boot_delay */
171
172static int __init boot_delay_setup(char *str)
173{
174 unsigned long lpj;
175 unsigned long long loops_per_msec;
176
177 lpj = preset_lpj ? preset_lpj : 1000000; /* some guess */
178 loops_per_msec = (unsigned long long)lpj / 1000 * HZ;
179
180 get_option(&str, &boot_delay);
181 if (boot_delay > 10 * 1000)
182 boot_delay = 0;
183
184 printk_delay_msec = loops_per_msec;
185 printk(KERN_DEBUG "boot_delay: %u, preset_lpj: %ld, lpj: %lu, "
186 "HZ: %d, printk_delay_msec: %llu\n",
187 boot_delay, preset_lpj, lpj, HZ, printk_delay_msec);
188 return 1;
189}
190__setup("boot_delay=", boot_delay_setup);
191
192static void boot_delay_msec(void)
193{
194 unsigned long long k;
195 unsigned long timeout;
196
197 if (boot_delay == 0 || system_state != SYSTEM_BOOTING)
198 return;
199
200 k = (unsigned long long)printk_delay_msec * boot_delay;
201
202 timeout = jiffies + msecs_to_jiffies(boot_delay);
203 while (k) {
204 k--;
205 cpu_relax();
206 /*
207 * use (volatile) jiffies to prevent
208 * compiler reduction; loop termination via jiffies
209 * is secondary and may or may not happen.
210 */
211 if (time_after(jiffies, timeout))
212 break;
213 touch_nmi_watchdog();
214 }
215}
216#else
217static inline void boot_delay_msec(void)
218{
219}
220#endif
221
165/* 222/*
166 * Commands to do_syslog: 223 * Commands to do_syslog:
167 * 224 *
@@ -527,6 +584,8 @@ asmlinkage int vprintk(const char *fmt, va_list args)
527 static char printk_buf[1024]; 584 static char printk_buf[1024];
528 static int log_level_unknown = 1; 585 static int log_level_unknown = 1;
529 586
587 boot_delay_msec();
588
530 preempt_disable(); 589 preempt_disable();
531 if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id()) 590 if (unlikely(oops_in_progress) && printk_cpu == smp_processor_id())
532 /* If a crash is occurring during printk() on this CPU, 591 /* If a crash is occurring during printk() on this CPU,
diff --git a/kernel/profile.c b/kernel/profile.c
index cb1e37d2dac3..6f69bf792d96 100644
--- a/kernel/profile.c
+++ b/kernel/profile.c
@@ -346,7 +346,7 @@ static int __devinit profile_cpu_callback(struct notifier_block *info,
346 per_cpu(cpu_profile_flip, cpu) = 0; 346 per_cpu(cpu_profile_flip, cpu) = 0;
347 if (!per_cpu(cpu_profile_hits, cpu)[1]) { 347 if (!per_cpu(cpu_profile_hits, cpu)[1]) {
348 page = alloc_pages_node(node, 348 page = alloc_pages_node(node,
349 GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, 349 GFP_KERNEL | __GFP_ZERO,
350 0); 350 0);
351 if (!page) 351 if (!page)
352 return NOTIFY_BAD; 352 return NOTIFY_BAD;
@@ -354,7 +354,7 @@ static int __devinit profile_cpu_callback(struct notifier_block *info,
354 } 354 }
355 if (!per_cpu(cpu_profile_hits, cpu)[0]) { 355 if (!per_cpu(cpu_profile_hits, cpu)[0]) {
356 page = alloc_pages_node(node, 356 page = alloc_pages_node(node,
357 GFP_KERNEL | __GFP_ZERO | GFP_THISNODE, 357 GFP_KERNEL | __GFP_ZERO,
358 0); 358 0);
359 if (!page) 359 if (!page)
360 goto out_free; 360 goto out_free;
diff --git a/kernel/ptrace.c b/kernel/ptrace.c
index 3eca7a55f2ee..a73ebd3b9d4c 100644
--- a/kernel/ptrace.c
+++ b/kernel/ptrace.c
@@ -386,6 +386,9 @@ int ptrace_request(struct task_struct *child, long request,
386 case PTRACE_SETSIGINFO: 386 case PTRACE_SETSIGINFO:
387 ret = ptrace_setsiginfo(child, (siginfo_t __user *) data); 387 ret = ptrace_setsiginfo(child, (siginfo_t __user *) data);
388 break; 388 break;
389 case PTRACE_DETACH: /* detach a process that was attached. */
390 ret = ptrace_detach(child, data);
391 break;
389 default: 392 default:
390 break; 393 break;
391 } 394 }
@@ -450,6 +453,10 @@ struct task_struct *ptrace_get_task_struct(pid_t pid)
450 return child; 453 return child;
451} 454}
452 455
456#ifndef arch_ptrace_attach
457#define arch_ptrace_attach(child) do { } while (0)
458#endif
459
453#ifndef __ARCH_SYS_PTRACE 460#ifndef __ARCH_SYS_PTRACE
454asmlinkage long sys_ptrace(long request, long pid, long addr, long data) 461asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
455{ 462{
@@ -473,6 +480,12 @@ asmlinkage long sys_ptrace(long request, long pid, long addr, long data)
473 480
474 if (request == PTRACE_ATTACH) { 481 if (request == PTRACE_ATTACH) {
475 ret = ptrace_attach(child); 482 ret = ptrace_attach(child);
483 /*
484 * Some architectures need to do book-keeping after
485 * a ptrace attach.
486 */
487 if (!ret)
488 arch_ptrace_attach(child);
476 goto out_put_task_struct; 489 goto out_put_task_struct;
477 } 490 }
478 491
diff --git a/kernel/resource.c b/kernel/resource.c
index 9bd14fd3e6de..a358142ff48f 100644
--- a/kernel/resource.c
+++ b/kernel/resource.c
@@ -234,7 +234,7 @@ EXPORT_SYMBOL(release_resource);
234 * the caller must specify res->start, res->end, res->flags. 234 * the caller must specify res->start, res->end, res->flags.
235 * If found, returns 0, res is overwritten, if not found, returns -1. 235 * If found, returns 0, res is overwritten, if not found, returns -1.
236 */ 236 */
237int find_next_system_ram(struct resource *res) 237static int find_next_system_ram(struct resource *res)
238{ 238{
239 resource_size_t start, end; 239 resource_size_t start, end;
240 struct resource *p; 240 struct resource *p;
@@ -267,6 +267,30 @@ int find_next_system_ram(struct resource *res)
267 res->end = p->end; 267 res->end = p->end;
268 return 0; 268 return 0;
269} 269}
270int
271walk_memory_resource(unsigned long start_pfn, unsigned long nr_pages, void *arg,
272 int (*func)(unsigned long, unsigned long, void *))
273{
274 struct resource res;
275 unsigned long pfn, len;
276 u64 orig_end;
277 int ret = -1;
278 res.start = (u64) start_pfn << PAGE_SHIFT;
279 res.end = ((u64)(start_pfn + nr_pages) << PAGE_SHIFT) - 1;
280 res.flags = IORESOURCE_MEM;
281 orig_end = res.end;
282 while ((res.start < res.end) && (find_next_system_ram(&res) >= 0)) {
283 pfn = (unsigned long)(res.start >> PAGE_SHIFT);
284 len = (unsigned long)((res.end + 1 - res.start) >> PAGE_SHIFT);
285 ret = (*func)(pfn, len, arg);
286 if (ret)
287 break;
288 res.start = res.end + 1;
289 res.end = orig_end;
290 }
291 return ret;
292}
293
270#endif 294#endif
271 295
272/* 296/*
diff --git a/kernel/sched.c b/kernel/sched.c
index bba57adb9504..0da2b2635c54 100644
--- a/kernel/sched.c
+++ b/kernel/sched.c
@@ -5869,7 +5869,7 @@ static int cpu_to_core_group(int cpu, const cpumask_t *cpu_map,
5869 struct sched_group **sg) 5869 struct sched_group **sg)
5870{ 5870{
5871 int group; 5871 int group;
5872 cpumask_t mask = cpu_sibling_map[cpu]; 5872 cpumask_t mask = per_cpu(cpu_sibling_map, cpu);
5873 cpus_and(mask, mask, *cpu_map); 5873 cpus_and(mask, mask, *cpu_map);
5874 group = first_cpu(mask); 5874 group = first_cpu(mask);
5875 if (sg) 5875 if (sg)
@@ -5898,7 +5898,7 @@ static int cpu_to_phys_group(int cpu, const cpumask_t *cpu_map,
5898 cpus_and(mask, mask, *cpu_map); 5898 cpus_and(mask, mask, *cpu_map);
5899 group = first_cpu(mask); 5899 group = first_cpu(mask);
5900#elif defined(CONFIG_SCHED_SMT) 5900#elif defined(CONFIG_SCHED_SMT)
5901 cpumask_t mask = cpu_sibling_map[cpu]; 5901 cpumask_t mask = per_cpu(cpu_sibling_map, cpu);
5902 cpus_and(mask, mask, *cpu_map); 5902 cpus_and(mask, mask, *cpu_map);
5903 group = first_cpu(mask); 5903 group = first_cpu(mask);
5904#else 5904#else
@@ -6132,7 +6132,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
6132 p = sd; 6132 p = sd;
6133 sd = &per_cpu(cpu_domains, i); 6133 sd = &per_cpu(cpu_domains, i);
6134 *sd = SD_SIBLING_INIT; 6134 *sd = SD_SIBLING_INIT;
6135 sd->span = cpu_sibling_map[i]; 6135 sd->span = per_cpu(cpu_sibling_map, i);
6136 cpus_and(sd->span, sd->span, *cpu_map); 6136 cpus_and(sd->span, sd->span, *cpu_map);
6137 sd->parent = p; 6137 sd->parent = p;
6138 p->child = sd; 6138 p->child = sd;
@@ -6143,7 +6143,7 @@ static int build_sched_domains(const cpumask_t *cpu_map)
6143#ifdef CONFIG_SCHED_SMT 6143#ifdef CONFIG_SCHED_SMT
6144 /* Set up CPU (sibling) groups */ 6144 /* Set up CPU (sibling) groups */
6145 for_each_cpu_mask(i, *cpu_map) { 6145 for_each_cpu_mask(i, *cpu_map) {
6146 cpumask_t this_sibling_map = cpu_sibling_map[i]; 6146 cpumask_t this_sibling_map = per_cpu(cpu_sibling_map, i);
6147 cpus_and(this_sibling_map, this_sibling_map, *cpu_map); 6147 cpus_and(this_sibling_map, this_sibling_map, *cpu_map);
6148 if (i != first_cpu(this_sibling_map)) 6148 if (i != first_cpu(this_sibling_map))
6149 continue; 6149 continue;
@@ -6348,35 +6348,6 @@ static void detach_destroy_domains(const cpumask_t *cpu_map)
6348 arch_destroy_sched_domains(cpu_map); 6348 arch_destroy_sched_domains(cpu_map);
6349} 6349}
6350 6350
6351/*
6352 * Partition sched domains as specified by the cpumasks below.
6353 * This attaches all cpus from the cpumasks to the NULL domain,
6354 * waits for a RCU quiescent period, recalculates sched
6355 * domain information and then attaches them back to the
6356 * correct sched domains
6357 * Call with hotplug lock held
6358 */
6359int partition_sched_domains(cpumask_t *partition1, cpumask_t *partition2)
6360{
6361 cpumask_t change_map;
6362 int err = 0;
6363
6364 cpus_and(*partition1, *partition1, cpu_online_map);
6365 cpus_and(*partition2, *partition2, cpu_online_map);
6366 cpus_or(change_map, *partition1, *partition2);
6367
6368 /* Detach sched domains from all of the affected cpus */
6369 detach_destroy_domains(&change_map);
6370 if (!cpus_empty(*partition1))
6371 err = build_sched_domains(partition1);
6372 if (!err && !cpus_empty(*partition2))
6373 err = build_sched_domains(partition2);
6374
6375 register_sched_domain_sysctl();
6376
6377 return err;
6378}
6379
6380#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT) 6351#if defined(CONFIG_SCHED_MC) || defined(CONFIG_SCHED_SMT)
6381static int arch_reinit_sched_domains(void) 6352static int arch_reinit_sched_domains(void)
6382{ 6353{
diff --git a/kernel/sysctl.c b/kernel/sysctl.c
index ec14aa8ac51f..96efbb859997 100644
--- a/kernel/sysctl.c
+++ b/kernel/sysctl.c
@@ -880,6 +880,14 @@ static ctl_table vm_table[] = {
880 .mode = 0644, 880 .mode = 0644,
881 .proc_handler = &hugetlb_treat_movable_handler, 881 .proc_handler = &hugetlb_treat_movable_handler,
882 }, 882 },
883 {
884 .ctl_name = CTL_UNNUMBERED,
885 .procname = "hugetlb_dynamic_pool",
886 .data = &hugetlb_dynamic_pool,
887 .maxlen = sizeof(hugetlb_dynamic_pool),
888 .mode = 0644,
889 .proc_handler = &proc_dointvec,
890 },
883#endif 891#endif
884 { 892 {
885 .ctl_name = VM_LOWMEM_RESERVE_RATIO, 893 .ctl_name = VM_LOWMEM_RESERVE_RATIO,
diff --git a/kernel/time.c b/kernel/time.c
index 2289a8d68314..1afcc78dc3b1 100644
--- a/kernel/time.c
+++ b/kernel/time.c
@@ -57,11 +57,7 @@ EXPORT_SYMBOL(sys_tz);
57 */ 57 */
58asmlinkage long sys_time(time_t __user * tloc) 58asmlinkage long sys_time(time_t __user * tloc)
59{ 59{
60 time_t i; 60 time_t i = get_seconds();
61 struct timespec tv;
62
63 getnstimeofday(&tv);
64 i = tv.tv_sec;
65 61
66 if (tloc) { 62 if (tloc) {
67 if (put_user(i,tloc)) 63 if (put_user(i,tloc))
diff --git a/kernel/time/timekeeping.c b/kernel/time/timekeeping.c
index 4ad79f6bdec6..7e8983aecf83 100644
--- a/kernel/time/timekeeping.c
+++ b/kernel/time/timekeeping.c
@@ -49,19 +49,12 @@ struct timespec wall_to_monotonic __attribute__ ((aligned (16)));
49static unsigned long total_sleep_time; /* seconds */ 49static unsigned long total_sleep_time; /* seconds */
50EXPORT_SYMBOL(xtime); 50EXPORT_SYMBOL(xtime);
51 51
52
53#ifdef CONFIG_NO_HZ
54static struct timespec xtime_cache __attribute__ ((aligned (16))); 52static struct timespec xtime_cache __attribute__ ((aligned (16)));
55static inline void update_xtime_cache(u64 nsec) 53static inline void update_xtime_cache(u64 nsec)
56{ 54{
57 xtime_cache = xtime; 55 xtime_cache = xtime;
58 timespec_add_ns(&xtime_cache, nsec); 56 timespec_add_ns(&xtime_cache, nsec);
59} 57}
60#else
61#define xtime_cache xtime
62/* We do *not* want to evaluate the argument for this case */
63#define update_xtime_cache(n) do { } while (0)
64#endif
65 58
66static struct clocksource *clock; /* pointer to current clocksource */ 59static struct clocksource *clock; /* pointer to current clocksource */
67 60
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 396c38b3cb69..7d16e6433302 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -413,6 +413,24 @@ config FORCED_INLINING
413 become the default in the future, until then this option is there to 413 become the default in the future, until then this option is there to
414 test gcc for this. 414 test gcc for this.
415 415
416config BOOT_PRINTK_DELAY
417 bool "Delay each boot printk message by N milliseconds"
418 depends on DEBUG_KERNEL && PRINTK && GENERIC_CALIBRATE_DELAY
419 help
420 This build option allows you to read kernel boot messages
421 by inserting a short delay after each one. The delay is
422 specified in milliseconds on the kernel command line,
423 using "boot_delay=N".
424
425 It is likely that you would also need to use "lpj=M" to preset
426 the "loops per jiffie" value.
427 See a previous boot log for the "lpj" value to use for your
428 system, and then set "lpj=M" before setting "boot_delay=N".
429 NOTE: Using this option may adversely affect SMP systems.
430 I.e., processors other than the first one may not boot up.
431 BOOT_PRINTK_DELAY also may cause DETECT_SOFTLOCKUP to detect
432 what it believes to be lockup conditions.
433
416config RCU_TORTURE_TEST 434config RCU_TORTURE_TEST
417 tristate "torture tests for RCU" 435 tristate "torture tests for RCU"
418 depends on DEBUG_KERNEL 436 depends on DEBUG_KERNEL
diff --git a/lib/radix-tree.c b/lib/radix-tree.c
index 514efb200be6..6b26f9d39800 100644
--- a/lib/radix-tree.c
+++ b/lib/radix-tree.c
@@ -60,9 +60,14 @@ struct radix_tree_path {
60}; 60};
61 61
62#define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long)) 62#define RADIX_TREE_INDEX_BITS (8 /* CHAR_BIT */ * sizeof(unsigned long))
63#define RADIX_TREE_MAX_PATH (RADIX_TREE_INDEX_BITS/RADIX_TREE_MAP_SHIFT + 2) 63#define RADIX_TREE_MAX_PATH (DIV_ROUND_UP(RADIX_TREE_INDEX_BITS, \
64 RADIX_TREE_MAP_SHIFT))
64 65
65static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH] __read_mostly; 66/*
67 * The height_to_maxindex array needs to be one deeper than the maximum
68 * path as height 0 holds only 1 entry.
69 */
70static unsigned long height_to_maxindex[RADIX_TREE_MAX_PATH + 1] __read_mostly;
66 71
67/* 72/*
68 * Radix tree node cache. 73 * Radix tree node cache.
@@ -93,7 +98,8 @@ radix_tree_node_alloc(struct radix_tree_root *root)
93 struct radix_tree_node *ret; 98 struct radix_tree_node *ret;
94 gfp_t gfp_mask = root_gfp_mask(root); 99 gfp_t gfp_mask = root_gfp_mask(root);
95 100
96 ret = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask); 101 ret = kmem_cache_alloc(radix_tree_node_cachep,
102 set_migrateflags(gfp_mask, __GFP_RECLAIMABLE));
97 if (ret == NULL && !(gfp_mask & __GFP_WAIT)) { 103 if (ret == NULL && !(gfp_mask & __GFP_WAIT)) {
98 struct radix_tree_preload *rtp; 104 struct radix_tree_preload *rtp;
99 105
@@ -104,7 +110,7 @@ radix_tree_node_alloc(struct radix_tree_root *root)
104 rtp->nr--; 110 rtp->nr--;
105 } 111 }
106 } 112 }
107 BUG_ON(radix_tree_is_direct_ptr(ret)); 113 BUG_ON(radix_tree_is_indirect_ptr(ret));
108 return ret; 114 return ret;
109} 115}
110 116
@@ -137,7 +143,8 @@ int radix_tree_preload(gfp_t gfp_mask)
137 rtp = &__get_cpu_var(radix_tree_preloads); 143 rtp = &__get_cpu_var(radix_tree_preloads);
138 while (rtp->nr < ARRAY_SIZE(rtp->nodes)) { 144 while (rtp->nr < ARRAY_SIZE(rtp->nodes)) {
139 preempt_enable(); 145 preempt_enable();
140 node = kmem_cache_alloc(radix_tree_node_cachep, gfp_mask); 146 node = kmem_cache_alloc(radix_tree_node_cachep,
147 set_migrateflags(gfp_mask, __GFP_RECLAIMABLE));
141 if (node == NULL) 148 if (node == NULL)
142 goto out; 149 goto out;
143 preempt_disable(); 150 preempt_disable();
@@ -240,7 +247,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
240 return -ENOMEM; 247 return -ENOMEM;
241 248
242 /* Increase the height. */ 249 /* Increase the height. */
243 node->slots[0] = radix_tree_direct_to_ptr(root->rnode); 250 node->slots[0] = radix_tree_indirect_to_ptr(root->rnode);
244 251
245 /* Propagate the aggregated tag info into the new root */ 252 /* Propagate the aggregated tag info into the new root */
246 for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) { 253 for (tag = 0; tag < RADIX_TREE_MAX_TAGS; tag++) {
@@ -251,6 +258,7 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
251 newheight = root->height+1; 258 newheight = root->height+1;
252 node->height = newheight; 259 node->height = newheight;
253 node->count = 1; 260 node->count = 1;
261 node = radix_tree_ptr_to_indirect(node);
254 rcu_assign_pointer(root->rnode, node); 262 rcu_assign_pointer(root->rnode, node);
255 root->height = newheight; 263 root->height = newheight;
256 } while (height > root->height); 264 } while (height > root->height);
@@ -274,7 +282,7 @@ int radix_tree_insert(struct radix_tree_root *root,
274 int offset; 282 int offset;
275 int error; 283 int error;
276 284
277 BUG_ON(radix_tree_is_direct_ptr(item)); 285 BUG_ON(radix_tree_is_indirect_ptr(item));
278 286
279 /* Make sure the tree is high enough. */ 287 /* Make sure the tree is high enough. */
280 if (index > radix_tree_maxindex(root->height)) { 288 if (index > radix_tree_maxindex(root->height)) {
@@ -283,7 +291,8 @@ int radix_tree_insert(struct radix_tree_root *root,
283 return error; 291 return error;
284 } 292 }
285 293
286 slot = root->rnode; 294 slot = radix_tree_indirect_to_ptr(root->rnode);
295
287 height = root->height; 296 height = root->height;
288 shift = (height-1) * RADIX_TREE_MAP_SHIFT; 297 shift = (height-1) * RADIX_TREE_MAP_SHIFT;
289 298
@@ -298,7 +307,8 @@ int radix_tree_insert(struct radix_tree_root *root,
298 rcu_assign_pointer(node->slots[offset], slot); 307 rcu_assign_pointer(node->slots[offset], slot);
299 node->count++; 308 node->count++;
300 } else 309 } else
301 rcu_assign_pointer(root->rnode, slot); 310 rcu_assign_pointer(root->rnode,
311 radix_tree_ptr_to_indirect(slot));
302 } 312 }
303 313
304 /* Go a level down */ 314 /* Go a level down */
@@ -318,7 +328,7 @@ int radix_tree_insert(struct radix_tree_root *root,
318 BUG_ON(tag_get(node, 0, offset)); 328 BUG_ON(tag_get(node, 0, offset));
319 BUG_ON(tag_get(node, 1, offset)); 329 BUG_ON(tag_get(node, 1, offset));
320 } else { 330 } else {
321 rcu_assign_pointer(root->rnode, radix_tree_ptr_to_direct(item)); 331 rcu_assign_pointer(root->rnode, item);
322 BUG_ON(root_tag_get(root, 0)); 332 BUG_ON(root_tag_get(root, 0));
323 BUG_ON(root_tag_get(root, 1)); 333 BUG_ON(root_tag_get(root, 1));
324 } 334 }
@@ -350,11 +360,12 @@ void **radix_tree_lookup_slot(struct radix_tree_root *root, unsigned long index)
350 if (node == NULL) 360 if (node == NULL)
351 return NULL; 361 return NULL;
352 362
353 if (radix_tree_is_direct_ptr(node)) { 363 if (!radix_tree_is_indirect_ptr(node)) {
354 if (index > 0) 364 if (index > 0)
355 return NULL; 365 return NULL;
356 return (void **)&root->rnode; 366 return (void **)&root->rnode;
357 } 367 }
368 node = radix_tree_indirect_to_ptr(node);
358 369
359 height = node->height; 370 height = node->height;
360 if (index > radix_tree_maxindex(height)) 371 if (index > radix_tree_maxindex(height))
@@ -398,11 +409,12 @@ void *radix_tree_lookup(struct radix_tree_root *root, unsigned long index)
398 if (node == NULL) 409 if (node == NULL)
399 return NULL; 410 return NULL;
400 411
401 if (radix_tree_is_direct_ptr(node)) { 412 if (!radix_tree_is_indirect_ptr(node)) {
402 if (index > 0) 413 if (index > 0)
403 return NULL; 414 return NULL;
404 return radix_tree_direct_to_ptr(node); 415 return node;
405 } 416 }
417 node = radix_tree_indirect_to_ptr(node);
406 418
407 height = node->height; 419 height = node->height;
408 if (index > radix_tree_maxindex(height)) 420 if (index > radix_tree_maxindex(height))
@@ -447,7 +459,7 @@ void *radix_tree_tag_set(struct radix_tree_root *root,
447 height = root->height; 459 height = root->height;
448 BUG_ON(index > radix_tree_maxindex(height)); 460 BUG_ON(index > radix_tree_maxindex(height));
449 461
450 slot = root->rnode; 462 slot = radix_tree_indirect_to_ptr(root->rnode);
451 shift = (height - 1) * RADIX_TREE_MAP_SHIFT; 463 shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
452 464
453 while (height > 0) { 465 while (height > 0) {
@@ -487,7 +499,11 @@ EXPORT_SYMBOL(radix_tree_tag_set);
487void *radix_tree_tag_clear(struct radix_tree_root *root, 499void *radix_tree_tag_clear(struct radix_tree_root *root,
488 unsigned long index, unsigned int tag) 500 unsigned long index, unsigned int tag)
489{ 501{
490 struct radix_tree_path path[RADIX_TREE_MAX_PATH], *pathp = path; 502 /*
503 * The radix tree path needs to be one longer than the maximum path
504 * since the "list" is null terminated.
505 */
506 struct radix_tree_path path[RADIX_TREE_MAX_PATH + 1], *pathp = path;
491 struct radix_tree_node *slot = NULL; 507 struct radix_tree_node *slot = NULL;
492 unsigned int height, shift; 508 unsigned int height, shift;
493 509
@@ -497,7 +513,7 @@ void *radix_tree_tag_clear(struct radix_tree_root *root,
497 513
498 shift = (height - 1) * RADIX_TREE_MAP_SHIFT; 514 shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
499 pathp->node = NULL; 515 pathp->node = NULL;
500 slot = root->rnode; 516 slot = radix_tree_indirect_to_ptr(root->rnode);
501 517
502 while (height > 0) { 518 while (height > 0) {
503 int offset; 519 int offset;
@@ -562,8 +578,9 @@ int radix_tree_tag_get(struct radix_tree_root *root,
562 if (node == NULL) 578 if (node == NULL)
563 return 0; 579 return 0;
564 580
565 if (radix_tree_is_direct_ptr(node)) 581 if (!radix_tree_is_indirect_ptr(node))
566 return (index == 0); 582 return (index == 0);
583 node = radix_tree_indirect_to_ptr(node);
567 584
568 height = node->height; 585 height = node->height;
569 if (index > radix_tree_maxindex(height)) 586 if (index > radix_tree_maxindex(height))
@@ -599,6 +616,42 @@ int radix_tree_tag_get(struct radix_tree_root *root,
599EXPORT_SYMBOL(radix_tree_tag_get); 616EXPORT_SYMBOL(radix_tree_tag_get);
600#endif 617#endif
601 618
619/**
620 * radix_tree_next_hole - find the next hole (not-present entry)
621 * @root: tree root
622 * @index: index key
623 * @max_scan: maximum range to search
624 *
625 * Search the set [index, min(index+max_scan-1, MAX_INDEX)] for the lowest
626 * indexed hole.
627 *
628 * Returns: the index of the hole if found, otherwise returns an index
629 * outside of the set specified (in which case 'return - index >= max_scan'
630 * will be true).
631 *
632 * radix_tree_next_hole may be called under rcu_read_lock. However, like
633 * radix_tree_gang_lookup, this will not atomically search a snapshot of the
634 * tree at a single point in time. For example, if a hole is created at index
635 * 5, then subsequently a hole is created at index 10, radix_tree_next_hole
636 * covering both indexes may return 10 if called under rcu_read_lock.
637 */
638unsigned long radix_tree_next_hole(struct radix_tree_root *root,
639 unsigned long index, unsigned long max_scan)
640{
641 unsigned long i;
642
643 for (i = 0; i < max_scan; i++) {
644 if (!radix_tree_lookup(root, index))
645 break;
646 index++;
647 if (index == 0)
648 break;
649 }
650
651 return index;
652}
653EXPORT_SYMBOL(radix_tree_next_hole);
654
602static unsigned int 655static unsigned int
603__lookup(struct radix_tree_node *slot, void **results, unsigned long index, 656__lookup(struct radix_tree_node *slot, void **results, unsigned long index,
604 unsigned int max_items, unsigned long *next_index) 657 unsigned int max_items, unsigned long *next_index)
@@ -680,13 +733,13 @@ radix_tree_gang_lookup(struct radix_tree_root *root, void **results,
680 if (!node) 733 if (!node)
681 return 0; 734 return 0;
682 735
683 if (radix_tree_is_direct_ptr(node)) { 736 if (!radix_tree_is_indirect_ptr(node)) {
684 if (first_index > 0) 737 if (first_index > 0)
685 return 0; 738 return 0;
686 node = radix_tree_direct_to_ptr(node); 739 results[0] = node;
687 results[0] = rcu_dereference(node);
688 return 1; 740 return 1;
689 } 741 }
742 node = radix_tree_indirect_to_ptr(node);
690 743
691 max_index = radix_tree_maxindex(node->height); 744 max_index = radix_tree_maxindex(node->height);
692 745
@@ -808,13 +861,13 @@ radix_tree_gang_lookup_tag(struct radix_tree_root *root, void **results,
808 if (!node) 861 if (!node)
809 return 0; 862 return 0;
810 863
811 if (radix_tree_is_direct_ptr(node)) { 864 if (!radix_tree_is_indirect_ptr(node)) {
812 if (first_index > 0) 865 if (first_index > 0)
813 return 0; 866 return 0;
814 node = radix_tree_direct_to_ptr(node); 867 results[0] = node;
815 results[0] = rcu_dereference(node);
816 return 1; 868 return 1;
817 } 869 }
870 node = radix_tree_indirect_to_ptr(node);
818 871
819 max_index = radix_tree_maxindex(node->height); 872 max_index = radix_tree_maxindex(node->height);
820 873
@@ -844,12 +897,22 @@ EXPORT_SYMBOL(radix_tree_gang_lookup_tag);
844static inline void radix_tree_shrink(struct radix_tree_root *root) 897static inline void radix_tree_shrink(struct radix_tree_root *root)
845{ 898{
846 /* try to shrink tree height */ 899 /* try to shrink tree height */
847 while (root->height > 0 && 900 while (root->height > 0) {
848 root->rnode->count == 1 &&
849 root->rnode->slots[0]) {
850 struct radix_tree_node *to_free = root->rnode; 901 struct radix_tree_node *to_free = root->rnode;
851 void *newptr; 902 void *newptr;
852 903
904 BUG_ON(!radix_tree_is_indirect_ptr(to_free));
905 to_free = radix_tree_indirect_to_ptr(to_free);
906
907 /*
908 * The candidate node has more than one child, or its child
909 * is not at the leftmost slot, we cannot shrink.
910 */
911 if (to_free->count != 1)
912 break;
913 if (!to_free->slots[0])
914 break;
915
853 /* 916 /*
854 * We don't need rcu_assign_pointer(), since we are simply 917 * We don't need rcu_assign_pointer(), since we are simply
855 * moving the node from one part of the tree to another. If 918 * moving the node from one part of the tree to another. If
@@ -858,8 +921,8 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)
858 * one (root->rnode). 921 * one (root->rnode).
859 */ 922 */
860 newptr = to_free->slots[0]; 923 newptr = to_free->slots[0];
861 if (root->height == 1) 924 if (root->height > 1)
862 newptr = radix_tree_ptr_to_direct(newptr); 925 newptr = radix_tree_ptr_to_indirect(newptr);
863 root->rnode = newptr; 926 root->rnode = newptr;
864 root->height--; 927 root->height--;
865 /* must only free zeroed nodes into the slab */ 928 /* must only free zeroed nodes into the slab */
@@ -882,7 +945,11 @@ static inline void radix_tree_shrink(struct radix_tree_root *root)
882 */ 945 */
883void *radix_tree_delete(struct radix_tree_root *root, unsigned long index) 946void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
884{ 947{
885 struct radix_tree_path path[RADIX_TREE_MAX_PATH], *pathp = path; 948 /*
949 * The radix tree path needs to be one longer than the maximum path
950 * since the "list" is null terminated.
951 */
952 struct radix_tree_path path[RADIX_TREE_MAX_PATH + 1], *pathp = path;
886 struct radix_tree_node *slot = NULL; 953 struct radix_tree_node *slot = NULL;
887 struct radix_tree_node *to_free; 954 struct radix_tree_node *to_free;
888 unsigned int height, shift; 955 unsigned int height, shift;
@@ -894,12 +961,12 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
894 goto out; 961 goto out;
895 962
896 slot = root->rnode; 963 slot = root->rnode;
897 if (height == 0 && root->rnode) { 964 if (height == 0) {
898 slot = radix_tree_direct_to_ptr(slot);
899 root_tag_clear_all(root); 965 root_tag_clear_all(root);
900 root->rnode = NULL; 966 root->rnode = NULL;
901 goto out; 967 goto out;
902 } 968 }
969 slot = radix_tree_indirect_to_ptr(slot);
903 970
904 shift = (height - 1) * RADIX_TREE_MAP_SHIFT; 971 shift = (height - 1) * RADIX_TREE_MAP_SHIFT;
905 pathp->node = NULL; 972 pathp->node = NULL;
@@ -941,7 +1008,8 @@ void *radix_tree_delete(struct radix_tree_root *root, unsigned long index)
941 radix_tree_node_free(to_free); 1008 radix_tree_node_free(to_free);
942 1009
943 if (pathp->node->count) { 1010 if (pathp->node->count) {
944 if (pathp->node == root->rnode) 1011 if (pathp->node ==
1012 radix_tree_indirect_to_ptr(root->rnode))
945 radix_tree_shrink(root); 1013 radix_tree_shrink(root);
946 goto out; 1014 goto out;
947 } 1015 }
diff --git a/lib/swiotlb.c b/lib/swiotlb.c
index 30c1400e749e..c419ecf334c3 100644
--- a/lib/swiotlb.c
+++ b/lib/swiotlb.c
@@ -677,16 +677,17 @@ swiotlb_sync_single_range_for_device(struct device *hwdev, dma_addr_t dev_addr,
677 * same here. 677 * same here.
678 */ 678 */
679int 679int
680swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems, 680swiotlb_map_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
681 int dir) 681 int dir)
682{ 682{
683 struct scatterlist *sg;
683 void *addr; 684 void *addr;
684 dma_addr_t dev_addr; 685 dma_addr_t dev_addr;
685 int i; 686 int i;
686 687
687 BUG_ON(dir == DMA_NONE); 688 BUG_ON(dir == DMA_NONE);
688 689
689 for (i = 0; i < nelems; i++, sg++) { 690 for_each_sg(sgl, sg, nelems, i) {
690 addr = SG_ENT_VIRT_ADDRESS(sg); 691 addr = SG_ENT_VIRT_ADDRESS(sg);
691 dev_addr = virt_to_bus(addr); 692 dev_addr = virt_to_bus(addr);
692 if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) { 693 if (swiotlb_force || address_needs_mapping(hwdev, dev_addr)) {
@@ -696,7 +697,7 @@ swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
696 to do proper error handling. */ 697 to do proper error handling. */
697 swiotlb_full(hwdev, sg->length, dir, 0); 698 swiotlb_full(hwdev, sg->length, dir, 0);
698 swiotlb_unmap_sg(hwdev, sg - i, i, dir); 699 swiotlb_unmap_sg(hwdev, sg - i, i, dir);
699 sg[0].dma_length = 0; 700 sgl[0].dma_length = 0;
700 return 0; 701 return 0;
701 } 702 }
702 sg->dma_address = virt_to_bus(map); 703 sg->dma_address = virt_to_bus(map);
@@ -712,19 +713,21 @@ swiotlb_map_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
712 * concerning calls here are the same as for swiotlb_unmap_single() above. 713 * concerning calls here are the same as for swiotlb_unmap_single() above.
713 */ 714 */
714void 715void
715swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems, 716swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sgl, int nelems,
716 int dir) 717 int dir)
717{ 718{
719 struct scatterlist *sg;
718 int i; 720 int i;
719 721
720 BUG_ON(dir == DMA_NONE); 722 BUG_ON(dir == DMA_NONE);
721 723
722 for (i = 0; i < nelems; i++, sg++) 724 for_each_sg(sgl, sg, nelems, i) {
723 if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) 725 if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
724 unmap_single(hwdev, bus_to_virt(sg->dma_address), 726 unmap_single(hwdev, bus_to_virt(sg->dma_address),
725 sg->dma_length, dir); 727 sg->dma_length, dir);
726 else if (dir == DMA_FROM_DEVICE) 728 else if (dir == DMA_FROM_DEVICE)
727 dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); 729 dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length);
730 }
728} 731}
729 732
730/* 733/*
@@ -735,19 +738,21 @@ swiotlb_unmap_sg(struct device *hwdev, struct scatterlist *sg, int nelems,
735 * and usage. 738 * and usage.
736 */ 739 */
737static void 740static void
738swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sg, 741swiotlb_sync_sg(struct device *hwdev, struct scatterlist *sgl,
739 int nelems, int dir, int target) 742 int nelems, int dir, int target)
740{ 743{
744 struct scatterlist *sg;
741 int i; 745 int i;
742 746
743 BUG_ON(dir == DMA_NONE); 747 BUG_ON(dir == DMA_NONE);
744 748
745 for (i = 0; i < nelems; i++, sg++) 749 for_each_sg(sgl, sg, nelems, i) {
746 if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg)) 750 if (sg->dma_address != SG_ENT_PHYS_ADDRESS(sg))
747 sync_single(hwdev, bus_to_virt(sg->dma_address), 751 sync_single(hwdev, bus_to_virt(sg->dma_address),
748 sg->dma_length, dir, target); 752 sg->dma_length, dir, target);
749 else if (dir == DMA_FROM_DEVICE) 753 else if (dir == DMA_FROM_DEVICE)
750 dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length); 754 dma_mark_clean(SG_ENT_VIRT_ADDRESS(sg), sg->dma_length);
755 }
751} 756}
752 757
753void 758void
diff --git a/mm/Kconfig b/mm/Kconfig
index a7609cbcb00d..1cc6cada2bbf 100644
--- a/mm/Kconfig
+++ b/mm/Kconfig
@@ -112,6 +112,19 @@ config SPARSEMEM_EXTREME
112 def_bool y 112 def_bool y
113 depends on SPARSEMEM && !SPARSEMEM_STATIC 113 depends on SPARSEMEM && !SPARSEMEM_STATIC
114 114
115#
116# SPARSEMEM_VMEMMAP uses a virtually mapped mem_map to optimise pfn_to_page
117# and page_to_pfn. The most efficient option where kernel virtual space is
118# not under pressure.
119#
120config SPARSEMEM_VMEMMAP_ENABLE
121 def_bool n
122
123config SPARSEMEM_VMEMMAP
124 bool
125 depends on SPARSEMEM
126 default y if (SPARSEMEM_VMEMMAP_ENABLE)
127
115# eventually, we can have this option just 'select SPARSEMEM' 128# eventually, we can have this option just 'select SPARSEMEM'
116config MEMORY_HOTPLUG 129config MEMORY_HOTPLUG
117 bool "Allow for memory hot-add" 130 bool "Allow for memory hot-add"
@@ -126,6 +139,11 @@ config MEMORY_HOTPLUG_SPARSE
126 def_bool y 139 def_bool y
127 depends on SPARSEMEM && MEMORY_HOTPLUG 140 depends on SPARSEMEM && MEMORY_HOTPLUG
128 141
142config MEMORY_HOTREMOVE
143 bool "Allow for memory hot remove"
144 depends on MEMORY_HOTPLUG && ARCH_ENABLE_MEMORY_HOTREMOVE
145 depends on MIGRATION
146
129# Heavily threaded applications may benefit from splitting the mm-wide 147# Heavily threaded applications may benefit from splitting the mm-wide
130# page_table_lock, so that faults on different parts of the user address 148# page_table_lock, so that faults on different parts of the user address
131# space can be handled with less contention: split it at this NR_CPUS. 149# space can be handled with less contention: split it at this NR_CPUS.
diff --git a/mm/Makefile b/mm/Makefile
index 245e33ab00c4..5c0b0ea7572d 100644
--- a/mm/Makefile
+++ b/mm/Makefile
@@ -11,13 +11,14 @@ obj-y := bootmem.o filemap.o mempool.o oom_kill.o fadvise.o \
11 page_alloc.o page-writeback.o pdflush.o \ 11 page_alloc.o page-writeback.o pdflush.o \
12 readahead.o swap.o truncate.o vmscan.o \ 12 readahead.o swap.o truncate.o vmscan.o \
13 prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \ 13 prio_tree.o util.o mmzone.o vmstat.o backing-dev.o \
14 $(mmu-y) 14 page_isolation.o $(mmu-y)
15 15
16obj-$(CONFIG_BOUNCE) += bounce.o 16obj-$(CONFIG_BOUNCE) += bounce.o
17obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o 17obj-$(CONFIG_SWAP) += page_io.o swap_state.o swapfile.o thrash.o
18obj-$(CONFIG_HUGETLBFS) += hugetlb.o 18obj-$(CONFIG_HUGETLBFS) += hugetlb.o
19obj-$(CONFIG_NUMA) += mempolicy.o 19obj-$(CONFIG_NUMA) += mempolicy.o
20obj-$(CONFIG_SPARSEMEM) += sparse.o 20obj-$(CONFIG_SPARSEMEM) += sparse.o
21obj-$(CONFIG_SPARSEMEM_VMEMMAP) += sparse-vmemmap.o
21obj-$(CONFIG_SHMEM) += shmem.o 22obj-$(CONFIG_SHMEM) += shmem.o
22obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o 23obj-$(CONFIG_TMPFS_POSIX_ACL) += shmem_acl.o
23obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o 24obj-$(CONFIG_TINY_SHMEM) += tiny-shmem.o
diff --git a/mm/bounce.c b/mm/bounce.c
index 3b549bf31f7d..b6d2d0f1019b 100644
--- a/mm/bounce.c
+++ b/mm/bounce.c
@@ -265,6 +265,12 @@ void blk_queue_bounce(struct request_queue *q, struct bio **bio_orig)
265 mempool_t *pool; 265 mempool_t *pool;
266 266
267 /* 267 /*
268 * Data-less bio, nothing to bounce
269 */
270 if (bio_empty_barrier(*bio_orig))
271 return;
272
273 /*
268 * for non-isa bounce case, just check if the bounce pfn is equal 274 * for non-isa bounce case, just check if the bounce pfn is equal
269 * to or bigger than the highest pfn in the system -- in that case, 275 * to or bigger than the highest pfn in the system -- in that case,
270 * don't waste time iterating over bio segments 276 * don't waste time iterating over bio segments
diff --git a/mm/filemap.c b/mm/filemap.c
index 15c8413ee929..c6049e947cd9 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -30,7 +30,7 @@
30#include <linux/security.h> 30#include <linux/security.h>
31#include <linux/syscalls.h> 31#include <linux/syscalls.h>
32#include <linux/cpuset.h> 32#include <linux/cpuset.h>
33#include "filemap.h" 33#include <linux/hardirq.h> /* for BUG_ON(!in_atomic()) only */
34#include "internal.h" 34#include "internal.h"
35 35
36/* 36/*
@@ -593,7 +593,7 @@ void fastcall __lock_page_nosync(struct page *page)
593 * Is there a pagecache struct page at the given (mapping, offset) tuple? 593 * Is there a pagecache struct page at the given (mapping, offset) tuple?
594 * If yes, increment its refcount and return it; if no, return NULL. 594 * If yes, increment its refcount and return it; if no, return NULL.
595 */ 595 */
596struct page * find_get_page(struct address_space *mapping, unsigned long offset) 596struct page * find_get_page(struct address_space *mapping, pgoff_t offset)
597{ 597{
598 struct page *page; 598 struct page *page;
599 599
@@ -617,30 +617,31 @@ EXPORT_SYMBOL(find_get_page);
617 * Returns zero if the page was not present. find_lock_page() may sleep. 617 * Returns zero if the page was not present. find_lock_page() may sleep.
618 */ 618 */
619struct page *find_lock_page(struct address_space *mapping, 619struct page *find_lock_page(struct address_space *mapping,
620 unsigned long offset) 620 pgoff_t offset)
621{ 621{
622 struct page *page; 622 struct page *page;
623 623
624 read_lock_irq(&mapping->tree_lock);
625repeat: 624repeat:
625 read_lock_irq(&mapping->tree_lock);
626 page = radix_tree_lookup(&mapping->page_tree, offset); 626 page = radix_tree_lookup(&mapping->page_tree, offset);
627 if (page) { 627 if (page) {
628 page_cache_get(page); 628 page_cache_get(page);
629 if (TestSetPageLocked(page)) { 629 if (TestSetPageLocked(page)) {
630 read_unlock_irq(&mapping->tree_lock); 630 read_unlock_irq(&mapping->tree_lock);
631 __lock_page(page); 631 __lock_page(page);
632 read_lock_irq(&mapping->tree_lock);
633 632
634 /* Has the page been truncated while we slept? */ 633 /* Has the page been truncated while we slept? */
635 if (unlikely(page->mapping != mapping || 634 if (unlikely(page->mapping != mapping)) {
636 page->index != offset)) {
637 unlock_page(page); 635 unlock_page(page);
638 page_cache_release(page); 636 page_cache_release(page);
639 goto repeat; 637 goto repeat;
640 } 638 }
639 VM_BUG_ON(page->index != offset);
640 goto out;
641 } 641 }
642 } 642 }
643 read_unlock_irq(&mapping->tree_lock); 643 read_unlock_irq(&mapping->tree_lock);
644out:
644 return page; 645 return page;
645} 646}
646EXPORT_SYMBOL(find_lock_page); 647EXPORT_SYMBOL(find_lock_page);
@@ -663,29 +664,24 @@ EXPORT_SYMBOL(find_lock_page);
663 * memory exhaustion. 664 * memory exhaustion.
664 */ 665 */
665struct page *find_or_create_page(struct address_space *mapping, 666struct page *find_or_create_page(struct address_space *mapping,
666 unsigned long index, gfp_t gfp_mask) 667 pgoff_t index, gfp_t gfp_mask)
667{ 668{
668 struct page *page, *cached_page = NULL; 669 struct page *page;
669 int err; 670 int err;
670repeat: 671repeat:
671 page = find_lock_page(mapping, index); 672 page = find_lock_page(mapping, index);
672 if (!page) { 673 if (!page) {
673 if (!cached_page) { 674 page = __page_cache_alloc(gfp_mask);
674 cached_page = 675 if (!page)
675 __page_cache_alloc(gfp_mask); 676 return NULL;
676 if (!cached_page) 677 err = add_to_page_cache_lru(page, mapping, index, gfp_mask);
677 return NULL; 678 if (unlikely(err)) {
679 page_cache_release(page);
680 page = NULL;
681 if (err == -EEXIST)
682 goto repeat;
678 } 683 }
679 err = add_to_page_cache_lru(cached_page, mapping,
680 index, gfp_mask);
681 if (!err) {
682 page = cached_page;
683 cached_page = NULL;
684 } else if (err == -EEXIST)
685 goto repeat;
686 } 684 }
687 if (cached_page)
688 page_cache_release(cached_page);
689 return page; 685 return page;
690} 686}
691EXPORT_SYMBOL(find_or_create_page); 687EXPORT_SYMBOL(find_or_create_page);
@@ -797,7 +793,7 @@ EXPORT_SYMBOL(find_get_pages_tag);
797 * and deadlock against the caller's locked page. 793 * and deadlock against the caller's locked page.
798 */ 794 */
799struct page * 795struct page *
800grab_cache_page_nowait(struct address_space *mapping, unsigned long index) 796grab_cache_page_nowait(struct address_space *mapping, pgoff_t index)
801{ 797{
802 struct page *page = find_get_page(mapping, index); 798 struct page *page = find_get_page(mapping, index);
803 799
@@ -859,34 +855,29 @@ static void shrink_readahead_size_eio(struct file *filp,
859 * It may be NULL. 855 * It may be NULL.
860 */ 856 */
861void do_generic_mapping_read(struct address_space *mapping, 857void do_generic_mapping_read(struct address_space *mapping,
862 struct file_ra_state *_ra, 858 struct file_ra_state *ra,
863 struct file *filp, 859 struct file *filp,
864 loff_t *ppos, 860 loff_t *ppos,
865 read_descriptor_t *desc, 861 read_descriptor_t *desc,
866 read_actor_t actor) 862 read_actor_t actor)
867{ 863{
868 struct inode *inode = mapping->host; 864 struct inode *inode = mapping->host;
869 unsigned long index; 865 pgoff_t index;
870 unsigned long offset; 866 pgoff_t last_index;
871 unsigned long last_index; 867 pgoff_t prev_index;
872 unsigned long next_index; 868 unsigned long offset; /* offset into pagecache page */
873 unsigned long prev_index;
874 unsigned int prev_offset; 869 unsigned int prev_offset;
875 struct page *cached_page;
876 int error; 870 int error;
877 struct file_ra_state ra = *_ra;
878 871
879 cached_page = NULL;
880 index = *ppos >> PAGE_CACHE_SHIFT; 872 index = *ppos >> PAGE_CACHE_SHIFT;
881 next_index = index; 873 prev_index = ra->prev_pos >> PAGE_CACHE_SHIFT;
882 prev_index = ra.prev_index; 874 prev_offset = ra->prev_pos & (PAGE_CACHE_SIZE-1);
883 prev_offset = ra.prev_offset;
884 last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT; 875 last_index = (*ppos + desc->count + PAGE_CACHE_SIZE-1) >> PAGE_CACHE_SHIFT;
885 offset = *ppos & ~PAGE_CACHE_MASK; 876 offset = *ppos & ~PAGE_CACHE_MASK;
886 877
887 for (;;) { 878 for (;;) {
888 struct page *page; 879 struct page *page;
889 unsigned long end_index; 880 pgoff_t end_index;
890 loff_t isize; 881 loff_t isize;
891 unsigned long nr, ret; 882 unsigned long nr, ret;
892 883
@@ -895,7 +886,7 @@ find_page:
895 page = find_get_page(mapping, index); 886 page = find_get_page(mapping, index);
896 if (!page) { 887 if (!page) {
897 page_cache_sync_readahead(mapping, 888 page_cache_sync_readahead(mapping,
898 &ra, filp, 889 ra, filp,
899 index, last_index - index); 890 index, last_index - index);
900 page = find_get_page(mapping, index); 891 page = find_get_page(mapping, index);
901 if (unlikely(page == NULL)) 892 if (unlikely(page == NULL))
@@ -903,7 +894,7 @@ find_page:
903 } 894 }
904 if (PageReadahead(page)) { 895 if (PageReadahead(page)) {
905 page_cache_async_readahead(mapping, 896 page_cache_async_readahead(mapping,
906 &ra, filp, page, 897 ra, filp, page,
907 index, last_index - index); 898 index, last_index - index);
908 } 899 }
909 if (!PageUptodate(page)) 900 if (!PageUptodate(page))
@@ -966,7 +957,6 @@ page_ok:
966 index += offset >> PAGE_CACHE_SHIFT; 957 index += offset >> PAGE_CACHE_SHIFT;
967 offset &= ~PAGE_CACHE_MASK; 958 offset &= ~PAGE_CACHE_MASK;
968 prev_offset = offset; 959 prev_offset = offset;
969 ra.prev_offset = offset;
970 960
971 page_cache_release(page); 961 page_cache_release(page);
972 if (ret == nr && desc->count) 962 if (ret == nr && desc->count)
@@ -1015,7 +1005,7 @@ readpage:
1015 } 1005 }
1016 unlock_page(page); 1006 unlock_page(page);
1017 error = -EIO; 1007 error = -EIO;
1018 shrink_readahead_size_eio(filp, &ra); 1008 shrink_readahead_size_eio(filp, ra);
1019 goto readpage_error; 1009 goto readpage_error;
1020 } 1010 }
1021 unlock_page(page); 1011 unlock_page(page);
@@ -1034,33 +1024,29 @@ no_cached_page:
1034 * Ok, it wasn't cached, so we need to create a new 1024 * Ok, it wasn't cached, so we need to create a new
1035 * page.. 1025 * page..
1036 */ 1026 */
1037 if (!cached_page) { 1027 page = page_cache_alloc_cold(mapping);
1038 cached_page = page_cache_alloc_cold(mapping); 1028 if (!page) {
1039 if (!cached_page) { 1029 desc->error = -ENOMEM;
1040 desc->error = -ENOMEM; 1030 goto out;
1041 goto out;
1042 }
1043 } 1031 }
1044 error = add_to_page_cache_lru(cached_page, mapping, 1032 error = add_to_page_cache_lru(page, mapping,
1045 index, GFP_KERNEL); 1033 index, GFP_KERNEL);
1046 if (error) { 1034 if (error) {
1035 page_cache_release(page);
1047 if (error == -EEXIST) 1036 if (error == -EEXIST)
1048 goto find_page; 1037 goto find_page;
1049 desc->error = error; 1038 desc->error = error;
1050 goto out; 1039 goto out;
1051 } 1040 }
1052 page = cached_page;
1053 cached_page = NULL;
1054 goto readpage; 1041 goto readpage;
1055 } 1042 }
1056 1043
1057out: 1044out:
1058 *_ra = ra; 1045 ra->prev_pos = prev_index;
1059 _ra->prev_index = prev_index; 1046 ra->prev_pos <<= PAGE_CACHE_SHIFT;
1047 ra->prev_pos |= prev_offset;
1060 1048
1061 *ppos = ((loff_t) index << PAGE_CACHE_SHIFT) + offset; 1049 *ppos = ((loff_t)index << PAGE_CACHE_SHIFT) + offset;
1062 if (cached_page)
1063 page_cache_release(cached_page);
1064 if (filp) 1050 if (filp)
1065 file_accessed(filp); 1051 file_accessed(filp);
1066} 1052}
@@ -1220,7 +1206,7 @@ EXPORT_SYMBOL(generic_file_aio_read);
1220 1206
1221static ssize_t 1207static ssize_t
1222do_readahead(struct address_space *mapping, struct file *filp, 1208do_readahead(struct address_space *mapping, struct file *filp,
1223 unsigned long index, unsigned long nr) 1209 pgoff_t index, unsigned long nr)
1224{ 1210{
1225 if (!mapping || !mapping->a_ops || !mapping->a_ops->readpage) 1211 if (!mapping || !mapping->a_ops || !mapping->a_ops->readpage)
1226 return -EINVAL; 1212 return -EINVAL;
@@ -1240,8 +1226,8 @@ asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count)
1240 if (file) { 1226 if (file) {
1241 if (file->f_mode & FMODE_READ) { 1227 if (file->f_mode & FMODE_READ) {
1242 struct address_space *mapping = file->f_mapping; 1228 struct address_space *mapping = file->f_mapping;
1243 unsigned long start = offset >> PAGE_CACHE_SHIFT; 1229 pgoff_t start = offset >> PAGE_CACHE_SHIFT;
1244 unsigned long end = (offset + count - 1) >> PAGE_CACHE_SHIFT; 1230 pgoff_t end = (offset + count - 1) >> PAGE_CACHE_SHIFT;
1245 unsigned long len = end - start + 1; 1231 unsigned long len = end - start + 1;
1246 ret = do_readahead(mapping, file, start, len); 1232 ret = do_readahead(mapping, file, start, len);
1247 } 1233 }
@@ -1251,7 +1237,6 @@ asmlinkage ssize_t sys_readahead(int fd, loff_t offset, size_t count)
1251} 1237}
1252 1238
1253#ifdef CONFIG_MMU 1239#ifdef CONFIG_MMU
1254static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
1255/** 1240/**
1256 * page_cache_read - adds requested page to the page cache if not already there 1241 * page_cache_read - adds requested page to the page cache if not already there
1257 * @file: file to read 1242 * @file: file to read
@@ -1260,7 +1245,7 @@ static int FASTCALL(page_cache_read(struct file * file, unsigned long offset));
1260 * This adds the requested page to the page cache if it isn't already there, 1245 * This adds the requested page to the page cache if it isn't already there,
1261 * and schedules an I/O to read in its contents from disk. 1246 * and schedules an I/O to read in its contents from disk.
1262 */ 1247 */
1263static int fastcall page_cache_read(struct file * file, unsigned long offset) 1248static int fastcall page_cache_read(struct file * file, pgoff_t offset)
1264{ 1249{
1265 struct address_space *mapping = file->f_mapping; 1250 struct address_space *mapping = file->f_mapping;
1266 struct page *page; 1251 struct page *page;
@@ -1349,7 +1334,7 @@ retry_find:
1349 * Do we miss much more than hit in this file? If so, 1334 * Do we miss much more than hit in this file? If so,
1350 * stop bothering with read-ahead. It will only hurt. 1335 * stop bothering with read-ahead. It will only hurt.
1351 */ 1336 */
1352 if (ra->mmap_miss > ra->mmap_hit + MMAP_LOTSAMISS) 1337 if (ra->mmap_miss > MMAP_LOTSAMISS)
1353 goto no_cached_page; 1338 goto no_cached_page;
1354 1339
1355 /* 1340 /*
@@ -1375,7 +1360,7 @@ retry_find:
1375 } 1360 }
1376 1361
1377 if (!did_readaround) 1362 if (!did_readaround)
1378 ra->mmap_hit++; 1363 ra->mmap_miss--;
1379 1364
1380 /* 1365 /*
1381 * We have a locked page in the page cache, now we need to check 1366 * We have a locked page in the page cache, now we need to check
@@ -1396,7 +1381,7 @@ retry_find:
1396 * Found the page and have a reference on it. 1381 * Found the page and have a reference on it.
1397 */ 1382 */
1398 mark_page_accessed(page); 1383 mark_page_accessed(page);
1399 ra->prev_index = page->index; 1384 ra->prev_pos = (loff_t)page->index << PAGE_CACHE_SHIFT;
1400 vmf->page = page; 1385 vmf->page = page;
1401 return ret | VM_FAULT_LOCKED; 1386 return ret | VM_FAULT_LOCKED;
1402 1387
@@ -1501,39 +1486,32 @@ EXPORT_SYMBOL(generic_file_mmap);
1501EXPORT_SYMBOL(generic_file_readonly_mmap); 1486EXPORT_SYMBOL(generic_file_readonly_mmap);
1502 1487
1503static struct page *__read_cache_page(struct address_space *mapping, 1488static struct page *__read_cache_page(struct address_space *mapping,
1504 unsigned long index, 1489 pgoff_t index,
1505 int (*filler)(void *,struct page*), 1490 int (*filler)(void *,struct page*),
1506 void *data) 1491 void *data)
1507{ 1492{
1508 struct page *page, *cached_page = NULL; 1493 struct page *page;
1509 int err; 1494 int err;
1510repeat: 1495repeat:
1511 page = find_get_page(mapping, index); 1496 page = find_get_page(mapping, index);
1512 if (!page) { 1497 if (!page) {
1513 if (!cached_page) { 1498 page = page_cache_alloc_cold(mapping);
1514 cached_page = page_cache_alloc_cold(mapping); 1499 if (!page)
1515 if (!cached_page) 1500 return ERR_PTR(-ENOMEM);
1516 return ERR_PTR(-ENOMEM); 1501 err = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL);
1517 } 1502 if (unlikely(err)) {
1518 err = add_to_page_cache_lru(cached_page, mapping, 1503 page_cache_release(page);
1519 index, GFP_KERNEL); 1504 if (err == -EEXIST)
1520 if (err == -EEXIST) 1505 goto repeat;
1521 goto repeat;
1522 if (err < 0) {
1523 /* Presumably ENOMEM for radix tree node */ 1506 /* Presumably ENOMEM for radix tree node */
1524 page_cache_release(cached_page);
1525 return ERR_PTR(err); 1507 return ERR_PTR(err);
1526 } 1508 }
1527 page = cached_page;
1528 cached_page = NULL;
1529 err = filler(data, page); 1509 err = filler(data, page);
1530 if (err < 0) { 1510 if (err < 0) {
1531 page_cache_release(page); 1511 page_cache_release(page);
1532 page = ERR_PTR(err); 1512 page = ERR_PTR(err);
1533 } 1513 }
1534 } 1514 }
1535 if (cached_page)
1536 page_cache_release(cached_page);
1537 return page; 1515 return page;
1538} 1516}
1539 1517
@@ -1542,7 +1520,7 @@ repeat:
1542 * after submitting it to the filler. 1520 * after submitting it to the filler.
1543 */ 1521 */
1544struct page *read_cache_page_async(struct address_space *mapping, 1522struct page *read_cache_page_async(struct address_space *mapping,
1545 unsigned long index, 1523 pgoff_t index,
1546 int (*filler)(void *,struct page*), 1524 int (*filler)(void *,struct page*),
1547 void *data) 1525 void *data)
1548{ 1526{
@@ -1590,7 +1568,7 @@ EXPORT_SYMBOL(read_cache_page_async);
1590 * If the page does not get brought uptodate, return -EIO. 1568 * If the page does not get brought uptodate, return -EIO.
1591 */ 1569 */
1592struct page *read_cache_page(struct address_space *mapping, 1570struct page *read_cache_page(struct address_space *mapping,
1593 unsigned long index, 1571 pgoff_t index,
1594 int (*filler)(void *,struct page*), 1572 int (*filler)(void *,struct page*),
1595 void *data) 1573 void *data)
1596{ 1574{
@@ -1610,40 +1588,6 @@ struct page *read_cache_page(struct address_space *mapping,
1610EXPORT_SYMBOL(read_cache_page); 1588EXPORT_SYMBOL(read_cache_page);
1611 1589
1612/* 1590/*
1613 * If the page was newly created, increment its refcount and add it to the
1614 * caller's lru-buffering pagevec. This function is specifically for
1615 * generic_file_write().
1616 */
1617static inline struct page *
1618__grab_cache_page(struct address_space *mapping, unsigned long index,
1619 struct page **cached_page, struct pagevec *lru_pvec)
1620{
1621 int err;
1622 struct page *page;
1623repeat:
1624 page = find_lock_page(mapping, index);
1625 if (!page) {
1626 if (!*cached_page) {
1627 *cached_page = page_cache_alloc(mapping);
1628 if (!*cached_page)
1629 return NULL;
1630 }
1631 err = add_to_page_cache(*cached_page, mapping,
1632 index, GFP_KERNEL);
1633 if (err == -EEXIST)
1634 goto repeat;
1635 if (err == 0) {
1636 page = *cached_page;
1637 page_cache_get(page);
1638 if (!pagevec_add(lru_pvec, page))
1639 __pagevec_lru_add(lru_pvec);
1640 *cached_page = NULL;
1641 }
1642 }
1643 return page;
1644}
1645
1646/*
1647 * The logic we want is 1591 * The logic we want is
1648 * 1592 *
1649 * if suid or (sgid and xgrp) 1593 * if suid or (sgid and xgrp)
@@ -1691,8 +1635,7 @@ int remove_suid(struct dentry *dentry)
1691} 1635}
1692EXPORT_SYMBOL(remove_suid); 1636EXPORT_SYMBOL(remove_suid);
1693 1637
1694size_t 1638static size_t __iovec_copy_from_user_inatomic(char *vaddr,
1695__filemap_copy_from_user_iovec_inatomic(char *vaddr,
1696 const struct iovec *iov, size_t base, size_t bytes) 1639 const struct iovec *iov, size_t base, size_t bytes)
1697{ 1640{
1698 size_t copied = 0, left = 0; 1641 size_t copied = 0, left = 0;
@@ -1715,6 +1658,124 @@ __filemap_copy_from_user_iovec_inatomic(char *vaddr,
1715} 1658}
1716 1659
1717/* 1660/*
1661 * Copy as much as we can into the page and return the number of bytes which
1662 * were sucessfully copied. If a fault is encountered then return the number of
1663 * bytes which were copied.
1664 */
1665size_t iov_iter_copy_from_user_atomic(struct page *page,
1666 struct iov_iter *i, unsigned long offset, size_t bytes)
1667{
1668 char *kaddr;
1669 size_t copied;
1670
1671 BUG_ON(!in_atomic());
1672 kaddr = kmap_atomic(page, KM_USER0);
1673 if (likely(i->nr_segs == 1)) {
1674 int left;
1675 char __user *buf = i->iov->iov_base + i->iov_offset;
1676 left = __copy_from_user_inatomic_nocache(kaddr + offset,
1677 buf, bytes);
1678 copied = bytes - left;
1679 } else {
1680 copied = __iovec_copy_from_user_inatomic(kaddr + offset,
1681 i->iov, i->iov_offset, bytes);
1682 }
1683 kunmap_atomic(kaddr, KM_USER0);
1684
1685 return copied;
1686}
1687EXPORT_SYMBOL(iov_iter_copy_from_user_atomic);
1688
1689/*
1690 * This has the same sideeffects and return value as
1691 * iov_iter_copy_from_user_atomic().
1692 * The difference is that it attempts to resolve faults.
1693 * Page must not be locked.
1694 */
1695size_t iov_iter_copy_from_user(struct page *page,
1696 struct iov_iter *i, unsigned long offset, size_t bytes)
1697{
1698 char *kaddr;
1699 size_t copied;
1700
1701 kaddr = kmap(page);
1702 if (likely(i->nr_segs == 1)) {
1703 int left;
1704 char __user *buf = i->iov->iov_base + i->iov_offset;
1705 left = __copy_from_user_nocache(kaddr + offset, buf, bytes);
1706 copied = bytes - left;
1707 } else {
1708 copied = __iovec_copy_from_user_inatomic(kaddr + offset,
1709 i->iov, i->iov_offset, bytes);
1710 }
1711 kunmap(page);
1712 return copied;
1713}
1714EXPORT_SYMBOL(iov_iter_copy_from_user);
1715
1716static void __iov_iter_advance_iov(struct iov_iter *i, size_t bytes)
1717{
1718 if (likely(i->nr_segs == 1)) {
1719 i->iov_offset += bytes;
1720 } else {
1721 const struct iovec *iov = i->iov;
1722 size_t base = i->iov_offset;
1723
1724 while (bytes) {
1725 int copy = min(bytes, iov->iov_len - base);
1726
1727 bytes -= copy;
1728 base += copy;
1729 if (iov->iov_len == base) {
1730 iov++;
1731 base = 0;
1732 }
1733 }
1734 i->iov = iov;
1735 i->iov_offset = base;
1736 }
1737}
1738
1739void iov_iter_advance(struct iov_iter *i, size_t bytes)
1740{
1741 BUG_ON(i->count < bytes);
1742
1743 __iov_iter_advance_iov(i, bytes);
1744 i->count -= bytes;
1745}
1746EXPORT_SYMBOL(iov_iter_advance);
1747
1748/*
1749 * Fault in the first iovec of the given iov_iter, to a maximum length
1750 * of bytes. Returns 0 on success, or non-zero if the memory could not be
1751 * accessed (ie. because it is an invalid address).
1752 *
1753 * writev-intensive code may want this to prefault several iovecs -- that
1754 * would be possible (callers must not rely on the fact that _only_ the
1755 * first iovec will be faulted with the current implementation).
1756 */
1757int iov_iter_fault_in_readable(struct iov_iter *i, size_t bytes)
1758{
1759 char __user *buf = i->iov->iov_base + i->iov_offset;
1760 bytes = min(bytes, i->iov->iov_len - i->iov_offset);
1761 return fault_in_pages_readable(buf, bytes);
1762}
1763EXPORT_SYMBOL(iov_iter_fault_in_readable);
1764
1765/*
1766 * Return the count of just the current iov_iter segment.
1767 */
1768size_t iov_iter_single_seg_count(struct iov_iter *i)
1769{
1770 const struct iovec *iov = i->iov;
1771 if (i->nr_segs == 1)
1772 return i->count;
1773 else
1774 return min(i->count, iov->iov_len - i->iov_offset);
1775}
1776EXPORT_SYMBOL(iov_iter_single_seg_count);
1777
1778/*
1718 * Performs necessary checks before doing a write 1779 * Performs necessary checks before doing a write
1719 * 1780 *
1720 * Can adjust writing position or amount of bytes to write. 1781 * Can adjust writing position or amount of bytes to write.
@@ -1796,6 +1857,91 @@ inline int generic_write_checks(struct file *file, loff_t *pos, size_t *count, i
1796} 1857}
1797EXPORT_SYMBOL(generic_write_checks); 1858EXPORT_SYMBOL(generic_write_checks);
1798 1859
1860int pagecache_write_begin(struct file *file, struct address_space *mapping,
1861 loff_t pos, unsigned len, unsigned flags,
1862 struct page **pagep, void **fsdata)
1863{
1864 const struct address_space_operations *aops = mapping->a_ops;
1865
1866 if (aops->write_begin) {
1867 return aops->write_begin(file, mapping, pos, len, flags,
1868 pagep, fsdata);
1869 } else {
1870 int ret;
1871 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
1872 unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
1873 struct inode *inode = mapping->host;
1874 struct page *page;
1875again:
1876 page = __grab_cache_page(mapping, index);
1877 *pagep = page;
1878 if (!page)
1879 return -ENOMEM;
1880
1881 if (flags & AOP_FLAG_UNINTERRUPTIBLE && !PageUptodate(page)) {
1882 /*
1883 * There is no way to resolve a short write situation
1884 * for a !Uptodate page (except by double copying in
1885 * the caller done by generic_perform_write_2copy).
1886 *
1887 * Instead, we have to bring it uptodate here.
1888 */
1889 ret = aops->readpage(file, page);
1890 page_cache_release(page);
1891 if (ret) {
1892 if (ret == AOP_TRUNCATED_PAGE)
1893 goto again;
1894 return ret;
1895 }
1896 goto again;
1897 }
1898
1899 ret = aops->prepare_write(file, page, offset, offset+len);
1900 if (ret) {
1901 unlock_page(page);
1902 page_cache_release(page);
1903 if (pos + len > inode->i_size)
1904 vmtruncate(inode, inode->i_size);
1905 }
1906 return ret;
1907 }
1908}
1909EXPORT_SYMBOL(pagecache_write_begin);
1910
1911int pagecache_write_end(struct file *file, struct address_space *mapping,
1912 loff_t pos, unsigned len, unsigned copied,
1913 struct page *page, void *fsdata)
1914{
1915 const struct address_space_operations *aops = mapping->a_ops;
1916 int ret;
1917
1918 if (aops->write_end) {
1919 mark_page_accessed(page);
1920 ret = aops->write_end(file, mapping, pos, len, copied,
1921 page, fsdata);
1922 } else {
1923 unsigned offset = pos & (PAGE_CACHE_SIZE - 1);
1924 struct inode *inode = mapping->host;
1925
1926 flush_dcache_page(page);
1927 ret = aops->commit_write(file, page, offset, offset+len);
1928 unlock_page(page);
1929 mark_page_accessed(page);
1930 page_cache_release(page);
1931
1932 if (ret < 0) {
1933 if (pos + len > inode->i_size)
1934 vmtruncate(inode, inode->i_size);
1935 } else if (ret > 0)
1936 ret = min_t(size_t, copied, ret);
1937 else
1938 ret = copied;
1939 }
1940
1941 return ret;
1942}
1943EXPORT_SYMBOL(pagecache_write_end);
1944
1799ssize_t 1945ssize_t
1800generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov, 1946generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
1801 unsigned long *nr_segs, loff_t pos, loff_t *ppos, 1947 unsigned long *nr_segs, loff_t pos, loff_t *ppos,
@@ -1835,151 +1981,314 @@ generic_file_direct_write(struct kiocb *iocb, const struct iovec *iov,
1835} 1981}
1836EXPORT_SYMBOL(generic_file_direct_write); 1982EXPORT_SYMBOL(generic_file_direct_write);
1837 1983
1838ssize_t 1984/*
1839generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov, 1985 * Find or create a page at the given pagecache position. Return the locked
1840 unsigned long nr_segs, loff_t pos, loff_t *ppos, 1986 * page. This function is specifically for buffered writes.
1841 size_t count, ssize_t written) 1987 */
1988struct page *__grab_cache_page(struct address_space *mapping, pgoff_t index)
1842{ 1989{
1843 struct file *file = iocb->ki_filp; 1990 int status;
1844 struct address_space * mapping = file->f_mapping; 1991 struct page *page;
1845 const struct address_space_operations *a_ops = mapping->a_ops; 1992repeat:
1846 struct inode *inode = mapping->host; 1993 page = find_lock_page(mapping, index);
1847 long status = 0; 1994 if (likely(page))
1848 struct page *page; 1995 return page;
1849 struct page *cached_page = NULL;
1850 size_t bytes;
1851 struct pagevec lru_pvec;
1852 const struct iovec *cur_iov = iov; /* current iovec */
1853 size_t iov_base = 0; /* offset in the current iovec */
1854 char __user *buf;
1855
1856 pagevec_init(&lru_pvec, 0);
1857 1996
1858 /* 1997 page = page_cache_alloc(mapping);
1859 * handle partial DIO write. Adjust cur_iov if needed. 1998 if (!page)
1860 */ 1999 return NULL;
1861 if (likely(nr_segs == 1)) 2000 status = add_to_page_cache_lru(page, mapping, index, GFP_KERNEL);
1862 buf = iov->iov_base + written; 2001 if (unlikely(status)) {
1863 else { 2002 page_cache_release(page);
1864 filemap_set_next_iovec(&cur_iov, &iov_base, written); 2003 if (status == -EEXIST)
1865 buf = cur_iov->iov_base + iov_base; 2004 goto repeat;
2005 return NULL;
1866 } 2006 }
2007 return page;
2008}
2009EXPORT_SYMBOL(__grab_cache_page);
2010
2011static ssize_t generic_perform_write_2copy(struct file *file,
2012 struct iov_iter *i, loff_t pos)
2013{
2014 struct address_space *mapping = file->f_mapping;
2015 const struct address_space_operations *a_ops = mapping->a_ops;
2016 struct inode *inode = mapping->host;
2017 long status = 0;
2018 ssize_t written = 0;
1867 2019
1868 do { 2020 do {
1869 unsigned long index; 2021 struct page *src_page;
1870 unsigned long offset; 2022 struct page *page;
1871 size_t copied; 2023 pgoff_t index; /* Pagecache index for current page */
2024 unsigned long offset; /* Offset into pagecache page */
2025 unsigned long bytes; /* Bytes to write to page */
2026 size_t copied; /* Bytes copied from user */
1872 2027
1873 offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ 2028 offset = (pos & (PAGE_CACHE_SIZE - 1));
1874 index = pos >> PAGE_CACHE_SHIFT; 2029 index = pos >> PAGE_CACHE_SHIFT;
1875 bytes = PAGE_CACHE_SIZE - offset; 2030 bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
1876 2031 iov_iter_count(i));
1877 /* Limit the size of the copy to the caller's write size */
1878 bytes = min(bytes, count);
1879 2032
1880 /* We only need to worry about prefaulting when writes are from 2033 /*
1881 * user-space. NFSd uses vfs_writev with several non-aligned 2034 * a non-NULL src_page indicates that we're doing the
1882 * segments in the vector, and limiting to one segment a time is 2035 * copy via get_user_pages and kmap.
1883 * a noticeable performance for re-write
1884 */ 2036 */
1885 if (!segment_eq(get_fs(), KERNEL_DS)) { 2037 src_page = NULL;
1886 /*
1887 * Limit the size of the copy to that of the current
1888 * segment, because fault_in_pages_readable() doesn't
1889 * know how to walk segments.
1890 */
1891 bytes = min(bytes, cur_iov->iov_len - iov_base);
1892 2038
1893 /* 2039 /*
1894 * Bring in the user page that we will copy from 2040 * Bring in the user page that we will copy from _first_.
1895 * _first_. Otherwise there's a nasty deadlock on 2041 * Otherwise there's a nasty deadlock on copying from the
1896 * copying from the same page as we're writing to, 2042 * same page as we're writing to, without it being marked
1897 * without it being marked up-to-date. 2043 * up-to-date.
1898 */ 2044 *
1899 fault_in_pages_readable(buf, bytes); 2045 * Not only is this an optimisation, but it is also required
2046 * to check that the address is actually valid, when atomic
2047 * usercopies are used, below.
2048 */
2049 if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
2050 status = -EFAULT;
2051 break;
1900 } 2052 }
1901 page = __grab_cache_page(mapping,index,&cached_page,&lru_pvec); 2053
2054 page = __grab_cache_page(mapping, index);
1902 if (!page) { 2055 if (!page) {
1903 status = -ENOMEM; 2056 status = -ENOMEM;
1904 break; 2057 break;
1905 } 2058 }
1906 2059
1907 if (unlikely(bytes == 0)) { 2060 /*
1908 status = 0; 2061 * non-uptodate pages cannot cope with short copies, and we
1909 copied = 0; 2062 * cannot take a pagefault with the destination page locked.
1910 goto zero_length_segment; 2063 * So pin the source page to copy it.
1911 } 2064 */
2065 if (!PageUptodate(page) && !segment_eq(get_fs(), KERNEL_DS)) {
2066 unlock_page(page);
1912 2067
1913 status = a_ops->prepare_write(file, page, offset, offset+bytes); 2068 src_page = alloc_page(GFP_KERNEL);
1914 if (unlikely(status)) { 2069 if (!src_page) {
1915 loff_t isize = i_size_read(inode); 2070 page_cache_release(page);
2071 status = -ENOMEM;
2072 break;
2073 }
2074
2075 /*
2076 * Cannot get_user_pages with a page locked for the
2077 * same reason as we can't take a page fault with a
2078 * page locked (as explained below).
2079 */
2080 copied = iov_iter_copy_from_user(src_page, i,
2081 offset, bytes);
2082 if (unlikely(copied == 0)) {
2083 status = -EFAULT;
2084 page_cache_release(page);
2085 page_cache_release(src_page);
2086 break;
2087 }
2088 bytes = copied;
1916 2089
1917 if (status != AOP_TRUNCATED_PAGE) 2090 lock_page(page);
2091 /*
2092 * Can't handle the page going uptodate here, because
2093 * that means we would use non-atomic usercopies, which
2094 * zero out the tail of the page, which can cause
2095 * zeroes to become transiently visible. We could just
2096 * use a non-zeroing copy, but the APIs aren't too
2097 * consistent.
2098 */
2099 if (unlikely(!page->mapping || PageUptodate(page))) {
1918 unlock_page(page); 2100 unlock_page(page);
1919 page_cache_release(page); 2101 page_cache_release(page);
1920 if (status == AOP_TRUNCATED_PAGE) 2102 page_cache_release(src_page);
1921 continue; 2103 continue;
2104 }
2105 }
2106
2107 status = a_ops->prepare_write(file, page, offset, offset+bytes);
2108 if (unlikely(status))
2109 goto fs_write_aop_error;
2110
2111 if (!src_page) {
1922 /* 2112 /*
1923 * prepare_write() may have instantiated a few blocks 2113 * Must not enter the pagefault handler here, because
1924 * outside i_size. Trim these off again. 2114 * we hold the page lock, so we might recursively
2115 * deadlock on the same lock, or get an ABBA deadlock
2116 * against a different lock, or against the mmap_sem
2117 * (which nests outside the page lock). So increment
2118 * preempt count, and use _atomic usercopies.
2119 *
2120 * The page is uptodate so we are OK to encounter a
2121 * short copy: if unmodified parts of the page are
2122 * marked dirty and written out to disk, it doesn't
2123 * really matter.
1925 */ 2124 */
1926 if (pos + bytes > isize) 2125 pagefault_disable();
1927 vmtruncate(inode, isize); 2126 copied = iov_iter_copy_from_user_atomic(page, i,
1928 break; 2127 offset, bytes);
2128 pagefault_enable();
2129 } else {
2130 void *src, *dst;
2131 src = kmap_atomic(src_page, KM_USER0);
2132 dst = kmap_atomic(page, KM_USER1);
2133 memcpy(dst + offset, src + offset, bytes);
2134 kunmap_atomic(dst, KM_USER1);
2135 kunmap_atomic(src, KM_USER0);
2136 copied = bytes;
1929 } 2137 }
1930 if (likely(nr_segs == 1))
1931 copied = filemap_copy_from_user(page, offset,
1932 buf, bytes);
1933 else
1934 copied = filemap_copy_from_user_iovec(page, offset,
1935 cur_iov, iov_base, bytes);
1936 flush_dcache_page(page); 2138 flush_dcache_page(page);
2139
1937 status = a_ops->commit_write(file, page, offset, offset+bytes); 2140 status = a_ops->commit_write(file, page, offset, offset+bytes);
1938 if (status == AOP_TRUNCATED_PAGE) { 2141 if (unlikely(status < 0))
1939 page_cache_release(page); 2142 goto fs_write_aop_error;
1940 continue; 2143 if (unlikely(status > 0)) /* filesystem did partial write */
1941 } 2144 copied = min_t(size_t, copied, status);
1942zero_length_segment: 2145
1943 if (likely(copied >= 0)) {
1944 if (!status)
1945 status = copied;
1946
1947 if (status >= 0) {
1948 written += status;
1949 count -= status;
1950 pos += status;
1951 buf += status;
1952 if (unlikely(nr_segs > 1)) {
1953 filemap_set_next_iovec(&cur_iov,
1954 &iov_base, status);
1955 if (count)
1956 buf = cur_iov->iov_base +
1957 iov_base;
1958 } else {
1959 iov_base += status;
1960 }
1961 }
1962 }
1963 if (unlikely(copied != bytes))
1964 if (status >= 0)
1965 status = -EFAULT;
1966 unlock_page(page); 2146 unlock_page(page);
1967 mark_page_accessed(page); 2147 mark_page_accessed(page);
1968 page_cache_release(page); 2148 page_cache_release(page);
1969 if (status < 0) 2149 if (src_page)
1970 break; 2150 page_cache_release(src_page);
2151
2152 iov_iter_advance(i, copied);
2153 pos += copied;
2154 written += copied;
2155
1971 balance_dirty_pages_ratelimited(mapping); 2156 balance_dirty_pages_ratelimited(mapping);
1972 cond_resched(); 2157 cond_resched();
1973 } while (count); 2158 continue;
1974 *ppos = pos;
1975 2159
1976 if (cached_page) 2160fs_write_aop_error:
1977 page_cache_release(cached_page); 2161 unlock_page(page);
2162 page_cache_release(page);
2163 if (src_page)
2164 page_cache_release(src_page);
2165
2166 /*
2167 * prepare_write() may have instantiated a few blocks
2168 * outside i_size. Trim these off again. Don't need
2169 * i_size_read because we hold i_mutex.
2170 */
2171 if (pos + bytes > inode->i_size)
2172 vmtruncate(inode, inode->i_size);
2173 break;
2174 } while (iov_iter_count(i));
2175
2176 return written ? written : status;
2177}
2178
2179static ssize_t generic_perform_write(struct file *file,
2180 struct iov_iter *i, loff_t pos)
2181{
2182 struct address_space *mapping = file->f_mapping;
2183 const struct address_space_operations *a_ops = mapping->a_ops;
2184 long status = 0;
2185 ssize_t written = 0;
2186 unsigned int flags = 0;
1978 2187
1979 /* 2188 /*
1980 * For now, when the user asks for O_SYNC, we'll actually give O_DSYNC 2189 * Copies from kernel address space cannot fail (NFSD is a big user).
1981 */ 2190 */
2191 if (segment_eq(get_fs(), KERNEL_DS))
2192 flags |= AOP_FLAG_UNINTERRUPTIBLE;
2193
2194 do {
2195 struct page *page;
2196 pgoff_t index; /* Pagecache index for current page */
2197 unsigned long offset; /* Offset into pagecache page */
2198 unsigned long bytes; /* Bytes to write to page */
2199 size_t copied; /* Bytes copied from user */
2200 void *fsdata;
2201
2202 offset = (pos & (PAGE_CACHE_SIZE - 1));
2203 index = pos >> PAGE_CACHE_SHIFT;
2204 bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
2205 iov_iter_count(i));
2206
2207again:
2208
2209 /*
2210 * Bring in the user page that we will copy from _first_.
2211 * Otherwise there's a nasty deadlock on copying from the
2212 * same page as we're writing to, without it being marked
2213 * up-to-date.
2214 *
2215 * Not only is this an optimisation, but it is also required
2216 * to check that the address is actually valid, when atomic
2217 * usercopies are used, below.
2218 */
2219 if (unlikely(iov_iter_fault_in_readable(i, bytes))) {
2220 status = -EFAULT;
2221 break;
2222 }
2223
2224 status = a_ops->write_begin(file, mapping, pos, bytes, flags,
2225 &page, &fsdata);
2226 if (unlikely(status))
2227 break;
2228
2229 pagefault_disable();
2230 copied = iov_iter_copy_from_user_atomic(page, i, offset, bytes);
2231 pagefault_enable();
2232 flush_dcache_page(page);
2233
2234 status = a_ops->write_end(file, mapping, pos, bytes, copied,
2235 page, fsdata);
2236 if (unlikely(status < 0))
2237 break;
2238 copied = status;
2239
2240 cond_resched();
2241
2242 if (unlikely(copied == 0)) {
2243 /*
2244 * If we were unable to copy any data at all, we must
2245 * fall back to a single segment length write.
2246 *
2247 * If we didn't fallback here, we could livelock
2248 * because not all segments in the iov can be copied at
2249 * once without a pagefault.
2250 */
2251 bytes = min_t(unsigned long, PAGE_CACHE_SIZE - offset,
2252 iov_iter_single_seg_count(i));
2253 goto again;
2254 }
2255 iov_iter_advance(i, copied);
2256 pos += copied;
2257 written += copied;
2258
2259 balance_dirty_pages_ratelimited(mapping);
2260
2261 } while (iov_iter_count(i));
2262
2263 return written ? written : status;
2264}
2265
2266ssize_t
2267generic_file_buffered_write(struct kiocb *iocb, const struct iovec *iov,
2268 unsigned long nr_segs, loff_t pos, loff_t *ppos,
2269 size_t count, ssize_t written)
2270{
2271 struct file *file = iocb->ki_filp;
2272 struct address_space *mapping = file->f_mapping;
2273 const struct address_space_operations *a_ops = mapping->a_ops;
2274 struct inode *inode = mapping->host;
2275 ssize_t status;
2276 struct iov_iter i;
2277
2278 iov_iter_init(&i, iov, nr_segs, count, written);
2279 if (a_ops->write_begin)
2280 status = generic_perform_write(file, &i, pos);
2281 else
2282 status = generic_perform_write_2copy(file, &i, pos);
2283
1982 if (likely(status >= 0)) { 2284 if (likely(status >= 0)) {
2285 written += status;
2286 *ppos = pos + status;
2287
2288 /*
2289 * For now, when the user asks for O_SYNC, we'll actually give
2290 * O_DSYNC
2291 */
1983 if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))) { 2292 if (unlikely((file->f_flags & O_SYNC) || IS_SYNC(inode))) {
1984 if (!a_ops->writepage || !is_sync_kiocb(iocb)) 2293 if (!a_ops->writepage || !is_sync_kiocb(iocb))
1985 status = generic_osync_inode(inode, mapping, 2294 status = generic_osync_inode(inode, mapping,
@@ -1995,7 +2304,6 @@ zero_length_segment:
1995 if (unlikely(file->f_flags & O_DIRECT) && written) 2304 if (unlikely(file->f_flags & O_DIRECT) && written)
1996 status = filemap_write_and_wait(mapping); 2305 status = filemap_write_and_wait(mapping);
1997 2306
1998 pagevec_lru_add(&lru_pvec);
1999 return written ? written : status; 2307 return written ? written : status;
2000} 2308}
2001EXPORT_SYMBOL(generic_file_buffered_write); 2309EXPORT_SYMBOL(generic_file_buffered_write);
diff --git a/mm/filemap.h b/mm/filemap.h
deleted file mode 100644
index c2bff04c84ed..000000000000
--- a/mm/filemap.h
+++ /dev/null
@@ -1,103 +0,0 @@
1/*
2 * linux/mm/filemap.h
3 *
4 * Copyright (C) 1994-1999 Linus Torvalds
5 */
6
7#ifndef __FILEMAP_H
8#define __FILEMAP_H
9
10#include <linux/types.h>
11#include <linux/fs.h>
12#include <linux/mm.h>
13#include <linux/highmem.h>
14#include <linux/uio.h>
15#include <linux/uaccess.h>
16
17size_t
18__filemap_copy_from_user_iovec_inatomic(char *vaddr,
19 const struct iovec *iov,
20 size_t base,
21 size_t bytes);
22
23/*
24 * Copy as much as we can into the page and return the number of bytes which
25 * were sucessfully copied. If a fault is encountered then clear the page
26 * out to (offset+bytes) and return the number of bytes which were copied.
27 *
28 * NOTE: For this to work reliably we really want copy_from_user_inatomic_nocache
29 * to *NOT* zero any tail of the buffer that it failed to copy. If it does,
30 * and if the following non-atomic copy succeeds, then there is a small window
31 * where the target page contains neither the data before the write, nor the
32 * data after the write (it contains zero). A read at this time will see
33 * data that is inconsistent with any ordering of the read and the write.
34 * (This has been detected in practice).
35 */
36static inline size_t
37filemap_copy_from_user(struct page *page, unsigned long offset,
38 const char __user *buf, unsigned bytes)
39{
40 char *kaddr;
41 int left;
42
43 kaddr = kmap_atomic(page, KM_USER0);
44 left = __copy_from_user_inatomic_nocache(kaddr + offset, buf, bytes);
45 kunmap_atomic(kaddr, KM_USER0);
46
47 if (left != 0) {
48 /* Do it the slow way */
49 kaddr = kmap(page);
50 left = __copy_from_user_nocache(kaddr + offset, buf, bytes);
51 kunmap(page);
52 }
53 return bytes - left;
54}
55
56/*
57 * This has the same sideeffects and return value as filemap_copy_from_user().
58 * The difference is that on a fault we need to memset the remainder of the
59 * page (out to offset+bytes), to emulate filemap_copy_from_user()'s
60 * single-segment behaviour.
61 */
62static inline size_t
63filemap_copy_from_user_iovec(struct page *page, unsigned long offset,
64 const struct iovec *iov, size_t base, size_t bytes)
65{
66 char *kaddr;
67 size_t copied;
68
69 kaddr = kmap_atomic(page, KM_USER0);
70 copied = __filemap_copy_from_user_iovec_inatomic(kaddr + offset, iov,
71 base, bytes);
72 kunmap_atomic(kaddr, KM_USER0);
73 if (copied != bytes) {
74 kaddr = kmap(page);
75 copied = __filemap_copy_from_user_iovec_inatomic(kaddr + offset, iov,
76 base, bytes);
77 if (bytes - copied)
78 memset(kaddr + offset + copied, 0, bytes - copied);
79 kunmap(page);
80 }
81 return copied;
82}
83
84static inline void
85filemap_set_next_iovec(const struct iovec **iovp, size_t *basep, size_t bytes)
86{
87 const struct iovec *iov = *iovp;
88 size_t base = *basep;
89
90 do {
91 int copy = min(bytes, iov->iov_len - base);
92
93 bytes -= copy;
94 base += copy;
95 if (iov->iov_len == base) {
96 iov++;
97 base = 0;
98 }
99 } while (bytes);
100 *iovp = iov;
101 *basep = base;
102}
103#endif
diff --git a/mm/filemap_xip.c b/mm/filemap_xip.c
index 53ee6a299635..32132f3cd641 100644
--- a/mm/filemap_xip.c
+++ b/mm/filemap_xip.c
@@ -15,7 +15,6 @@
15#include <linux/rmap.h> 15#include <linux/rmap.h>
16#include <linux/sched.h> 16#include <linux/sched.h>
17#include <asm/tlbflush.h> 17#include <asm/tlbflush.h>
18#include "filemap.h"
19 18
20/* 19/*
21 * We do use our own empty page to avoid interference with other users 20 * We do use our own empty page to avoid interference with other users
@@ -288,6 +287,7 @@ __xip_file_write(struct file *filp, const char __user *buf,
288 unsigned long index; 287 unsigned long index;
289 unsigned long offset; 288 unsigned long offset;
290 size_t copied; 289 size_t copied;
290 char *kaddr;
291 291
292 offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */ 292 offset = (pos & (PAGE_CACHE_SIZE -1)); /* Within page */
293 index = pos >> PAGE_CACHE_SHIFT; 293 index = pos >> PAGE_CACHE_SHIFT;
@@ -295,14 +295,6 @@ __xip_file_write(struct file *filp, const char __user *buf,
295 if (bytes > count) 295 if (bytes > count)
296 bytes = count; 296 bytes = count;
297 297
298 /*
299 * Bring in the user page that we will copy from _first_.
300 * Otherwise there's a nasty deadlock on copying from the
301 * same page as we're writing to, without it being marked
302 * up-to-date.
303 */
304 fault_in_pages_readable(buf, bytes);
305
306 page = a_ops->get_xip_page(mapping, 298 page = a_ops->get_xip_page(mapping,
307 index*(PAGE_SIZE/512), 0); 299 index*(PAGE_SIZE/512), 0);
308 if (IS_ERR(page) && (PTR_ERR(page) == -ENODATA)) { 300 if (IS_ERR(page) && (PTR_ERR(page) == -ENODATA)) {
@@ -319,8 +311,13 @@ __xip_file_write(struct file *filp, const char __user *buf,
319 break; 311 break;
320 } 312 }
321 313
322 copied = filemap_copy_from_user(page, offset, buf, bytes); 314 fault_in_pages_readable(buf, bytes);
315 kaddr = kmap_atomic(page, KM_USER0);
316 copied = bytes -
317 __copy_from_user_inatomic_nocache(kaddr, buf, bytes);
318 kunmap_atomic(kaddr, KM_USER0);
323 flush_dcache_page(page); 319 flush_dcache_page(page);
320
324 if (likely(copied > 0)) { 321 if (likely(copied > 0)) {
325 status = copied; 322 status = copied;
326 323
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index eab8c428cc93..ae2959bb59cb 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -23,12 +23,16 @@
23 23
24const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL; 24const unsigned long hugetlb_zero = 0, hugetlb_infinity = ~0UL;
25static unsigned long nr_huge_pages, free_huge_pages, resv_huge_pages; 25static unsigned long nr_huge_pages, free_huge_pages, resv_huge_pages;
26static unsigned long surplus_huge_pages;
26unsigned long max_huge_pages; 27unsigned long max_huge_pages;
27static struct list_head hugepage_freelists[MAX_NUMNODES]; 28static struct list_head hugepage_freelists[MAX_NUMNODES];
28static unsigned int nr_huge_pages_node[MAX_NUMNODES]; 29static unsigned int nr_huge_pages_node[MAX_NUMNODES];
29static unsigned int free_huge_pages_node[MAX_NUMNODES]; 30static unsigned int free_huge_pages_node[MAX_NUMNODES];
31static unsigned int surplus_huge_pages_node[MAX_NUMNODES];
30static gfp_t htlb_alloc_mask = GFP_HIGHUSER; 32static gfp_t htlb_alloc_mask = GFP_HIGHUSER;
31unsigned long hugepages_treat_as_movable; 33unsigned long hugepages_treat_as_movable;
34int hugetlb_dynamic_pool;
35static int hugetlb_next_nid;
32 36
33/* 37/*
34 * Protects updates to hugepage_freelists, nr_huge_pages, and free_huge_pages 38 * Protects updates to hugepage_freelists, nr_huge_pages, and free_huge_pages
@@ -85,6 +89,8 @@ static struct page *dequeue_huge_page(struct vm_area_struct *vma,
85 list_del(&page->lru); 89 list_del(&page->lru);
86 free_huge_pages--; 90 free_huge_pages--;
87 free_huge_pages_node[nid]--; 91 free_huge_pages_node[nid]--;
92 if (vma && vma->vm_flags & VM_MAYSHARE)
93 resv_huge_pages--;
88 break; 94 break;
89 } 95 }
90 } 96 }
@@ -92,58 +98,269 @@ static struct page *dequeue_huge_page(struct vm_area_struct *vma,
92 return page; 98 return page;
93} 99}
94 100
101static void update_and_free_page(struct page *page)
102{
103 int i;
104 nr_huge_pages--;
105 nr_huge_pages_node[page_to_nid(page)]--;
106 for (i = 0; i < (HPAGE_SIZE / PAGE_SIZE); i++) {
107 page[i].flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced |
108 1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
109 1 << PG_private | 1<< PG_writeback);
110 }
111 set_compound_page_dtor(page, NULL);
112 set_page_refcounted(page);
113 __free_pages(page, HUGETLB_PAGE_ORDER);
114}
115
95static void free_huge_page(struct page *page) 116static void free_huge_page(struct page *page)
96{ 117{
97 BUG_ON(page_count(page)); 118 int nid = page_to_nid(page);
98 119
120 BUG_ON(page_count(page));
99 INIT_LIST_HEAD(&page->lru); 121 INIT_LIST_HEAD(&page->lru);
100 122
101 spin_lock(&hugetlb_lock); 123 spin_lock(&hugetlb_lock);
102 enqueue_huge_page(page); 124 if (surplus_huge_pages_node[nid]) {
125 update_and_free_page(page);
126 surplus_huge_pages--;
127 surplus_huge_pages_node[nid]--;
128 } else {
129 enqueue_huge_page(page);
130 }
103 spin_unlock(&hugetlb_lock); 131 spin_unlock(&hugetlb_lock);
104} 132}
105 133
106static int alloc_fresh_huge_page(void) 134/*
135 * Increment or decrement surplus_huge_pages. Keep node-specific counters
136 * balanced by operating on them in a round-robin fashion.
137 * Returns 1 if an adjustment was made.
138 */
139static int adjust_pool_surplus(int delta)
107{ 140{
108 static int prev_nid; 141 static int prev_nid;
109 struct page *page; 142 int nid = prev_nid;
110 int nid; 143 int ret = 0;
144
145 VM_BUG_ON(delta != -1 && delta != 1);
146 do {
147 nid = next_node(nid, node_online_map);
148 if (nid == MAX_NUMNODES)
149 nid = first_node(node_online_map);
150
151 /* To shrink on this node, there must be a surplus page */
152 if (delta < 0 && !surplus_huge_pages_node[nid])
153 continue;
154 /* Surplus cannot exceed the total number of pages */
155 if (delta > 0 && surplus_huge_pages_node[nid] >=
156 nr_huge_pages_node[nid])
157 continue;
158
159 surplus_huge_pages += delta;
160 surplus_huge_pages_node[nid] += delta;
161 ret = 1;
162 break;
163 } while (nid != prev_nid);
111 164
112 /*
113 * Copy static prev_nid to local nid, work on that, then copy it
114 * back to prev_nid afterwards: otherwise there's a window in which
115 * a racer might pass invalid nid MAX_NUMNODES to alloc_pages_node.
116 * But we don't need to use a spin_lock here: it really doesn't
117 * matter if occasionally a racer chooses the same nid as we do.
118 */
119 nid = next_node(prev_nid, node_online_map);
120 if (nid == MAX_NUMNODES)
121 nid = first_node(node_online_map);
122 prev_nid = nid; 165 prev_nid = nid;
166 return ret;
167}
168
169static struct page *alloc_fresh_huge_page_node(int nid)
170{
171 struct page *page;
123 172
124 page = alloc_pages_node(nid, htlb_alloc_mask|__GFP_COMP|__GFP_NOWARN, 173 page = alloc_pages_node(nid,
174 htlb_alloc_mask|__GFP_COMP|__GFP_THISNODE|__GFP_NOWARN,
175 HUGETLB_PAGE_ORDER);
176 if (page) {
177 set_compound_page_dtor(page, free_huge_page);
178 spin_lock(&hugetlb_lock);
179 nr_huge_pages++;
180 nr_huge_pages_node[nid]++;
181 spin_unlock(&hugetlb_lock);
182 put_page(page); /* free it into the hugepage allocator */
183 }
184
185 return page;
186}
187
188static int alloc_fresh_huge_page(void)
189{
190 struct page *page;
191 int start_nid;
192 int next_nid;
193 int ret = 0;
194
195 start_nid = hugetlb_next_nid;
196
197 do {
198 page = alloc_fresh_huge_page_node(hugetlb_next_nid);
199 if (page)
200 ret = 1;
201 /*
202 * Use a helper variable to find the next node and then
203 * copy it back to hugetlb_next_nid afterwards:
204 * otherwise there's a window in which a racer might
205 * pass invalid nid MAX_NUMNODES to alloc_pages_node.
206 * But we don't need to use a spin_lock here: it really
207 * doesn't matter if occasionally a racer chooses the
208 * same nid as we do. Move nid forward in the mask even
209 * if we just successfully allocated a hugepage so that
210 * the next caller gets hugepages on the next node.
211 */
212 next_nid = next_node(hugetlb_next_nid, node_online_map);
213 if (next_nid == MAX_NUMNODES)
214 next_nid = first_node(node_online_map);
215 hugetlb_next_nid = next_nid;
216 } while (!page && hugetlb_next_nid != start_nid);
217
218 return ret;
219}
220
221static struct page *alloc_buddy_huge_page(struct vm_area_struct *vma,
222 unsigned long address)
223{
224 struct page *page;
225
226 /* Check if the dynamic pool is enabled */
227 if (!hugetlb_dynamic_pool)
228 return NULL;
229
230 page = alloc_pages(htlb_alloc_mask|__GFP_COMP|__GFP_NOWARN,
125 HUGETLB_PAGE_ORDER); 231 HUGETLB_PAGE_ORDER);
126 if (page) { 232 if (page) {
127 set_compound_page_dtor(page, free_huge_page); 233 set_compound_page_dtor(page, free_huge_page);
128 spin_lock(&hugetlb_lock); 234 spin_lock(&hugetlb_lock);
129 nr_huge_pages++; 235 nr_huge_pages++;
130 nr_huge_pages_node[page_to_nid(page)]++; 236 nr_huge_pages_node[page_to_nid(page)]++;
237 surplus_huge_pages++;
238 surplus_huge_pages_node[page_to_nid(page)]++;
131 spin_unlock(&hugetlb_lock); 239 spin_unlock(&hugetlb_lock);
132 put_page(page); /* free it into the hugepage allocator */
133 return 1;
134 } 240 }
135 return 0; 241
242 return page;
243}
244
245/*
246 * Increase the hugetlb pool such that it can accomodate a reservation
247 * of size 'delta'.
248 */
249static int gather_surplus_pages(int delta)
250{
251 struct list_head surplus_list;
252 struct page *page, *tmp;
253 int ret, i;
254 int needed, allocated;
255
256 needed = (resv_huge_pages + delta) - free_huge_pages;
257 if (needed <= 0)
258 return 0;
259
260 allocated = 0;
261 INIT_LIST_HEAD(&surplus_list);
262
263 ret = -ENOMEM;
264retry:
265 spin_unlock(&hugetlb_lock);
266 for (i = 0; i < needed; i++) {
267 page = alloc_buddy_huge_page(NULL, 0);
268 if (!page) {
269 /*
270 * We were not able to allocate enough pages to
271 * satisfy the entire reservation so we free what
272 * we've allocated so far.
273 */
274 spin_lock(&hugetlb_lock);
275 needed = 0;
276 goto free;
277 }
278
279 list_add(&page->lru, &surplus_list);
280 }
281 allocated += needed;
282
283 /*
284 * After retaking hugetlb_lock, we need to recalculate 'needed'
285 * because either resv_huge_pages or free_huge_pages may have changed.
286 */
287 spin_lock(&hugetlb_lock);
288 needed = (resv_huge_pages + delta) - (free_huge_pages + allocated);
289 if (needed > 0)
290 goto retry;
291
292 /*
293 * The surplus_list now contains _at_least_ the number of extra pages
294 * needed to accomodate the reservation. Add the appropriate number
295 * of pages to the hugetlb pool and free the extras back to the buddy
296 * allocator.
297 */
298 needed += allocated;
299 ret = 0;
300free:
301 list_for_each_entry_safe(page, tmp, &surplus_list, lru) {
302 list_del(&page->lru);
303 if ((--needed) >= 0)
304 enqueue_huge_page(page);
305 else {
306 /*
307 * Decrement the refcount and free the page using its
308 * destructor. This must be done with hugetlb_lock
309 * unlocked which is safe because free_huge_page takes
310 * hugetlb_lock before deciding how to free the page.
311 */
312 spin_unlock(&hugetlb_lock);
313 put_page(page);
314 spin_lock(&hugetlb_lock);
315 }
316 }
317
318 return ret;
319}
320
321/*
322 * When releasing a hugetlb pool reservation, any surplus pages that were
323 * allocated to satisfy the reservation must be explicitly freed if they were
324 * never used.
325 */
326void return_unused_surplus_pages(unsigned long unused_resv_pages)
327{
328 static int nid = -1;
329 struct page *page;
330 unsigned long nr_pages;
331
332 nr_pages = min(unused_resv_pages, surplus_huge_pages);
333
334 while (nr_pages) {
335 nid = next_node(nid, node_online_map);
336 if (nid == MAX_NUMNODES)
337 nid = first_node(node_online_map);
338
339 if (!surplus_huge_pages_node[nid])
340 continue;
341
342 if (!list_empty(&hugepage_freelists[nid])) {
343 page = list_entry(hugepage_freelists[nid].next,
344 struct page, lru);
345 list_del(&page->lru);
346 update_and_free_page(page);
347 free_huge_pages--;
348 free_huge_pages_node[nid]--;
349 surplus_huge_pages--;
350 surplus_huge_pages_node[nid]--;
351 nr_pages--;
352 }
353 }
136} 354}
137 355
138static struct page *alloc_huge_page(struct vm_area_struct *vma, 356static struct page *alloc_huge_page(struct vm_area_struct *vma,
139 unsigned long addr) 357 unsigned long addr)
140{ 358{
141 struct page *page; 359 struct page *page = NULL;
360 int use_reserved_page = vma->vm_flags & VM_MAYSHARE;
142 361
143 spin_lock(&hugetlb_lock); 362 spin_lock(&hugetlb_lock);
144 if (vma->vm_flags & VM_MAYSHARE) 363 if (!use_reserved_page && (free_huge_pages <= resv_huge_pages))
145 resv_huge_pages--;
146 else if (free_huge_pages <= resv_huge_pages)
147 goto fail; 364 goto fail;
148 365
149 page = dequeue_huge_page(vma, addr); 366 page = dequeue_huge_page(vma, addr);
@@ -155,10 +372,17 @@ static struct page *alloc_huge_page(struct vm_area_struct *vma,
155 return page; 372 return page;
156 373
157fail: 374fail:
158 if (vma->vm_flags & VM_MAYSHARE)
159 resv_huge_pages++;
160 spin_unlock(&hugetlb_lock); 375 spin_unlock(&hugetlb_lock);
161 return NULL; 376
377 /*
378 * Private mappings do not use reserved huge pages so the allocation
379 * may have failed due to an undersized hugetlb pool. Try to grab a
380 * surplus huge page from the buddy allocator.
381 */
382 if (!use_reserved_page)
383 page = alloc_buddy_huge_page(vma, addr);
384
385 return page;
162} 386}
163 387
164static int __init hugetlb_init(void) 388static int __init hugetlb_init(void)
@@ -171,6 +395,8 @@ static int __init hugetlb_init(void)
171 for (i = 0; i < MAX_NUMNODES; ++i) 395 for (i = 0; i < MAX_NUMNODES; ++i)
172 INIT_LIST_HEAD(&hugepage_freelists[i]); 396 INIT_LIST_HEAD(&hugepage_freelists[i]);
173 397
398 hugetlb_next_nid = first_node(node_online_map);
399
174 for (i = 0; i < max_huge_pages; ++i) { 400 for (i = 0; i < max_huge_pages; ++i) {
175 if (!alloc_fresh_huge_page()) 401 if (!alloc_fresh_huge_page())
176 break; 402 break;
@@ -201,21 +427,6 @@ static unsigned int cpuset_mems_nr(unsigned int *array)
201} 427}
202 428
203#ifdef CONFIG_SYSCTL 429#ifdef CONFIG_SYSCTL
204static void update_and_free_page(struct page *page)
205{
206 int i;
207 nr_huge_pages--;
208 nr_huge_pages_node[page_to_nid(page)]--;
209 for (i = 0; i < (HPAGE_SIZE / PAGE_SIZE); i++) {
210 page[i].flags &= ~(1 << PG_locked | 1 << PG_error | 1 << PG_referenced |
211 1 << PG_dirty | 1 << PG_active | 1 << PG_reserved |
212 1 << PG_private | 1<< PG_writeback);
213 }
214 set_compound_page_dtor(page, NULL);
215 set_page_refcounted(page);
216 __free_pages(page, HUGETLB_PAGE_ORDER);
217}
218
219#ifdef CONFIG_HIGHMEM 430#ifdef CONFIG_HIGHMEM
220static void try_to_free_low(unsigned long count) 431static void try_to_free_low(unsigned long count)
221{ 432{
@@ -224,14 +435,14 @@ static void try_to_free_low(unsigned long count)
224 for (i = 0; i < MAX_NUMNODES; ++i) { 435 for (i = 0; i < MAX_NUMNODES; ++i) {
225 struct page *page, *next; 436 struct page *page, *next;
226 list_for_each_entry_safe(page, next, &hugepage_freelists[i], lru) { 437 list_for_each_entry_safe(page, next, &hugepage_freelists[i], lru) {
438 if (count >= nr_huge_pages)
439 return;
227 if (PageHighMem(page)) 440 if (PageHighMem(page))
228 continue; 441 continue;
229 list_del(&page->lru); 442 list_del(&page->lru);
230 update_and_free_page(page); 443 update_and_free_page(page);
231 free_huge_pages--; 444 free_huge_pages--;
232 free_huge_pages_node[page_to_nid(page)]--; 445 free_huge_pages_node[page_to_nid(page)]--;
233 if (count >= nr_huge_pages)
234 return;
235 } 446 }
236 } 447 }
237} 448}
@@ -241,26 +452,61 @@ static inline void try_to_free_low(unsigned long count)
241} 452}
242#endif 453#endif
243 454
455#define persistent_huge_pages (nr_huge_pages - surplus_huge_pages)
244static unsigned long set_max_huge_pages(unsigned long count) 456static unsigned long set_max_huge_pages(unsigned long count)
245{ 457{
246 while (count > nr_huge_pages) { 458 unsigned long min_count, ret;
247 if (!alloc_fresh_huge_page())
248 return nr_huge_pages;
249 }
250 if (count >= nr_huge_pages)
251 return nr_huge_pages;
252 459
460 /*
461 * Increase the pool size
462 * First take pages out of surplus state. Then make up the
463 * remaining difference by allocating fresh huge pages.
464 */
253 spin_lock(&hugetlb_lock); 465 spin_lock(&hugetlb_lock);
254 count = max(count, resv_huge_pages); 466 while (surplus_huge_pages && count > persistent_huge_pages) {
255 try_to_free_low(count); 467 if (!adjust_pool_surplus(-1))
256 while (count < nr_huge_pages) { 468 break;
469 }
470
471 while (count > persistent_huge_pages) {
472 int ret;
473 /*
474 * If this allocation races such that we no longer need the
475 * page, free_huge_page will handle it by freeing the page
476 * and reducing the surplus.
477 */
478 spin_unlock(&hugetlb_lock);
479 ret = alloc_fresh_huge_page();
480 spin_lock(&hugetlb_lock);
481 if (!ret)
482 goto out;
483
484 }
485
486 /*
487 * Decrease the pool size
488 * First return free pages to the buddy allocator (being careful
489 * to keep enough around to satisfy reservations). Then place
490 * pages into surplus state as needed so the pool will shrink
491 * to the desired size as pages become free.
492 */
493 min_count = resv_huge_pages + nr_huge_pages - free_huge_pages;
494 min_count = max(count, min_count);
495 try_to_free_low(min_count);
496 while (min_count < persistent_huge_pages) {
257 struct page *page = dequeue_huge_page(NULL, 0); 497 struct page *page = dequeue_huge_page(NULL, 0);
258 if (!page) 498 if (!page)
259 break; 499 break;
260 update_and_free_page(page); 500 update_and_free_page(page);
261 } 501 }
502 while (count < persistent_huge_pages) {
503 if (!adjust_pool_surplus(1))
504 break;
505 }
506out:
507 ret = persistent_huge_pages;
262 spin_unlock(&hugetlb_lock); 508 spin_unlock(&hugetlb_lock);
263 return nr_huge_pages; 509 return ret;
264} 510}
265 511
266int hugetlb_sysctl_handler(struct ctl_table *table, int write, 512int hugetlb_sysctl_handler(struct ctl_table *table, int write,
@@ -292,10 +538,12 @@ int hugetlb_report_meminfo(char *buf)
292 "HugePages_Total: %5lu\n" 538 "HugePages_Total: %5lu\n"
293 "HugePages_Free: %5lu\n" 539 "HugePages_Free: %5lu\n"
294 "HugePages_Rsvd: %5lu\n" 540 "HugePages_Rsvd: %5lu\n"
541 "HugePages_Surp: %5lu\n"
295 "Hugepagesize: %5lu kB\n", 542 "Hugepagesize: %5lu kB\n",
296 nr_huge_pages, 543 nr_huge_pages,
297 free_huge_pages, 544 free_huge_pages,
298 resv_huge_pages, 545 resv_huge_pages,
546 surplus_huge_pages,
299 HPAGE_SIZE/1024); 547 HPAGE_SIZE/1024);
300} 548}
301 549
@@ -355,7 +603,6 @@ static void set_huge_ptep_writable(struct vm_area_struct *vma,
355 entry = pte_mkwrite(pte_mkdirty(*ptep)); 603 entry = pte_mkwrite(pte_mkdirty(*ptep));
356 if (ptep_set_access_flags(vma, address, ptep, entry, 1)) { 604 if (ptep_set_access_flags(vma, address, ptep, entry, 1)) {
357 update_mmu_cache(vma, address, entry); 605 update_mmu_cache(vma, address, entry);
358 lazy_mmu_prot_update(entry);
359 } 606 }
360} 607}
361 608
@@ -708,7 +955,6 @@ void hugetlb_change_protection(struct vm_area_struct *vma,
708 pte = huge_ptep_get_and_clear(mm, address, ptep); 955 pte = huge_ptep_get_and_clear(mm, address, ptep);
709 pte = pte_mkhuge(pte_modify(pte, newprot)); 956 pte = pte_mkhuge(pte_modify(pte, newprot));
710 set_huge_pte_at(mm, address, ptep, pte); 957 set_huge_pte_at(mm, address, ptep, pte);
711 lazy_mmu_prot_update(pte);
712 } 958 }
713 } 959 }
714 spin_unlock(&mm->page_table_lock); 960 spin_unlock(&mm->page_table_lock);
@@ -843,21 +1089,6 @@ static int hugetlb_acct_memory(long delta)
843 int ret = -ENOMEM; 1089 int ret = -ENOMEM;
844 1090
845 spin_lock(&hugetlb_lock); 1091 spin_lock(&hugetlb_lock);
846 if ((delta + resv_huge_pages) <= free_huge_pages) {
847 resv_huge_pages += delta;
848 ret = 0;
849 }
850 spin_unlock(&hugetlb_lock);
851 return ret;
852}
853
854int hugetlb_reserve_pages(struct inode *inode, long from, long to)
855{
856 long ret, chg;
857
858 chg = region_chg(&inode->i_mapping->private_list, from, to);
859 if (chg < 0)
860 return chg;
861 /* 1092 /*
862 * When cpuset is configured, it breaks the strict hugetlb page 1093 * When cpuset is configured, it breaks the strict hugetlb page
863 * reservation as the accounting is done on a global variable. Such 1094 * reservation as the accounting is done on a global variable. Such
@@ -875,8 +1106,31 @@ int hugetlb_reserve_pages(struct inode *inode, long from, long to)
875 * a best attempt and hopefully to minimize the impact of changing 1106 * a best attempt and hopefully to minimize the impact of changing
876 * semantics that cpuset has. 1107 * semantics that cpuset has.
877 */ 1108 */
878 if (chg > cpuset_mems_nr(free_huge_pages_node)) 1109 if (delta > 0) {
879 return -ENOMEM; 1110 if (gather_surplus_pages(delta) < 0)
1111 goto out;
1112
1113 if (delta > cpuset_mems_nr(free_huge_pages_node))
1114 goto out;
1115 }
1116
1117 ret = 0;
1118 resv_huge_pages += delta;
1119 if (delta < 0)
1120 return_unused_surplus_pages((unsigned long) -delta);
1121
1122out:
1123 spin_unlock(&hugetlb_lock);
1124 return ret;
1125}
1126
1127int hugetlb_reserve_pages(struct inode *inode, long from, long to)
1128{
1129 long ret, chg;
1130
1131 chg = region_chg(&inode->i_mapping->private_list, from, to);
1132 if (chg < 0)
1133 return chg;
880 1134
881 ret = hugetlb_acct_memory(chg); 1135 ret = hugetlb_acct_memory(chg);
882 if (ret < 0) 1136 if (ret < 0)
diff --git a/mm/internal.h b/mm/internal.h
index a3110c02aea7..953f941ea867 100644
--- a/mm/internal.h
+++ b/mm/internal.h
@@ -37,4 +37,14 @@ static inline void __put_page(struct page *page)
37extern void fastcall __init __free_pages_bootmem(struct page *page, 37extern void fastcall __init __free_pages_bootmem(struct page *page,
38 unsigned int order); 38 unsigned int order);
39 39
40/*
41 * function for dealing with page's order in buddy system.
42 * zone->lock is already acquired when we use these.
43 * So, we don't need atomic page->flags operations here.
44 */
45static inline unsigned long page_order(struct page *page)
46{
47 VM_BUG_ON(!PageBuddy(page));
48 return page_private(page);
49}
40#endif 50#endif
diff --git a/mm/memory.c b/mm/memory.c
index f82b359b2745..bd16dcaeefb8 100644
--- a/mm/memory.c
+++ b/mm/memory.c
@@ -966,7 +966,7 @@ no_page_table:
966 * has touched so far, we don't want to allocate page tables. 966 * has touched so far, we don't want to allocate page tables.
967 */ 967 */
968 if (flags & FOLL_ANON) { 968 if (flags & FOLL_ANON) {
969 page = ZERO_PAGE(address); 969 page = ZERO_PAGE(0);
970 if (flags & FOLL_GET) 970 if (flags & FOLL_GET)
971 get_page(page); 971 get_page(page);
972 BUG_ON(flags & FOLL_WRITE); 972 BUG_ON(flags & FOLL_WRITE);
@@ -1111,95 +1111,6 @@ int get_user_pages(struct task_struct *tsk, struct mm_struct *mm,
1111} 1111}
1112EXPORT_SYMBOL(get_user_pages); 1112EXPORT_SYMBOL(get_user_pages);
1113 1113
1114static int zeromap_pte_range(struct mm_struct *mm, pmd_t *pmd,
1115 unsigned long addr, unsigned long end, pgprot_t prot)
1116{
1117 pte_t *pte;
1118 spinlock_t *ptl;
1119 int err = 0;
1120
1121 pte = pte_alloc_map_lock(mm, pmd, addr, &ptl);
1122 if (!pte)
1123 return -EAGAIN;
1124 arch_enter_lazy_mmu_mode();
1125 do {
1126 struct page *page = ZERO_PAGE(addr);
1127 pte_t zero_pte = pte_wrprotect(mk_pte(page, prot));
1128
1129 if (unlikely(!pte_none(*pte))) {
1130 err = -EEXIST;
1131 pte++;
1132 break;
1133 }
1134 page_cache_get(page);
1135 page_add_file_rmap(page);
1136 inc_mm_counter(mm, file_rss);
1137 set_pte_at(mm, addr, pte, zero_pte);
1138 } while (pte++, addr += PAGE_SIZE, addr != end);
1139 arch_leave_lazy_mmu_mode();
1140 pte_unmap_unlock(pte - 1, ptl);
1141 return err;
1142}
1143
1144static inline int zeromap_pmd_range(struct mm_struct *mm, pud_t *pud,
1145 unsigned long addr, unsigned long end, pgprot_t prot)
1146{
1147 pmd_t *pmd;
1148 unsigned long next;
1149 int err;
1150
1151 pmd = pmd_alloc(mm, pud, addr);
1152 if (!pmd)
1153 return -EAGAIN;
1154 do {
1155 next = pmd_addr_end(addr, end);
1156 err = zeromap_pte_range(mm, pmd, addr, next, prot);
1157 if (err)
1158 break;
1159 } while (pmd++, addr = next, addr != end);
1160 return err;
1161}
1162
1163static inline int zeromap_pud_range(struct mm_struct *mm, pgd_t *pgd,
1164 unsigned long addr, unsigned long end, pgprot_t prot)
1165{
1166 pud_t *pud;
1167 unsigned long next;
1168 int err;
1169
1170 pud = pud_alloc(mm, pgd, addr);
1171 if (!pud)
1172 return -EAGAIN;
1173 do {
1174 next = pud_addr_end(addr, end);
1175 err = zeromap_pmd_range(mm, pud, addr, next, prot);
1176 if (err)
1177 break;
1178 } while (pud++, addr = next, addr != end);
1179 return err;
1180}
1181
1182int zeromap_page_range(struct vm_area_struct *vma,
1183 unsigned long addr, unsigned long size, pgprot_t prot)
1184{
1185 pgd_t *pgd;
1186 unsigned long next;
1187 unsigned long end = addr + size;
1188 struct mm_struct *mm = vma->vm_mm;
1189 int err;
1190
1191 BUG_ON(addr >= end);
1192 pgd = pgd_offset(mm, addr);
1193 flush_cache_range(vma, addr, end);
1194 do {
1195 next = pgd_addr_end(addr, end);
1196 err = zeromap_pud_range(mm, pgd, addr, next, prot);
1197 if (err)
1198 break;
1199 } while (pgd++, addr = next, addr != end);
1200 return err;
1201}
1202
1203pte_t * fastcall get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl) 1114pte_t * fastcall get_locked_pte(struct mm_struct *mm, unsigned long addr, spinlock_t **ptl)
1204{ 1115{
1205 pgd_t * pgd = pgd_offset(mm, addr); 1116 pgd_t * pgd = pgd_offset(mm, addr);
@@ -1700,10 +1611,8 @@ static int do_wp_page(struct mm_struct *mm, struct vm_area_struct *vma,
1700 flush_cache_page(vma, address, pte_pfn(orig_pte)); 1611 flush_cache_page(vma, address, pte_pfn(orig_pte));
1701 entry = pte_mkyoung(orig_pte); 1612 entry = pte_mkyoung(orig_pte);
1702 entry = maybe_mkwrite(pte_mkdirty(entry), vma); 1613 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
1703 if (ptep_set_access_flags(vma, address, page_table, entry,1)) { 1614 if (ptep_set_access_flags(vma, address, page_table, entry,1))
1704 update_mmu_cache(vma, address, entry); 1615 update_mmu_cache(vma, address, entry);
1705 lazy_mmu_prot_update(entry);
1706 }
1707 ret |= VM_FAULT_WRITE; 1616 ret |= VM_FAULT_WRITE;
1708 goto unlock; 1617 goto unlock;
1709 } 1618 }
@@ -1717,16 +1626,11 @@ gotten:
1717 1626
1718 if (unlikely(anon_vma_prepare(vma))) 1627 if (unlikely(anon_vma_prepare(vma)))
1719 goto oom; 1628 goto oom;
1720 if (old_page == ZERO_PAGE(address)) { 1629 VM_BUG_ON(old_page == ZERO_PAGE(0));
1721 new_page = alloc_zeroed_user_highpage_movable(vma, address); 1630 new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
1722 if (!new_page) 1631 if (!new_page)
1723 goto oom; 1632 goto oom;
1724 } else { 1633 cow_user_page(new_page, old_page, address, vma);
1725 new_page = alloc_page_vma(GFP_HIGHUSER_MOVABLE, vma, address);
1726 if (!new_page)
1727 goto oom;
1728 cow_user_page(new_page, old_page, address, vma);
1729 }
1730 1634
1731 /* 1635 /*
1732 * Re-check the pte - we dropped the lock 1636 * Re-check the pte - we dropped the lock
@@ -1744,7 +1648,6 @@ gotten:
1744 flush_cache_page(vma, address, pte_pfn(orig_pte)); 1648 flush_cache_page(vma, address, pte_pfn(orig_pte));
1745 entry = mk_pte(new_page, vma->vm_page_prot); 1649 entry = mk_pte(new_page, vma->vm_page_prot);
1746 entry = maybe_mkwrite(pte_mkdirty(entry), vma); 1650 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
1747 lazy_mmu_prot_update(entry);
1748 /* 1651 /*
1749 * Clear the pte entry and flush it first, before updating the 1652 * Clear the pte entry and flush it first, before updating the
1750 * pte with the new entry. This will avoid a race condition 1653 * pte with the new entry. This will avoid a race condition
@@ -2252,44 +2155,28 @@ static int do_anonymous_page(struct mm_struct *mm, struct vm_area_struct *vma,
2252 spinlock_t *ptl; 2155 spinlock_t *ptl;
2253 pte_t entry; 2156 pte_t entry;
2254 2157
2255 if (write_access) { 2158 /* Allocate our own private page. */
2256 /* Allocate our own private page. */ 2159 pte_unmap(page_table);
2257 pte_unmap(page_table);
2258
2259 if (unlikely(anon_vma_prepare(vma)))
2260 goto oom;
2261 page = alloc_zeroed_user_highpage_movable(vma, address);
2262 if (!page)
2263 goto oom;
2264
2265 entry = mk_pte(page, vma->vm_page_prot);
2266 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
2267 2160
2268 page_table = pte_offset_map_lock(mm, pmd, address, &ptl); 2161 if (unlikely(anon_vma_prepare(vma)))
2269 if (!pte_none(*page_table)) 2162 goto oom;
2270 goto release; 2163 page = alloc_zeroed_user_highpage_movable(vma, address);
2271 inc_mm_counter(mm, anon_rss); 2164 if (!page)
2272 lru_cache_add_active(page); 2165 goto oom;
2273 page_add_new_anon_rmap(page, vma, address);
2274 } else {
2275 /* Map the ZERO_PAGE - vm_page_prot is readonly */
2276 page = ZERO_PAGE(address);
2277 page_cache_get(page);
2278 entry = mk_pte(page, vma->vm_page_prot);
2279 2166
2280 ptl = pte_lockptr(mm, pmd); 2167 entry = mk_pte(page, vma->vm_page_prot);
2281 spin_lock(ptl); 2168 entry = maybe_mkwrite(pte_mkdirty(entry), vma);
2282 if (!pte_none(*page_table))
2283 goto release;
2284 inc_mm_counter(mm, file_rss);
2285 page_add_file_rmap(page);
2286 }
2287 2169
2170 page_table = pte_offset_map_lock(mm, pmd, address, &ptl);
2171 if (!pte_none(*page_table))
2172 goto release;
2173 inc_mm_counter(mm, anon_rss);
2174 lru_cache_add_active(page);
2175 page_add_new_anon_rmap(page, vma, address);
2288 set_pte_at(mm, address, page_table, entry); 2176 set_pte_at(mm, address, page_table, entry);
2289 2177
2290 /* No need to invalidate - it was non-present before */ 2178 /* No need to invalidate - it was non-present before */
2291 update_mmu_cache(vma, address, entry); 2179 update_mmu_cache(vma, address, entry);
2292 lazy_mmu_prot_update(entry);
2293unlock: 2180unlock:
2294 pte_unmap_unlock(page_table, ptl); 2181 pte_unmap_unlock(page_table, ptl);
2295 return 0; 2182 return 0;
@@ -2442,7 +2329,6 @@ static int __do_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2442 2329
2443 /* no need to invalidate: a not-present page won't be cached */ 2330 /* no need to invalidate: a not-present page won't be cached */
2444 update_mmu_cache(vma, address, entry); 2331 update_mmu_cache(vma, address, entry);
2445 lazy_mmu_prot_update(entry);
2446 } else { 2332 } else {
2447 if (anon) 2333 if (anon)
2448 page_cache_release(page); 2334 page_cache_release(page);
@@ -2470,7 +2356,7 @@ static int do_linear_fault(struct mm_struct *mm, struct vm_area_struct *vma,
2470 int write_access, pte_t orig_pte) 2356 int write_access, pte_t orig_pte)
2471{ 2357{
2472 pgoff_t pgoff = (((address & PAGE_MASK) 2358 pgoff_t pgoff = (((address & PAGE_MASK)
2473 - vma->vm_start) >> PAGE_CACHE_SHIFT) + vma->vm_pgoff; 2359 - vma->vm_start) >> PAGE_SHIFT) + vma->vm_pgoff;
2474 unsigned int flags = (write_access ? FAULT_FLAG_WRITE : 0); 2360 unsigned int flags = (write_access ? FAULT_FLAG_WRITE : 0);
2475 2361
2476 pte_unmap(page_table); 2362 pte_unmap(page_table);
@@ -2614,7 +2500,6 @@ static inline int handle_pte_fault(struct mm_struct *mm,
2614 entry = pte_mkyoung(entry); 2500 entry = pte_mkyoung(entry);
2615 if (ptep_set_access_flags(vma, address, pte, entry, write_access)) { 2501 if (ptep_set_access_flags(vma, address, pte, entry, write_access)) {
2616 update_mmu_cache(vma, address, entry); 2502 update_mmu_cache(vma, address, entry);
2617 lazy_mmu_prot_update(entry);
2618 } else { 2503 } else {
2619 /* 2504 /*
2620 * This is needed only for protection faults but the arch code 2505 * This is needed only for protection faults but the arch code
diff --git a/mm/memory_hotplug.c b/mm/memory_hotplug.c
index df9d554bea30..091b9c6c2529 100644
--- a/mm/memory_hotplug.c
+++ b/mm/memory_hotplug.c
@@ -23,6 +23,9 @@
23#include <linux/vmalloc.h> 23#include <linux/vmalloc.h>
24#include <linux/ioport.h> 24#include <linux/ioport.h>
25#include <linux/cpuset.h> 25#include <linux/cpuset.h>
26#include <linux/delay.h>
27#include <linux/migrate.h>
28#include <linux/page-isolation.h>
26 29
27#include <asm/tlbflush.h> 30#include <asm/tlbflush.h>
28 31
@@ -161,14 +164,27 @@ static void grow_pgdat_span(struct pglist_data *pgdat,
161 pgdat->node_start_pfn; 164 pgdat->node_start_pfn;
162} 165}
163 166
164int online_pages(unsigned long pfn, unsigned long nr_pages) 167static int online_pages_range(unsigned long start_pfn, unsigned long nr_pages,
168 void *arg)
165{ 169{
166 unsigned long i; 170 unsigned long i;
171 unsigned long onlined_pages = *(unsigned long *)arg;
172 struct page *page;
173 if (PageReserved(pfn_to_page(start_pfn)))
174 for (i = 0; i < nr_pages; i++) {
175 page = pfn_to_page(start_pfn + i);
176 online_page(page);
177 onlined_pages++;
178 }
179 *(unsigned long *)arg = onlined_pages;
180 return 0;
181}
182
183
184int online_pages(unsigned long pfn, unsigned long nr_pages)
185{
167 unsigned long flags; 186 unsigned long flags;
168 unsigned long onlined_pages = 0; 187 unsigned long onlined_pages = 0;
169 struct resource res;
170 u64 section_end;
171 unsigned long start_pfn;
172 struct zone *zone; 188 struct zone *zone;
173 int need_zonelists_rebuild = 0; 189 int need_zonelists_rebuild = 0;
174 190
@@ -191,32 +207,16 @@ int online_pages(unsigned long pfn, unsigned long nr_pages)
191 if (!populated_zone(zone)) 207 if (!populated_zone(zone))
192 need_zonelists_rebuild = 1; 208 need_zonelists_rebuild = 1;
193 209
194 res.start = (u64)pfn << PAGE_SHIFT; 210 walk_memory_resource(pfn, nr_pages, &onlined_pages,
195 res.end = res.start + ((u64)nr_pages << PAGE_SHIFT) - 1; 211 online_pages_range);
196 res.flags = IORESOURCE_MEM; /* we just need system ram */
197 section_end = res.end;
198
199 while ((res.start < res.end) && (find_next_system_ram(&res) >= 0)) {
200 start_pfn = (unsigned long)(res.start >> PAGE_SHIFT);
201 nr_pages = (unsigned long)
202 ((res.end + 1 - res.start) >> PAGE_SHIFT);
203
204 if (PageReserved(pfn_to_page(start_pfn))) {
205 /* this region's page is not onlined now */
206 for (i = 0; i < nr_pages; i++) {
207 struct page *page = pfn_to_page(start_pfn + i);
208 online_page(page);
209 onlined_pages++;
210 }
211 }
212
213 res.start = res.end + 1;
214 res.end = section_end;
215 }
216 zone->present_pages += onlined_pages; 212 zone->present_pages += onlined_pages;
217 zone->zone_pgdat->node_present_pages += onlined_pages; 213 zone->zone_pgdat->node_present_pages += onlined_pages;
218 214
219 setup_per_zone_pages_min(); 215 setup_per_zone_pages_min();
216 if (onlined_pages) {
217 kswapd_run(zone_to_nid(zone));
218 node_set_state(zone_to_nid(zone), N_HIGH_MEMORY);
219 }
220 220
221 if (need_zonelists_rebuild) 221 if (need_zonelists_rebuild)
222 build_all_zonelists(); 222 build_all_zonelists();
@@ -271,9 +271,6 @@ int add_memory(int nid, u64 start, u64 size)
271 if (!pgdat) 271 if (!pgdat)
272 return -ENOMEM; 272 return -ENOMEM;
273 new_pgdat = 1; 273 new_pgdat = 1;
274 ret = kswapd_run(nid);
275 if (ret)
276 goto error;
277 } 274 }
278 275
279 /* call arch's memory hotadd */ 276 /* call arch's memory hotadd */
@@ -308,3 +305,260 @@ error:
308 return ret; 305 return ret;
309} 306}
310EXPORT_SYMBOL_GPL(add_memory); 307EXPORT_SYMBOL_GPL(add_memory);
308
309#ifdef CONFIG_MEMORY_HOTREMOVE
310/*
311 * Confirm all pages in a range [start, end) is belongs to the same zone.
312 */
313static int test_pages_in_a_zone(unsigned long start_pfn, unsigned long end_pfn)
314{
315 unsigned long pfn;
316 struct zone *zone = NULL;
317 struct page *page;
318 int i;
319 for (pfn = start_pfn;
320 pfn < end_pfn;
321 pfn += MAX_ORDER_NR_PAGES) {
322 i = 0;
323 /* This is just a CONFIG_HOLES_IN_ZONE check.*/
324 while ((i < MAX_ORDER_NR_PAGES) && !pfn_valid_within(pfn + i))
325 i++;
326 if (i == MAX_ORDER_NR_PAGES)
327 continue;
328 page = pfn_to_page(pfn + i);
329 if (zone && page_zone(page) != zone)
330 return 0;
331 zone = page_zone(page);
332 }
333 return 1;
334}
335
336/*
337 * Scanning pfn is much easier than scanning lru list.
338 * Scan pfn from start to end and Find LRU page.
339 */
340int scan_lru_pages(unsigned long start, unsigned long end)
341{
342 unsigned long pfn;
343 struct page *page;
344 for (pfn = start; pfn < end; pfn++) {
345 if (pfn_valid(pfn)) {
346 page = pfn_to_page(pfn);
347 if (PageLRU(page))
348 return pfn;
349 }
350 }
351 return 0;
352}
353
354static struct page *
355hotremove_migrate_alloc(struct page *page,
356 unsigned long private,
357 int **x)
358{
359 /* This should be improoooooved!! */
360 return alloc_page(GFP_HIGHUSER_PAGECACHE);
361}
362
363
364#define NR_OFFLINE_AT_ONCE_PAGES (256)
365static int
366do_migrate_range(unsigned long start_pfn, unsigned long end_pfn)
367{
368 unsigned long pfn;
369 struct page *page;
370 int move_pages = NR_OFFLINE_AT_ONCE_PAGES;
371 int not_managed = 0;
372 int ret = 0;
373 LIST_HEAD(source);
374
375 for (pfn = start_pfn; pfn < end_pfn && move_pages > 0; pfn++) {
376 if (!pfn_valid(pfn))
377 continue;
378 page = pfn_to_page(pfn);
379 if (!page_count(page))
380 continue;
381 /*
382 * We can skip free pages. And we can only deal with pages on
383 * LRU.
384 */
385 ret = isolate_lru_page(page, &source);
386 if (!ret) { /* Success */
387 move_pages--;
388 } else {
389 /* Becasue we don't have big zone->lock. we should
390 check this again here. */
391 if (page_count(page))
392 not_managed++;
393#ifdef CONFIG_DEBUG_VM
394 printk(KERN_INFO "removing from LRU failed"
395 " %lx/%d/%lx\n",
396 pfn, page_count(page), page->flags);
397#endif
398 }
399 }
400 ret = -EBUSY;
401 if (not_managed) {
402 if (!list_empty(&source))
403 putback_lru_pages(&source);
404 goto out;
405 }
406 ret = 0;
407 if (list_empty(&source))
408 goto out;
409 /* this function returns # of failed pages */
410 ret = migrate_pages(&source, hotremove_migrate_alloc, 0);
411
412out:
413 return ret;
414}
415
416/*
417 * remove from free_area[] and mark all as Reserved.
418 */
419static int
420offline_isolated_pages_cb(unsigned long start, unsigned long nr_pages,
421 void *data)
422{
423 __offline_isolated_pages(start, start + nr_pages);
424 return 0;
425}
426
427static void
428offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
429{
430 walk_memory_resource(start_pfn, end_pfn - start_pfn, NULL,
431 offline_isolated_pages_cb);
432}
433
434/*
435 * Check all pages in range, recoreded as memory resource, are isolated.
436 */
437static int
438check_pages_isolated_cb(unsigned long start_pfn, unsigned long nr_pages,
439 void *data)
440{
441 int ret;
442 long offlined = *(long *)data;
443 ret = test_pages_isolated(start_pfn, start_pfn + nr_pages);
444 offlined = nr_pages;
445 if (!ret)
446 *(long *)data += offlined;
447 return ret;
448}
449
450static long
451check_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
452{
453 long offlined = 0;
454 int ret;
455
456 ret = walk_memory_resource(start_pfn, end_pfn - start_pfn, &offlined,
457 check_pages_isolated_cb);
458 if (ret < 0)
459 offlined = (long)ret;
460 return offlined;
461}
462
463extern void drain_all_local_pages(void);
464
465int offline_pages(unsigned long start_pfn,
466 unsigned long end_pfn, unsigned long timeout)
467{
468 unsigned long pfn, nr_pages, expire;
469 long offlined_pages;
470 int ret, drain, retry_max;
471 struct zone *zone;
472
473 BUG_ON(start_pfn >= end_pfn);
474 /* at least, alignment against pageblock is necessary */
475 if (!IS_ALIGNED(start_pfn, pageblock_nr_pages))
476 return -EINVAL;
477 if (!IS_ALIGNED(end_pfn, pageblock_nr_pages))
478 return -EINVAL;
479 /* This makes hotplug much easier...and readable.
480 we assume this for now. .*/
481 if (!test_pages_in_a_zone(start_pfn, end_pfn))
482 return -EINVAL;
483 /* set above range as isolated */
484 ret = start_isolate_page_range(start_pfn, end_pfn);
485 if (ret)
486 return ret;
487 nr_pages = end_pfn - start_pfn;
488 pfn = start_pfn;
489 expire = jiffies + timeout;
490 drain = 0;
491 retry_max = 5;
492repeat:
493 /* start memory hot removal */
494 ret = -EAGAIN;
495 if (time_after(jiffies, expire))
496 goto failed_removal;
497 ret = -EINTR;
498 if (signal_pending(current))
499 goto failed_removal;
500 ret = 0;
501 if (drain) {
502 lru_add_drain_all();
503 flush_scheduled_work();
504 cond_resched();
505 drain_all_local_pages();
506 }
507
508 pfn = scan_lru_pages(start_pfn, end_pfn);
509 if (pfn) { /* We have page on LRU */
510 ret = do_migrate_range(pfn, end_pfn);
511 if (!ret) {
512 drain = 1;
513 goto repeat;
514 } else {
515 if (ret < 0)
516 if (--retry_max == 0)
517 goto failed_removal;
518 yield();
519 drain = 1;
520 goto repeat;
521 }
522 }
523 /* drain all zone's lru pagevec, this is asyncronous... */
524 lru_add_drain_all();
525 flush_scheduled_work();
526 yield();
527 /* drain pcp pages , this is synchrouns. */
528 drain_all_local_pages();
529 /* check again */
530 offlined_pages = check_pages_isolated(start_pfn, end_pfn);
531 if (offlined_pages < 0) {
532 ret = -EBUSY;
533 goto failed_removal;
534 }
535 printk(KERN_INFO "Offlined Pages %ld\n", offlined_pages);
536 /* Ok, all of our target is islaoted.
537 We cannot do rollback at this point. */
538 offline_isolated_pages(start_pfn, end_pfn);
539 /* reset pagetype flags */
540 start_isolate_page_range(start_pfn, end_pfn);
541 /* removal success */
542 zone = page_zone(pfn_to_page(start_pfn));
543 zone->present_pages -= offlined_pages;
544 zone->zone_pgdat->node_present_pages -= offlined_pages;
545 totalram_pages -= offlined_pages;
546 num_physpages -= offlined_pages;
547 vm_total_pages = nr_free_pagecache_pages();
548 writeback_set_ratelimit();
549 return 0;
550
551failed_removal:
552 printk(KERN_INFO "memory offlining %lx to %lx failed\n",
553 start_pfn, end_pfn);
554 /* pushback to free area */
555 undo_isolate_page_range(start_pfn, end_pfn);
556 return ret;
557}
558#else
559int remove_memory(u64 start, u64 size)
560{
561 return -EINVAL;
562}
563EXPORT_SYMBOL_GPL(remove_memory);
564#endif /* CONFIG_MEMORY_HOTREMOVE */
diff --git a/mm/mempolicy.c b/mm/mempolicy.c
index 3d6ac9505d07..568152ae6caf 100644
--- a/mm/mempolicy.c
+++ b/mm/mempolicy.c
@@ -72,7 +72,6 @@
72#include <linux/hugetlb.h> 72#include <linux/hugetlb.h>
73#include <linux/kernel.h> 73#include <linux/kernel.h>
74#include <linux/sched.h> 74#include <linux/sched.h>
75#include <linux/mm.h>
76#include <linux/nodemask.h> 75#include <linux/nodemask.h>
77#include <linux/cpuset.h> 76#include <linux/cpuset.h>
78#include <linux/gfp.h> 77#include <linux/gfp.h>
@@ -82,13 +81,13 @@
82#include <linux/interrupt.h> 81#include <linux/interrupt.h>
83#include <linux/init.h> 82#include <linux/init.h>
84#include <linux/compat.h> 83#include <linux/compat.h>
85#include <linux/mempolicy.h>
86#include <linux/swap.h> 84#include <linux/swap.h>
87#include <linux/seq_file.h> 85#include <linux/seq_file.h>
88#include <linux/proc_fs.h> 86#include <linux/proc_fs.h>
89#include <linux/migrate.h> 87#include <linux/migrate.h>
90#include <linux/rmap.h> 88#include <linux/rmap.h>
91#include <linux/security.h> 89#include <linux/security.h>
90#include <linux/syscalls.h>
92 91
93#include <asm/tlbflush.h> 92#include <asm/tlbflush.h>
94#include <asm/uaccess.h> 93#include <asm/uaccess.h>
@@ -110,6 +109,9 @@ struct mempolicy default_policy = {
110 .policy = MPOL_DEFAULT, 109 .policy = MPOL_DEFAULT,
111}; 110};
112 111
112static void mpol_rebind_policy(struct mempolicy *pol,
113 const nodemask_t *newmask);
114
113/* Do sanity checking on a policy */ 115/* Do sanity checking on a policy */
114static int mpol_check_policy(int mode, nodemask_t *nodes) 116static int mpol_check_policy(int mode, nodemask_t *nodes)
115{ 117{
@@ -128,7 +130,7 @@ static int mpol_check_policy(int mode, nodemask_t *nodes)
128 return -EINVAL; 130 return -EINVAL;
129 break; 131 break;
130 } 132 }
131 return nodes_subset(*nodes, node_online_map) ? 0 : -EINVAL; 133 return nodes_subset(*nodes, node_states[N_HIGH_MEMORY]) ? 0 : -EINVAL;
132} 134}
133 135
134/* Generate a custom zonelist for the BIND policy. */ 136/* Generate a custom zonelist for the BIND policy. */
@@ -185,7 +187,9 @@ static struct mempolicy *mpol_new(int mode, nodemask_t *nodes)
185 switch (mode) { 187 switch (mode) {
186 case MPOL_INTERLEAVE: 188 case MPOL_INTERLEAVE:
187 policy->v.nodes = *nodes; 189 policy->v.nodes = *nodes;
188 if (nodes_weight(*nodes) == 0) { 190 nodes_and(policy->v.nodes, policy->v.nodes,
191 node_states[N_HIGH_MEMORY]);
192 if (nodes_weight(policy->v.nodes) == 0) {
189 kmem_cache_free(policy_cache, policy); 193 kmem_cache_free(policy_cache, policy);
190 return ERR_PTR(-EINVAL); 194 return ERR_PTR(-EINVAL);
191 } 195 }
@@ -459,7 +463,7 @@ static void mpol_set_task_struct_flag(void)
459} 463}
460 464
461/* Set the process memory policy */ 465/* Set the process memory policy */
462long do_set_mempolicy(int mode, nodemask_t *nodes) 466static long do_set_mempolicy(int mode, nodemask_t *nodes)
463{ 467{
464 struct mempolicy *new; 468 struct mempolicy *new;
465 469
@@ -494,9 +498,9 @@ static void get_zonemask(struct mempolicy *p, nodemask_t *nodes)
494 *nodes = p->v.nodes; 498 *nodes = p->v.nodes;
495 break; 499 break;
496 case MPOL_PREFERRED: 500 case MPOL_PREFERRED:
497 /* or use current node instead of online map? */ 501 /* or use current node instead of memory_map? */
498 if (p->v.preferred_node < 0) 502 if (p->v.preferred_node < 0)
499 *nodes = node_online_map; 503 *nodes = node_states[N_HIGH_MEMORY];
500 else 504 else
501 node_set(p->v.preferred_node, *nodes); 505 node_set(p->v.preferred_node, *nodes);
502 break; 506 break;
@@ -519,8 +523,8 @@ static int lookup_node(struct mm_struct *mm, unsigned long addr)
519} 523}
520 524
521/* Retrieve NUMA policy */ 525/* Retrieve NUMA policy */
522long do_get_mempolicy(int *policy, nodemask_t *nmask, 526static long do_get_mempolicy(int *policy, nodemask_t *nmask,
523 unsigned long addr, unsigned long flags) 527 unsigned long addr, unsigned long flags)
524{ 528{
525 int err; 529 int err;
526 struct mm_struct *mm = current->mm; 530 struct mm_struct *mm = current->mm;
@@ -528,8 +532,18 @@ long do_get_mempolicy(int *policy, nodemask_t *nmask,
528 struct mempolicy *pol = current->mempolicy; 532 struct mempolicy *pol = current->mempolicy;
529 533
530 cpuset_update_task_memory_state(); 534 cpuset_update_task_memory_state();
531 if (flags & ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR)) 535 if (flags &
536 ~(unsigned long)(MPOL_F_NODE|MPOL_F_ADDR|MPOL_F_MEMS_ALLOWED))
532 return -EINVAL; 537 return -EINVAL;
538
539 if (flags & MPOL_F_MEMS_ALLOWED) {
540 if (flags & (MPOL_F_NODE|MPOL_F_ADDR))
541 return -EINVAL;
542 *policy = 0; /* just so it's initialized */
543 *nmask = cpuset_current_mems_allowed;
544 return 0;
545 }
546
533 if (flags & MPOL_F_ADDR) { 547 if (flags & MPOL_F_ADDR) {
534 down_read(&mm->mmap_sem); 548 down_read(&mm->mmap_sem);
535 vma = find_vma_intersection(mm, addr, addr+1); 549 vma = find_vma_intersection(mm, addr, addr+1);
@@ -601,7 +615,8 @@ static struct page *new_node_page(struct page *page, unsigned long node, int **x
601 * Migrate pages from one node to a target node. 615 * Migrate pages from one node to a target node.
602 * Returns error or the number of pages not migrated. 616 * Returns error or the number of pages not migrated.
603 */ 617 */
604int migrate_to_node(struct mm_struct *mm, int source, int dest, int flags) 618static int migrate_to_node(struct mm_struct *mm, int source, int dest,
619 int flags)
605{ 620{
606 nodemask_t nmask; 621 nodemask_t nmask;
607 LIST_HEAD(pagelist); 622 LIST_HEAD(pagelist);
@@ -732,8 +747,9 @@ static struct page *new_vma_page(struct page *page, unsigned long private, int *
732} 747}
733#endif 748#endif
734 749
735long do_mbind(unsigned long start, unsigned long len, 750static long do_mbind(unsigned long start, unsigned long len,
736 unsigned long mode, nodemask_t *nmask, unsigned long flags) 751 unsigned long mode, nodemask_t *nmask,
752 unsigned long flags)
737{ 753{
738 struct vm_area_struct *vma; 754 struct vm_area_struct *vma;
739 struct mm_struct *mm = current->mm; 755 struct mm_struct *mm = current->mm;
@@ -955,7 +971,7 @@ asmlinkage long sys_migrate_pages(pid_t pid, unsigned long maxnode,
955 goto out; 971 goto out;
956 } 972 }
957 973
958 if (!nodes_subset(new, node_online_map)) { 974 if (!nodes_subset(new, node_states[N_HIGH_MEMORY])) {
959 err = -EINVAL; 975 err = -EINVAL;
960 goto out; 976 goto out;
961 } 977 }
@@ -978,7 +994,8 @@ asmlinkage long sys_get_mempolicy(int __user *policy,
978 unsigned long maxnode, 994 unsigned long maxnode,
979 unsigned long addr, unsigned long flags) 995 unsigned long addr, unsigned long flags)
980{ 996{
981 int err, pval; 997 int err;
998 int uninitialized_var(pval);
982 nodemask_t nodes; 999 nodemask_t nodes;
983 1000
984 if (nmask != NULL && maxnode < MAX_NUMNODES) 1001 if (nmask != NULL && maxnode < MAX_NUMNODES)
@@ -1527,8 +1544,8 @@ static void sp_delete(struct shared_policy *sp, struct sp_node *n)
1527 kmem_cache_free(sn_cache, n); 1544 kmem_cache_free(sn_cache, n);
1528} 1545}
1529 1546
1530struct sp_node * 1547static struct sp_node *sp_alloc(unsigned long start, unsigned long end,
1531sp_alloc(unsigned long start, unsigned long end, struct mempolicy *pol) 1548 struct mempolicy *pol)
1532{ 1549{
1533 struct sp_node *n = kmem_cache_alloc(sn_cache, GFP_KERNEL); 1550 struct sp_node *n = kmem_cache_alloc(sn_cache, GFP_KERNEL);
1534 1551
@@ -1677,7 +1694,7 @@ void __init numa_policy_init(void)
1677 * fall back to the largest node if they're all smaller. 1694 * fall back to the largest node if they're all smaller.
1678 */ 1695 */
1679 nodes_clear(interleave_nodes); 1696 nodes_clear(interleave_nodes);
1680 for_each_online_node(nid) { 1697 for_each_node_state(nid, N_HIGH_MEMORY) {
1681 unsigned long total_pages = node_present_pages(nid); 1698 unsigned long total_pages = node_present_pages(nid);
1682 1699
1683 /* Preserve the largest node */ 1700 /* Preserve the largest node */
@@ -1706,7 +1723,8 @@ void numa_default_policy(void)
1706} 1723}
1707 1724
1708/* Migrate a policy to a different set of nodes */ 1725/* Migrate a policy to a different set of nodes */
1709void mpol_rebind_policy(struct mempolicy *pol, const nodemask_t *newmask) 1726static void mpol_rebind_policy(struct mempolicy *pol,
1727 const nodemask_t *newmask)
1710{ 1728{
1711 nodemask_t *mpolmask; 1729 nodemask_t *mpolmask;
1712 nodemask_t tmp; 1730 nodemask_t tmp;
@@ -1963,7 +1981,7 @@ int show_numa_map(struct seq_file *m, void *v)
1963 seq_printf(m, " huge"); 1981 seq_printf(m, " huge");
1964 } else { 1982 } else {
1965 check_pgd_range(vma, vma->vm_start, vma->vm_end, 1983 check_pgd_range(vma, vma->vm_start, vma->vm_end,
1966 &node_online_map, MPOL_MF_STATS, md); 1984 &node_states[N_HIGH_MEMORY], MPOL_MF_STATS, md);
1967 } 1985 }
1968 1986
1969 if (!md->pages) 1987 if (!md->pages)
@@ -1990,7 +2008,7 @@ int show_numa_map(struct seq_file *m, void *v)
1990 if (md->writeback) 2008 if (md->writeback)
1991 seq_printf(m," writeback=%lu", md->writeback); 2009 seq_printf(m," writeback=%lu", md->writeback);
1992 2010
1993 for_each_online_node(n) 2011 for_each_node_state(n, N_HIGH_MEMORY)
1994 if (md->node[n]) 2012 if (md->node[n])
1995 seq_printf(m, " N%d=%lu", n, md->node[n]); 2013 seq_printf(m, " N%d=%lu", n, md->node[n]);
1996out: 2014out:
diff --git a/mm/migrate.c b/mm/migrate.c
index 07f22d4a431f..06d0877a66ef 100644
--- a/mm/migrate.c
+++ b/mm/migrate.c
@@ -171,6 +171,7 @@ static void remove_migration_pte(struct vm_area_struct *vma,
171 pte = pte_mkold(mk_pte(new, vma->vm_page_prot)); 171 pte = pte_mkold(mk_pte(new, vma->vm_page_prot));
172 if (is_write_migration_entry(entry)) 172 if (is_write_migration_entry(entry))
173 pte = pte_mkwrite(pte); 173 pte = pte_mkwrite(pte);
174 flush_cache_page(vma, addr, pte_pfn(pte));
174 set_pte_at(mm, addr, ptep, pte); 175 set_pte_at(mm, addr, ptep, pte);
175 176
176 if (PageAnon(new)) 177 if (PageAnon(new))
@@ -180,7 +181,6 @@ static void remove_migration_pte(struct vm_area_struct *vma,
180 181
181 /* No need to invalidate - it was non-present before */ 182 /* No need to invalidate - it was non-present before */
182 update_mmu_cache(vma, addr, pte); 183 update_mmu_cache(vma, addr, pte);
183 lazy_mmu_prot_update(pte);
184 184
185out: 185out:
186 pte_unmap_unlock(ptep, ptl); 186 pte_unmap_unlock(ptep, ptl);
@@ -986,7 +986,7 @@ asmlinkage long sys_move_pages(pid_t pid, unsigned long nr_pages,
986 goto out; 986 goto out;
987 987
988 err = -ENODEV; 988 err = -ENODEV;
989 if (!node_online(node)) 989 if (!node_state(node, N_HIGH_MEMORY))
990 goto out; 990 goto out;
991 991
992 err = -EACCES; 992 err = -EACCES;
diff --git a/mm/mprotect.c b/mm/mprotect.c
index e8346c30abec..1d4d69790e59 100644
--- a/mm/mprotect.c
+++ b/mm/mprotect.c
@@ -53,7 +53,6 @@ static void change_pte_range(struct mm_struct *mm, pmd_t *pmd,
53 if (dirty_accountable && pte_dirty(ptent)) 53 if (dirty_accountable && pte_dirty(ptent))
54 ptent = pte_mkwrite(ptent); 54 ptent = pte_mkwrite(ptent);
55 set_pte_at(mm, addr, pte, ptent); 55 set_pte_at(mm, addr, pte, ptent);
56 lazy_mmu_prot_update(ptent);
57#ifdef CONFIG_MIGRATION 56#ifdef CONFIG_MIGRATION
58 } else if (!pte_file(oldpte)) { 57 } else if (!pte_file(oldpte)) {
59 swp_entry_t entry = pte_to_swp_entry(oldpte); 58 swp_entry_t entry = pte_to_swp_entry(oldpte);
diff --git a/mm/oom_kill.c b/mm/oom_kill.c
index f9b82ad5047f..41b4e362221d 100644
--- a/mm/oom_kill.c
+++ b/mm/oom_kill.c
@@ -177,14 +177,7 @@ static inline int constrained_alloc(struct zonelist *zonelist, gfp_t gfp_mask)
177{ 177{
178#ifdef CONFIG_NUMA 178#ifdef CONFIG_NUMA
179 struct zone **z; 179 struct zone **z;
180 nodemask_t nodes; 180 nodemask_t nodes = node_states[N_HIGH_MEMORY];
181 int node;
182
183 nodes_clear(nodes);
184 /* node has memory ? */
185 for_each_online_node(node)
186 if (NODE_DATA(node)->node_present_pages)
187 node_set(node, nodes);
188 181
189 for (z = zonelist->zones; *z; z++) 182 for (z = zonelist->zones; *z; z++)
190 if (cpuset_zone_allowed_softwall(*z, gfp_mask)) 183 if (cpuset_zone_allowed_softwall(*z, gfp_mask))
diff --git a/mm/page-writeback.c b/mm/page-writeback.c
index 44720363374c..d821321326e3 100644
--- a/mm/page-writeback.c
+++ b/mm/page-writeback.c
@@ -126,7 +126,7 @@ static unsigned long highmem_dirtyable_memory(unsigned long total)
126 int node; 126 int node;
127 unsigned long x = 0; 127 unsigned long x = 0;
128 128
129 for_each_online_node(node) { 129 for_each_node_state(node, N_HIGH_MEMORY) {
130 struct zone *z = 130 struct zone *z =
131 &NODE_DATA(node)->node_zones[ZONE_HIGHMEM]; 131 &NODE_DATA(node)->node_zones[ZONE_HIGHMEM];
132 132
@@ -1022,17 +1022,15 @@ int test_set_page_writeback(struct page *page)
1022EXPORT_SYMBOL(test_set_page_writeback); 1022EXPORT_SYMBOL(test_set_page_writeback);
1023 1023
1024/* 1024/*
1025 * Return true if any of the pages in the mapping are marged with the 1025 * Return true if any of the pages in the mapping are marked with the
1026 * passed tag. 1026 * passed tag.
1027 */ 1027 */
1028int mapping_tagged(struct address_space *mapping, int tag) 1028int mapping_tagged(struct address_space *mapping, int tag)
1029{ 1029{
1030 unsigned long flags;
1031 int ret; 1030 int ret;
1032 1031 rcu_read_lock();
1033 read_lock_irqsave(&mapping->tree_lock, flags);
1034 ret = radix_tree_tagged(&mapping->page_tree, tag); 1032 ret = radix_tree_tagged(&mapping->page_tree, tag);
1035 read_unlock_irqrestore(&mapping->tree_lock, flags); 1033 rcu_read_unlock();
1036 return ret; 1034 return ret;
1037} 1035}
1038EXPORT_SYMBOL(mapping_tagged); 1036EXPORT_SYMBOL(mapping_tagged);
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index 1a8c59571cb7..d315e1127dc9 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -41,24 +41,37 @@
41#include <linux/pfn.h> 41#include <linux/pfn.h>
42#include <linux/backing-dev.h> 42#include <linux/backing-dev.h>
43#include <linux/fault-inject.h> 43#include <linux/fault-inject.h>
44#include <linux/page-isolation.h>
44 45
45#include <asm/tlbflush.h> 46#include <asm/tlbflush.h>
46#include <asm/div64.h> 47#include <asm/div64.h>
47#include "internal.h" 48#include "internal.h"
48 49
49/* 50/*
50 * MCD - HACK: Find somewhere to initialize this EARLY, or make this 51 * Array of node states.
51 * initializer cleaner
52 */ 52 */
53nodemask_t node_online_map __read_mostly = { { [0] = 1UL } }; 53nodemask_t node_states[NR_NODE_STATES] __read_mostly = {
54EXPORT_SYMBOL(node_online_map); 54 [N_POSSIBLE] = NODE_MASK_ALL,
55nodemask_t node_possible_map __read_mostly = NODE_MASK_ALL; 55 [N_ONLINE] = { { [0] = 1UL } },
56EXPORT_SYMBOL(node_possible_map); 56#ifndef CONFIG_NUMA
57 [N_NORMAL_MEMORY] = { { [0] = 1UL } },
58#ifdef CONFIG_HIGHMEM
59 [N_HIGH_MEMORY] = { { [0] = 1UL } },
60#endif
61 [N_CPU] = { { [0] = 1UL } },
62#endif /* NUMA */
63};
64EXPORT_SYMBOL(node_states);
65
57unsigned long totalram_pages __read_mostly; 66unsigned long totalram_pages __read_mostly;
58unsigned long totalreserve_pages __read_mostly; 67unsigned long totalreserve_pages __read_mostly;
59long nr_swap_pages; 68long nr_swap_pages;
60int percpu_pagelist_fraction; 69int percpu_pagelist_fraction;
61 70
71#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
72int pageblock_order __read_mostly;
73#endif
74
62static void __free_pages_ok(struct page *page, unsigned int order); 75static void __free_pages_ok(struct page *page, unsigned int order);
63 76
64/* 77/*
@@ -137,7 +150,7 @@ static unsigned long __meminitdata dma_reserve;
137 static unsigned long __meminitdata node_boundary_end_pfn[MAX_NUMNODES]; 150 static unsigned long __meminitdata node_boundary_end_pfn[MAX_NUMNODES];
138#endif /* CONFIG_MEMORY_HOTPLUG_RESERVE */ 151#endif /* CONFIG_MEMORY_HOTPLUG_RESERVE */
139 unsigned long __initdata required_kernelcore; 152 unsigned long __initdata required_kernelcore;
140 unsigned long __initdata required_movablecore; 153 static unsigned long __initdata required_movablecore;
141 unsigned long __meminitdata zone_movable_pfn[MAX_NUMNODES]; 154 unsigned long __meminitdata zone_movable_pfn[MAX_NUMNODES];
142 155
143 /* movable_zone is the "real" zone pages in ZONE_MOVABLE are taken from */ 156 /* movable_zone is the "real" zone pages in ZONE_MOVABLE are taken from */
@@ -150,6 +163,14 @@ int nr_node_ids __read_mostly = MAX_NUMNODES;
150EXPORT_SYMBOL(nr_node_ids); 163EXPORT_SYMBOL(nr_node_ids);
151#endif 164#endif
152 165
166int page_group_by_mobility_disabled __read_mostly;
167
168static void set_pageblock_migratetype(struct page *page, int migratetype)
169{
170 set_pageblock_flags_group(page, (unsigned long)migratetype,
171 PB_migrate, PB_migrate_end);
172}
173
153#ifdef CONFIG_DEBUG_VM 174#ifdef CONFIG_DEBUG_VM
154static int page_outside_zone_boundaries(struct zone *zone, struct page *page) 175static int page_outside_zone_boundaries(struct zone *zone, struct page *page)
155{ 176{
@@ -293,16 +314,6 @@ static inline void prep_zero_page(struct page *page, int order, gfp_t gfp_flags)
293 clear_highpage(page + i); 314 clear_highpage(page + i);
294} 315}
295 316
296/*
297 * function for dealing with page's order in buddy system.
298 * zone->lock is already acquired when we use these.
299 * So, we don't need atomic page->flags operations here.
300 */
301static inline unsigned long page_order(struct page *page)
302{
303 return page_private(page);
304}
305
306static inline void set_page_order(struct page *page, int order) 317static inline void set_page_order(struct page *page, int order)
307{ 318{
308 set_page_private(page, order); 319 set_page_private(page, order);
@@ -404,6 +415,7 @@ static inline void __free_one_page(struct page *page,
404{ 415{
405 unsigned long page_idx; 416 unsigned long page_idx;
406 int order_size = 1 << order; 417 int order_size = 1 << order;
418 int migratetype = get_pageblock_migratetype(page);
407 419
408 if (unlikely(PageCompound(page))) 420 if (unlikely(PageCompound(page)))
409 destroy_compound_page(page, order); 421 destroy_compound_page(page, order);
@@ -416,7 +428,6 @@ static inline void __free_one_page(struct page *page,
416 __mod_zone_page_state(zone, NR_FREE_PAGES, order_size); 428 __mod_zone_page_state(zone, NR_FREE_PAGES, order_size);
417 while (order < MAX_ORDER-1) { 429 while (order < MAX_ORDER-1) {
418 unsigned long combined_idx; 430 unsigned long combined_idx;
419 struct free_area *area;
420 struct page *buddy; 431 struct page *buddy;
421 432
422 buddy = __page_find_buddy(page, page_idx, order); 433 buddy = __page_find_buddy(page, page_idx, order);
@@ -424,8 +435,7 @@ static inline void __free_one_page(struct page *page,
424 break; /* Move the buddy up one level. */ 435 break; /* Move the buddy up one level. */
425 436
426 list_del(&buddy->lru); 437 list_del(&buddy->lru);
427 area = zone->free_area + order; 438 zone->free_area[order].nr_free--;
428 area->nr_free--;
429 rmv_page_order(buddy); 439 rmv_page_order(buddy);
430 combined_idx = __find_combined_index(page_idx, order); 440 combined_idx = __find_combined_index(page_idx, order);
431 page = page + (combined_idx - page_idx); 441 page = page + (combined_idx - page_idx);
@@ -433,7 +443,8 @@ static inline void __free_one_page(struct page *page,
433 order++; 443 order++;
434 } 444 }
435 set_page_order(page, order); 445 set_page_order(page, order);
436 list_add(&page->lru, &zone->free_area[order].free_list); 446 list_add(&page->lru,
447 &zone->free_area[order].free_list[migratetype]);
437 zone->free_area[order].nr_free++; 448 zone->free_area[order].nr_free++;
438} 449}
439 450
@@ -567,7 +578,8 @@ void fastcall __init __free_pages_bootmem(struct page *page, unsigned int order)
567 * -- wli 578 * -- wli
568 */ 579 */
569static inline void expand(struct zone *zone, struct page *page, 580static inline void expand(struct zone *zone, struct page *page,
570 int low, int high, struct free_area *area) 581 int low, int high, struct free_area *area,
582 int migratetype)
571{ 583{
572 unsigned long size = 1 << high; 584 unsigned long size = 1 << high;
573 585
@@ -576,7 +588,7 @@ static inline void expand(struct zone *zone, struct page *page,
576 high--; 588 high--;
577 size >>= 1; 589 size >>= 1;
578 VM_BUG_ON(bad_range(zone, &page[size])); 590 VM_BUG_ON(bad_range(zone, &page[size]));
579 list_add(&page[size].lru, &area->free_list); 591 list_add(&page[size].lru, &area->free_list[migratetype]);
580 area->nr_free++; 592 area->nr_free++;
581 set_page_order(&page[size], high); 593 set_page_order(&page[size], high);
582 } 594 }
@@ -628,49 +640,235 @@ static int prep_new_page(struct page *page, int order, gfp_t gfp_flags)
628 return 0; 640 return 0;
629} 641}
630 642
631/* 643/*
632 * Do the hard work of removing an element from the buddy allocator. 644 * Go through the free lists for the given migratetype and remove
633 * Call me with the zone->lock already held. 645 * the smallest available page from the freelists
634 */ 646 */
635static struct page *__rmqueue(struct zone *zone, unsigned int order) 647static struct page *__rmqueue_smallest(struct zone *zone, unsigned int order,
648 int migratetype)
636{ 649{
637 struct free_area * area;
638 unsigned int current_order; 650 unsigned int current_order;
651 struct free_area * area;
639 struct page *page; 652 struct page *page;
640 653
654 /* Find a page of the appropriate size in the preferred list */
641 for (current_order = order; current_order < MAX_ORDER; ++current_order) { 655 for (current_order = order; current_order < MAX_ORDER; ++current_order) {
642 area = zone->free_area + current_order; 656 area = &(zone->free_area[current_order]);
643 if (list_empty(&area->free_list)) 657 if (list_empty(&area->free_list[migratetype]))
644 continue; 658 continue;
645 659
646 page = list_entry(area->free_list.next, struct page, lru); 660 page = list_entry(area->free_list[migratetype].next,
661 struct page, lru);
647 list_del(&page->lru); 662 list_del(&page->lru);
648 rmv_page_order(page); 663 rmv_page_order(page);
649 area->nr_free--; 664 area->nr_free--;
650 __mod_zone_page_state(zone, NR_FREE_PAGES, - (1UL << order)); 665 __mod_zone_page_state(zone, NR_FREE_PAGES, - (1UL << order));
651 expand(zone, page, order, current_order, area); 666 expand(zone, page, order, current_order, area, migratetype);
652 return page; 667 return page;
653 } 668 }
654 669
655 return NULL; 670 return NULL;
656} 671}
657 672
673
674/*
675 * This array describes the order lists are fallen back to when
676 * the free lists for the desirable migrate type are depleted
677 */
678static int fallbacks[MIGRATE_TYPES][MIGRATE_TYPES-1] = {
679 [MIGRATE_UNMOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE },
680 [MIGRATE_RECLAIMABLE] = { MIGRATE_UNMOVABLE, MIGRATE_MOVABLE, MIGRATE_RESERVE },
681 [MIGRATE_MOVABLE] = { MIGRATE_RECLAIMABLE, MIGRATE_UNMOVABLE, MIGRATE_RESERVE },
682 [MIGRATE_RESERVE] = { MIGRATE_RESERVE, MIGRATE_RESERVE, MIGRATE_RESERVE }, /* Never used */
683};
684
685/*
686 * Move the free pages in a range to the free lists of the requested type.
687 * Note that start_page and end_pages are not aligned on a pageblock
688 * boundary. If alignment is required, use move_freepages_block()
689 */
690int move_freepages(struct zone *zone,
691 struct page *start_page, struct page *end_page,
692 int migratetype)
693{
694 struct page *page;
695 unsigned long order;
696 int pages_moved = 0;
697
698#ifndef CONFIG_HOLES_IN_ZONE
699 /*
700 * page_zone is not safe to call in this context when
701 * CONFIG_HOLES_IN_ZONE is set. This bug check is probably redundant
702 * anyway as we check zone boundaries in move_freepages_block().
703 * Remove at a later date when no bug reports exist related to
704 * grouping pages by mobility
705 */
706 BUG_ON(page_zone(start_page) != page_zone(end_page));
707#endif
708
709 for (page = start_page; page <= end_page;) {
710 if (!pfn_valid_within(page_to_pfn(page))) {
711 page++;
712 continue;
713 }
714
715 if (!PageBuddy(page)) {
716 page++;
717 continue;
718 }
719
720 order = page_order(page);
721 list_del(&page->lru);
722 list_add(&page->lru,
723 &zone->free_area[order].free_list[migratetype]);
724 page += 1 << order;
725 pages_moved += 1 << order;
726 }
727
728 return pages_moved;
729}
730
731int move_freepages_block(struct zone *zone, struct page *page, int migratetype)
732{
733 unsigned long start_pfn, end_pfn;
734 struct page *start_page, *end_page;
735
736 start_pfn = page_to_pfn(page);
737 start_pfn = start_pfn & ~(pageblock_nr_pages-1);
738 start_page = pfn_to_page(start_pfn);
739 end_page = start_page + pageblock_nr_pages - 1;
740 end_pfn = start_pfn + pageblock_nr_pages - 1;
741
742 /* Do not cross zone boundaries */
743 if (start_pfn < zone->zone_start_pfn)
744 start_page = page;
745 if (end_pfn >= zone->zone_start_pfn + zone->spanned_pages)
746 return 0;
747
748 return move_freepages(zone, start_page, end_page, migratetype);
749}
750
751/* Return the page with the lowest PFN in the list */
752static struct page *min_page(struct list_head *list)
753{
754 unsigned long min_pfn = -1UL;
755 struct page *min_page = NULL, *page;;
756
757 list_for_each_entry(page, list, lru) {
758 unsigned long pfn = page_to_pfn(page);
759 if (pfn < min_pfn) {
760 min_pfn = pfn;
761 min_page = page;
762 }
763 }
764
765 return min_page;
766}
767
768/* Remove an element from the buddy allocator from the fallback list */
769static struct page *__rmqueue_fallback(struct zone *zone, int order,
770 int start_migratetype)
771{
772 struct free_area * area;
773 int current_order;
774 struct page *page;
775 int migratetype, i;
776
777 /* Find the largest possible block of pages in the other list */
778 for (current_order = MAX_ORDER-1; current_order >= order;
779 --current_order) {
780 for (i = 0; i < MIGRATE_TYPES - 1; i++) {
781 migratetype = fallbacks[start_migratetype][i];
782
783 /* MIGRATE_RESERVE handled later if necessary */
784 if (migratetype == MIGRATE_RESERVE)
785 continue;
786
787 area = &(zone->free_area[current_order]);
788 if (list_empty(&area->free_list[migratetype]))
789 continue;
790
791 /* Bias kernel allocations towards low pfns */
792 page = list_entry(area->free_list[migratetype].next,
793 struct page, lru);
794 if (unlikely(start_migratetype != MIGRATE_MOVABLE))
795 page = min_page(&area->free_list[migratetype]);
796 area->nr_free--;
797
798 /*
799 * If breaking a large block of pages, move all free
800 * pages to the preferred allocation list. If falling
801 * back for a reclaimable kernel allocation, be more
802 * agressive about taking ownership of free pages
803 */
804 if (unlikely(current_order >= (pageblock_order >> 1)) ||
805 start_migratetype == MIGRATE_RECLAIMABLE) {
806 unsigned long pages;
807 pages = move_freepages_block(zone, page,
808 start_migratetype);
809
810 /* Claim the whole block if over half of it is free */
811 if (pages >= (1 << (pageblock_order-1)))
812 set_pageblock_migratetype(page,
813 start_migratetype);
814
815 migratetype = start_migratetype;
816 }
817
818 /* Remove the page from the freelists */
819 list_del(&page->lru);
820 rmv_page_order(page);
821 __mod_zone_page_state(zone, NR_FREE_PAGES,
822 -(1UL << order));
823
824 if (current_order == pageblock_order)
825 set_pageblock_migratetype(page,
826 start_migratetype);
827
828 expand(zone, page, order, current_order, area, migratetype);
829 return page;
830 }
831 }
832
833 /* Use MIGRATE_RESERVE rather than fail an allocation */
834 return __rmqueue_smallest(zone, order, MIGRATE_RESERVE);
835}
836
837/*
838 * Do the hard work of removing an element from the buddy allocator.
839 * Call me with the zone->lock already held.
840 */
841static struct page *__rmqueue(struct zone *zone, unsigned int order,
842 int migratetype)
843{
844 struct page *page;
845
846 page = __rmqueue_smallest(zone, order, migratetype);
847
848 if (unlikely(!page))
849 page = __rmqueue_fallback(zone, order, migratetype);
850
851 return page;
852}
853
658/* 854/*
659 * Obtain a specified number of elements from the buddy allocator, all under 855 * Obtain a specified number of elements from the buddy allocator, all under
660 * a single hold of the lock, for efficiency. Add them to the supplied list. 856 * a single hold of the lock, for efficiency. Add them to the supplied list.
661 * Returns the number of new pages which were placed at *list. 857 * Returns the number of new pages which were placed at *list.
662 */ 858 */
663static int rmqueue_bulk(struct zone *zone, unsigned int order, 859static int rmqueue_bulk(struct zone *zone, unsigned int order,
664 unsigned long count, struct list_head *list) 860 unsigned long count, struct list_head *list,
861 int migratetype)
665{ 862{
666 int i; 863 int i;
667 864
668 spin_lock(&zone->lock); 865 spin_lock(&zone->lock);
669 for (i = 0; i < count; ++i) { 866 for (i = 0; i < count; ++i) {
670 struct page *page = __rmqueue(zone, order); 867 struct page *page = __rmqueue(zone, order, migratetype);
671 if (unlikely(page == NULL)) 868 if (unlikely(page == NULL))
672 break; 869 break;
673 list_add_tail(&page->lru, list); 870 list_add(&page->lru, list);
871 set_page_private(page, migratetype);
674 } 872 }
675 spin_unlock(&zone->lock); 873 spin_unlock(&zone->lock);
676 return i; 874 return i;
@@ -732,7 +930,7 @@ void mark_free_pages(struct zone *zone)
732{ 930{
733 unsigned long pfn, max_zone_pfn; 931 unsigned long pfn, max_zone_pfn;
734 unsigned long flags; 932 unsigned long flags;
735 int order; 933 int order, t;
736 struct list_head *curr; 934 struct list_head *curr;
737 935
738 if (!zone->spanned_pages) 936 if (!zone->spanned_pages)
@@ -749,17 +947,18 @@ void mark_free_pages(struct zone *zone)
749 swsusp_unset_page_free(page); 947 swsusp_unset_page_free(page);
750 } 948 }
751 949
752 for (order = MAX_ORDER - 1; order >= 0; --order) 950 for_each_migratetype_order(order, t) {
753 list_for_each(curr, &zone->free_area[order].free_list) { 951 list_for_each(curr, &zone->free_area[order].free_list[t]) {
754 unsigned long i; 952 unsigned long i;
755 953
756 pfn = page_to_pfn(list_entry(curr, struct page, lru)); 954 pfn = page_to_pfn(list_entry(curr, struct page, lru));
757 for (i = 0; i < (1UL << order); i++) 955 for (i = 0; i < (1UL << order); i++)
758 swsusp_set_page_free(pfn_to_page(pfn + i)); 956 swsusp_set_page_free(pfn_to_page(pfn + i));
759 } 957 }
760 958 }
761 spin_unlock_irqrestore(&zone->lock, flags); 959 spin_unlock_irqrestore(&zone->lock, flags);
762} 960}
961#endif /* CONFIG_PM */
763 962
764/* 963/*
765 * Spill all of this CPU's per-cpu pages back into the buddy allocator. 964 * Spill all of this CPU's per-cpu pages back into the buddy allocator.
@@ -772,7 +971,25 @@ void drain_local_pages(void)
772 __drain_pages(smp_processor_id()); 971 __drain_pages(smp_processor_id());
773 local_irq_restore(flags); 972 local_irq_restore(flags);
774} 973}
775#endif /* CONFIG_HIBERNATION */ 974
975void smp_drain_local_pages(void *arg)
976{
977 drain_local_pages();
978}
979
980/*
981 * Spill all the per-cpu pages from all CPUs back into the buddy allocator
982 */
983void drain_all_local_pages(void)
984{
985 unsigned long flags;
986
987 local_irq_save(flags);
988 __drain_pages(smp_processor_id());
989 local_irq_restore(flags);
990
991 smp_call_function(smp_drain_local_pages, NULL, 0, 1);
992}
776 993
777/* 994/*
778 * Free a 0-order page 995 * Free a 0-order page
@@ -797,6 +1014,7 @@ static void fastcall free_hot_cold_page(struct page *page, int cold)
797 local_irq_save(flags); 1014 local_irq_save(flags);
798 __count_vm_event(PGFREE); 1015 __count_vm_event(PGFREE);
799 list_add(&page->lru, &pcp->list); 1016 list_add(&page->lru, &pcp->list);
1017 set_page_private(page, get_pageblock_migratetype(page));
800 pcp->count++; 1018 pcp->count++;
801 if (pcp->count >= pcp->high) { 1019 if (pcp->count >= pcp->high) {
802 free_pages_bulk(zone, pcp->batch, &pcp->list, 0); 1020 free_pages_bulk(zone, pcp->batch, &pcp->list, 0);
@@ -846,6 +1064,7 @@ static struct page *buffered_rmqueue(struct zonelist *zonelist,
846 struct page *page; 1064 struct page *page;
847 int cold = !!(gfp_flags & __GFP_COLD); 1065 int cold = !!(gfp_flags & __GFP_COLD);
848 int cpu; 1066 int cpu;
1067 int migratetype = allocflags_to_migratetype(gfp_flags);
849 1068
850again: 1069again:
851 cpu = get_cpu(); 1070 cpu = get_cpu();
@@ -856,16 +1075,28 @@ again:
856 local_irq_save(flags); 1075 local_irq_save(flags);
857 if (!pcp->count) { 1076 if (!pcp->count) {
858 pcp->count = rmqueue_bulk(zone, 0, 1077 pcp->count = rmqueue_bulk(zone, 0,
859 pcp->batch, &pcp->list); 1078 pcp->batch, &pcp->list, migratetype);
860 if (unlikely(!pcp->count)) 1079 if (unlikely(!pcp->count))
861 goto failed; 1080 goto failed;
862 } 1081 }
863 page = list_entry(pcp->list.next, struct page, lru); 1082
1083 /* Find a page of the appropriate migrate type */
1084 list_for_each_entry(page, &pcp->list, lru)
1085 if (page_private(page) == migratetype)
1086 break;
1087
1088 /* Allocate more to the pcp list if necessary */
1089 if (unlikely(&page->lru == &pcp->list)) {
1090 pcp->count += rmqueue_bulk(zone, 0,
1091 pcp->batch, &pcp->list, migratetype);
1092 page = list_entry(pcp->list.next, struct page, lru);
1093 }
1094
864 list_del(&page->lru); 1095 list_del(&page->lru);
865 pcp->count--; 1096 pcp->count--;
866 } else { 1097 } else {
867 spin_lock_irqsave(&zone->lock, flags); 1098 spin_lock_irqsave(&zone->lock, flags);
868 page = __rmqueue(zone, order); 1099 page = __rmqueue(zone, order, migratetype);
869 spin_unlock(&zone->lock); 1100 spin_unlock(&zone->lock);
870 if (!page) 1101 if (!page)
871 goto failed; 1102 goto failed;
@@ -1032,7 +1263,7 @@ int zone_watermark_ok(struct zone *z, int order, unsigned long mark,
1032 * 1263 *
1033 * If the zonelist cache is present in the passed in zonelist, then 1264 * If the zonelist cache is present in the passed in zonelist, then
1034 * returns a pointer to the allowed node mask (either the current 1265 * returns a pointer to the allowed node mask (either the current
1035 * tasks mems_allowed, or node_online_map.) 1266 * tasks mems_allowed, or node_states[N_HIGH_MEMORY].)
1036 * 1267 *
1037 * If the zonelist cache is not available for this zonelist, does 1268 * If the zonelist cache is not available for this zonelist, does
1038 * nothing and returns NULL. 1269 * nothing and returns NULL.
@@ -1061,7 +1292,7 @@ static nodemask_t *zlc_setup(struct zonelist *zonelist, int alloc_flags)
1061 1292
1062 allowednodes = !in_interrupt() && (alloc_flags & ALLOC_CPUSET) ? 1293 allowednodes = !in_interrupt() && (alloc_flags & ALLOC_CPUSET) ?
1063 &cpuset_current_mems_allowed : 1294 &cpuset_current_mems_allowed :
1064 &node_online_map; 1295 &node_states[N_HIGH_MEMORY];
1065 return allowednodes; 1296 return allowednodes;
1066} 1297}
1067 1298
@@ -1183,9 +1414,6 @@ zonelist_scan:
1183 !zlc_zone_worth_trying(zonelist, z, allowednodes)) 1414 !zlc_zone_worth_trying(zonelist, z, allowednodes))
1184 continue; 1415 continue;
1185 zone = *z; 1416 zone = *z;
1186 if (unlikely(NUMA_BUILD && (gfp_mask & __GFP_THISNODE) &&
1187 zone->zone_pgdat != zonelist->zones[0]->zone_pgdat))
1188 break;
1189 if ((alloc_flags & ALLOC_CPUSET) && 1417 if ((alloc_flags & ALLOC_CPUSET) &&
1190 !cpuset_zone_allowed_softwall(zone, gfp_mask)) 1418 !cpuset_zone_allowed_softwall(zone, gfp_mask))
1191 goto try_next_zone; 1419 goto try_next_zone;
@@ -1254,7 +1482,10 @@ restart:
1254 z = zonelist->zones; /* the list of zones suitable for gfp_mask */ 1482 z = zonelist->zones; /* the list of zones suitable for gfp_mask */
1255 1483
1256 if (unlikely(*z == NULL)) { 1484 if (unlikely(*z == NULL)) {
1257 /* Should this ever happen?? */ 1485 /*
1486 * Happens if we have an empty zonelist as a result of
1487 * GFP_THISNODE being used on a memoryless node
1488 */
1258 return NULL; 1489 return NULL;
1259 } 1490 }
1260 1491
@@ -1346,6 +1577,9 @@ nofail_alloc:
1346 1577
1347 cond_resched(); 1578 cond_resched();
1348 1579
1580 if (order != 0)
1581 drain_all_local_pages();
1582
1349 if (likely(did_some_progress)) { 1583 if (likely(did_some_progress)) {
1350 page = get_page_from_freelist(gfp_mask, order, 1584 page = get_page_from_freelist(gfp_mask, order,
1351 zonelist, alloc_flags); 1585 zonelist, alloc_flags);
@@ -1794,7 +2028,7 @@ static int find_next_best_node(int node, nodemask_t *used_node_mask)
1794 return node; 2028 return node;
1795 } 2029 }
1796 2030
1797 for_each_online_node(n) { 2031 for_each_node_state(n, N_HIGH_MEMORY) {
1798 cpumask_t tmp; 2032 cpumask_t tmp;
1799 2033
1800 /* Don't want a node to appear more than once */ 2034 /* Don't want a node to appear more than once */
@@ -1850,6 +2084,22 @@ static void build_zonelists_in_node_order(pg_data_t *pgdat, int node)
1850} 2084}
1851 2085
1852/* 2086/*
2087 * Build gfp_thisnode zonelists
2088 */
2089static void build_thisnode_zonelists(pg_data_t *pgdat)
2090{
2091 enum zone_type i;
2092 int j;
2093 struct zonelist *zonelist;
2094
2095 for (i = 0; i < MAX_NR_ZONES; i++) {
2096 zonelist = pgdat->node_zonelists + MAX_NR_ZONES + i;
2097 j = build_zonelists_node(pgdat, zonelist, 0, i);
2098 zonelist->zones[j] = NULL;
2099 }
2100}
2101
2102/*
1853 * Build zonelists ordered by zone and nodes within zones. 2103 * Build zonelists ordered by zone and nodes within zones.
1854 * This results in conserving DMA zone[s] until all Normal memory is 2104 * This results in conserving DMA zone[s] until all Normal memory is
1855 * exhausted, but results in overflowing to remote node while memory 2105 * exhausted, but results in overflowing to remote node while memory
@@ -1915,7 +2165,8 @@ static int default_zonelist_order(void)
1915 * If there is a node whose DMA/DMA32 memory is very big area on 2165 * If there is a node whose DMA/DMA32 memory is very big area on
1916 * local memory, NODE_ORDER may be suitable. 2166 * local memory, NODE_ORDER may be suitable.
1917 */ 2167 */
1918 average_size = total_size / (num_online_nodes() + 1); 2168 average_size = total_size /
2169 (nodes_weight(node_states[N_HIGH_MEMORY]) + 1);
1919 for_each_online_node(nid) { 2170 for_each_online_node(nid) {
1920 low_kmem_size = 0; 2171 low_kmem_size = 0;
1921 total_size = 0; 2172 total_size = 0;
@@ -1953,7 +2204,7 @@ static void build_zonelists(pg_data_t *pgdat)
1953 int order = current_zonelist_order; 2204 int order = current_zonelist_order;
1954 2205
1955 /* initialize zonelists */ 2206 /* initialize zonelists */
1956 for (i = 0; i < MAX_NR_ZONES; i++) { 2207 for (i = 0; i < MAX_ZONELISTS; i++) {
1957 zonelist = pgdat->node_zonelists + i; 2208 zonelist = pgdat->node_zonelists + i;
1958 zonelist->zones[0] = NULL; 2209 zonelist->zones[0] = NULL;
1959 } 2210 }
@@ -1998,6 +2249,8 @@ static void build_zonelists(pg_data_t *pgdat)
1998 /* calculate node order -- i.e., DMA last! */ 2249 /* calculate node order -- i.e., DMA last! */
1999 build_zonelists_in_zone_order(pgdat, j); 2250 build_zonelists_in_zone_order(pgdat, j);
2000 } 2251 }
2252
2253 build_thisnode_zonelists(pgdat);
2001} 2254}
2002 2255
2003/* Construct the zonelist performance cache - see further mmzone.h */ 2256/* Construct the zonelist performance cache - see further mmzone.h */
@@ -2078,8 +2331,10 @@ static int __build_all_zonelists(void *dummy)
2078 int nid; 2331 int nid;
2079 2332
2080 for_each_online_node(nid) { 2333 for_each_online_node(nid) {
2081 build_zonelists(NODE_DATA(nid)); 2334 pg_data_t *pgdat = NODE_DATA(nid);
2082 build_zonelist_cache(NODE_DATA(nid)); 2335
2336 build_zonelists(pgdat);
2337 build_zonelist_cache(pgdat);
2083 } 2338 }
2084 return 0; 2339 return 0;
2085} 2340}
@@ -2098,9 +2353,23 @@ void build_all_zonelists(void)
2098 /* cpuset refresh routine should be here */ 2353 /* cpuset refresh routine should be here */
2099 } 2354 }
2100 vm_total_pages = nr_free_pagecache_pages(); 2355 vm_total_pages = nr_free_pagecache_pages();
2101 printk("Built %i zonelists in %s order. Total pages: %ld\n", 2356 /*
2357 * Disable grouping by mobility if the number of pages in the
2358 * system is too low to allow the mechanism to work. It would be
2359 * more accurate, but expensive to check per-zone. This check is
2360 * made on memory-hotadd so a system can start with mobility
2361 * disabled and enable it later
2362 */
2363 if (vm_total_pages < (pageblock_nr_pages * MIGRATE_TYPES))
2364 page_group_by_mobility_disabled = 1;
2365 else
2366 page_group_by_mobility_disabled = 0;
2367
2368 printk("Built %i zonelists in %s order, mobility grouping %s. "
2369 "Total pages: %ld\n",
2102 num_online_nodes(), 2370 num_online_nodes(),
2103 zonelist_order_name[current_zonelist_order], 2371 zonelist_order_name[current_zonelist_order],
2372 page_group_by_mobility_disabled ? "off" : "on",
2104 vm_total_pages); 2373 vm_total_pages);
2105#ifdef CONFIG_NUMA 2374#ifdef CONFIG_NUMA
2106 printk("Policy zone: %s\n", zone_names[policy_zone]); 2375 printk("Policy zone: %s\n", zone_names[policy_zone]);
@@ -2176,6 +2445,61 @@ static inline unsigned long wait_table_bits(unsigned long size)
2176#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1)) 2445#define LONG_ALIGN(x) (((x)+(sizeof(long))-1)&~((sizeof(long))-1))
2177 2446
2178/* 2447/*
2448 * Mark a number of pageblocks as MIGRATE_RESERVE. The number
2449 * of blocks reserved is based on zone->pages_min. The memory within the
2450 * reserve will tend to store contiguous free pages. Setting min_free_kbytes
2451 * higher will lead to a bigger reserve which will get freed as contiguous
2452 * blocks as reclaim kicks in
2453 */
2454static void setup_zone_migrate_reserve(struct zone *zone)
2455{
2456 unsigned long start_pfn, pfn, end_pfn;
2457 struct page *page;
2458 unsigned long reserve, block_migratetype;
2459
2460 /* Get the start pfn, end pfn and the number of blocks to reserve */
2461 start_pfn = zone->zone_start_pfn;
2462 end_pfn = start_pfn + zone->spanned_pages;
2463 reserve = roundup(zone->pages_min, pageblock_nr_pages) >>
2464 pageblock_order;
2465
2466 for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
2467 if (!pfn_valid(pfn))
2468 continue;
2469 page = pfn_to_page(pfn);
2470
2471 /* Blocks with reserved pages will never free, skip them. */
2472 if (PageReserved(page))
2473 continue;
2474
2475 block_migratetype = get_pageblock_migratetype(page);
2476
2477 /* If this block is reserved, account for it */
2478 if (reserve > 0 && block_migratetype == MIGRATE_RESERVE) {
2479 reserve--;
2480 continue;
2481 }
2482
2483 /* Suitable for reserving if this block is movable */
2484 if (reserve > 0 && block_migratetype == MIGRATE_MOVABLE) {
2485 set_pageblock_migratetype(page, MIGRATE_RESERVE);
2486 move_freepages_block(zone, page, MIGRATE_RESERVE);
2487 reserve--;
2488 continue;
2489 }
2490
2491 /*
2492 * If the reserve is met and this is a previous reserved block,
2493 * take it back
2494 */
2495 if (block_migratetype == MIGRATE_RESERVE) {
2496 set_pageblock_migratetype(page, MIGRATE_MOVABLE);
2497 move_freepages_block(zone, page, MIGRATE_MOVABLE);
2498 }
2499 }
2500}
2501
2502/*
2179 * Initially all pages are reserved - free ones are freed 2503 * Initially all pages are reserved - free ones are freed
2180 * up by free_all_bootmem() once the early boot process is 2504 * up by free_all_bootmem() once the early boot process is
2181 * done. Non-atomic initialization, single-pass. 2505 * done. Non-atomic initialization, single-pass.
@@ -2204,6 +2528,19 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
2204 init_page_count(page); 2528 init_page_count(page);
2205 reset_page_mapcount(page); 2529 reset_page_mapcount(page);
2206 SetPageReserved(page); 2530 SetPageReserved(page);
2531
2532 /*
2533 * Mark the block movable so that blocks are reserved for
2534 * movable at startup. This will force kernel allocations
2535 * to reserve their blocks rather than leaking throughout
2536 * the address space during boot when many long-lived
2537 * kernel allocations are made. Later some blocks near
2538 * the start are marked MIGRATE_RESERVE by
2539 * setup_zone_migrate_reserve()
2540 */
2541 if ((pfn & (pageblock_nr_pages-1)))
2542 set_pageblock_migratetype(page, MIGRATE_MOVABLE);
2543
2207 INIT_LIST_HEAD(&page->lru); 2544 INIT_LIST_HEAD(&page->lru);
2208#ifdef WANT_PAGE_VIRTUAL 2545#ifdef WANT_PAGE_VIRTUAL
2209 /* The shift won't overflow because ZONE_NORMAL is below 4G. */ 2546 /* The shift won't overflow because ZONE_NORMAL is below 4G. */
@@ -2216,9 +2553,9 @@ void __meminit memmap_init_zone(unsigned long size, int nid, unsigned long zone,
2216static void __meminit zone_init_free_lists(struct pglist_data *pgdat, 2553static void __meminit zone_init_free_lists(struct pglist_data *pgdat,
2217 struct zone *zone, unsigned long size) 2554 struct zone *zone, unsigned long size)
2218{ 2555{
2219 int order; 2556 int order, t;
2220 for (order = 0; order < MAX_ORDER ; order++) { 2557 for_each_migratetype_order(order, t) {
2221 INIT_LIST_HEAD(&zone->free_area[order].free_list); 2558 INIT_LIST_HEAD(&zone->free_area[order].free_list[t]);
2222 zone->free_area[order].nr_free = 0; 2559 zone->free_area[order].nr_free = 0;
2223 } 2560 }
2224} 2561}
@@ -2324,6 +2661,9 @@ static struct per_cpu_pageset boot_pageset[NR_CPUS];
2324static int __cpuinit process_zones(int cpu) 2661static int __cpuinit process_zones(int cpu)
2325{ 2662{
2326 struct zone *zone, *dzone; 2663 struct zone *zone, *dzone;
2664 int node = cpu_to_node(cpu);
2665
2666 node_set_state(node, N_CPU); /* this node has a cpu */
2327 2667
2328 for_each_zone(zone) { 2668 for_each_zone(zone) {
2329 2669
@@ -2331,7 +2671,7 @@ static int __cpuinit process_zones(int cpu)
2331 continue; 2671 continue;
2332 2672
2333 zone_pcp(zone, cpu) = kmalloc_node(sizeof(struct per_cpu_pageset), 2673 zone_pcp(zone, cpu) = kmalloc_node(sizeof(struct per_cpu_pageset),
2334 GFP_KERNEL, cpu_to_node(cpu)); 2674 GFP_KERNEL, node);
2335 if (!zone_pcp(zone, cpu)) 2675 if (!zone_pcp(zone, cpu))
2336 goto bad; 2676 goto bad;
2337 2677
@@ -2444,7 +2784,7 @@ int zone_wait_table_init(struct zone *zone, unsigned long zone_size_pages)
2444 * To use this new node's memory, further consideration will be 2784 * To use this new node's memory, further consideration will be
2445 * necessary. 2785 * necessary.
2446 */ 2786 */
2447 zone->wait_table = (wait_queue_head_t *)vmalloc(alloc_size); 2787 zone->wait_table = vmalloc(alloc_size);
2448 } 2788 }
2449 if (!zone->wait_table) 2789 if (!zone->wait_table)
2450 return -ENOMEM; 2790 return -ENOMEM;
@@ -2680,10 +3020,8 @@ void __meminit get_pfn_range_for_nid(unsigned int nid,
2680 *end_pfn = max(*end_pfn, early_node_map[i].end_pfn); 3020 *end_pfn = max(*end_pfn, early_node_map[i].end_pfn);
2681 } 3021 }
2682 3022
2683 if (*start_pfn == -1UL) { 3023 if (*start_pfn == -1UL)
2684 printk(KERN_WARNING "Node %u active with no memory\n", nid);
2685 *start_pfn = 0; 3024 *start_pfn = 0;
2686 }
2687 3025
2688 /* Push the node boundaries out if requested */ 3026 /* Push the node boundaries out if requested */
2689 account_node_boundary(nid, start_pfn, end_pfn); 3027 account_node_boundary(nid, start_pfn, end_pfn);
@@ -2901,6 +3239,62 @@ static void __meminit calculate_node_totalpages(struct pglist_data *pgdat,
2901 realtotalpages); 3239 realtotalpages);
2902} 3240}
2903 3241
3242#ifndef CONFIG_SPARSEMEM
3243/*
3244 * Calculate the size of the zone->blockflags rounded to an unsigned long
3245 * Start by making sure zonesize is a multiple of pageblock_order by rounding
3246 * up. Then use 1 NR_PAGEBLOCK_BITS worth of bits per pageblock, finally
3247 * round what is now in bits to nearest long in bits, then return it in
3248 * bytes.
3249 */
3250static unsigned long __init usemap_size(unsigned long zonesize)
3251{
3252 unsigned long usemapsize;
3253
3254 usemapsize = roundup(zonesize, pageblock_nr_pages);
3255 usemapsize = usemapsize >> pageblock_order;
3256 usemapsize *= NR_PAGEBLOCK_BITS;
3257 usemapsize = roundup(usemapsize, 8 * sizeof(unsigned long));
3258
3259 return usemapsize / 8;
3260}
3261
3262static void __init setup_usemap(struct pglist_data *pgdat,
3263 struct zone *zone, unsigned long zonesize)
3264{
3265 unsigned long usemapsize = usemap_size(zonesize);
3266 zone->pageblock_flags = NULL;
3267 if (usemapsize) {
3268 zone->pageblock_flags = alloc_bootmem_node(pgdat, usemapsize);
3269 memset(zone->pageblock_flags, 0, usemapsize);
3270 }
3271}
3272#else
3273static void inline setup_usemap(struct pglist_data *pgdat,
3274 struct zone *zone, unsigned long zonesize) {}
3275#endif /* CONFIG_SPARSEMEM */
3276
3277#ifdef CONFIG_HUGETLB_PAGE_SIZE_VARIABLE
3278/* Initialise the number of pages represented by NR_PAGEBLOCK_BITS */
3279static inline void __init set_pageblock_order(unsigned int order)
3280{
3281 /* Check that pageblock_nr_pages has not already been setup */
3282 if (pageblock_order)
3283 return;
3284
3285 /*
3286 * Assume the largest contiguous order of interest is a huge page.
3287 * This value may be variable depending on boot parameters on IA64
3288 */
3289 pageblock_order = order;
3290}
3291#else /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
3292
3293/* Defined this way to avoid accidently referencing HUGETLB_PAGE_ORDER */
3294#define set_pageblock_order(x) do {} while (0)
3295
3296#endif /* CONFIG_HUGETLB_PAGE_SIZE_VARIABLE */
3297
2904/* 3298/*
2905 * Set up the zone data structures: 3299 * Set up the zone data structures:
2906 * - mark all pages reserved 3300 * - mark all pages reserved
@@ -2981,6 +3375,8 @@ static void __meminit free_area_init_core(struct pglist_data *pgdat,
2981 if (!size) 3375 if (!size)
2982 continue; 3376 continue;
2983 3377
3378 set_pageblock_order(HUGETLB_PAGE_ORDER);
3379 setup_usemap(pgdat, zone, size);
2984 ret = init_currently_empty_zone(zone, zone_start_pfn, 3380 ret = init_currently_empty_zone(zone, zone_start_pfn,
2985 size, MEMMAP_EARLY); 3381 size, MEMMAP_EARLY);
2986 BUG_ON(ret); 3382 BUG_ON(ret);
@@ -3234,16 +3630,24 @@ unsigned long __init find_max_pfn_with_active_regions(void)
3234 return max_pfn; 3630 return max_pfn;
3235} 3631}
3236 3632
3237unsigned long __init early_calculate_totalpages(void) 3633/*
3634 * early_calculate_totalpages()
3635 * Sum pages in active regions for movable zone.
3636 * Populate N_HIGH_MEMORY for calculating usable_nodes.
3637 */
3638static unsigned long __init early_calculate_totalpages(void)
3238{ 3639{
3239 int i; 3640 int i;
3240 unsigned long totalpages = 0; 3641 unsigned long totalpages = 0;
3241 3642
3242 for (i = 0; i < nr_nodemap_entries; i++) 3643 for (i = 0; i < nr_nodemap_entries; i++) {
3243 totalpages += early_node_map[i].end_pfn - 3644 unsigned long pages = early_node_map[i].end_pfn -
3244 early_node_map[i].start_pfn; 3645 early_node_map[i].start_pfn;
3245 3646 totalpages += pages;
3246 return totalpages; 3647 if (pages)
3648 node_set_state(early_node_map[i].nid, N_HIGH_MEMORY);
3649 }
3650 return totalpages;
3247} 3651}
3248 3652
3249/* 3653/*
@@ -3257,7 +3661,8 @@ void __init find_zone_movable_pfns_for_nodes(unsigned long *movable_pfn)
3257 int i, nid; 3661 int i, nid;
3258 unsigned long usable_startpfn; 3662 unsigned long usable_startpfn;
3259 unsigned long kernelcore_node, kernelcore_remaining; 3663 unsigned long kernelcore_node, kernelcore_remaining;
3260 int usable_nodes = num_online_nodes(); 3664 unsigned long totalpages = early_calculate_totalpages();
3665 int usable_nodes = nodes_weight(node_states[N_HIGH_MEMORY]);
3261 3666
3262 /* 3667 /*
3263 * If movablecore was specified, calculate what size of 3668 * If movablecore was specified, calculate what size of
@@ -3268,7 +3673,6 @@ void __init find_zone_movable_pfns_for_nodes(unsigned long *movable_pfn)
3268 * what movablecore would have allowed. 3673 * what movablecore would have allowed.
3269 */ 3674 */
3270 if (required_movablecore) { 3675 if (required_movablecore) {
3271 unsigned long totalpages = early_calculate_totalpages();
3272 unsigned long corepages; 3676 unsigned long corepages;
3273 3677
3274 /* 3678 /*
@@ -3293,7 +3697,7 @@ void __init find_zone_movable_pfns_for_nodes(unsigned long *movable_pfn)
3293restart: 3697restart:
3294 /* Spread kernelcore memory as evenly as possible throughout nodes */ 3698 /* Spread kernelcore memory as evenly as possible throughout nodes */
3295 kernelcore_node = required_kernelcore / usable_nodes; 3699 kernelcore_node = required_kernelcore / usable_nodes;
3296 for_each_online_node(nid) { 3700 for_each_node_state(nid, N_HIGH_MEMORY) {
3297 /* 3701 /*
3298 * Recalculate kernelcore_node if the division per node 3702 * Recalculate kernelcore_node if the division per node
3299 * now exceeds what is necessary to satisfy the requested 3703 * now exceeds what is necessary to satisfy the requested
@@ -3385,6 +3789,20 @@ restart:
3385 roundup(zone_movable_pfn[nid], MAX_ORDER_NR_PAGES); 3789 roundup(zone_movable_pfn[nid], MAX_ORDER_NR_PAGES);
3386} 3790}
3387 3791
3792/* Any regular memory on that node ? */
3793static void check_for_regular_memory(pg_data_t *pgdat)
3794{
3795#ifdef CONFIG_HIGHMEM
3796 enum zone_type zone_type;
3797
3798 for (zone_type = 0; zone_type <= ZONE_NORMAL; zone_type++) {
3799 struct zone *zone = &pgdat->node_zones[zone_type];
3800 if (zone->present_pages)
3801 node_set_state(zone_to_nid(zone), N_NORMAL_MEMORY);
3802 }
3803#endif
3804}
3805
3388/** 3806/**
3389 * free_area_init_nodes - Initialise all pg_data_t and zone data 3807 * free_area_init_nodes - Initialise all pg_data_t and zone data
3390 * @max_zone_pfn: an array of max PFNs for each zone 3808 * @max_zone_pfn: an array of max PFNs for each zone
@@ -3459,6 +3877,11 @@ void __init free_area_init_nodes(unsigned long *max_zone_pfn)
3459 pg_data_t *pgdat = NODE_DATA(nid); 3877 pg_data_t *pgdat = NODE_DATA(nid);
3460 free_area_init_node(nid, pgdat, NULL, 3878 free_area_init_node(nid, pgdat, NULL,
3461 find_min_pfn_for_node(nid), NULL); 3879 find_min_pfn_for_node(nid), NULL);
3880
3881 /* Any memory on that node */
3882 if (pgdat->node_present_pages)
3883 node_set_state(nid, N_HIGH_MEMORY);
3884 check_for_regular_memory(pgdat);
3462 } 3885 }
3463} 3886}
3464 3887
@@ -3673,6 +4096,7 @@ void setup_per_zone_pages_min(void)
3673 4096
3674 zone->pages_low = zone->pages_min + (tmp >> 2); 4097 zone->pages_low = zone->pages_min + (tmp >> 2);
3675 zone->pages_high = zone->pages_min + (tmp >> 1); 4098 zone->pages_high = zone->pages_min + (tmp >> 1);
4099 setup_zone_migrate_reserve(zone);
3676 spin_unlock_irqrestore(&zone->lru_lock, flags); 4100 spin_unlock_irqrestore(&zone->lru_lock, flags);
3677 } 4101 }
3678 4102
@@ -3934,4 +4358,169 @@ EXPORT_SYMBOL(pfn_to_page);
3934EXPORT_SYMBOL(page_to_pfn); 4358EXPORT_SYMBOL(page_to_pfn);
3935#endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */ 4359#endif /* CONFIG_OUT_OF_LINE_PFN_TO_PAGE */
3936 4360
4361/* Return a pointer to the bitmap storing bits affecting a block of pages */
4362static inline unsigned long *get_pageblock_bitmap(struct zone *zone,
4363 unsigned long pfn)
4364{
4365#ifdef CONFIG_SPARSEMEM
4366 return __pfn_to_section(pfn)->pageblock_flags;
4367#else
4368 return zone->pageblock_flags;
4369#endif /* CONFIG_SPARSEMEM */
4370}
4371
4372static inline int pfn_to_bitidx(struct zone *zone, unsigned long pfn)
4373{
4374#ifdef CONFIG_SPARSEMEM
4375 pfn &= (PAGES_PER_SECTION-1);
4376 return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS;
4377#else
4378 pfn = pfn - zone->zone_start_pfn;
4379 return (pfn >> pageblock_order) * NR_PAGEBLOCK_BITS;
4380#endif /* CONFIG_SPARSEMEM */
4381}
4382
4383/**
4384 * get_pageblock_flags_group - Return the requested group of flags for the pageblock_nr_pages block of pages
4385 * @page: The page within the block of interest
4386 * @start_bitidx: The first bit of interest to retrieve
4387 * @end_bitidx: The last bit of interest
4388 * returns pageblock_bits flags
4389 */
4390unsigned long get_pageblock_flags_group(struct page *page,
4391 int start_bitidx, int end_bitidx)
4392{
4393 struct zone *zone;
4394 unsigned long *bitmap;
4395 unsigned long pfn, bitidx;
4396 unsigned long flags = 0;
4397 unsigned long value = 1;
4398
4399 zone = page_zone(page);
4400 pfn = page_to_pfn(page);
4401 bitmap = get_pageblock_bitmap(zone, pfn);
4402 bitidx = pfn_to_bitidx(zone, pfn);
4403
4404 for (; start_bitidx <= end_bitidx; start_bitidx++, value <<= 1)
4405 if (test_bit(bitidx + start_bitidx, bitmap))
4406 flags |= value;
4407
4408 return flags;
4409}
3937 4410
4411/**
4412 * set_pageblock_flags_group - Set the requested group of flags for a pageblock_nr_pages block of pages
4413 * @page: The page within the block of interest
4414 * @start_bitidx: The first bit of interest
4415 * @end_bitidx: The last bit of interest
4416 * @flags: The flags to set
4417 */
4418void set_pageblock_flags_group(struct page *page, unsigned long flags,
4419 int start_bitidx, int end_bitidx)
4420{
4421 struct zone *zone;
4422 unsigned long *bitmap;
4423 unsigned long pfn, bitidx;
4424 unsigned long value = 1;
4425
4426 zone = page_zone(page);
4427 pfn = page_to_pfn(page);
4428 bitmap = get_pageblock_bitmap(zone, pfn);
4429 bitidx = pfn_to_bitidx(zone, pfn);
4430
4431 for (; start_bitidx <= end_bitidx; start_bitidx++, value <<= 1)
4432 if (flags & value)
4433 __set_bit(bitidx + start_bitidx, bitmap);
4434 else
4435 __clear_bit(bitidx + start_bitidx, bitmap);
4436}
4437
4438/*
4439 * This is designed as sub function...plz see page_isolation.c also.
4440 * set/clear page block's type to be ISOLATE.
4441 * page allocater never alloc memory from ISOLATE block.
4442 */
4443
4444int set_migratetype_isolate(struct page *page)
4445{
4446 struct zone *zone;
4447 unsigned long flags;
4448 int ret = -EBUSY;
4449
4450 zone = page_zone(page);
4451 spin_lock_irqsave(&zone->lock, flags);
4452 /*
4453 * In future, more migrate types will be able to be isolation target.
4454 */
4455 if (get_pageblock_migratetype(page) != MIGRATE_MOVABLE)
4456 goto out;
4457 set_pageblock_migratetype(page, MIGRATE_ISOLATE);
4458 move_freepages_block(zone, page, MIGRATE_ISOLATE);
4459 ret = 0;
4460out:
4461 spin_unlock_irqrestore(&zone->lock, flags);
4462 if (!ret)
4463 drain_all_local_pages();
4464 return ret;
4465}
4466
4467void unset_migratetype_isolate(struct page *page)
4468{
4469 struct zone *zone;
4470 unsigned long flags;
4471 zone = page_zone(page);
4472 spin_lock_irqsave(&zone->lock, flags);
4473 if (get_pageblock_migratetype(page) != MIGRATE_ISOLATE)
4474 goto out;
4475 set_pageblock_migratetype(page, MIGRATE_MOVABLE);
4476 move_freepages_block(zone, page, MIGRATE_MOVABLE);
4477out:
4478 spin_unlock_irqrestore(&zone->lock, flags);
4479}
4480
4481#ifdef CONFIG_MEMORY_HOTREMOVE
4482/*
4483 * All pages in the range must be isolated before calling this.
4484 */
4485void
4486__offline_isolated_pages(unsigned long start_pfn, unsigned long end_pfn)
4487{
4488 struct page *page;
4489 struct zone *zone;
4490 int order, i;
4491 unsigned long pfn;
4492 unsigned long flags;
4493 /* find the first valid pfn */
4494 for (pfn = start_pfn; pfn < end_pfn; pfn++)
4495 if (pfn_valid(pfn))
4496 break;
4497 if (pfn == end_pfn)
4498 return;
4499 zone = page_zone(pfn_to_page(pfn));
4500 spin_lock_irqsave(&zone->lock, flags);
4501 pfn = start_pfn;
4502 while (pfn < end_pfn) {
4503 if (!pfn_valid(pfn)) {
4504 pfn++;
4505 continue;
4506 }
4507 page = pfn_to_page(pfn);
4508 BUG_ON(page_count(page));
4509 BUG_ON(!PageBuddy(page));
4510 order = page_order(page);
4511#ifdef CONFIG_DEBUG_VM
4512 printk(KERN_INFO "remove from free list %lx %d %lx\n",
4513 pfn, 1 << order, end_pfn);
4514#endif
4515 list_del(&page->lru);
4516 rmv_page_order(page);
4517 zone->free_area[order].nr_free--;
4518 __mod_zone_page_state(zone, NR_FREE_PAGES,
4519 - (1UL << order));
4520 for (i = 0; i < (1 << order); i++)
4521 SetPageReserved((page+i));
4522 pfn += (1 << order);
4523 }
4524 spin_unlock_irqrestore(&zone->lock, flags);
4525}
4526#endif
diff --git a/mm/page_isolation.c b/mm/page_isolation.c
new file mode 100644
index 000000000000..8f92a29695cc
--- /dev/null
+++ b/mm/page_isolation.c
@@ -0,0 +1,138 @@
1/*
2 * linux/mm/page_isolation.c
3 */
4
5#include <stddef.h>
6#include <linux/mm.h>
7#include <linux/page-isolation.h>
8#include <linux/pageblock-flags.h>
9#include "internal.h"
10
11static inline struct page *
12__first_valid_page(unsigned long pfn, unsigned long nr_pages)
13{
14 int i;
15 for (i = 0; i < nr_pages; i++)
16 if (pfn_valid_within(pfn + i))
17 break;
18 if (unlikely(i == nr_pages))
19 return NULL;
20 return pfn_to_page(pfn + i);
21}
22
23/*
24 * start_isolate_page_range() -- make page-allocation-type of range of pages
25 * to be MIGRATE_ISOLATE.
26 * @start_pfn: The lower PFN of the range to be isolated.
27 * @end_pfn: The upper PFN of the range to be isolated.
28 *
29 * Making page-allocation-type to be MIGRATE_ISOLATE means free pages in
30 * the range will never be allocated. Any free pages and pages freed in the
31 * future will not be allocated again.
32 *
33 * start_pfn/end_pfn must be aligned to pageblock_order.
34 * Returns 0 on success and -EBUSY if any part of range cannot be isolated.
35 */
36int
37start_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn)
38{
39 unsigned long pfn;
40 unsigned long undo_pfn;
41 struct page *page;
42
43 BUG_ON((start_pfn) & (pageblock_nr_pages - 1));
44 BUG_ON((end_pfn) & (pageblock_nr_pages - 1));
45
46 for (pfn = start_pfn;
47 pfn < end_pfn;
48 pfn += pageblock_nr_pages) {
49 page = __first_valid_page(pfn, pageblock_nr_pages);
50 if (page && set_migratetype_isolate(page)) {
51 undo_pfn = pfn;
52 goto undo;
53 }
54 }
55 return 0;
56undo:
57 for (pfn = start_pfn;
58 pfn <= undo_pfn;
59 pfn += pageblock_nr_pages)
60 unset_migratetype_isolate(pfn_to_page(pfn));
61
62 return -EBUSY;
63}
64
65/*
66 * Make isolated pages available again.
67 */
68int
69undo_isolate_page_range(unsigned long start_pfn, unsigned long end_pfn)
70{
71 unsigned long pfn;
72 struct page *page;
73 BUG_ON((start_pfn) & (pageblock_nr_pages - 1));
74 BUG_ON((end_pfn) & (pageblock_nr_pages - 1));
75 for (pfn = start_pfn;
76 pfn < end_pfn;
77 pfn += pageblock_nr_pages) {
78 page = __first_valid_page(pfn, pageblock_nr_pages);
79 if (!page || get_pageblock_flags(page) != MIGRATE_ISOLATE)
80 continue;
81 unset_migratetype_isolate(page);
82 }
83 return 0;
84}
85/*
86 * Test all pages in the range is free(means isolated) or not.
87 * all pages in [start_pfn...end_pfn) must be in the same zone.
88 * zone->lock must be held before call this.
89 *
90 * Returns 0 if all pages in the range is isolated.
91 */
92static int
93__test_page_isolated_in_pageblock(unsigned long pfn, unsigned long end_pfn)
94{
95 struct page *page;
96
97 while (pfn < end_pfn) {
98 if (!pfn_valid_within(pfn)) {
99 pfn++;
100 continue;
101 }
102 page = pfn_to_page(pfn);
103 if (PageBuddy(page))
104 pfn += 1 << page_order(page);
105 else if (page_count(page) == 0 &&
106 page_private(page) == MIGRATE_ISOLATE)
107 pfn += 1;
108 else
109 break;
110 }
111 if (pfn < end_pfn)
112 return 0;
113 return 1;
114}
115
116int test_pages_isolated(unsigned long start_pfn, unsigned long end_pfn)
117{
118 unsigned long pfn;
119 struct page *page;
120
121 pfn = start_pfn;
122 /*
123 * Note: pageblock_nr_page != MAX_ORDER. Then, chunks of free page
124 * is not aligned to pageblock_nr_pages.
125 * Then we just check pagetype fist.
126 */
127 for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
128 page = __first_valid_page(pfn, pageblock_nr_pages);
129 if (page && get_pageblock_flags(page) != MIGRATE_ISOLATE)
130 break;
131 }
132 if (pfn < end_pfn)
133 return -EBUSY;
134 /* Check all pages are free or Marked as ISOLATED */
135 if (__test_page_isolated_in_pageblock(start_pfn, end_pfn))
136 return 0;
137 return -EBUSY;
138}
diff --git a/mm/readahead.c b/mm/readahead.c
index be20c9d699d3..229788884010 100644
--- a/mm/readahead.c
+++ b/mm/readahead.c
@@ -22,16 +22,8 @@ void default_unplug_io_fn(struct backing_dev_info *bdi, struct page *page)
22} 22}
23EXPORT_SYMBOL(default_unplug_io_fn); 23EXPORT_SYMBOL(default_unplug_io_fn);
24 24
25/*
26 * Convienent macros for min/max read-ahead pages.
27 * Note that MAX_RA_PAGES is rounded down, while MIN_RA_PAGES is rounded up.
28 * The latter is necessary for systems with large page size(i.e. 64k).
29 */
30#define MAX_RA_PAGES (VM_MAX_READAHEAD*1024 / PAGE_CACHE_SIZE)
31#define MIN_RA_PAGES DIV_ROUND_UP(VM_MIN_READAHEAD*1024, PAGE_CACHE_SIZE)
32
33struct backing_dev_info default_backing_dev_info = { 25struct backing_dev_info default_backing_dev_info = {
34 .ra_pages = MAX_RA_PAGES, 26 .ra_pages = VM_MAX_READAHEAD * 1024 / PAGE_CACHE_SIZE,
35 .state = 0, 27 .state = 0,
36 .capabilities = BDI_CAP_MAP_COPY, 28 .capabilities = BDI_CAP_MAP_COPY,
37 .unplug_io_fn = default_unplug_io_fn, 29 .unplug_io_fn = default_unplug_io_fn,
@@ -46,7 +38,7 @@ void
46file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping) 38file_ra_state_init(struct file_ra_state *ra, struct address_space *mapping)
47{ 39{
48 ra->ra_pages = mapping->backing_dev_info->ra_pages; 40 ra->ra_pages = mapping->backing_dev_info->ra_pages;
49 ra->prev_index = -1; 41 ra->prev_pos = -1;
50} 42}
51EXPORT_SYMBOL_GPL(file_ra_state_init); 43EXPORT_SYMBOL_GPL(file_ra_state_init);
52 44
@@ -66,28 +58,25 @@ int read_cache_pages(struct address_space *mapping, struct list_head *pages,
66 int (*filler)(void *, struct page *), void *data) 58 int (*filler)(void *, struct page *), void *data)
67{ 59{
68 struct page *page; 60 struct page *page;
69 struct pagevec lru_pvec;
70 int ret = 0; 61 int ret = 0;
71 62
72 pagevec_init(&lru_pvec, 0);
73
74 while (!list_empty(pages)) { 63 while (!list_empty(pages)) {
75 page = list_to_page(pages); 64 page = list_to_page(pages);
76 list_del(&page->lru); 65 list_del(&page->lru);
77 if (add_to_page_cache(page, mapping, page->index, GFP_KERNEL)) { 66 if (add_to_page_cache_lru(page, mapping,
67 page->index, GFP_KERNEL)) {
78 page_cache_release(page); 68 page_cache_release(page);
79 continue; 69 continue;
80 } 70 }
71 page_cache_release(page);
72
81 ret = filler(data, page); 73 ret = filler(data, page);
82 if (!pagevec_add(&lru_pvec, page)) 74 if (unlikely(ret)) {
83 __pagevec_lru_add(&lru_pvec);
84 if (ret) {
85 put_pages_list(pages); 75 put_pages_list(pages);
86 break; 76 break;
87 } 77 }
88 task_io_account_read(PAGE_CACHE_SIZE); 78 task_io_account_read(PAGE_CACHE_SIZE);
89 } 79 }
90 pagevec_lru_add(&lru_pvec);
91 return ret; 80 return ret;
92} 81}
93 82
@@ -97,7 +86,6 @@ static int read_pages(struct address_space *mapping, struct file *filp,
97 struct list_head *pages, unsigned nr_pages) 86 struct list_head *pages, unsigned nr_pages)
98{ 87{
99 unsigned page_idx; 88 unsigned page_idx;
100 struct pagevec lru_pvec;
101 int ret; 89 int ret;
102 90
103 if (mapping->a_ops->readpages) { 91 if (mapping->a_ops->readpages) {
@@ -107,19 +95,15 @@ static int read_pages(struct address_space *mapping, struct file *filp,
107 goto out; 95 goto out;
108 } 96 }
109 97
110 pagevec_init(&lru_pvec, 0);
111 for (page_idx = 0; page_idx < nr_pages; page_idx++) { 98 for (page_idx = 0; page_idx < nr_pages; page_idx++) {
112 struct page *page = list_to_page(pages); 99 struct page *page = list_to_page(pages);
113 list_del(&page->lru); 100 list_del(&page->lru);
114 if (!add_to_page_cache(page, mapping, 101 if (!add_to_page_cache_lru(page, mapping,
115 page->index, GFP_KERNEL)) { 102 page->index, GFP_KERNEL)) {
116 mapping->a_ops->readpage(filp, page); 103 mapping->a_ops->readpage(filp, page);
117 if (!pagevec_add(&lru_pvec, page)) 104 }
118 __pagevec_lru_add(&lru_pvec); 105 page_cache_release(page);
119 } else
120 page_cache_release(page);
121 } 106 }
122 pagevec_lru_add(&lru_pvec);
123 ret = 0; 107 ret = 0;
124out: 108out:
125 return ret; 109 return ret;
@@ -157,20 +141,19 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
157 /* 141 /*
158 * Preallocate as many pages as we will need. 142 * Preallocate as many pages as we will need.
159 */ 143 */
160 read_lock_irq(&mapping->tree_lock);
161 for (page_idx = 0; page_idx < nr_to_read; page_idx++) { 144 for (page_idx = 0; page_idx < nr_to_read; page_idx++) {
162 pgoff_t page_offset = offset + page_idx; 145 pgoff_t page_offset = offset + page_idx;
163 146
164 if (page_offset > end_index) 147 if (page_offset > end_index)
165 break; 148 break;
166 149
150 rcu_read_lock();
167 page = radix_tree_lookup(&mapping->page_tree, page_offset); 151 page = radix_tree_lookup(&mapping->page_tree, page_offset);
152 rcu_read_unlock();
168 if (page) 153 if (page)
169 continue; 154 continue;
170 155
171 read_unlock_irq(&mapping->tree_lock);
172 page = page_cache_alloc_cold(mapping); 156 page = page_cache_alloc_cold(mapping);
173 read_lock_irq(&mapping->tree_lock);
174 if (!page) 157 if (!page)
175 break; 158 break;
176 page->index = page_offset; 159 page->index = page_offset;
@@ -179,7 +162,6 @@ __do_page_cache_readahead(struct address_space *mapping, struct file *filp,
179 SetPageReadahead(page); 162 SetPageReadahead(page);
180 ret++; 163 ret++;
181 } 164 }
182 read_unlock_irq(&mapping->tree_lock);
183 165
184 /* 166 /*
185 * Now start the IO. We ignore I/O errors - if the page is not 167 * Now start the IO. We ignore I/O errors - if the page is not
@@ -327,7 +309,7 @@ static unsigned long get_next_ra_size(struct file_ra_state *ra,
327 * indicator. The flag won't be set on already cached pages, to avoid the 309 * indicator. The flag won't be set on already cached pages, to avoid the
328 * readahead-for-nothing fuss, saving pointless page cache lookups. 310 * readahead-for-nothing fuss, saving pointless page cache lookups.
329 * 311 *
330 * prev_index tracks the last visited page in the _previous_ read request. 312 * prev_pos tracks the last visited byte in the _previous_ read request.
331 * It should be maintained by the caller, and will be used for detecting 313 * It should be maintained by the caller, and will be used for detecting
332 * small random reads. Note that the readahead algorithm checks loosely 314 * small random reads. Note that the readahead algorithm checks loosely
333 * for sequential patterns. Hence interleaved reads might be served as 315 * for sequential patterns. Hence interleaved reads might be served as
@@ -351,11 +333,9 @@ ondemand_readahead(struct address_space *mapping,
351 bool hit_readahead_marker, pgoff_t offset, 333 bool hit_readahead_marker, pgoff_t offset,
352 unsigned long req_size) 334 unsigned long req_size)
353{ 335{
354 unsigned long max; /* max readahead pages */ 336 int max = ra->ra_pages; /* max readahead pages */
355 int sequential; 337 pgoff_t prev_offset;
356 338 int sequential;
357 max = ra->ra_pages;
358 sequential = (offset - ra->prev_index <= 1UL) || (req_size > max);
359 339
360 /* 340 /*
361 * It's the expected callback offset, assume sequential access. 341 * It's the expected callback offset, assume sequential access.
@@ -369,6 +349,9 @@ ondemand_readahead(struct address_space *mapping,
369 goto readit; 349 goto readit;
370 } 350 }
371 351
352 prev_offset = ra->prev_pos >> PAGE_CACHE_SHIFT;
353 sequential = offset - prev_offset <= 1UL || req_size > max;
354
372 /* 355 /*
373 * Standalone, small read. 356 * Standalone, small read.
374 * Read as is, and do not pollute the readahead state. 357 * Read as is, and do not pollute the readahead state.
@@ -379,6 +362,29 @@ ondemand_readahead(struct address_space *mapping,
379 } 362 }
380 363
381 /* 364 /*
365 * Hit a marked page without valid readahead state.
366 * E.g. interleaved reads.
367 * Query the pagecache for async_size, which normally equals to
368 * readahead size. Ramp it up and use it as the new readahead size.
369 */
370 if (hit_readahead_marker) {
371 pgoff_t start;
372
373 read_lock_irq(&mapping->tree_lock);
374 start = radix_tree_next_hole(&mapping->page_tree, offset, max+1);
375 read_unlock_irq(&mapping->tree_lock);
376
377 if (!start || start - offset > max)
378 return 0;
379
380 ra->start = start;
381 ra->size = start - offset; /* old async_size */
382 ra->size = get_next_ra_size(ra, max);
383 ra->async_size = ra->size;
384 goto readit;
385 }
386
387 /*
382 * It may be one of 388 * It may be one of
383 * - first read on start of file 389 * - first read on start of file
384 * - sequential cache miss 390 * - sequential cache miss
@@ -389,16 +395,6 @@ ondemand_readahead(struct address_space *mapping,
389 ra->size = get_init_ra_size(req_size, max); 395 ra->size = get_init_ra_size(req_size, max);
390 ra->async_size = ra->size > req_size ? ra->size - req_size : ra->size; 396 ra->async_size = ra->size > req_size ? ra->size - req_size : ra->size;
391 397
392 /*
393 * Hit on a marked page without valid readahead state.
394 * E.g. interleaved reads.
395 * Not knowing its readahead pos/size, bet on the minimal possible one.
396 */
397 if (hit_readahead_marker) {
398 ra->start++;
399 ra->size = get_next_ra_size(ra, max);
400 }
401
402readit: 398readit:
403 return ra_submit(ra, mapping, filp); 399 return ra_submit(ra, mapping, filp);
404} 400}
diff --git a/mm/rmap.c b/mm/rmap.c
index 41ac39749ef4..2b9f413c9c00 100644
--- a/mm/rmap.c
+++ b/mm/rmap.c
@@ -436,7 +436,6 @@ static int page_mkclean_one(struct page *page, struct vm_area_struct *vma)
436 entry = pte_wrprotect(entry); 436 entry = pte_wrprotect(entry);
437 entry = pte_mkclean(entry); 437 entry = pte_mkclean(entry);
438 set_pte_at(mm, address, pte, entry); 438 set_pte_at(mm, address, pte, entry);
439 lazy_mmu_prot_update(entry);
440 ret = 1; 439 ret = 1;
441 } 440 }
442 441
diff --git a/mm/shmem.c b/mm/shmem.c
index fcd19d323f9f..8a82342a8595 100644
--- a/mm/shmem.c
+++ b/mm/shmem.c
@@ -49,7 +49,6 @@
49#include <linux/ctype.h> 49#include <linux/ctype.h>
50#include <linux/migrate.h> 50#include <linux/migrate.h>
51#include <linux/highmem.h> 51#include <linux/highmem.h>
52#include <linux/backing-dev.h>
53 52
54#include <asm/uaccess.h> 53#include <asm/uaccess.h>
55#include <asm/div64.h> 54#include <asm/div64.h>
@@ -96,9 +95,9 @@ static inline struct page *shmem_dir_alloc(gfp_t gfp_mask)
96 * BLOCKS_PER_PAGE on indirect pages, assume PAGE_CACHE_SIZE: 95 * BLOCKS_PER_PAGE on indirect pages, assume PAGE_CACHE_SIZE:
97 * might be reconsidered if it ever diverges from PAGE_SIZE. 96 * might be reconsidered if it ever diverges from PAGE_SIZE.
98 * 97 *
99 * __GFP_MOVABLE is masked out as swap vectors cannot move 98 * Mobility flags are masked out as swap vectors cannot move
100 */ 99 */
101 return alloc_pages((gfp_mask & ~__GFP_MOVABLE) | __GFP_ZERO, 100 return alloc_pages((gfp_mask & ~GFP_MOVABLE_MASK) | __GFP_ZERO,
102 PAGE_CACHE_SHIFT-PAGE_SHIFT); 101 PAGE_CACHE_SHIFT-PAGE_SHIFT);
103} 102}
104 103
@@ -972,7 +971,7 @@ static inline int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_
972 *nodelist++ = '\0'; 971 *nodelist++ = '\0';
973 if (nodelist_parse(nodelist, *policy_nodes)) 972 if (nodelist_parse(nodelist, *policy_nodes))
974 goto out; 973 goto out;
975 if (!nodes_subset(*policy_nodes, node_online_map)) 974 if (!nodes_subset(*policy_nodes, node_states[N_HIGH_MEMORY]))
976 goto out; 975 goto out;
977 } 976 }
978 if (!strcmp(value, "default")) { 977 if (!strcmp(value, "default")) {
@@ -997,9 +996,11 @@ static inline int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_
997 err = 0; 996 err = 0;
998 } else if (!strcmp(value, "interleave")) { 997 } else if (!strcmp(value, "interleave")) {
999 *policy = MPOL_INTERLEAVE; 998 *policy = MPOL_INTERLEAVE;
1000 /* Default to nodes online if no nodelist */ 999 /*
1000 * Default to online nodes with memory if no nodelist
1001 */
1001 if (!nodelist) 1002 if (!nodelist)
1002 *policy_nodes = node_online_map; 1003 *policy_nodes = node_states[N_HIGH_MEMORY];
1003 err = 0; 1004 err = 0;
1004 } 1005 }
1005out: 1006out:
@@ -1025,8 +1026,8 @@ static struct page *shmem_swapin_async(struct shared_policy *p,
1025 return page; 1026 return page;
1026} 1027}
1027 1028
1028struct page *shmem_swapin(struct shmem_inode_info *info, swp_entry_t entry, 1029static struct page *shmem_swapin(struct shmem_inode_info *info,
1029 unsigned long idx) 1030 swp_entry_t entry, unsigned long idx)
1030{ 1031{
1031 struct shared_policy *p = &info->policy; 1032 struct shared_policy *p = &info->policy;
1032 int i, num; 1033 int i, num;
@@ -1061,7 +1062,8 @@ shmem_alloc_page(gfp_t gfp, struct shmem_inode_info *info,
1061 return page; 1062 return page;
1062} 1063}
1063#else 1064#else
1064static inline int shmem_parse_mpol(char *value, int *policy, nodemask_t *policy_nodes) 1065static inline int shmem_parse_mpol(char *value, int *policy,
1066 nodemask_t *policy_nodes)
1065{ 1067{
1066 return 1; 1068 return 1;
1067} 1069}
@@ -1109,7 +1111,7 @@ static int shmem_getpage(struct inode *inode, unsigned long idx,
1109 * Normally, filepage is NULL on entry, and either found 1111 * Normally, filepage is NULL on entry, and either found
1110 * uptodate immediately, or allocated and zeroed, or read 1112 * uptodate immediately, or allocated and zeroed, or read
1111 * in under swappage, which is then assigned to filepage. 1113 * in under swappage, which is then assigned to filepage.
1112 * But shmem_readpage and shmem_prepare_write pass in a locked 1114 * But shmem_readpage and shmem_write_begin pass in a locked
1113 * filepage, which may be found not uptodate by other callers 1115 * filepage, which may be found not uptodate by other callers
1114 * too, and may need to be copied from the swappage read in. 1116 * too, and may need to be copied from the swappage read in.
1115 */ 1117 */
@@ -1327,14 +1329,14 @@ static int shmem_fault(struct vm_area_struct *vma, struct vm_fault *vmf)
1327} 1329}
1328 1330
1329#ifdef CONFIG_NUMA 1331#ifdef CONFIG_NUMA
1330int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new) 1332static int shmem_set_policy(struct vm_area_struct *vma, struct mempolicy *new)
1331{ 1333{
1332 struct inode *i = vma->vm_file->f_path.dentry->d_inode; 1334 struct inode *i = vma->vm_file->f_path.dentry->d_inode;
1333 return mpol_set_shared_policy(&SHMEM_I(i)->policy, vma, new); 1335 return mpol_set_shared_policy(&SHMEM_I(i)->policy, vma, new);
1334} 1336}
1335 1337
1336struct mempolicy * 1338static struct mempolicy *shmem_get_policy(struct vm_area_struct *vma,
1337shmem_get_policy(struct vm_area_struct *vma, unsigned long addr) 1339 unsigned long addr)
1338{ 1340{
1339 struct inode *i = vma->vm_file->f_path.dentry->d_inode; 1341 struct inode *i = vma->vm_file->f_path.dentry->d_inode;
1340 unsigned long idx; 1342 unsigned long idx;
@@ -1446,7 +1448,7 @@ static const struct inode_operations shmem_symlink_inode_operations;
1446static const struct inode_operations shmem_symlink_inline_operations; 1448static const struct inode_operations shmem_symlink_inline_operations;
1447 1449
1448/* 1450/*
1449 * Normally tmpfs avoids the use of shmem_readpage and shmem_prepare_write; 1451 * Normally tmpfs avoids the use of shmem_readpage and shmem_write_begin;
1450 * but providing them allows a tmpfs file to be used for splice, sendfile, and 1452 * but providing them allows a tmpfs file to be used for splice, sendfile, and
1451 * below the loop driver, in the generic fashion that many filesystems support. 1453 * below the loop driver, in the generic fashion that many filesystems support.
1452 */ 1454 */
@@ -1459,10 +1461,30 @@ static int shmem_readpage(struct file *file, struct page *page)
1459} 1461}
1460 1462
1461static int 1463static int
1462shmem_prepare_write(struct file *file, struct page *page, unsigned offset, unsigned to) 1464shmem_write_begin(struct file *file, struct address_space *mapping,
1465 loff_t pos, unsigned len, unsigned flags,
1466 struct page **pagep, void **fsdata)
1463{ 1467{
1464 struct inode *inode = page->mapping->host; 1468 struct inode *inode = mapping->host;
1465 return shmem_getpage(inode, page->index, &page, SGP_WRITE, NULL); 1469 pgoff_t index = pos >> PAGE_CACHE_SHIFT;
1470 *pagep = NULL;
1471 return shmem_getpage(inode, index, pagep, SGP_WRITE, NULL);
1472}
1473
1474static int
1475shmem_write_end(struct file *file, struct address_space *mapping,
1476 loff_t pos, unsigned len, unsigned copied,
1477 struct page *page, void *fsdata)
1478{
1479 struct inode *inode = mapping->host;
1480
1481 set_page_dirty(page);
1482 page_cache_release(page);
1483
1484 if (pos+copied > inode->i_size)
1485 i_size_write(inode, pos+copied);
1486
1487 return copied;
1466} 1488}
1467 1489
1468static ssize_t 1490static ssize_t
@@ -2219,7 +2241,7 @@ static int shmem_fill_super(struct super_block *sb,
2219 unsigned long blocks = 0; 2241 unsigned long blocks = 0;
2220 unsigned long inodes = 0; 2242 unsigned long inodes = 0;
2221 int policy = MPOL_DEFAULT; 2243 int policy = MPOL_DEFAULT;
2222 nodemask_t policy_nodes = node_online_map; 2244 nodemask_t policy_nodes = node_states[N_HIGH_MEMORY];
2223 2245
2224#ifdef CONFIG_TMPFS 2246#ifdef CONFIG_TMPFS
2225 /* 2247 /*
@@ -2338,8 +2360,8 @@ static const struct address_space_operations shmem_aops = {
2338 .set_page_dirty = __set_page_dirty_no_writeback, 2360 .set_page_dirty = __set_page_dirty_no_writeback,
2339#ifdef CONFIG_TMPFS 2361#ifdef CONFIG_TMPFS
2340 .readpage = shmem_readpage, 2362 .readpage = shmem_readpage,
2341 .prepare_write = shmem_prepare_write, 2363 .write_begin = shmem_write_begin,
2342 .commit_write = simple_commit_write, 2364 .write_end = shmem_write_end,
2343#endif 2365#endif
2344 .migratepage = migrate_page, 2366 .migratepage = migrate_page,
2345}; 2367};
diff --git a/mm/slab.c b/mm/slab.c
index 6f6abef83a1a..e34bcb87a6ee 100644
--- a/mm/slab.c
+++ b/mm/slab.c
@@ -1568,7 +1568,7 @@ void __init kmem_cache_init(void)
1568 /* Replace the static kmem_list3 structures for the boot cpu */ 1568 /* Replace the static kmem_list3 structures for the boot cpu */
1569 init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], node); 1569 init_list(&cache_cache, &initkmem_list3[CACHE_CACHE], node);
1570 1570
1571 for_each_online_node(nid) { 1571 for_each_node_state(nid, N_NORMAL_MEMORY) {
1572 init_list(malloc_sizes[INDEX_AC].cs_cachep, 1572 init_list(malloc_sizes[INDEX_AC].cs_cachep,
1573 &initkmem_list3[SIZE_AC + nid], nid); 1573 &initkmem_list3[SIZE_AC + nid], nid);
1574 1574
@@ -1643,6 +1643,8 @@ static void *kmem_getpages(struct kmem_cache *cachep, gfp_t flags, int nodeid)
1643#endif 1643#endif
1644 1644
1645 flags |= cachep->gfpflags; 1645 flags |= cachep->gfpflags;
1646 if (cachep->flags & SLAB_RECLAIM_ACCOUNT)
1647 flags |= __GFP_RECLAIMABLE;
1646 1648
1647 page = alloc_pages_node(nodeid, flags, cachep->gfporder); 1649 page = alloc_pages_node(nodeid, flags, cachep->gfporder);
1648 if (!page) 1650 if (!page)
@@ -1944,7 +1946,7 @@ static void __init set_up_list3s(struct kmem_cache *cachep, int index)
1944{ 1946{
1945 int node; 1947 int node;
1946 1948
1947 for_each_online_node(node) { 1949 for_each_node_state(node, N_NORMAL_MEMORY) {
1948 cachep->nodelists[node] = &initkmem_list3[index + node]; 1950 cachep->nodelists[node] = &initkmem_list3[index + node];
1949 cachep->nodelists[node]->next_reap = jiffies + 1951 cachep->nodelists[node]->next_reap = jiffies +
1950 REAPTIMEOUT_LIST3 + 1952 REAPTIMEOUT_LIST3 +
@@ -2075,7 +2077,7 @@ static int __init_refok setup_cpu_cache(struct kmem_cache *cachep)
2075 g_cpucache_up = PARTIAL_L3; 2077 g_cpucache_up = PARTIAL_L3;
2076 } else { 2078 } else {
2077 int node; 2079 int node;
2078 for_each_online_node(node) { 2080 for_each_node_state(node, N_NORMAL_MEMORY) {
2079 cachep->nodelists[node] = 2081 cachep->nodelists[node] =
2080 kmalloc_node(sizeof(struct kmem_list3), 2082 kmalloc_node(sizeof(struct kmem_list3),
2081 GFP_KERNEL, node); 2083 GFP_KERNEL, node);
@@ -2746,9 +2748,9 @@ static int cache_grow(struct kmem_cache *cachep,
2746 * Be lazy and only check for valid flags here, keeping it out of the 2748 * Be lazy and only check for valid flags here, keeping it out of the
2747 * critical path in kmem_cache_alloc(). 2749 * critical path in kmem_cache_alloc().
2748 */ 2750 */
2749 BUG_ON(flags & ~(GFP_DMA | __GFP_ZERO | GFP_LEVEL_MASK)); 2751 BUG_ON(flags & GFP_SLAB_BUG_MASK);
2752 local_flags = flags & (GFP_CONSTRAINT_MASK|GFP_RECLAIM_MASK);
2750 2753
2751 local_flags = (flags & GFP_LEVEL_MASK);
2752 /* Take the l3 list lock to change the colour_next on this node */ 2754 /* Take the l3 list lock to change the colour_next on this node */
2753 check_irq_off(); 2755 check_irq_off();
2754 l3 = cachep->nodelists[nodeid]; 2756 l3 = cachep->nodelists[nodeid];
@@ -2785,7 +2787,7 @@ static int cache_grow(struct kmem_cache *cachep,
2785 2787
2786 /* Get slab management. */ 2788 /* Get slab management. */
2787 slabp = alloc_slabmgmt(cachep, objp, offset, 2789 slabp = alloc_slabmgmt(cachep, objp, offset,
2788 local_flags & ~GFP_THISNODE, nodeid); 2790 local_flags & ~GFP_CONSTRAINT_MASK, nodeid);
2789 if (!slabp) 2791 if (!slabp)
2790 goto opps1; 2792 goto opps1;
2791 2793
@@ -3225,7 +3227,7 @@ static void *fallback_alloc(struct kmem_cache *cache, gfp_t flags)
3225 3227
3226 zonelist = &NODE_DATA(slab_node(current->mempolicy)) 3228 zonelist = &NODE_DATA(slab_node(current->mempolicy))
3227 ->node_zonelists[gfp_zone(flags)]; 3229 ->node_zonelists[gfp_zone(flags)];
3228 local_flags = (flags & GFP_LEVEL_MASK); 3230 local_flags = flags & (GFP_CONSTRAINT_MASK|GFP_RECLAIM_MASK);
3229 3231
3230retry: 3232retry:
3231 /* 3233 /*
@@ -3792,7 +3794,7 @@ static int alloc_kmemlist(struct kmem_cache *cachep)
3792 struct array_cache *new_shared; 3794 struct array_cache *new_shared;
3793 struct array_cache **new_alien = NULL; 3795 struct array_cache **new_alien = NULL;
3794 3796
3795 for_each_online_node(node) { 3797 for_each_node_state(node, N_NORMAL_MEMORY) {
3796 3798
3797 if (use_alien_caches) { 3799 if (use_alien_caches) {
3798 new_alien = alloc_alien_cache(node, cachep->limit); 3800 new_alien = alloc_alien_cache(node, cachep->limit);
@@ -4446,7 +4448,8 @@ const struct seq_operations slabstats_op = {
4446 */ 4448 */
4447size_t ksize(const void *objp) 4449size_t ksize(const void *objp)
4448{ 4450{
4449 if (unlikely(ZERO_OR_NULL_PTR(objp))) 4451 BUG_ON(!objp);
4452 if (unlikely(objp == ZERO_SIZE_PTR))
4450 return 0; 4453 return 0;
4451 4454
4452 return obj_size(virt_to_cache(objp)); 4455 return obj_size(virt_to_cache(objp));
diff --git a/mm/slob.c b/mm/slob.c
index ec33fcdc852e..de5d5563a46c 100644
--- a/mm/slob.c
+++ b/mm/slob.c
@@ -360,7 +360,7 @@ static void slob_free(void *block, int size)
360 slobidx_t units; 360 slobidx_t units;
361 unsigned long flags; 361 unsigned long flags;
362 362
363 if (ZERO_OR_NULL_PTR(block)) 363 if (unlikely(ZERO_OR_NULL_PTR(block)))
364 return; 364 return;
365 BUG_ON(!size); 365 BUG_ON(!size);
366 366
@@ -466,7 +466,7 @@ void kfree(const void *block)
466{ 466{
467 struct slob_page *sp; 467 struct slob_page *sp;
468 468
469 if (ZERO_OR_NULL_PTR(block)) 469 if (unlikely(ZERO_OR_NULL_PTR(block)))
470 return; 470 return;
471 471
472 sp = (struct slob_page *)virt_to_page(block); 472 sp = (struct slob_page *)virt_to_page(block);
@@ -484,7 +484,8 @@ size_t ksize(const void *block)
484{ 484{
485 struct slob_page *sp; 485 struct slob_page *sp;
486 486
487 if (ZERO_OR_NULL_PTR(block)) 487 BUG_ON(!block);
488 if (unlikely(block == ZERO_SIZE_PTR))
488 return 0; 489 return 0;
489 490
490 sp = (struct slob_page *)virt_to_page(block); 491 sp = (struct slob_page *)virt_to_page(block);
diff --git a/mm/slub.c b/mm/slub.c
index addb20a6d67d..f426f9bc644b 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -90,7 +90,7 @@
90 * One use of this flag is to mark slabs that are 90 * One use of this flag is to mark slabs that are
91 * used for allocations. Then such a slab becomes a cpu 91 * used for allocations. Then such a slab becomes a cpu
92 * slab. The cpu slab may be equipped with an additional 92 * slab. The cpu slab may be equipped with an additional
93 * lockless_freelist that allows lockless access to 93 * freelist that allows lockless access to
94 * free objects in addition to the regular freelist 94 * free objects in addition to the regular freelist
95 * that requires the slab lock. 95 * that requires the slab lock.
96 * 96 *
@@ -140,11 +140,6 @@ static inline void ClearSlabDebug(struct page *page)
140/* 140/*
141 * Issues still to be resolved: 141 * Issues still to be resolved:
142 * 142 *
143 * - The per cpu array is updated for each new slab and and is a remote
144 * cacheline for most nodes. This could become a bouncing cacheline given
145 * enough frequent updates. There are 16 pointers in a cacheline, so at
146 * max 16 cpus could compete for the cacheline which may be okay.
147 *
148 * - Support PAGE_ALLOC_DEBUG. Should be easy to do. 143 * - Support PAGE_ALLOC_DEBUG. Should be easy to do.
149 * 144 *
150 * - Variable sizing of the per node arrays 145 * - Variable sizing of the per node arrays
@@ -205,11 +200,6 @@ static inline void ClearSlabDebug(struct page *page)
205#define ARCH_SLAB_MINALIGN __alignof__(unsigned long long) 200#define ARCH_SLAB_MINALIGN __alignof__(unsigned long long)
206#endif 201#endif
207 202
208/*
209 * The page->inuse field is 16 bit thus we have this limitation
210 */
211#define MAX_OBJECTS_PER_SLAB 65535
212
213/* Internal SLUB flags */ 203/* Internal SLUB flags */
214#define __OBJECT_POISON 0x80000000 /* Poison object */ 204#define __OBJECT_POISON 0x80000000 /* Poison object */
215#define __SYSFS_ADD_DEFERRED 0x40000000 /* Not yet visible via sysfs */ 205#define __SYSFS_ADD_DEFERRED 0x40000000 /* Not yet visible via sysfs */
@@ -277,6 +267,15 @@ static inline struct kmem_cache_node *get_node(struct kmem_cache *s, int node)
277#endif 267#endif
278} 268}
279 269
270static inline struct kmem_cache_cpu *get_cpu_slab(struct kmem_cache *s, int cpu)
271{
272#ifdef CONFIG_SMP
273 return s->cpu_slab[cpu];
274#else
275 return &s->cpu_slab;
276#endif
277}
278
280static inline int check_valid_pointer(struct kmem_cache *s, 279static inline int check_valid_pointer(struct kmem_cache *s,
281 struct page *page, const void *object) 280 struct page *page, const void *object)
282{ 281{
@@ -729,11 +728,6 @@ static int check_slab(struct kmem_cache *s, struct page *page)
729 slab_err(s, page, "Not a valid slab page"); 728 slab_err(s, page, "Not a valid slab page");
730 return 0; 729 return 0;
731 } 730 }
732 if (page->offset * sizeof(void *) != s->offset) {
733 slab_err(s, page, "Corrupted offset %lu",
734 (unsigned long)(page->offset * sizeof(void *)));
735 return 0;
736 }
737 if (page->inuse > s->objects) { 731 if (page->inuse > s->objects) {
738 slab_err(s, page, "inuse %u > max %u", 732 slab_err(s, page, "inuse %u > max %u",
739 s->name, page->inuse, s->objects); 733 s->name, page->inuse, s->objects);
@@ -872,8 +866,6 @@ bad:
872 slab_fix(s, "Marking all objects used"); 866 slab_fix(s, "Marking all objects used");
873 page->inuse = s->objects; 867 page->inuse = s->objects;
874 page->freelist = NULL; 868 page->freelist = NULL;
875 /* Fix up fields that may be corrupted */
876 page->offset = s->offset / sizeof(void *);
877 } 869 }
878 return 0; 870 return 0;
879} 871}
@@ -1055,6 +1047,9 @@ static struct page *allocate_slab(struct kmem_cache *s, gfp_t flags, int node)
1055 if (s->flags & SLAB_CACHE_DMA) 1047 if (s->flags & SLAB_CACHE_DMA)
1056 flags |= SLUB_DMA; 1048 flags |= SLUB_DMA;
1057 1049
1050 if (s->flags & SLAB_RECLAIM_ACCOUNT)
1051 flags |= __GFP_RECLAIMABLE;
1052
1058 if (node == -1) 1053 if (node == -1)
1059 page = alloc_pages(flags, s->order); 1054 page = alloc_pages(flags, s->order);
1060 else 1055 else
@@ -1088,19 +1083,19 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
1088 void *last; 1083 void *last;
1089 void *p; 1084 void *p;
1090 1085
1091 BUG_ON(flags & ~(GFP_DMA | __GFP_ZERO | GFP_LEVEL_MASK)); 1086 BUG_ON(flags & GFP_SLAB_BUG_MASK);
1092 1087
1093 if (flags & __GFP_WAIT) 1088 if (flags & __GFP_WAIT)
1094 local_irq_enable(); 1089 local_irq_enable();
1095 1090
1096 page = allocate_slab(s, flags & GFP_LEVEL_MASK, node); 1091 page = allocate_slab(s,
1092 flags & (GFP_RECLAIM_MASK | GFP_CONSTRAINT_MASK), node);
1097 if (!page) 1093 if (!page)
1098 goto out; 1094 goto out;
1099 1095
1100 n = get_node(s, page_to_nid(page)); 1096 n = get_node(s, page_to_nid(page));
1101 if (n) 1097 if (n)
1102 atomic_long_inc(&n->nr_slabs); 1098 atomic_long_inc(&n->nr_slabs);
1103 page->offset = s->offset / sizeof(void *);
1104 page->slab = s; 1099 page->slab = s;
1105 page->flags |= 1 << PG_slab; 1100 page->flags |= 1 << PG_slab;
1106 if (s->flags & (SLAB_DEBUG_FREE | SLAB_RED_ZONE | SLAB_POISON | 1101 if (s->flags & (SLAB_DEBUG_FREE | SLAB_RED_ZONE | SLAB_POISON |
@@ -1123,7 +1118,6 @@ static struct page *new_slab(struct kmem_cache *s, gfp_t flags, int node)
1123 set_freepointer(s, last, NULL); 1118 set_freepointer(s, last, NULL);
1124 1119
1125 page->freelist = start; 1120 page->freelist = start;
1126 page->lockless_freelist = NULL;
1127 page->inuse = 0; 1121 page->inuse = 0;
1128out: 1122out:
1129 if (flags & __GFP_WAIT) 1123 if (flags & __GFP_WAIT)
@@ -1149,7 +1143,6 @@ static void __free_slab(struct kmem_cache *s, struct page *page)
1149 NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE, 1143 NR_SLAB_RECLAIMABLE : NR_SLAB_UNRECLAIMABLE,
1150 - pages); 1144 - pages);
1151 1145
1152 page->mapping = NULL;
1153 __free_pages(page, s->order); 1146 __free_pages(page, s->order);
1154} 1147}
1155 1148
@@ -1383,33 +1376,34 @@ static void unfreeze_slab(struct kmem_cache *s, struct page *page)
1383/* 1376/*
1384 * Remove the cpu slab 1377 * Remove the cpu slab
1385 */ 1378 */
1386static void deactivate_slab(struct kmem_cache *s, struct page *page, int cpu) 1379static void deactivate_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
1387{ 1380{
1381 struct page *page = c->page;
1388 /* 1382 /*
1389 * Merge cpu freelist into freelist. Typically we get here 1383 * Merge cpu freelist into freelist. Typically we get here
1390 * because both freelists are empty. So this is unlikely 1384 * because both freelists are empty. So this is unlikely
1391 * to occur. 1385 * to occur.
1392 */ 1386 */
1393 while (unlikely(page->lockless_freelist)) { 1387 while (unlikely(c->freelist)) {
1394 void **object; 1388 void **object;
1395 1389
1396 /* Retrieve object from cpu_freelist */ 1390 /* Retrieve object from cpu_freelist */
1397 object = page->lockless_freelist; 1391 object = c->freelist;
1398 page->lockless_freelist = page->lockless_freelist[page->offset]; 1392 c->freelist = c->freelist[c->offset];
1399 1393
1400 /* And put onto the regular freelist */ 1394 /* And put onto the regular freelist */
1401 object[page->offset] = page->freelist; 1395 object[c->offset] = page->freelist;
1402 page->freelist = object; 1396 page->freelist = object;
1403 page->inuse--; 1397 page->inuse--;
1404 } 1398 }
1405 s->cpu_slab[cpu] = NULL; 1399 c->page = NULL;
1406 unfreeze_slab(s, page); 1400 unfreeze_slab(s, page);
1407} 1401}
1408 1402
1409static inline void flush_slab(struct kmem_cache *s, struct page *page, int cpu) 1403static inline void flush_slab(struct kmem_cache *s, struct kmem_cache_cpu *c)
1410{ 1404{
1411 slab_lock(page); 1405 slab_lock(c->page);
1412 deactivate_slab(s, page, cpu); 1406 deactivate_slab(s, c);
1413} 1407}
1414 1408
1415/* 1409/*
@@ -1418,18 +1412,17 @@ static inline void flush_slab(struct kmem_cache *s, struct page *page, int cpu)
1418 */ 1412 */
1419static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu) 1413static inline void __flush_cpu_slab(struct kmem_cache *s, int cpu)
1420{ 1414{
1421 struct page *page = s->cpu_slab[cpu]; 1415 struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
1422 1416
1423 if (likely(page)) 1417 if (likely(c && c->page))
1424 flush_slab(s, page, cpu); 1418 flush_slab(s, c);
1425} 1419}
1426 1420
1427static void flush_cpu_slab(void *d) 1421static void flush_cpu_slab(void *d)
1428{ 1422{
1429 struct kmem_cache *s = d; 1423 struct kmem_cache *s = d;
1430 int cpu = smp_processor_id();
1431 1424
1432 __flush_cpu_slab(s, cpu); 1425 __flush_cpu_slab(s, smp_processor_id());
1433} 1426}
1434 1427
1435static void flush_all(struct kmem_cache *s) 1428static void flush_all(struct kmem_cache *s)
@@ -1446,6 +1439,19 @@ static void flush_all(struct kmem_cache *s)
1446} 1439}
1447 1440
1448/* 1441/*
1442 * Check if the objects in a per cpu structure fit numa
1443 * locality expectations.
1444 */
1445static inline int node_match(struct kmem_cache_cpu *c, int node)
1446{
1447#ifdef CONFIG_NUMA
1448 if (node != -1 && c->node != node)
1449 return 0;
1450#endif
1451 return 1;
1452}
1453
1454/*
1449 * Slow path. The lockless freelist is empty or we need to perform 1455 * Slow path. The lockless freelist is empty or we need to perform
1450 * debugging duties. 1456 * debugging duties.
1451 * 1457 *
@@ -1463,45 +1469,46 @@ static void flush_all(struct kmem_cache *s)
1463 * we need to allocate a new slab. This is slowest path since we may sleep. 1469 * we need to allocate a new slab. This is slowest path since we may sleep.
1464 */ 1470 */
1465static void *__slab_alloc(struct kmem_cache *s, 1471static void *__slab_alloc(struct kmem_cache *s,
1466 gfp_t gfpflags, int node, void *addr, struct page *page) 1472 gfp_t gfpflags, int node, void *addr, struct kmem_cache_cpu *c)
1467{ 1473{
1468 void **object; 1474 void **object;
1469 int cpu = smp_processor_id(); 1475 struct page *new;
1470 1476
1471 if (!page) 1477 if (!c->page)
1472 goto new_slab; 1478 goto new_slab;
1473 1479
1474 slab_lock(page); 1480 slab_lock(c->page);
1475 if (unlikely(node != -1 && page_to_nid(page) != node)) 1481 if (unlikely(!node_match(c, node)))
1476 goto another_slab; 1482 goto another_slab;
1477load_freelist: 1483load_freelist:
1478 object = page->freelist; 1484 object = c->page->freelist;
1479 if (unlikely(!object)) 1485 if (unlikely(!object))
1480 goto another_slab; 1486 goto another_slab;
1481 if (unlikely(SlabDebug(page))) 1487 if (unlikely(SlabDebug(c->page)))
1482 goto debug; 1488 goto debug;
1483 1489
1484 object = page->freelist; 1490 object = c->page->freelist;
1485 page->lockless_freelist = object[page->offset]; 1491 c->freelist = object[c->offset];
1486 page->inuse = s->objects; 1492 c->page->inuse = s->objects;
1487 page->freelist = NULL; 1493 c->page->freelist = NULL;
1488 slab_unlock(page); 1494 c->node = page_to_nid(c->page);
1495 slab_unlock(c->page);
1489 return object; 1496 return object;
1490 1497
1491another_slab: 1498another_slab:
1492 deactivate_slab(s, page, cpu); 1499 deactivate_slab(s, c);
1493 1500
1494new_slab: 1501new_slab:
1495 page = get_partial(s, gfpflags, node); 1502 new = get_partial(s, gfpflags, node);
1496 if (page) { 1503 if (new) {
1497 s->cpu_slab[cpu] = page; 1504 c->page = new;
1498 goto load_freelist; 1505 goto load_freelist;
1499 } 1506 }
1500 1507
1501 page = new_slab(s, gfpflags, node); 1508 new = new_slab(s, gfpflags, node);
1502 if (page) { 1509 if (new) {
1503 cpu = smp_processor_id(); 1510 c = get_cpu_slab(s, smp_processor_id());
1504 if (s->cpu_slab[cpu]) { 1511 if (c->page) {
1505 /* 1512 /*
1506 * Someone else populated the cpu_slab while we 1513 * Someone else populated the cpu_slab while we
1507 * enabled interrupts, or we have gotten scheduled 1514 * enabled interrupts, or we have gotten scheduled
@@ -1509,34 +1516,33 @@ new_slab:
1509 * requested node even if __GFP_THISNODE was 1516 * requested node even if __GFP_THISNODE was
1510 * specified. So we need to recheck. 1517 * specified. So we need to recheck.
1511 */ 1518 */
1512 if (node == -1 || 1519 if (node_match(c, node)) {
1513 page_to_nid(s->cpu_slab[cpu]) == node) {
1514 /* 1520 /*
1515 * Current cpuslab is acceptable and we 1521 * Current cpuslab is acceptable and we
1516 * want the current one since its cache hot 1522 * want the current one since its cache hot
1517 */ 1523 */
1518 discard_slab(s, page); 1524 discard_slab(s, new);
1519 page = s->cpu_slab[cpu]; 1525 slab_lock(c->page);
1520 slab_lock(page);
1521 goto load_freelist; 1526 goto load_freelist;
1522 } 1527 }
1523 /* New slab does not fit our expectations */ 1528 /* New slab does not fit our expectations */
1524 flush_slab(s, s->cpu_slab[cpu], cpu); 1529 flush_slab(s, c);
1525 } 1530 }
1526 slab_lock(page); 1531 slab_lock(new);
1527 SetSlabFrozen(page); 1532 SetSlabFrozen(new);
1528 s->cpu_slab[cpu] = page; 1533 c->page = new;
1529 goto load_freelist; 1534 goto load_freelist;
1530 } 1535 }
1531 return NULL; 1536 return NULL;
1532debug: 1537debug:
1533 object = page->freelist; 1538 object = c->page->freelist;
1534 if (!alloc_debug_processing(s, page, object, addr)) 1539 if (!alloc_debug_processing(s, c->page, object, addr))
1535 goto another_slab; 1540 goto another_slab;
1536 1541
1537 page->inuse++; 1542 c->page->inuse++;
1538 page->freelist = object[page->offset]; 1543 c->page->freelist = object[c->offset];
1539 slab_unlock(page); 1544 c->node = -1;
1545 slab_unlock(c->page);
1540 return object; 1546 return object;
1541} 1547}
1542 1548
@@ -1553,25 +1559,24 @@ debug:
1553static void __always_inline *slab_alloc(struct kmem_cache *s, 1559static void __always_inline *slab_alloc(struct kmem_cache *s,
1554 gfp_t gfpflags, int node, void *addr) 1560 gfp_t gfpflags, int node, void *addr)
1555{ 1561{
1556 struct page *page;
1557 void **object; 1562 void **object;
1558 unsigned long flags; 1563 unsigned long flags;
1564 struct kmem_cache_cpu *c;
1559 1565
1560 local_irq_save(flags); 1566 local_irq_save(flags);
1561 page = s->cpu_slab[smp_processor_id()]; 1567 c = get_cpu_slab(s, smp_processor_id());
1562 if (unlikely(!page || !page->lockless_freelist || 1568 if (unlikely(!c->freelist || !node_match(c, node)))
1563 (node != -1 && page_to_nid(page) != node)))
1564 1569
1565 object = __slab_alloc(s, gfpflags, node, addr, page); 1570 object = __slab_alloc(s, gfpflags, node, addr, c);
1566 1571
1567 else { 1572 else {
1568 object = page->lockless_freelist; 1573 object = c->freelist;
1569 page->lockless_freelist = object[page->offset]; 1574 c->freelist = object[c->offset];
1570 } 1575 }
1571 local_irq_restore(flags); 1576 local_irq_restore(flags);
1572 1577
1573 if (unlikely((gfpflags & __GFP_ZERO) && object)) 1578 if (unlikely((gfpflags & __GFP_ZERO) && object))
1574 memset(object, 0, s->objsize); 1579 memset(object, 0, c->objsize);
1575 1580
1576 return object; 1581 return object;
1577} 1582}
@@ -1599,7 +1604,7 @@ EXPORT_SYMBOL(kmem_cache_alloc_node);
1599 * handling required then we can return immediately. 1604 * handling required then we can return immediately.
1600 */ 1605 */
1601static void __slab_free(struct kmem_cache *s, struct page *page, 1606static void __slab_free(struct kmem_cache *s, struct page *page,
1602 void *x, void *addr) 1607 void *x, void *addr, unsigned int offset)
1603{ 1608{
1604 void *prior; 1609 void *prior;
1605 void **object = (void *)x; 1610 void **object = (void *)x;
@@ -1609,7 +1614,7 @@ static void __slab_free(struct kmem_cache *s, struct page *page,
1609 if (unlikely(SlabDebug(page))) 1614 if (unlikely(SlabDebug(page)))
1610 goto debug; 1615 goto debug;
1611checks_ok: 1616checks_ok:
1612 prior = object[page->offset] = page->freelist; 1617 prior = object[offset] = page->freelist;
1613 page->freelist = object; 1618 page->freelist = object;
1614 page->inuse--; 1619 page->inuse--;
1615 1620
@@ -1664,15 +1669,16 @@ static void __always_inline slab_free(struct kmem_cache *s,
1664{ 1669{
1665 void **object = (void *)x; 1670 void **object = (void *)x;
1666 unsigned long flags; 1671 unsigned long flags;
1672 struct kmem_cache_cpu *c;
1667 1673
1668 local_irq_save(flags); 1674 local_irq_save(flags);
1669 debug_check_no_locks_freed(object, s->objsize); 1675 debug_check_no_locks_freed(object, s->objsize);
1670 if (likely(page == s->cpu_slab[smp_processor_id()] && 1676 c = get_cpu_slab(s, smp_processor_id());
1671 !SlabDebug(page))) { 1677 if (likely(page == c->page && c->node >= 0)) {
1672 object[page->offset] = page->lockless_freelist; 1678 object[c->offset] = c->freelist;
1673 page->lockless_freelist = object; 1679 c->freelist = object;
1674 } else 1680 } else
1675 __slab_free(s, page, x, addr); 1681 __slab_free(s, page, x, addr, c->offset);
1676 1682
1677 local_irq_restore(flags); 1683 local_irq_restore(flags);
1678} 1684}
@@ -1759,14 +1765,6 @@ static inline int slab_order(int size, int min_objects,
1759 int rem; 1765 int rem;
1760 int min_order = slub_min_order; 1766 int min_order = slub_min_order;
1761 1767
1762 /*
1763 * If we would create too many object per slab then reduce
1764 * the slab order even if it goes below slub_min_order.
1765 */
1766 while (min_order > 0 &&
1767 (PAGE_SIZE << min_order) >= MAX_OBJECTS_PER_SLAB * size)
1768 min_order--;
1769
1770 for (order = max(min_order, 1768 for (order = max(min_order,
1771 fls(min_objects * size - 1) - PAGE_SHIFT); 1769 fls(min_objects * size - 1) - PAGE_SHIFT);
1772 order <= max_order; order++) { 1770 order <= max_order; order++) {
@@ -1781,9 +1779,6 @@ static inline int slab_order(int size, int min_objects,
1781 if (rem <= slab_size / fract_leftover) 1779 if (rem <= slab_size / fract_leftover)
1782 break; 1780 break;
1783 1781
1784 /* If the next size is too high then exit now */
1785 if (slab_size * 2 >= MAX_OBJECTS_PER_SLAB * size)
1786 break;
1787 } 1782 }
1788 1783
1789 return order; 1784 return order;
@@ -1858,6 +1853,16 @@ static unsigned long calculate_alignment(unsigned long flags,
1858 return ALIGN(align, sizeof(void *)); 1853 return ALIGN(align, sizeof(void *));
1859} 1854}
1860 1855
1856static void init_kmem_cache_cpu(struct kmem_cache *s,
1857 struct kmem_cache_cpu *c)
1858{
1859 c->page = NULL;
1860 c->freelist = NULL;
1861 c->node = 0;
1862 c->offset = s->offset / sizeof(void *);
1863 c->objsize = s->objsize;
1864}
1865
1861static void init_kmem_cache_node(struct kmem_cache_node *n) 1866static void init_kmem_cache_node(struct kmem_cache_node *n)
1862{ 1867{
1863 n->nr_partial = 0; 1868 n->nr_partial = 0;
@@ -1869,6 +1874,131 @@ static void init_kmem_cache_node(struct kmem_cache_node *n)
1869#endif 1874#endif
1870} 1875}
1871 1876
1877#ifdef CONFIG_SMP
1878/*
1879 * Per cpu array for per cpu structures.
1880 *
1881 * The per cpu array places all kmem_cache_cpu structures from one processor
1882 * close together meaning that it becomes possible that multiple per cpu
1883 * structures are contained in one cacheline. This may be particularly
1884 * beneficial for the kmalloc caches.
1885 *
1886 * A desktop system typically has around 60-80 slabs. With 100 here we are
1887 * likely able to get per cpu structures for all caches from the array defined
1888 * here. We must be able to cover all kmalloc caches during bootstrap.
1889 *
1890 * If the per cpu array is exhausted then fall back to kmalloc
1891 * of individual cachelines. No sharing is possible then.
1892 */
1893#define NR_KMEM_CACHE_CPU 100
1894
1895static DEFINE_PER_CPU(struct kmem_cache_cpu,
1896 kmem_cache_cpu)[NR_KMEM_CACHE_CPU];
1897
1898static DEFINE_PER_CPU(struct kmem_cache_cpu *, kmem_cache_cpu_free);
1899static cpumask_t kmem_cach_cpu_free_init_once = CPU_MASK_NONE;
1900
1901static struct kmem_cache_cpu *alloc_kmem_cache_cpu(struct kmem_cache *s,
1902 int cpu, gfp_t flags)
1903{
1904 struct kmem_cache_cpu *c = per_cpu(kmem_cache_cpu_free, cpu);
1905
1906 if (c)
1907 per_cpu(kmem_cache_cpu_free, cpu) =
1908 (void *)c->freelist;
1909 else {
1910 /* Table overflow: So allocate ourselves */
1911 c = kmalloc_node(
1912 ALIGN(sizeof(struct kmem_cache_cpu), cache_line_size()),
1913 flags, cpu_to_node(cpu));
1914 if (!c)
1915 return NULL;
1916 }
1917
1918 init_kmem_cache_cpu(s, c);
1919 return c;
1920}
1921
1922static void free_kmem_cache_cpu(struct kmem_cache_cpu *c, int cpu)
1923{
1924 if (c < per_cpu(kmem_cache_cpu, cpu) ||
1925 c > per_cpu(kmem_cache_cpu, cpu) + NR_KMEM_CACHE_CPU) {
1926 kfree(c);
1927 return;
1928 }
1929 c->freelist = (void *)per_cpu(kmem_cache_cpu_free, cpu);
1930 per_cpu(kmem_cache_cpu_free, cpu) = c;
1931}
1932
1933static void free_kmem_cache_cpus(struct kmem_cache *s)
1934{
1935 int cpu;
1936
1937 for_each_online_cpu(cpu) {
1938 struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
1939
1940 if (c) {
1941 s->cpu_slab[cpu] = NULL;
1942 free_kmem_cache_cpu(c, cpu);
1943 }
1944 }
1945}
1946
1947static int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
1948{
1949 int cpu;
1950
1951 for_each_online_cpu(cpu) {
1952 struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
1953
1954 if (c)
1955 continue;
1956
1957 c = alloc_kmem_cache_cpu(s, cpu, flags);
1958 if (!c) {
1959 free_kmem_cache_cpus(s);
1960 return 0;
1961 }
1962 s->cpu_slab[cpu] = c;
1963 }
1964 return 1;
1965}
1966
1967/*
1968 * Initialize the per cpu array.
1969 */
1970static void init_alloc_cpu_cpu(int cpu)
1971{
1972 int i;
1973
1974 if (cpu_isset(cpu, kmem_cach_cpu_free_init_once))
1975 return;
1976
1977 for (i = NR_KMEM_CACHE_CPU - 1; i >= 0; i--)
1978 free_kmem_cache_cpu(&per_cpu(kmem_cache_cpu, cpu)[i], cpu);
1979
1980 cpu_set(cpu, kmem_cach_cpu_free_init_once);
1981}
1982
1983static void __init init_alloc_cpu(void)
1984{
1985 int cpu;
1986
1987 for_each_online_cpu(cpu)
1988 init_alloc_cpu_cpu(cpu);
1989 }
1990
1991#else
1992static inline void free_kmem_cache_cpus(struct kmem_cache *s) {}
1993static inline void init_alloc_cpu(void) {}
1994
1995static inline int alloc_kmem_cache_cpus(struct kmem_cache *s, gfp_t flags)
1996{
1997 init_kmem_cache_cpu(s, &s->cpu_slab);
1998 return 1;
1999}
2000#endif
2001
1872#ifdef CONFIG_NUMA 2002#ifdef CONFIG_NUMA
1873/* 2003/*
1874 * No kmalloc_node yet so do it by hand. We know that this is the first 2004 * No kmalloc_node yet so do it by hand. We know that this is the first
@@ -1876,10 +2006,11 @@ static void init_kmem_cache_node(struct kmem_cache_node *n)
1876 * possible. 2006 * possible.
1877 * 2007 *
1878 * Note that this function only works on the kmalloc_node_cache 2008 * Note that this function only works on the kmalloc_node_cache
1879 * when allocating for the kmalloc_node_cache. 2009 * when allocating for the kmalloc_node_cache. This is used for bootstrapping
2010 * memory on a fresh node that has no slab structures yet.
1880 */ 2011 */
1881static struct kmem_cache_node * __init early_kmem_cache_node_alloc(gfp_t gfpflags, 2012static struct kmem_cache_node *early_kmem_cache_node_alloc(gfp_t gfpflags,
1882 int node) 2013 int node)
1883{ 2014{
1884 struct page *page; 2015 struct page *page;
1885 struct kmem_cache_node *n; 2016 struct kmem_cache_node *n;
@@ -1921,7 +2052,7 @@ static void free_kmem_cache_nodes(struct kmem_cache *s)
1921{ 2052{
1922 int node; 2053 int node;
1923 2054
1924 for_each_online_node(node) { 2055 for_each_node_state(node, N_NORMAL_MEMORY) {
1925 struct kmem_cache_node *n = s->node[node]; 2056 struct kmem_cache_node *n = s->node[node];
1926 if (n && n != &s->local_node) 2057 if (n && n != &s->local_node)
1927 kmem_cache_free(kmalloc_caches, n); 2058 kmem_cache_free(kmalloc_caches, n);
@@ -1939,7 +2070,7 @@ static int init_kmem_cache_nodes(struct kmem_cache *s, gfp_t gfpflags)
1939 else 2070 else
1940 local_node = 0; 2071 local_node = 0;
1941 2072
1942 for_each_online_node(node) { 2073 for_each_node_state(node, N_NORMAL_MEMORY) {
1943 struct kmem_cache_node *n; 2074 struct kmem_cache_node *n;
1944 2075
1945 if (local_node == node) 2076 if (local_node == node)
@@ -2077,14 +2208,7 @@ static int calculate_sizes(struct kmem_cache *s)
2077 */ 2208 */
2078 s->objects = (PAGE_SIZE << s->order) / size; 2209 s->objects = (PAGE_SIZE << s->order) / size;
2079 2210
2080 /* 2211 return !!s->objects;
2081 * Verify that the number of objects is within permitted limits.
2082 * The page->inuse field is only 16 bit wide! So we cannot have
2083 * more than 64k objects per slab.
2084 */
2085 if (!s->objects || s->objects > MAX_OBJECTS_PER_SLAB)
2086 return 0;
2087 return 1;
2088 2212
2089} 2213}
2090 2214
@@ -2107,9 +2231,12 @@ static int kmem_cache_open(struct kmem_cache *s, gfp_t gfpflags,
2107#ifdef CONFIG_NUMA 2231#ifdef CONFIG_NUMA
2108 s->defrag_ratio = 100; 2232 s->defrag_ratio = 100;
2109#endif 2233#endif
2234 if (!init_kmem_cache_nodes(s, gfpflags & ~SLUB_DMA))
2235 goto error;
2110 2236
2111 if (init_kmem_cache_nodes(s, gfpflags & ~SLUB_DMA)) 2237 if (alloc_kmem_cache_cpus(s, gfpflags & ~SLUB_DMA))
2112 return 1; 2238 return 1;
2239 free_kmem_cache_nodes(s);
2113error: 2240error:
2114 if (flags & SLAB_PANIC) 2241 if (flags & SLAB_PANIC)
2115 panic("Cannot create slab %s size=%lu realsize=%u " 2242 panic("Cannot create slab %s size=%lu realsize=%u "
@@ -2192,7 +2319,8 @@ static inline int kmem_cache_close(struct kmem_cache *s)
2192 flush_all(s); 2319 flush_all(s);
2193 2320
2194 /* Attempt to free all objects */ 2321 /* Attempt to free all objects */
2195 for_each_online_node(node) { 2322 free_kmem_cache_cpus(s);
2323 for_each_node_state(node, N_NORMAL_MEMORY) {
2196 struct kmem_cache_node *n = get_node(s, node); 2324 struct kmem_cache_node *n = get_node(s, node);
2197 2325
2198 n->nr_partial -= free_list(s, n, &n->partial); 2326 n->nr_partial -= free_list(s, n, &n->partial);
@@ -2227,11 +2355,11 @@ EXPORT_SYMBOL(kmem_cache_destroy);
2227 * Kmalloc subsystem 2355 * Kmalloc subsystem
2228 *******************************************************************/ 2356 *******************************************************************/
2229 2357
2230struct kmem_cache kmalloc_caches[KMALLOC_SHIFT_HIGH + 1] __cacheline_aligned; 2358struct kmem_cache kmalloc_caches[PAGE_SHIFT] __cacheline_aligned;
2231EXPORT_SYMBOL(kmalloc_caches); 2359EXPORT_SYMBOL(kmalloc_caches);
2232 2360
2233#ifdef CONFIG_ZONE_DMA 2361#ifdef CONFIG_ZONE_DMA
2234static struct kmem_cache *kmalloc_caches_dma[KMALLOC_SHIFT_HIGH + 1]; 2362static struct kmem_cache *kmalloc_caches_dma[PAGE_SHIFT];
2235#endif 2363#endif
2236 2364
2237static int __init setup_slub_min_order(char *str) 2365static int __init setup_slub_min_order(char *str)
@@ -2397,12 +2525,8 @@ static struct kmem_cache *get_slab(size_t size, gfp_t flags)
2397 return ZERO_SIZE_PTR; 2525 return ZERO_SIZE_PTR;
2398 2526
2399 index = size_index[(size - 1) / 8]; 2527 index = size_index[(size - 1) / 8];
2400 } else { 2528 } else
2401 if (size > KMALLOC_MAX_SIZE)
2402 return NULL;
2403
2404 index = fls(size - 1); 2529 index = fls(size - 1);
2405 }
2406 2530
2407#ifdef CONFIG_ZONE_DMA 2531#ifdef CONFIG_ZONE_DMA
2408 if (unlikely((flags & SLUB_DMA))) 2532 if (unlikely((flags & SLUB_DMA)))
@@ -2414,9 +2538,15 @@ static struct kmem_cache *get_slab(size_t size, gfp_t flags)
2414 2538
2415void *__kmalloc(size_t size, gfp_t flags) 2539void *__kmalloc(size_t size, gfp_t flags)
2416{ 2540{
2417 struct kmem_cache *s = get_slab(size, flags); 2541 struct kmem_cache *s;
2542
2543 if (unlikely(size > PAGE_SIZE / 2))
2544 return (void *)__get_free_pages(flags | __GFP_COMP,
2545 get_order(size));
2418 2546
2419 if (ZERO_OR_NULL_PTR(s)) 2547 s = get_slab(size, flags);
2548
2549 if (unlikely(ZERO_OR_NULL_PTR(s)))
2420 return s; 2550 return s;
2421 2551
2422 return slab_alloc(s, flags, -1, __builtin_return_address(0)); 2552 return slab_alloc(s, flags, -1, __builtin_return_address(0));
@@ -2426,9 +2556,15 @@ EXPORT_SYMBOL(__kmalloc);
2426#ifdef CONFIG_NUMA 2556#ifdef CONFIG_NUMA
2427void *__kmalloc_node(size_t size, gfp_t flags, int node) 2557void *__kmalloc_node(size_t size, gfp_t flags, int node)
2428{ 2558{
2429 struct kmem_cache *s = get_slab(size, flags); 2559 struct kmem_cache *s;
2430 2560
2431 if (ZERO_OR_NULL_PTR(s)) 2561 if (unlikely(size > PAGE_SIZE / 2))
2562 return (void *)__get_free_pages(flags | __GFP_COMP,
2563 get_order(size));
2564
2565 s = get_slab(size, flags);
2566
2567 if (unlikely(ZERO_OR_NULL_PTR(s)))
2432 return s; 2568 return s;
2433 2569
2434 return slab_alloc(s, flags, node, __builtin_return_address(0)); 2570 return slab_alloc(s, flags, node, __builtin_return_address(0));
@@ -2441,7 +2577,8 @@ size_t ksize(const void *object)
2441 struct page *page; 2577 struct page *page;
2442 struct kmem_cache *s; 2578 struct kmem_cache *s;
2443 2579
2444 if (ZERO_OR_NULL_PTR(object)) 2580 BUG_ON(!object);
2581 if (unlikely(object == ZERO_SIZE_PTR))
2445 return 0; 2582 return 0;
2446 2583
2447 page = get_object_page(object); 2584 page = get_object_page(object);
@@ -2473,22 +2610,17 @@ EXPORT_SYMBOL(ksize);
2473 2610
2474void kfree(const void *x) 2611void kfree(const void *x)
2475{ 2612{
2476 struct kmem_cache *s;
2477 struct page *page; 2613 struct page *page;
2478 2614
2479 /* 2615 if (unlikely(ZERO_OR_NULL_PTR(x)))
2480 * This has to be an unsigned comparison. According to Linus
2481 * some gcc version treat a pointer as a signed entity. Then
2482 * this comparison would be true for all "negative" pointers
2483 * (which would cover the whole upper half of the address space).
2484 */
2485 if (ZERO_OR_NULL_PTR(x))
2486 return; 2616 return;
2487 2617
2488 page = virt_to_head_page(x); 2618 page = virt_to_head_page(x);
2489 s = page->slab; 2619 if (unlikely(!PageSlab(page))) {
2490 2620 put_page(page);
2491 slab_free(s, page, (void *)x, __builtin_return_address(0)); 2621 return;
2622 }
2623 slab_free(page->slab, page, (void *)x, __builtin_return_address(0));
2492} 2624}
2493EXPORT_SYMBOL(kfree); 2625EXPORT_SYMBOL(kfree);
2494 2626
@@ -2517,7 +2649,7 @@ int kmem_cache_shrink(struct kmem_cache *s)
2517 return -ENOMEM; 2649 return -ENOMEM;
2518 2650
2519 flush_all(s); 2651 flush_all(s);
2520 for_each_online_node(node) { 2652 for_each_node_state(node, N_NORMAL_MEMORY) {
2521 n = get_node(s, node); 2653 n = get_node(s, node);
2522 2654
2523 if (!n->nr_partial) 2655 if (!n->nr_partial)
@@ -2575,6 +2707,8 @@ void __init kmem_cache_init(void)
2575 int i; 2707 int i;
2576 int caches = 0; 2708 int caches = 0;
2577 2709
2710 init_alloc_cpu();
2711
2578#ifdef CONFIG_NUMA 2712#ifdef CONFIG_NUMA
2579 /* 2713 /*
2580 * Must first have the slab cache available for the allocations of the 2714 * Must first have the slab cache available for the allocations of the
@@ -2602,7 +2736,7 @@ void __init kmem_cache_init(void)
2602 caches++; 2736 caches++;
2603 } 2737 }
2604 2738
2605 for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) { 2739 for (i = KMALLOC_SHIFT_LOW; i < PAGE_SHIFT; i++) {
2606 create_kmalloc_cache(&kmalloc_caches[i], 2740 create_kmalloc_cache(&kmalloc_caches[i],
2607 "kmalloc", 1 << i, GFP_KERNEL); 2741 "kmalloc", 1 << i, GFP_KERNEL);
2608 caches++; 2742 caches++;
@@ -2629,16 +2763,18 @@ void __init kmem_cache_init(void)
2629 slab_state = UP; 2763 slab_state = UP;
2630 2764
2631 /* Provide the correct kmalloc names now that the caches are up */ 2765 /* Provide the correct kmalloc names now that the caches are up */
2632 for (i = KMALLOC_SHIFT_LOW; i <= KMALLOC_SHIFT_HIGH; i++) 2766 for (i = KMALLOC_SHIFT_LOW; i < PAGE_SHIFT; i++)
2633 kmalloc_caches[i]. name = 2767 kmalloc_caches[i]. name =
2634 kasprintf(GFP_KERNEL, "kmalloc-%d", 1 << i); 2768 kasprintf(GFP_KERNEL, "kmalloc-%d", 1 << i);
2635 2769
2636#ifdef CONFIG_SMP 2770#ifdef CONFIG_SMP
2637 register_cpu_notifier(&slab_notifier); 2771 register_cpu_notifier(&slab_notifier);
2772 kmem_size = offsetof(struct kmem_cache, cpu_slab) +
2773 nr_cpu_ids * sizeof(struct kmem_cache_cpu *);
2774#else
2775 kmem_size = sizeof(struct kmem_cache);
2638#endif 2776#endif
2639 2777
2640 kmem_size = offsetof(struct kmem_cache, cpu_slab) +
2641 nr_cpu_ids * sizeof(struct page *);
2642 2778
2643 printk(KERN_INFO "SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d," 2779 printk(KERN_INFO "SLUB: Genslabs=%d, HWalign=%d, Order=%d-%d, MinObjects=%d,"
2644 " CPUs=%d, Nodes=%d\n", 2780 " CPUs=%d, Nodes=%d\n",
@@ -2717,12 +2853,21 @@ struct kmem_cache *kmem_cache_create(const char *name, size_t size,
2717 down_write(&slub_lock); 2853 down_write(&slub_lock);
2718 s = find_mergeable(size, align, flags, name, ctor); 2854 s = find_mergeable(size, align, flags, name, ctor);
2719 if (s) { 2855 if (s) {
2856 int cpu;
2857
2720 s->refcount++; 2858 s->refcount++;
2721 /* 2859 /*
2722 * Adjust the object sizes so that we clear 2860 * Adjust the object sizes so that we clear
2723 * the complete object on kzalloc. 2861 * the complete object on kzalloc.
2724 */ 2862 */
2725 s->objsize = max(s->objsize, (int)size); 2863 s->objsize = max(s->objsize, (int)size);
2864
2865 /*
2866 * And then we need to update the object size in the
2867 * per cpu structures
2868 */
2869 for_each_online_cpu(cpu)
2870 get_cpu_slab(s, cpu)->objsize = s->objsize;
2726 s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *))); 2871 s->inuse = max_t(int, s->inuse, ALIGN(size, sizeof(void *)));
2727 up_write(&slub_lock); 2872 up_write(&slub_lock);
2728 if (sysfs_slab_alias(s, name)) 2873 if (sysfs_slab_alias(s, name))
@@ -2765,15 +2910,29 @@ static int __cpuinit slab_cpuup_callback(struct notifier_block *nfb,
2765 unsigned long flags; 2910 unsigned long flags;
2766 2911
2767 switch (action) { 2912 switch (action) {
2913 case CPU_UP_PREPARE:
2914 case CPU_UP_PREPARE_FROZEN:
2915 init_alloc_cpu_cpu(cpu);
2916 down_read(&slub_lock);
2917 list_for_each_entry(s, &slab_caches, list)
2918 s->cpu_slab[cpu] = alloc_kmem_cache_cpu(s, cpu,
2919 GFP_KERNEL);
2920 up_read(&slub_lock);
2921 break;
2922
2768 case CPU_UP_CANCELED: 2923 case CPU_UP_CANCELED:
2769 case CPU_UP_CANCELED_FROZEN: 2924 case CPU_UP_CANCELED_FROZEN:
2770 case CPU_DEAD: 2925 case CPU_DEAD:
2771 case CPU_DEAD_FROZEN: 2926 case CPU_DEAD_FROZEN:
2772 down_read(&slub_lock); 2927 down_read(&slub_lock);
2773 list_for_each_entry(s, &slab_caches, list) { 2928 list_for_each_entry(s, &slab_caches, list) {
2929 struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
2930
2774 local_irq_save(flags); 2931 local_irq_save(flags);
2775 __flush_cpu_slab(s, cpu); 2932 __flush_cpu_slab(s, cpu);
2776 local_irq_restore(flags); 2933 local_irq_restore(flags);
2934 free_kmem_cache_cpu(c, cpu);
2935 s->cpu_slab[cpu] = NULL;
2777 } 2936 }
2778 up_read(&slub_lock); 2937 up_read(&slub_lock);
2779 break; 2938 break;
@@ -2790,9 +2949,14 @@ static struct notifier_block __cpuinitdata slab_notifier =
2790 2949
2791void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller) 2950void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller)
2792{ 2951{
2793 struct kmem_cache *s = get_slab(size, gfpflags); 2952 struct kmem_cache *s;
2953
2954 if (unlikely(size > PAGE_SIZE / 2))
2955 return (void *)__get_free_pages(gfpflags | __GFP_COMP,
2956 get_order(size));
2957 s = get_slab(size, gfpflags);
2794 2958
2795 if (ZERO_OR_NULL_PTR(s)) 2959 if (unlikely(ZERO_OR_NULL_PTR(s)))
2796 return s; 2960 return s;
2797 2961
2798 return slab_alloc(s, gfpflags, -1, caller); 2962 return slab_alloc(s, gfpflags, -1, caller);
@@ -2801,9 +2965,14 @@ void *__kmalloc_track_caller(size_t size, gfp_t gfpflags, void *caller)
2801void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags, 2965void *__kmalloc_node_track_caller(size_t size, gfp_t gfpflags,
2802 int node, void *caller) 2966 int node, void *caller)
2803{ 2967{
2804 struct kmem_cache *s = get_slab(size, gfpflags); 2968 struct kmem_cache *s;
2969
2970 if (unlikely(size > PAGE_SIZE / 2))
2971 return (void *)__get_free_pages(gfpflags | __GFP_COMP,
2972 get_order(size));
2973 s = get_slab(size, gfpflags);
2805 2974
2806 if (ZERO_OR_NULL_PTR(s)) 2975 if (unlikely(ZERO_OR_NULL_PTR(s)))
2807 return s; 2976 return s;
2808 2977
2809 return slab_alloc(s, gfpflags, node, caller); 2978 return slab_alloc(s, gfpflags, node, caller);
@@ -2902,7 +3071,7 @@ static long validate_slab_cache(struct kmem_cache *s)
2902 return -ENOMEM; 3071 return -ENOMEM;
2903 3072
2904 flush_all(s); 3073 flush_all(s);
2905 for_each_online_node(node) { 3074 for_each_node_state(node, N_NORMAL_MEMORY) {
2906 struct kmem_cache_node *n = get_node(s, node); 3075 struct kmem_cache_node *n = get_node(s, node);
2907 3076
2908 count += validate_slab_node(s, n, map); 3077 count += validate_slab_node(s, n, map);
@@ -3116,13 +3285,13 @@ static int list_locations(struct kmem_cache *s, char *buf,
3116 int node; 3285 int node;
3117 3286
3118 if (!alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location), 3287 if (!alloc_loc_track(&t, PAGE_SIZE / sizeof(struct location),
3119 GFP_KERNEL)) 3288 GFP_TEMPORARY))
3120 return sprintf(buf, "Out of memory\n"); 3289 return sprintf(buf, "Out of memory\n");
3121 3290
3122 /* Push back cpu slabs */ 3291 /* Push back cpu slabs */
3123 flush_all(s); 3292 flush_all(s);
3124 3293
3125 for_each_online_node(node) { 3294 for_each_node_state(node, N_NORMAL_MEMORY) {
3126 struct kmem_cache_node *n = get_node(s, node); 3295 struct kmem_cache_node *n = get_node(s, node);
3127 unsigned long flags; 3296 unsigned long flags;
3128 struct page *page; 3297 struct page *page;
@@ -3230,11 +3399,18 @@ static unsigned long slab_objects(struct kmem_cache *s,
3230 per_cpu = nodes + nr_node_ids; 3399 per_cpu = nodes + nr_node_ids;
3231 3400
3232 for_each_possible_cpu(cpu) { 3401 for_each_possible_cpu(cpu) {
3233 struct page *page = s->cpu_slab[cpu]; 3402 struct page *page;
3234 int node; 3403 int node;
3404 struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
3235 3405
3406 if (!c)
3407 continue;
3408
3409 page = c->page;
3410 node = c->node;
3411 if (node < 0)
3412 continue;
3236 if (page) { 3413 if (page) {
3237 node = page_to_nid(page);
3238 if (flags & SO_CPU) { 3414 if (flags & SO_CPU) {
3239 int x = 0; 3415 int x = 0;
3240 3416
@@ -3249,7 +3425,7 @@ static unsigned long slab_objects(struct kmem_cache *s,
3249 } 3425 }
3250 } 3426 }
3251 3427
3252 for_each_online_node(node) { 3428 for_each_node_state(node, N_NORMAL_MEMORY) {
3253 struct kmem_cache_node *n = get_node(s, node); 3429 struct kmem_cache_node *n = get_node(s, node);
3254 3430
3255 if (flags & SO_PARTIAL) { 3431 if (flags & SO_PARTIAL) {
@@ -3277,7 +3453,7 @@ static unsigned long slab_objects(struct kmem_cache *s,
3277 3453
3278 x = sprintf(buf, "%lu", total); 3454 x = sprintf(buf, "%lu", total);
3279#ifdef CONFIG_NUMA 3455#ifdef CONFIG_NUMA
3280 for_each_online_node(node) 3456 for_each_node_state(node, N_NORMAL_MEMORY)
3281 if (nodes[node]) 3457 if (nodes[node])
3282 x += sprintf(buf + x, " N%d=%lu", 3458 x += sprintf(buf + x, " N%d=%lu",
3283 node, nodes[node]); 3459 node, nodes[node]);
@@ -3291,13 +3467,19 @@ static int any_slab_objects(struct kmem_cache *s)
3291 int node; 3467 int node;
3292 int cpu; 3468 int cpu;
3293 3469
3294 for_each_possible_cpu(cpu) 3470 for_each_possible_cpu(cpu) {
3295 if (s->cpu_slab[cpu]) 3471 struct kmem_cache_cpu *c = get_cpu_slab(s, cpu);
3472
3473 if (c && c->page)
3296 return 1; 3474 return 1;
3475 }
3297 3476
3298 for_each_node(node) { 3477 for_each_online_node(node) {
3299 struct kmem_cache_node *n = get_node(s, node); 3478 struct kmem_cache_node *n = get_node(s, node);
3300 3479
3480 if (!n)
3481 continue;
3482
3301 if (n->nr_partial || atomic_long_read(&n->nr_slabs)) 3483 if (n->nr_partial || atomic_long_read(&n->nr_slabs))
3302 return 1; 3484 return 1;
3303 } 3485 }
diff --git a/mm/sparse-vmemmap.c b/mm/sparse-vmemmap.c
new file mode 100644
index 000000000000..d3b718b0c20a
--- /dev/null
+++ b/mm/sparse-vmemmap.c
@@ -0,0 +1,148 @@
1/*
2 * Virtual Memory Map support
3 *
4 * (C) 2007 sgi. Christoph Lameter <clameter@sgi.com>.
5 *
6 * Virtual memory maps allow VM primitives pfn_to_page, page_to_pfn,
7 * virt_to_page, page_address() to be implemented as a base offset
8 * calculation without memory access.
9 *
10 * However, virtual mappings need a page table and TLBs. Many Linux
11 * architectures already map their physical space using 1-1 mappings
12 * via TLBs. For those arches the virtual memmory map is essentially
13 * for free if we use the same page size as the 1-1 mappings. In that
14 * case the overhead consists of a few additional pages that are
15 * allocated to create a view of memory for vmemmap.
16 *
17 * The architecture is expected to provide a vmemmap_populate() function
18 * to instantiate the mapping.
19 */
20#include <linux/mm.h>
21#include <linux/mmzone.h>
22#include <linux/bootmem.h>
23#include <linux/highmem.h>
24#include <linux/module.h>
25#include <linux/spinlock.h>
26#include <linux/vmalloc.h>
27#include <asm/dma.h>
28#include <asm/pgalloc.h>
29#include <asm/pgtable.h>
30
31/*
32 * Allocate a block of memory to be used to back the virtual memory map
33 * or to back the page tables that are used to create the mapping.
34 * Uses the main allocators if they are available, else bootmem.
35 */
36void * __meminit vmemmap_alloc_block(unsigned long size, int node)
37{
38 /* If the main allocator is up use that, fallback to bootmem. */
39 if (slab_is_available()) {
40 struct page *page = alloc_pages_node(node,
41 GFP_KERNEL | __GFP_ZERO, get_order(size));
42 if (page)
43 return page_address(page);
44 return NULL;
45 } else
46 return __alloc_bootmem_node(NODE_DATA(node), size, size,
47 __pa(MAX_DMA_ADDRESS));
48}
49
50void __meminit vmemmap_verify(pte_t *pte, int node,
51 unsigned long start, unsigned long end)
52{
53 unsigned long pfn = pte_pfn(*pte);
54 int actual_node = early_pfn_to_nid(pfn);
55
56 if (actual_node != node)
57 printk(KERN_WARNING "[%lx-%lx] potential offnode "
58 "page_structs\n", start, end - 1);
59}
60
61pte_t * __meminit vmemmap_pte_populate(pmd_t *pmd, unsigned long addr, int node)
62{
63 pte_t *pte = pte_offset_kernel(pmd, addr);
64 if (pte_none(*pte)) {
65 pte_t entry;
66 void *p = vmemmap_alloc_block(PAGE_SIZE, node);
67 if (!p)
68 return 0;
69 entry = pfn_pte(__pa(p) >> PAGE_SHIFT, PAGE_KERNEL);
70 set_pte_at(&init_mm, addr, pte, entry);
71 }
72 return pte;
73}
74
75pmd_t * __meminit vmemmap_pmd_populate(pud_t *pud, unsigned long addr, int node)
76{
77 pmd_t *pmd = pmd_offset(pud, addr);
78 if (pmd_none(*pmd)) {
79 void *p = vmemmap_alloc_block(PAGE_SIZE, node);
80 if (!p)
81 return 0;
82 pmd_populate_kernel(&init_mm, pmd, p);
83 }
84 return pmd;
85}
86
87pud_t * __meminit vmemmap_pud_populate(pgd_t *pgd, unsigned long addr, int node)
88{
89 pud_t *pud = pud_offset(pgd, addr);
90 if (pud_none(*pud)) {
91 void *p = vmemmap_alloc_block(PAGE_SIZE, node);
92 if (!p)
93 return 0;
94 pud_populate(&init_mm, pud, p);
95 }
96 return pud;
97}
98
99pgd_t * __meminit vmemmap_pgd_populate(unsigned long addr, int node)
100{
101 pgd_t *pgd = pgd_offset_k(addr);
102 if (pgd_none(*pgd)) {
103 void *p = vmemmap_alloc_block(PAGE_SIZE, node);
104 if (!p)
105 return 0;
106 pgd_populate(&init_mm, pgd, p);
107 }
108 return pgd;
109}
110
111int __meminit vmemmap_populate_basepages(struct page *start_page,
112 unsigned long size, int node)
113{
114 unsigned long addr = (unsigned long)start_page;
115 unsigned long end = (unsigned long)(start_page + size);
116 pgd_t *pgd;
117 pud_t *pud;
118 pmd_t *pmd;
119 pte_t *pte;
120
121 for (; addr < end; addr += PAGE_SIZE) {
122 pgd = vmemmap_pgd_populate(addr, node);
123 if (!pgd)
124 return -ENOMEM;
125 pud = vmemmap_pud_populate(pgd, addr, node);
126 if (!pud)
127 return -ENOMEM;
128 pmd = vmemmap_pmd_populate(pud, addr, node);
129 if (!pmd)
130 return -ENOMEM;
131 pte = vmemmap_pte_populate(pmd, addr, node);
132 if (!pte)
133 return -ENOMEM;
134 vmemmap_verify(pte, node, addr, addr + PAGE_SIZE);
135 }
136
137 return 0;
138}
139
140struct page * __meminit sparse_mem_map_populate(unsigned long pnum, int nid)
141{
142 struct page *map = pfn_to_page(pnum * PAGES_PER_SECTION);
143 int error = vmemmap_populate(map, PAGES_PER_SECTION, nid);
144 if (error)
145 return NULL;
146
147 return map;
148}
diff --git a/mm/sparse.c b/mm/sparse.c
index 239f5a720d38..08fb14f5eea3 100644
--- a/mm/sparse.c
+++ b/mm/sparse.c
@@ -9,6 +9,8 @@
9#include <linux/spinlock.h> 9#include <linux/spinlock.h>
10#include <linux/vmalloc.h> 10#include <linux/vmalloc.h>
11#include <asm/dma.h> 11#include <asm/dma.h>
12#include <asm/pgalloc.h>
13#include <asm/pgtable.h>
12 14
13/* 15/*
14 * Permanent SPARSEMEM data: 16 * Permanent SPARSEMEM data:
@@ -106,7 +108,7 @@ static inline int sparse_index_init(unsigned long section_nr, int nid)
106 108
107/* 109/*
108 * Although written for the SPARSEMEM_EXTREME case, this happens 110 * Although written for the SPARSEMEM_EXTREME case, this happens
109 * to also work for the flat array case becase 111 * to also work for the flat array case because
110 * NR_SECTION_ROOTS==NR_MEM_SECTIONS. 112 * NR_SECTION_ROOTS==NR_MEM_SECTIONS.
111 */ 113 */
112int __section_nr(struct mem_section* ms) 114int __section_nr(struct mem_section* ms)
@@ -176,7 +178,7 @@ unsigned long __init node_memmap_size_bytes(int nid, unsigned long start_pfn,
176 if (nid != early_pfn_to_nid(pfn)) 178 if (nid != early_pfn_to_nid(pfn))
177 continue; 179 continue;
178 180
179 if (pfn_valid(pfn)) 181 if (pfn_present(pfn))
180 nr_pages += PAGES_PER_SECTION; 182 nr_pages += PAGES_PER_SECTION;
181 } 183 }
182 184
@@ -204,13 +206,16 @@ struct page *sparse_decode_mem_map(unsigned long coded_mem_map, unsigned long pn
204} 206}
205 207
206static int __meminit sparse_init_one_section(struct mem_section *ms, 208static int __meminit sparse_init_one_section(struct mem_section *ms,
207 unsigned long pnum, struct page *mem_map) 209 unsigned long pnum, struct page *mem_map,
210 unsigned long *pageblock_bitmap)
208{ 211{
209 if (!valid_section(ms)) 212 if (!present_section(ms))
210 return -EINVAL; 213 return -EINVAL;
211 214
212 ms->section_mem_map &= ~SECTION_MAP_MASK; 215 ms->section_mem_map &= ~SECTION_MAP_MASK;
213 ms->section_mem_map |= sparse_encode_mem_map(mem_map, pnum); 216 ms->section_mem_map |= sparse_encode_mem_map(mem_map, pnum) |
217 SECTION_HAS_MEM_MAP;
218 ms->pageblock_flags = pageblock_bitmap;
214 219
215 return 1; 220 return 1;
216} 221}
@@ -221,12 +226,43 @@ void *alloc_bootmem_high_node(pg_data_t *pgdat, unsigned long size)
221 return NULL; 226 return NULL;
222} 227}
223 228
224static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum) 229static unsigned long usemap_size(void)
225{ 230{
226 struct page *map; 231 unsigned long size_bytes;
232 size_bytes = roundup(SECTION_BLOCKFLAGS_BITS, 8) / 8;
233 size_bytes = roundup(size_bytes, sizeof(unsigned long));
234 return size_bytes;
235}
236
237#ifdef CONFIG_MEMORY_HOTPLUG
238static unsigned long *__kmalloc_section_usemap(void)
239{
240 return kmalloc(usemap_size(), GFP_KERNEL);
241}
242#endif /* CONFIG_MEMORY_HOTPLUG */
243
244static unsigned long *sparse_early_usemap_alloc(unsigned long pnum)
245{
246 unsigned long *usemap;
227 struct mem_section *ms = __nr_to_section(pnum); 247 struct mem_section *ms = __nr_to_section(pnum);
228 int nid = sparse_early_nid(ms); 248 int nid = sparse_early_nid(ms);
229 249
250 usemap = alloc_bootmem_node(NODE_DATA(nid), usemap_size());
251 if (usemap)
252 return usemap;
253
254 /* Stupid: suppress gcc warning for SPARSEMEM && !NUMA */
255 nid = 0;
256
257 printk(KERN_WARNING "%s: allocation failed\n", __FUNCTION__);
258 return NULL;
259}
260
261#ifndef CONFIG_SPARSEMEM_VMEMMAP
262struct page __init *sparse_mem_map_populate(unsigned long pnum, int nid)
263{
264 struct page *map;
265
230 map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION); 266 map = alloc_remap(nid, sizeof(struct page) * PAGES_PER_SECTION);
231 if (map) 267 if (map)
232 return map; 268 return map;
@@ -238,10 +274,22 @@ static struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
238 274
239 map = alloc_bootmem_node(NODE_DATA(nid), 275 map = alloc_bootmem_node(NODE_DATA(nid),
240 sizeof(struct page) * PAGES_PER_SECTION); 276 sizeof(struct page) * PAGES_PER_SECTION);
277 return map;
278}
279#endif /* !CONFIG_SPARSEMEM_VMEMMAP */
280
281struct page __init *sparse_early_mem_map_alloc(unsigned long pnum)
282{
283 struct page *map;
284 struct mem_section *ms = __nr_to_section(pnum);
285 int nid = sparse_early_nid(ms);
286
287 map = sparse_mem_map_populate(pnum, nid);
241 if (map) 288 if (map)
242 return map; 289 return map;
243 290
244 printk(KERN_WARNING "%s: allocation failed\n", __FUNCTION__); 291 printk(KERN_ERR "%s: sparsemem memory map backing failed "
292 "some memory will not be available.\n", __FUNCTION__);
245 ms->section_mem_map = 0; 293 ms->section_mem_map = 0;
246 return NULL; 294 return NULL;
247} 295}
@@ -254,19 +302,38 @@ void __init sparse_init(void)
254{ 302{
255 unsigned long pnum; 303 unsigned long pnum;
256 struct page *map; 304 struct page *map;
305 unsigned long *usemap;
257 306
258 for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) { 307 for (pnum = 0; pnum < NR_MEM_SECTIONS; pnum++) {
259 if (!valid_section_nr(pnum)) 308 if (!present_section_nr(pnum))
260 continue; 309 continue;
261 310
262 map = sparse_early_mem_map_alloc(pnum); 311 map = sparse_early_mem_map_alloc(pnum);
263 if (!map) 312 if (!map)
264 continue; 313 continue;
265 sparse_init_one_section(__nr_to_section(pnum), pnum, map); 314
315 usemap = sparse_early_usemap_alloc(pnum);
316 if (!usemap)
317 continue;
318
319 sparse_init_one_section(__nr_to_section(pnum), pnum, map,
320 usemap);
266 } 321 }
267} 322}
268 323
269#ifdef CONFIG_MEMORY_HOTPLUG 324#ifdef CONFIG_MEMORY_HOTPLUG
325#ifdef CONFIG_SPARSEMEM_VMEMMAP
326static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
327 unsigned long nr_pages)
328{
329 /* This will make the necessary allocations eventually. */
330 return sparse_mem_map_populate(pnum, nid);
331}
332static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
333{
334 return; /* XXX: Not implemented yet */
335}
336#else
270static struct page *__kmalloc_section_memmap(unsigned long nr_pages) 337static struct page *__kmalloc_section_memmap(unsigned long nr_pages)
271{ 338{
272 struct page *page, *ret; 339 struct page *page, *ret;
@@ -289,6 +356,12 @@ got_map_ptr:
289 return ret; 356 return ret;
290} 357}
291 358
359static inline struct page *kmalloc_section_memmap(unsigned long pnum, int nid,
360 unsigned long nr_pages)
361{
362 return __kmalloc_section_memmap(nr_pages);
363}
364
292static int vaddr_in_vmalloc_area(void *addr) 365static int vaddr_in_vmalloc_area(void *addr)
293{ 366{
294 if (addr >= (void *)VMALLOC_START && 367 if (addr >= (void *)VMALLOC_START &&
@@ -305,6 +378,7 @@ static void __kfree_section_memmap(struct page *memmap, unsigned long nr_pages)
305 free_pages((unsigned long)memmap, 378 free_pages((unsigned long)memmap,
306 get_order(sizeof(struct page) * nr_pages)); 379 get_order(sizeof(struct page) * nr_pages));
307} 380}
381#endif /* CONFIG_SPARSEMEM_VMEMMAP */
308 382
309/* 383/*
310 * returns the number of sections whose mem_maps were properly 384 * returns the number of sections whose mem_maps were properly
@@ -318,6 +392,7 @@ int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
318 struct pglist_data *pgdat = zone->zone_pgdat; 392 struct pglist_data *pgdat = zone->zone_pgdat;
319 struct mem_section *ms; 393 struct mem_section *ms;
320 struct page *memmap; 394 struct page *memmap;
395 unsigned long *usemap;
321 unsigned long flags; 396 unsigned long flags;
322 int ret; 397 int ret;
323 398
@@ -326,7 +401,8 @@ int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
326 * plus, it does a kmalloc 401 * plus, it does a kmalloc
327 */ 402 */
328 sparse_index_init(section_nr, pgdat->node_id); 403 sparse_index_init(section_nr, pgdat->node_id);
329 memmap = __kmalloc_section_memmap(nr_pages); 404 memmap = kmalloc_section_memmap(section_nr, pgdat->node_id, nr_pages);
405 usemap = __kmalloc_section_usemap();
330 406
331 pgdat_resize_lock(pgdat, &flags); 407 pgdat_resize_lock(pgdat, &flags);
332 408
@@ -335,9 +411,14 @@ int sparse_add_one_section(struct zone *zone, unsigned long start_pfn,
335 ret = -EEXIST; 411 ret = -EEXIST;
336 goto out; 412 goto out;
337 } 413 }
414
415 if (!usemap) {
416 ret = -ENOMEM;
417 goto out;
418 }
338 ms->section_mem_map |= SECTION_MARKED_PRESENT; 419 ms->section_mem_map |= SECTION_MARKED_PRESENT;
339 420
340 ret = sparse_init_one_section(ms, section_nr, memmap); 421 ret = sparse_init_one_section(ms, section_nr, memmap, usemap);
341 422
342out: 423out:
343 pgdat_resize_unlock(pgdat, &flags); 424 pgdat_resize_unlock(pgdat, &flags);
diff --git a/mm/swap.c b/mm/swap.c
index d3cb966fe992..d034b2128d2b 100644
--- a/mm/swap.c
+++ b/mm/swap.c
@@ -24,16 +24,18 @@
24#include <linux/module.h> 24#include <linux/module.h>
25#include <linux/mm_inline.h> 25#include <linux/mm_inline.h>
26#include <linux/buffer_head.h> /* for try_to_release_page() */ 26#include <linux/buffer_head.h> /* for try_to_release_page() */
27#include <linux/module.h>
28#include <linux/percpu_counter.h> 27#include <linux/percpu_counter.h>
29#include <linux/percpu.h> 28#include <linux/percpu.h>
30#include <linux/cpu.h> 29#include <linux/cpu.h>
31#include <linux/notifier.h> 30#include <linux/notifier.h>
32#include <linux/init.h>
33 31
34/* How many pages do we try to swap or page in/out together? */ 32/* How many pages do we try to swap or page in/out together? */
35int page_cluster; 33int page_cluster;
36 34
35static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
36static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
37static DEFINE_PER_CPU(struct pagevec, lru_rotate_pvecs) = { 0, };
38
37/* 39/*
38 * This path almost never happens for VM activity - pages are normally 40 * This path almost never happens for VM activity - pages are normally
39 * freed via pagevecs. But it gets used by networking. 41 * freed via pagevecs. But it gets used by networking.
@@ -94,23 +96,47 @@ void put_pages_list(struct list_head *pages)
94EXPORT_SYMBOL(put_pages_list); 96EXPORT_SYMBOL(put_pages_list);
95 97
96/* 98/*
99 * pagevec_move_tail() must be called with IRQ disabled.
100 * Otherwise this may cause nasty races.
101 */
102static void pagevec_move_tail(struct pagevec *pvec)
103{
104 int i;
105 int pgmoved = 0;
106 struct zone *zone = NULL;
107
108 for (i = 0; i < pagevec_count(pvec); i++) {
109 struct page *page = pvec->pages[i];
110 struct zone *pagezone = page_zone(page);
111
112 if (pagezone != zone) {
113 if (zone)
114 spin_unlock(&zone->lru_lock);
115 zone = pagezone;
116 spin_lock(&zone->lru_lock);
117 }
118 if (PageLRU(page) && !PageActive(page)) {
119 list_move_tail(&page->lru, &zone->inactive_list);
120 pgmoved++;
121 }
122 }
123 if (zone)
124 spin_unlock(&zone->lru_lock);
125 __count_vm_events(PGROTATED, pgmoved);
126 release_pages(pvec->pages, pvec->nr, pvec->cold);
127 pagevec_reinit(pvec);
128}
129
130/*
97 * Writeback is about to end against a page which has been marked for immediate 131 * Writeback is about to end against a page which has been marked for immediate
98 * reclaim. If it still appears to be reclaimable, move it to the tail of the 132 * reclaim. If it still appears to be reclaimable, move it to the tail of the
99 * inactive list. The page still has PageWriteback set, which will pin it. 133 * inactive list.
100 *
101 * We don't expect many pages to come through here, so don't bother batching
102 * things up.
103 *
104 * To avoid placing the page at the tail of the LRU while PG_writeback is still
105 * set, this function will clear PG_writeback before performing the page
106 * motion. Do that inside the lru lock because once PG_writeback is cleared
107 * we may not touch the page.
108 * 134 *
109 * Returns zero if it cleared PG_writeback. 135 * Returns zero if it cleared PG_writeback.
110 */ 136 */
111int rotate_reclaimable_page(struct page *page) 137int rotate_reclaimable_page(struct page *page)
112{ 138{
113 struct zone *zone; 139 struct pagevec *pvec;
114 unsigned long flags; 140 unsigned long flags;
115 141
116 if (PageLocked(page)) 142 if (PageLocked(page))
@@ -122,15 +148,16 @@ int rotate_reclaimable_page(struct page *page)
122 if (!PageLRU(page)) 148 if (!PageLRU(page))
123 return 1; 149 return 1;
124 150
125 zone = page_zone(page); 151 page_cache_get(page);
126 spin_lock_irqsave(&zone->lru_lock, flags); 152 local_irq_save(flags);
127 if (PageLRU(page) && !PageActive(page)) { 153 pvec = &__get_cpu_var(lru_rotate_pvecs);
128 list_move_tail(&page->lru, &zone->inactive_list); 154 if (!pagevec_add(pvec, page))
129 __count_vm_event(PGROTATED); 155 pagevec_move_tail(pvec);
130 } 156 local_irq_restore(flags);
157
131 if (!test_clear_page_writeback(page)) 158 if (!test_clear_page_writeback(page))
132 BUG(); 159 BUG();
133 spin_unlock_irqrestore(&zone->lru_lock, flags); 160
134 return 0; 161 return 0;
135} 162}
136 163
@@ -174,9 +201,6 @@ EXPORT_SYMBOL(mark_page_accessed);
174 * lru_cache_add: add a page to the page lists 201 * lru_cache_add: add a page to the page lists
175 * @page: the page to add 202 * @page: the page to add
176 */ 203 */
177static DEFINE_PER_CPU(struct pagevec, lru_add_pvecs) = { 0, };
178static DEFINE_PER_CPU(struct pagevec, lru_add_active_pvecs) = { 0, };
179
180void fastcall lru_cache_add(struct page *page) 204void fastcall lru_cache_add(struct page *page)
181{ 205{
182 struct pagevec *pvec = &get_cpu_var(lru_add_pvecs); 206 struct pagevec *pvec = &get_cpu_var(lru_add_pvecs);
@@ -197,21 +221,37 @@ void fastcall lru_cache_add_active(struct page *page)
197 put_cpu_var(lru_add_active_pvecs); 221 put_cpu_var(lru_add_active_pvecs);
198} 222}
199 223
200static void __lru_add_drain(int cpu) 224/*
225 * Drain pages out of the cpu's pagevecs.
226 * Either "cpu" is the current CPU, and preemption has already been
227 * disabled; or "cpu" is being hot-unplugged, and is already dead.
228 */
229static void drain_cpu_pagevecs(int cpu)
201{ 230{
202 struct pagevec *pvec = &per_cpu(lru_add_pvecs, cpu); 231 struct pagevec *pvec;
203 232
204 /* CPU is dead, so no locking needed. */ 233 pvec = &per_cpu(lru_add_pvecs, cpu);
205 if (pagevec_count(pvec)) 234 if (pagevec_count(pvec))
206 __pagevec_lru_add(pvec); 235 __pagevec_lru_add(pvec);
236
207 pvec = &per_cpu(lru_add_active_pvecs, cpu); 237 pvec = &per_cpu(lru_add_active_pvecs, cpu);
208 if (pagevec_count(pvec)) 238 if (pagevec_count(pvec))
209 __pagevec_lru_add_active(pvec); 239 __pagevec_lru_add_active(pvec);
240
241 pvec = &per_cpu(lru_rotate_pvecs, cpu);
242 if (pagevec_count(pvec)) {
243 unsigned long flags;
244
245 /* No harm done if a racing interrupt already did this */
246 local_irq_save(flags);
247 pagevec_move_tail(pvec);
248 local_irq_restore(flags);
249 }
210} 250}
211 251
212void lru_add_drain(void) 252void lru_add_drain(void)
213{ 253{
214 __lru_add_drain(get_cpu()); 254 drain_cpu_pagevecs(get_cpu());
215 put_cpu(); 255 put_cpu();
216} 256}
217 257
@@ -258,6 +298,7 @@ void release_pages(struct page **pages, int nr, int cold)
258 int i; 298 int i;
259 struct pagevec pages_to_free; 299 struct pagevec pages_to_free;
260 struct zone *zone = NULL; 300 struct zone *zone = NULL;
301 unsigned long uninitialized_var(flags);
261 302
262 pagevec_init(&pages_to_free, cold); 303 pagevec_init(&pages_to_free, cold);
263 for (i = 0; i < nr; i++) { 304 for (i = 0; i < nr; i++) {
@@ -265,7 +306,7 @@ void release_pages(struct page **pages, int nr, int cold)
265 306
266 if (unlikely(PageCompound(page))) { 307 if (unlikely(PageCompound(page))) {
267 if (zone) { 308 if (zone) {
268 spin_unlock_irq(&zone->lru_lock); 309 spin_unlock_irqrestore(&zone->lru_lock, flags);
269 zone = NULL; 310 zone = NULL;
270 } 311 }
271 put_compound_page(page); 312 put_compound_page(page);
@@ -279,9 +320,10 @@ void release_pages(struct page **pages, int nr, int cold)
279 struct zone *pagezone = page_zone(page); 320 struct zone *pagezone = page_zone(page);
280 if (pagezone != zone) { 321 if (pagezone != zone) {
281 if (zone) 322 if (zone)
282 spin_unlock_irq(&zone->lru_lock); 323 spin_unlock_irqrestore(&zone->lru_lock,
324 flags);
283 zone = pagezone; 325 zone = pagezone;
284 spin_lock_irq(&zone->lru_lock); 326 spin_lock_irqsave(&zone->lru_lock, flags);
285 } 327 }
286 VM_BUG_ON(!PageLRU(page)); 328 VM_BUG_ON(!PageLRU(page));
287 __ClearPageLRU(page); 329 __ClearPageLRU(page);
@@ -290,7 +332,7 @@ void release_pages(struct page **pages, int nr, int cold)
290 332
291 if (!pagevec_add(&pages_to_free, page)) { 333 if (!pagevec_add(&pages_to_free, page)) {
292 if (zone) { 334 if (zone) {
293 spin_unlock_irq(&zone->lru_lock); 335 spin_unlock_irqrestore(&zone->lru_lock, flags);
294 zone = NULL; 336 zone = NULL;
295 } 337 }
296 __pagevec_free(&pages_to_free); 338 __pagevec_free(&pages_to_free);
@@ -298,7 +340,7 @@ void release_pages(struct page **pages, int nr, int cold)
298 } 340 }
299 } 341 }
300 if (zone) 342 if (zone)
301 spin_unlock_irq(&zone->lru_lock); 343 spin_unlock_irqrestore(&zone->lru_lock, flags);
302 344
303 pagevec_free(&pages_to_free); 345 pagevec_free(&pages_to_free);
304} 346}
@@ -491,7 +533,7 @@ static int cpu_swap_callback(struct notifier_block *nfb,
491 if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) { 533 if (action == CPU_DEAD || action == CPU_DEAD_FROZEN) {
492 atomic_add(*committed, &vm_committed_space); 534 atomic_add(*committed, &vm_committed_space);
493 *committed = 0; 535 *committed = 0;
494 __lru_add_drain((long)hcpu); 536 drain_cpu_pagevecs((long)hcpu);
495 } 537 }
496 return NOTIFY_OK; 538 return NOTIFY_OK;
497} 539}
diff --git a/mm/swap_state.c b/mm/swap_state.c
index 67daecb6031a..b52635601dfe 100644
--- a/mm/swap_state.c
+++ b/mm/swap_state.c
@@ -74,6 +74,7 @@ static int __add_to_swap_cache(struct page *page, swp_entry_t entry,
74{ 74{
75 int error; 75 int error;
76 76
77 BUG_ON(!PageLocked(page));
77 BUG_ON(PageSwapCache(page)); 78 BUG_ON(PageSwapCache(page));
78 BUG_ON(PagePrivate(page)); 79 BUG_ON(PagePrivate(page));
79 error = radix_tree_preload(gfp_mask); 80 error = radix_tree_preload(gfp_mask);
@@ -83,7 +84,6 @@ static int __add_to_swap_cache(struct page *page, swp_entry_t entry,
83 entry.val, page); 84 entry.val, page);
84 if (!error) { 85 if (!error) {
85 page_cache_get(page); 86 page_cache_get(page);
86 SetPageLocked(page);
87 SetPageSwapCache(page); 87 SetPageSwapCache(page);
88 set_page_private(page, entry.val); 88 set_page_private(page, entry.val);
89 total_swapcache_pages++; 89 total_swapcache_pages++;
@@ -99,15 +99,18 @@ static int add_to_swap_cache(struct page *page, swp_entry_t entry)
99{ 99{
100 int error; 100 int error;
101 101
102 BUG_ON(PageLocked(page));
102 if (!swap_duplicate(entry)) { 103 if (!swap_duplicate(entry)) {
103 INC_CACHE_INFO(noent_race); 104 INC_CACHE_INFO(noent_race);
104 return -ENOENT; 105 return -ENOENT;
105 } 106 }
107 SetPageLocked(page);
106 error = __add_to_swap_cache(page, entry, GFP_KERNEL); 108 error = __add_to_swap_cache(page, entry, GFP_KERNEL);
107 /* 109 /*
108 * Anon pages are already on the LRU, we don't run lru_cache_add here. 110 * Anon pages are already on the LRU, we don't run lru_cache_add here.
109 */ 111 */
110 if (error) { 112 if (error) {
113 ClearPageLocked(page);
111 swap_free(entry); 114 swap_free(entry);
112 if (error == -EEXIST) 115 if (error == -EEXIST)
113 INC_CACHE_INFO(exist_race); 116 INC_CACHE_INFO(exist_race);
diff --git a/mm/util.c b/mm/util.c
index bf340d806868..5f64026cbb4d 100644
--- a/mm/util.c
+++ b/mm/util.c
@@ -81,14 +81,16 @@ EXPORT_SYMBOL(kmemdup);
81void *krealloc(const void *p, size_t new_size, gfp_t flags) 81void *krealloc(const void *p, size_t new_size, gfp_t flags)
82{ 82{
83 void *ret; 83 void *ret;
84 size_t ks; 84 size_t ks = 0;
85 85
86 if (unlikely(!new_size)) { 86 if (unlikely(!new_size)) {
87 kfree(p); 87 kfree(p);
88 return ZERO_SIZE_PTR; 88 return ZERO_SIZE_PTR;
89 } 89 }
90 90
91 ks = ksize(p); 91 if (p)
92 ks = ksize(p);
93
92 if (ks >= new_size) 94 if (ks >= new_size)
93 return (void *)p; 95 return (void *)p;
94 96
diff --git a/mm/vmalloc.c b/mm/vmalloc.c
index 3cee76a8c9f0..2e01af365848 100644
--- a/mm/vmalloc.c
+++ b/mm/vmalloc.c
@@ -190,7 +190,8 @@ static struct vm_struct *__get_vm_area_node(unsigned long size, unsigned long fl
190 if (unlikely(!size)) 190 if (unlikely(!size))
191 return NULL; 191 return NULL;
192 192
193 area = kmalloc_node(sizeof(*area), gfp_mask & GFP_LEVEL_MASK, node); 193 area = kmalloc_node(sizeof(*area), gfp_mask & GFP_RECLAIM_MASK, node);
194
194 if (unlikely(!area)) 195 if (unlikely(!area))
195 return NULL; 196 return NULL;
196 197
@@ -439,7 +440,7 @@ void *__vmalloc_area_node(struct vm_struct *area, gfp_t gfp_mask,
439 area->flags |= VM_VPAGES; 440 area->flags |= VM_VPAGES;
440 } else { 441 } else {
441 pages = kmalloc_node(array_size, 442 pages = kmalloc_node(array_size,
442 (gfp_mask & GFP_LEVEL_MASK) | __GFP_ZERO, 443 (gfp_mask & GFP_RECLAIM_MASK) | __GFP_ZERO,
443 node); 444 node);
444 } 445 }
445 area->pages = pages; 446 area->pages = pages;
diff --git a/mm/vmscan.c b/mm/vmscan.c
index a6e65d024995..bbd194630c5b 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -932,6 +932,7 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
932 long mapped_ratio; 932 long mapped_ratio;
933 long distress; 933 long distress;
934 long swap_tendency; 934 long swap_tendency;
935 long imbalance;
935 936
936 if (zone_is_near_oom(zone)) 937 if (zone_is_near_oom(zone))
937 goto force_reclaim_mapped; 938 goto force_reclaim_mapped;
@@ -967,6 +968,46 @@ static void shrink_active_list(unsigned long nr_pages, struct zone *zone,
967 swap_tendency = mapped_ratio / 2 + distress + sc->swappiness; 968 swap_tendency = mapped_ratio / 2 + distress + sc->swappiness;
968 969
969 /* 970 /*
971 * If there's huge imbalance between active and inactive
972 * (think active 100 times larger than inactive) we should
973 * become more permissive, or the system will take too much
974 * cpu before it start swapping during memory pressure.
975 * Distress is about avoiding early-oom, this is about
976 * making swappiness graceful despite setting it to low
977 * values.
978 *
979 * Avoid div by zero with nr_inactive+1, and max resulting
980 * value is vm_total_pages.
981 */
982 imbalance = zone_page_state(zone, NR_ACTIVE);
983 imbalance /= zone_page_state(zone, NR_INACTIVE) + 1;
984
985 /*
986 * Reduce the effect of imbalance if swappiness is low,
987 * this means for a swappiness very low, the imbalance
988 * must be much higher than 100 for this logic to make
989 * the difference.
990 *
991 * Max temporary value is vm_total_pages*100.
992 */
993 imbalance *= (vm_swappiness + 1);
994 imbalance /= 100;
995
996 /*
997 * If not much of the ram is mapped, makes the imbalance
998 * less relevant, it's high priority we refill the inactive
999 * list with mapped pages only in presence of high ratio of
1000 * mapped pages.
1001 *
1002 * Max temporary value is vm_total_pages*100.
1003 */
1004 imbalance *= mapped_ratio;
1005 imbalance /= 100;
1006
1007 /* apply imbalance feedback to swap_tendency */
1008 swap_tendency += imbalance;
1009
1010 /*
970 * Now use this metric to decide whether to start moving mapped 1011 * Now use this metric to decide whether to start moving mapped
971 * memory onto the inactive list. 1012 * memory onto the inactive list.
972 */ 1013 */
@@ -1371,7 +1412,13 @@ loop_again:
1371 temp_priority[i] = priority; 1412 temp_priority[i] = priority;
1372 sc.nr_scanned = 0; 1413 sc.nr_scanned = 0;
1373 note_zone_scanning_priority(zone, priority); 1414 note_zone_scanning_priority(zone, priority);
1374 nr_reclaimed += shrink_zone(priority, zone, &sc); 1415 /*
1416 * We put equal pressure on every zone, unless one
1417 * zone has way too many pages free already.
1418 */
1419 if (!zone_watermark_ok(zone, order, 8*zone->pages_high,
1420 end_zone, 0))
1421 nr_reclaimed += shrink_zone(priority, zone, &sc);
1375 reclaim_state->reclaimed_slab = 0; 1422 reclaim_state->reclaimed_slab = 0;
1376 nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL, 1423 nr_slab = shrink_slab(sc.nr_scanned, GFP_KERNEL,
1377 lru_pages); 1424 lru_pages);
@@ -1688,9 +1735,11 @@ static int __devinit cpu_callback(struct notifier_block *nfb,
1688{ 1735{
1689 pg_data_t *pgdat; 1736 pg_data_t *pgdat;
1690 cpumask_t mask; 1737 cpumask_t mask;
1738 int nid;
1691 1739
1692 if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) { 1740 if (action == CPU_ONLINE || action == CPU_ONLINE_FROZEN) {
1693 for_each_online_pgdat(pgdat) { 1741 for_each_node_state(nid, N_HIGH_MEMORY) {
1742 pgdat = NODE_DATA(nid);
1694 mask = node_to_cpumask(pgdat->node_id); 1743 mask = node_to_cpumask(pgdat->node_id);
1695 if (any_online_cpu(mask) != NR_CPUS) 1744 if (any_online_cpu(mask) != NR_CPUS)
1696 /* One of our CPUs online: restore mask */ 1745 /* One of our CPUs online: restore mask */
@@ -1727,7 +1776,7 @@ static int __init kswapd_init(void)
1727 int nid; 1776 int nid;
1728 1777
1729 swap_setup(); 1778 swap_setup();
1730 for_each_online_node(nid) 1779 for_each_node_state(nid, N_HIGH_MEMORY)
1731 kswapd_run(nid); 1780 kswapd_run(nid);
1732 hotcpu_notifier(cpu_callback, 0); 1781 hotcpu_notifier(cpu_callback, 0);
1733 return 0; 1782 return 0;
@@ -1847,7 +1896,6 @@ static int __zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
1847 1896
1848int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order) 1897int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
1849{ 1898{
1850 cpumask_t mask;
1851 int node_id; 1899 int node_id;
1852 1900
1853 /* 1901 /*
@@ -1884,8 +1932,7 @@ int zone_reclaim(struct zone *zone, gfp_t gfp_mask, unsigned int order)
1884 * as wide as possible. 1932 * as wide as possible.
1885 */ 1933 */
1886 node_id = zone_to_nid(zone); 1934 node_id = zone_to_nid(zone);
1887 mask = node_to_cpumask(node_id); 1935 if (node_state(node_id, N_CPU) && node_id != numa_node_id())
1888 if (!cpus_empty(mask) && node_id != numa_node_id())
1889 return 0; 1936 return 0;
1890 return __zone_reclaim(zone, gfp_mask, order); 1937 return __zone_reclaim(zone, gfp_mask, order);
1891} 1938}
diff --git a/mm/vmstat.c b/mm/vmstat.c
index c64d169537bf..3b5e9043e7db 100644
--- a/mm/vmstat.c
+++ b/mm/vmstat.c
@@ -353,23 +353,6 @@ void refresh_cpu_vm_stats(int cpu)
353 } 353 }
354} 354}
355 355
356static void __refresh_cpu_vm_stats(void *dummy)
357{
358 refresh_cpu_vm_stats(smp_processor_id());
359}
360
361/*
362 * Consolidate all counters.
363 *
364 * Note that the result is less inaccurate but still inaccurate
365 * if concurrent processes are allowed to run.
366 */
367void refresh_vm_stats(void)
368{
369 on_each_cpu(__refresh_cpu_vm_stats, NULL, 0, 1);
370}
371EXPORT_SYMBOL(refresh_vm_stats);
372
373#endif 356#endif
374 357
375#ifdef CONFIG_NUMA 358#ifdef CONFIG_NUMA
@@ -398,6 +381,13 @@ void zone_statistics(struct zonelist *zonelist, struct zone *z)
398 381
399#include <linux/seq_file.h> 382#include <linux/seq_file.h>
400 383
384static char * const migratetype_names[MIGRATE_TYPES] = {
385 "Unmovable",
386 "Reclaimable",
387 "Movable",
388 "Reserve",
389};
390
401static void *frag_start(struct seq_file *m, loff_t *pos) 391static void *frag_start(struct seq_file *m, loff_t *pos)
402{ 392{
403 pg_data_t *pgdat; 393 pg_data_t *pgdat;
@@ -422,28 +412,144 @@ static void frag_stop(struct seq_file *m, void *arg)
422{ 412{
423} 413}
424 414
425/* 415/* Walk all the zones in a node and print using a callback */
426 * This walks the free areas for each zone. 416static void walk_zones_in_node(struct seq_file *m, pg_data_t *pgdat,
427 */ 417 void (*print)(struct seq_file *m, pg_data_t *, struct zone *))
428static int frag_show(struct seq_file *m, void *arg)
429{ 418{
430 pg_data_t *pgdat = (pg_data_t *)arg;
431 struct zone *zone; 419 struct zone *zone;
432 struct zone *node_zones = pgdat->node_zones; 420 struct zone *node_zones = pgdat->node_zones;
433 unsigned long flags; 421 unsigned long flags;
434 int order;
435 422
436 for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) { 423 for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; ++zone) {
437 if (!populated_zone(zone)) 424 if (!populated_zone(zone))
438 continue; 425 continue;
439 426
440 spin_lock_irqsave(&zone->lock, flags); 427 spin_lock_irqsave(&zone->lock, flags);
441 seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name); 428 print(m, pgdat, zone);
442 for (order = 0; order < MAX_ORDER; ++order)
443 seq_printf(m, "%6lu ", zone->free_area[order].nr_free);
444 spin_unlock_irqrestore(&zone->lock, flags); 429 spin_unlock_irqrestore(&zone->lock, flags);
430 }
431}
432
433static void frag_show_print(struct seq_file *m, pg_data_t *pgdat,
434 struct zone *zone)
435{
436 int order;
437
438 seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name);
439 for (order = 0; order < MAX_ORDER; ++order)
440 seq_printf(m, "%6lu ", zone->free_area[order].nr_free);
441 seq_putc(m, '\n');
442}
443
444/*
445 * This walks the free areas for each zone.
446 */
447static int frag_show(struct seq_file *m, void *arg)
448{
449 pg_data_t *pgdat = (pg_data_t *)arg;
450 walk_zones_in_node(m, pgdat, frag_show_print);
451 return 0;
452}
453
454static void pagetypeinfo_showfree_print(struct seq_file *m,
455 pg_data_t *pgdat, struct zone *zone)
456{
457 int order, mtype;
458
459 for (mtype = 0; mtype < MIGRATE_TYPES; mtype++) {
460 seq_printf(m, "Node %4d, zone %8s, type %12s ",
461 pgdat->node_id,
462 zone->name,
463 migratetype_names[mtype]);
464 for (order = 0; order < MAX_ORDER; ++order) {
465 unsigned long freecount = 0;
466 struct free_area *area;
467 struct list_head *curr;
468
469 area = &(zone->free_area[order]);
470
471 list_for_each(curr, &area->free_list[mtype])
472 freecount++;
473 seq_printf(m, "%6lu ", freecount);
474 }
445 seq_putc(m, '\n'); 475 seq_putc(m, '\n');
446 } 476 }
477}
478
479/* Print out the free pages at each order for each migatetype */
480static int pagetypeinfo_showfree(struct seq_file *m, void *arg)
481{
482 int order;
483 pg_data_t *pgdat = (pg_data_t *)arg;
484
485 /* Print header */
486 seq_printf(m, "%-43s ", "Free pages count per migrate type at order");
487 for (order = 0; order < MAX_ORDER; ++order)
488 seq_printf(m, "%6d ", order);
489 seq_putc(m, '\n');
490
491 walk_zones_in_node(m, pgdat, pagetypeinfo_showfree_print);
492
493 return 0;
494}
495
496static void pagetypeinfo_showblockcount_print(struct seq_file *m,
497 pg_data_t *pgdat, struct zone *zone)
498{
499 int mtype;
500 unsigned long pfn;
501 unsigned long start_pfn = zone->zone_start_pfn;
502 unsigned long end_pfn = start_pfn + zone->spanned_pages;
503 unsigned long count[MIGRATE_TYPES] = { 0, };
504
505 for (pfn = start_pfn; pfn < end_pfn; pfn += pageblock_nr_pages) {
506 struct page *page;
507
508 if (!pfn_valid(pfn))
509 continue;
510
511 page = pfn_to_page(pfn);
512 mtype = get_pageblock_migratetype(page);
513
514 count[mtype]++;
515 }
516
517 /* Print counts */
518 seq_printf(m, "Node %d, zone %8s ", pgdat->node_id, zone->name);
519 for (mtype = 0; mtype < MIGRATE_TYPES; mtype++)
520 seq_printf(m, "%12lu ", count[mtype]);
521 seq_putc(m, '\n');
522}
523
524/* Print out the free pages at each order for each migratetype */
525static int pagetypeinfo_showblockcount(struct seq_file *m, void *arg)
526{
527 int mtype;
528 pg_data_t *pgdat = (pg_data_t *)arg;
529
530 seq_printf(m, "\n%-23s", "Number of blocks type ");
531 for (mtype = 0; mtype < MIGRATE_TYPES; mtype++)
532 seq_printf(m, "%12s ", migratetype_names[mtype]);
533 seq_putc(m, '\n');
534 walk_zones_in_node(m, pgdat, pagetypeinfo_showblockcount_print);
535
536 return 0;
537}
538
539/*
540 * This prints out statistics in relation to grouping pages by mobility.
541 * It is expensive to collect so do not constantly read the file.
542 */
543static int pagetypeinfo_show(struct seq_file *m, void *arg)
544{
545 pg_data_t *pgdat = (pg_data_t *)arg;
546
547 seq_printf(m, "Page block order: %d\n", pageblock_order);
548 seq_printf(m, "Pages per block: %lu\n", pageblock_nr_pages);
549 seq_putc(m, '\n');
550 pagetypeinfo_showfree(m, pgdat);
551 pagetypeinfo_showblockcount(m, pgdat);
552
447 return 0; 553 return 0;
448} 554}
449 555
@@ -454,6 +560,13 @@ const struct seq_operations fragmentation_op = {
454 .show = frag_show, 560 .show = frag_show,
455}; 561};
456 562
563const struct seq_operations pagetypeinfo_op = {
564 .start = frag_start,
565 .next = frag_next,
566 .stop = frag_stop,
567 .show = pagetypeinfo_show,
568};
569
457#ifdef CONFIG_ZONE_DMA 570#ifdef CONFIG_ZONE_DMA
458#define TEXT_FOR_DMA(xx) xx "_dma", 571#define TEXT_FOR_DMA(xx) xx "_dma",
459#else 572#else
@@ -532,84 +645,78 @@ static const char * const vmstat_text[] = {
532#endif 645#endif
533}; 646};
534 647
535/* 648static void zoneinfo_show_print(struct seq_file *m, pg_data_t *pgdat,
536 * Output information about zones in @pgdat. 649 struct zone *zone)
537 */
538static int zoneinfo_show(struct seq_file *m, void *arg)
539{ 650{
540 pg_data_t *pgdat = arg; 651 int i;
541 struct zone *zone; 652 seq_printf(m, "Node %d, zone %8s", pgdat->node_id, zone->name);
542 struct zone *node_zones = pgdat->node_zones; 653 seq_printf(m,
543 unsigned long flags; 654 "\n pages free %lu"
544 655 "\n min %lu"
545 for (zone = node_zones; zone - node_zones < MAX_NR_ZONES; zone++) { 656 "\n low %lu"
546 int i; 657 "\n high %lu"
547 658 "\n scanned %lu (a: %lu i: %lu)"
548 if (!populated_zone(zone)) 659 "\n spanned %lu"
549 continue; 660 "\n present %lu",
550 661 zone_page_state(zone, NR_FREE_PAGES),
551 spin_lock_irqsave(&zone->lock, flags); 662 zone->pages_min,
552 seq_printf(m, "Node %d, zone %8s", pgdat->node_id, zone->name); 663 zone->pages_low,
553 seq_printf(m, 664 zone->pages_high,
554 "\n pages free %lu" 665 zone->pages_scanned,
555 "\n min %lu" 666 zone->nr_scan_active, zone->nr_scan_inactive,
556 "\n low %lu" 667 zone->spanned_pages,
557 "\n high %lu" 668 zone->present_pages);
558 "\n scanned %lu (a: %lu i: %lu)"
559 "\n spanned %lu"
560 "\n present %lu",
561 zone_page_state(zone, NR_FREE_PAGES),
562 zone->pages_min,
563 zone->pages_low,
564 zone->pages_high,
565 zone->pages_scanned,
566 zone->nr_scan_active, zone->nr_scan_inactive,
567 zone->spanned_pages,
568 zone->present_pages);
569 669
570 for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++) 670 for (i = 0; i < NR_VM_ZONE_STAT_ITEMS; i++)
571 seq_printf(m, "\n %-12s %lu", vmstat_text[i], 671 seq_printf(m, "\n %-12s %lu", vmstat_text[i],
572 zone_page_state(zone, i)); 672 zone_page_state(zone, i));
573 673
574 seq_printf(m, 674 seq_printf(m,
575 "\n protection: (%lu", 675 "\n protection: (%lu",
576 zone->lowmem_reserve[0]); 676 zone->lowmem_reserve[0]);
577 for (i = 1; i < ARRAY_SIZE(zone->lowmem_reserve); i++) 677 for (i = 1; i < ARRAY_SIZE(zone->lowmem_reserve); i++)
578 seq_printf(m, ", %lu", zone->lowmem_reserve[i]); 678 seq_printf(m, ", %lu", zone->lowmem_reserve[i]);
579 seq_printf(m, 679 seq_printf(m,
580 ")" 680 ")"
581 "\n pagesets"); 681 "\n pagesets");
582 for_each_online_cpu(i) { 682 for_each_online_cpu(i) {
583 struct per_cpu_pageset *pageset; 683 struct per_cpu_pageset *pageset;
584 int j; 684 int j;
585 685
586 pageset = zone_pcp(zone, i); 686 pageset = zone_pcp(zone, i);
587 for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) { 687 for (j = 0; j < ARRAY_SIZE(pageset->pcp); j++) {
588 seq_printf(m, 688 seq_printf(m,
589 "\n cpu: %i pcp: %i" 689 "\n cpu: %i pcp: %i"
590 "\n count: %i" 690 "\n count: %i"
591 "\n high: %i" 691 "\n high: %i"
592 "\n batch: %i", 692 "\n batch: %i",
593 i, j, 693 i, j,
594 pageset->pcp[j].count, 694 pageset->pcp[j].count,
595 pageset->pcp[j].high, 695 pageset->pcp[j].high,
596 pageset->pcp[j].batch); 696 pageset->pcp[j].batch);
597 } 697 }
598#ifdef CONFIG_SMP 698#ifdef CONFIG_SMP
599 seq_printf(m, "\n vm stats threshold: %d", 699 seq_printf(m, "\n vm stats threshold: %d",
600 pageset->stat_threshold); 700 pageset->stat_threshold);
601#endif 701#endif
602 }
603 seq_printf(m,
604 "\n all_unreclaimable: %u"
605 "\n prev_priority: %i"
606 "\n start_pfn: %lu",
607 zone->all_unreclaimable,
608 zone->prev_priority,
609 zone->zone_start_pfn);
610 spin_unlock_irqrestore(&zone->lock, flags);
611 seq_putc(m, '\n');
612 } 702 }
703 seq_printf(m,
704 "\n all_unreclaimable: %u"
705 "\n prev_priority: %i"
706 "\n start_pfn: %lu",
707 zone->all_unreclaimable,
708 zone->prev_priority,
709 zone->zone_start_pfn);
710 seq_putc(m, '\n');
711}
712
713/*
714 * Output information about zones in @pgdat.
715 */
716static int zoneinfo_show(struct seq_file *m, void *arg)
717{
718 pg_data_t *pgdat = (pg_data_t *)arg;
719 walk_zones_in_node(m, pgdat, zoneinfo_show_print);
613 return 0; 720 return 0;
614} 721}
615 722
@@ -741,7 +848,7 @@ static int __cpuinit vmstat_cpuup_callback(struct notifier_block *nfb,
741static struct notifier_block __cpuinitdata vmstat_notifier = 848static struct notifier_block __cpuinitdata vmstat_notifier =
742 { &vmstat_cpuup_callback, NULL, 0 }; 849 { &vmstat_cpuup_callback, NULL, 0 };
743 850
744int __init setup_vmstat(void) 851static int __init setup_vmstat(void)
745{ 852{
746 int cpu; 853 int cpu;
747 854
diff --git a/net/sunrpc/xprtrdma/verbs.c b/net/sunrpc/xprtrdma/verbs.c
index 9ec8ca4f6028..44b0fb942e8d 100644
--- a/net/sunrpc/xprtrdma/verbs.c
+++ b/net/sunrpc/xprtrdma/verbs.c
@@ -1263,7 +1263,8 @@ rpcrdma_register_internal(struct rpcrdma_ia *ia, void *va, int len,
1263 1263
1264 dprintk("RPC: %s: phys convert: 0x%llx " 1264 dprintk("RPC: %s: phys convert: 0x%llx "
1265 "registered 0x%llx length %d\n", 1265 "registered 0x%llx length %d\n",
1266 __func__, ipb.addr, iov->addr, len); 1266 __func__, (unsigned long long)ipb.addr,
1267 (unsigned long long)iov->addr, len);
1267 1268
1268 if (IS_ERR(mr)) { 1269 if (IS_ERR(mr)) {
1269 *mrp = NULL; 1270 *mrp = NULL;