(2006-08-06) rescue-bootcd

This commit is contained in:
2006-08-06 00:00:00 +02:00
parent 2f796b816a
commit decb062d20
21091 changed files with 7076462 additions and 0 deletions

View File

@@ -0,0 +1 @@
cmd_drivers/char/built-in.o := ld -m elf_i386 -r -o drivers/char/built-in.o drivers/char/mem.o drivers/char/random.o drivers/char/tty_io.o drivers/char/n_tty.o drivers/char/tty_ioctl.o drivers/char/pty.o drivers/char/misc.o drivers/char/vt_ioctl.o drivers/char/vc_screen.o drivers/char/consolemap.o drivers/char/consolemap_deftbl.o drivers/char/selection.o drivers/char/keyboard.o drivers/char/vt.o drivers/char/defkeymap.o drivers/char/rtc.o

View File

@@ -0,0 +1,261 @@
cmd_drivers/char/consolemap.o := gcc -Wp,-MD,drivers/char/.consolemap.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=consolemap -DKBUILD_MODNAME=consolemap -c -o drivers/char/consolemap.o drivers/char/consolemap.c
deps_drivers/char/consolemap.o := \
drivers/char/consolemap.c \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/module.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/thread_info.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/kd.h \
include/linux/mm.h \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/linux/prio_tree.h \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/err.h \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/x86/io/apic.h) \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/major.h \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
include/linux/consolemap.h \
include/linux/vt_kern.h \
$(wildcard include/config/vga/console.h) \
include/linux/vt.h \
include/linux/console_struct.h \
drivers/char/consolemap.o: $(deps_drivers/char/consolemap.o)
$(deps_drivers/char/consolemap.o):

View File

@@ -0,0 +1,21 @@
cmd_drivers/char/consolemap_deftbl.o := gcc -Wp,-MD,drivers/char/.consolemap_deftbl.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=consolemap_deftbl -DKBUILD_MODNAME=consolemap_deftbl -c -o drivers/char/consolemap_deftbl.o drivers/char/consolemap_deftbl.c
deps_drivers/char/consolemap_deftbl.o := \
drivers/char/consolemap_deftbl.c \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
drivers/char/consolemap_deftbl.o: $(deps_drivers/char/consolemap_deftbl.o)
$(deps_drivers/char/consolemap_deftbl.o):

View File

@@ -0,0 +1,79 @@
cmd_drivers/char/defkeymap.o := gcc -Wp,-MD,drivers/char/.defkeymap.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=defkeymap -DKBUILD_MODNAME=defkeymap -c -o drivers/char/defkeymap.o drivers/char/defkeymap.c
deps_drivers/char/defkeymap.o := \
drivers/char/defkeymap.c \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/keyboard.h \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/processor.h \
$(wildcard include/config/smp.h) \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/cpufeature.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/spinlock.h \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/thread_info.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/linux/stringify.h \
include/asm/current.h \
include/linux/kd.h \
drivers/char/defkeymap.o: $(deps_drivers/char/defkeymap.o)
$(deps_drivers/char/defkeymap.o):

View File

@@ -0,0 +1,296 @@
cmd_drivers/char/keyboard.o := gcc -Wp,-MD,drivers/char/.keyboard.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=keyboard -DKBUILD_MODNAME=keyboard -c -o drivers/char/keyboard.o drivers/char/keyboard.c
deps_drivers/char/keyboard.o := \
drivers/char/keyboard.c \
$(wildcard include/config/parisc.h) \
$(wildcard include/config/keyboard/hil.h) \
$(wildcard include/config/keyboard/hil/old.h) \
$(wildcard include/config/magic/sysrq.h) \
$(wildcard include/config/x86.h) \
$(wildcard include/config/ia64.h) \
$(wildcard include/config/alpha.h) \
$(wildcard include/config/mips.h) \
$(wildcard include/config/ppc.h) \
$(wildcard include/config/sparc32.h) \
$(wildcard include/config/sparc64.h) \
$(wildcard include/config/superh.h) \
$(wildcard include/config/mac/emumousebtn.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/module.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/preempt.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/thread_info.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/prio_tree.h \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/err.h \
include/linux/major.h \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
include/linux/tty_flip.h \
include/linux/mm.h \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/x86/io/apic.h) \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/linux/random.h \
include/linux/kbd_kern.h \
include/linux/interrupt.h \
$(wildcard include/config/generic/hardirqs.h) \
$(wildcard include/config/generic/irq/probe.h) \
include/linux/hardirq.h \
include/linux/smp_lock.h \
$(wildcard include/config/lock/kernel.h) \
include/asm/hardirq.h \
include/linux/irq.h \
$(wildcard include/config/arch/s390.h) \
include/asm/irq.h \
$(wildcard include/config/irqbalance.h) \
include/asm-i386/mach-default/irq_vectors.h \
include/asm-i386/mach-default/irq_vectors_limits.h \
$(wildcard include/config/pci/msi.h) \
include/asm/hw_irq.h \
include/linux/profile.h \
$(wildcard include/config/profiling.h) \
include/asm/sections.h \
include/asm-generic/sections.h \
include/linux/irq_cpustat.h \
include/linux/keyboard.h \
include/linux/kbd_diacr.h \
include/linux/kd.h \
include/linux/vt_kern.h \
$(wildcard include/config/vga/console.h) \
include/linux/vt.h \
include/linux/console_struct.h \
include/linux/sysrq.h \
include/linux/input.h \
drivers/char/keyboard.o: $(deps_drivers/char/keyboard.o)
$(deps_drivers/char/keyboard.o):

View File

@@ -0,0 +1,280 @@
cmd_drivers/char/mem.o := gcc -Wp,-MD,drivers/char/.mem.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=mem -DKBUILD_MODNAME=mem -c -o drivers/char/mem.o drivers/char/mem.c
deps_drivers/char/mem.o := \
drivers/char/mem.c \
$(wildcard include/config/ia64.h) \
$(wildcard include/config/s390/tape.h) \
$(wildcard include/config/s390/tape/char.h) \
$(wildcard include/config/ppc64.h) \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/isa.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/mm.h \
$(wildcard include/config/discontigmem.h) \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/thread_info.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/highmem4g.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/prio_tree.h \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/err.h \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/x86/io/apic.h) \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/linux/miscdevice.h \
include/linux/module.h \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/major.h \
include/linux/vmalloc.h \
include/linux/mman.h \
include/asm/mman.h \
include/linux/random.h \
include/linux/raw.h \
$(wildcard include/config/max/raw/devs.h) \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
include/linux/smp_lock.h \
$(wildcard include/config/lock/kernel.h) \
include/linux/devfs_fs_kernel.h \
$(wildcard include/config/devfs/fs.h) \
include/linux/ptrace.h \
include/linux/device.h \
include/linux/ioport.h \
include/linux/pm.h \
$(wildcard include/config/pm.h) \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
include/asm/io.h \
$(wildcard include/config/x86/ppro/fence.h) \
$(wildcard include/config/x86/numaq.h) \
include/asm-generic/iomap.h \
drivers/char/mem.o: $(deps_drivers/char/mem.o)
$(deps_drivers/char/mem.o):

View File

@@ -0,0 +1,242 @@
cmd_drivers/char/misc.o := gcc -Wp,-MD,drivers/char/.misc.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=misc -DKBUILD_MODNAME=misc -c -o drivers/char/misc.o drivers/char/misc.c
deps_drivers/char/misc.o := \
drivers/char/misc.c \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/mvme16x.h) \
$(wildcard include/config/bvme6000.h) \
$(wildcard include/config/pmac/pbook.h) \
$(wildcard include/config/toshiba.h) \
$(wildcard include/config/i8k.h) \
include/linux/module.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/thread_info.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/prio_tree.h \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/err.h \
include/linux/miscdevice.h \
include/linux/major.h \
include/linux/proc_fs.h \
$(wildcard include/config/proc/devicetree.h) \
$(wildcard include/config/proc/kcore.h) \
include/linux/seq_file.h \
include/linux/devfs_fs_kernel.h \
$(wildcard include/config/devfs/fs.h) \
include/linux/device.h \
include/linux/ioport.h \
include/linux/pm.h \
$(wildcard include/config/pm.h) \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
drivers/char/misc.o: $(deps_drivers/char/misc.o)
$(deps_drivers/char/misc.o):

View File

@@ -0,0 +1,278 @@
cmd_drivers/char/n_tty.o := gcc -Wp,-MD,drivers/char/.n_tty.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=n_tty -DKBUILD_MODNAME=n_tty -c -o drivers/char/n_tty.o drivers/char/n_tty.c
deps_drivers/char/n_tty.o := \
drivers/char/n_tty.c \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/major.h \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/signal.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/processor.h \
$(wildcard include/config/smp.h) \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/cpufeature.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/spinlock.h \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/thread_info.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/linux/stringify.h \
include/asm/signal.h \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/string.h \
include/asm/string.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/interrupt.h \
$(wildcard include/config/generic/hardirqs.h) \
$(wildcard include/config/generic/irq/probe.h) \
include/linux/hardirq.h \
include/linux/smp_lock.h \
$(wildcard include/config/lock/kernel.h) \
include/asm/hardirq.h \
include/linux/irq.h \
$(wildcard include/config/arch/s390.h) \
include/asm/irq.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/irqbalance.h) \
include/asm-i386/mach-default/irq_vectors.h \
include/asm-i386/mach-default/irq_vectors_limits.h \
$(wildcard include/config/pci/msi.h) \
$(wildcard include/config/x86/io/apic.h) \
include/asm/hw_irq.h \
include/linux/profile.h \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/profiling.h) \
include/asm/sections.h \
include/asm-generic/sections.h \
include/linux/irq_cpustat.h \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/prio_tree.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/err.h \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/linux/module.h \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
include/linux/ctype.h \
include/linux/mm.h \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/linux/poll.h \
include/asm/poll.h \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
drivers/char/n_tty.o: $(deps_drivers/char/n_tty.o)
$(deps_drivers/char/n_tty.o):

View File

@@ -0,0 +1,282 @@
cmd_drivers/char/pty.o := gcc -Wp,-MD,drivers/char/.pty.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=pty -DKBUILD_MODNAME=pty -c -o drivers/char/pty.o drivers/char/pty.c
deps_drivers/char/pty.o := \
drivers/char/pty.c \
$(wildcard include/config/unix98/ptys.h) \
$(wildcard include/config/legacy/ptys.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/module.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/thread_info.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/interrupt.h \
$(wildcard include/config/generic/hardirqs.h) \
$(wildcard include/config/generic/irq/probe.h) \
include/linux/hardirq.h \
include/linux/smp_lock.h \
$(wildcard include/config/lock/kernel.h) \
include/asm/hardirq.h \
include/linux/irq.h \
$(wildcard include/config/arch/s390.h) \
include/asm/irq.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/irqbalance.h) \
include/asm-i386/mach-default/irq_vectors.h \
include/asm-i386/mach-default/irq_vectors_limits.h \
$(wildcard include/config/pci/msi.h) \
$(wildcard include/config/x86/io/apic.h) \
include/asm/hw_irq.h \
include/linux/profile.h \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/profiling.h) \
include/asm/sections.h \
include/asm-generic/sections.h \
include/linux/irq_cpustat.h \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/prio_tree.h \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/err.h \
include/linux/major.h \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
include/linux/tty_flip.h \
include/linux/mm.h \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/linux/devfs_fs_kernel.h \
$(wildcard include/config/devfs/fs.h) \
include/linux/sysctl.h \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
include/linux/devpts_fs.h \
drivers/char/pty.o: $(deps_drivers/char/pty.o)
$(deps_drivers/char/pty.o):

View File

@@ -0,0 +1,288 @@
cmd_drivers/char/random.o := gcc -Wp,-MD,drivers/char/.random.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=random -DKBUILD_MODNAME=random -c -o drivers/char/random.o drivers/char/random.c
deps_drivers/char/random.o := \
drivers/char/random.c \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/inet.h) \
$(wildcard include/config/ipv6.h) \
$(wildcard include/config/ipv6/module.h) \
$(wildcard include/config/syn/cookies.h) \
include/linux/utsname.h \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/module.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/thread_info.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/major.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/random.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/poll.h \
include/asm/poll.h \
include/linux/mm.h \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/linux/prio_tree.h \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/err.h \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/x86/io/apic.h) \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
include/linux/genhd.h \
$(wildcard include/config/solaris/x86/partition.h) \
$(wildcard include/config/bsd/disklabel.h) \
$(wildcard include/config/unixware/disklabel.h) \
$(wildcard include/config/minix/subpartition.h) \
include/linux/device.h \
include/linux/ioport.h \
include/linux/pm.h \
$(wildcard include/config/pm.h) \
include/linux/interrupt.h \
$(wildcard include/config/generic/hardirqs.h) \
$(wildcard include/config/generic/irq/probe.h) \
include/linux/hardirq.h \
include/linux/smp_lock.h \
$(wildcard include/config/lock/kernel.h) \
include/asm/hardirq.h \
include/linux/irq.h \
$(wildcard include/config/arch/s390.h) \
include/asm/irq.h \
$(wildcard include/config/irqbalance.h) \
include/asm-i386/mach-default/irq_vectors.h \
include/asm-i386/mach-default/irq_vectors_limits.h \
$(wildcard include/config/pci/msi.h) \
include/asm/hw_irq.h \
include/linux/profile.h \
$(wildcard include/config/profiling.h) \
include/asm/sections.h \
include/asm-generic/sections.h \
include/linux/irq_cpustat.h \
include/asm/io.h \
$(wildcard include/config/x86/ppro/fence.h) \
$(wildcard include/config/x86/numaq.h) \
include/asm-generic/iomap.h \
include/linux/vmalloc.h \
include/linux/sysctl.h \
drivers/char/random.o: $(deps_drivers/char/random.o)
$(deps_drivers/char/random.o):

View File

@@ -0,0 +1,288 @@
cmd_drivers/char/rtc.o := gcc -Wp,-MD,drivers/char/.rtc.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=rtc -DKBUILD_MODNAME=rtc -c -o drivers/char/rtc.o drivers/char/rtc.c
deps_drivers/char/rtc.o := \
drivers/char/rtc.c \
$(wildcard include/config/hpet/emulate/rtc.h) \
$(wildcard include/config/hpet/rtc/irq.h) \
$(wildcard include/config/mach/decstation.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/interrupt.h \
$(wildcard include/config/generic/hardirqs.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/generic/irq/probe.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/preempt.h \
$(wildcard include/config/preempt.h) \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
$(wildcard include/config/x86/use/3dnow.h) \
include/linux/hardirq.h \
include/linux/smp_lock.h \
$(wildcard include/config/lock/kernel.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/thread_info.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/asm/hardirq.h \
include/linux/irq.h \
$(wildcard include/config/arch/s390.h) \
include/asm/irq.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/irqbalance.h) \
include/asm-i386/mach-default/irq_vectors.h \
include/asm-i386/mach-default/irq_vectors_limits.h \
$(wildcard include/config/pci/msi.h) \
$(wildcard include/config/x86/io/apic.h) \
include/asm/hw_irq.h \
include/linux/profile.h \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/profiling.h) \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/asm/sections.h \
include/asm-generic/sections.h \
include/linux/irq_cpustat.h \
include/linux/module.h \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/stat.h \
include/asm/stat.h \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/errno.h \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/miscdevice.h \
include/linux/major.h \
include/linux/ioport.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/mc146818rtc.h \
include/asm/io.h \
$(wildcard include/config/x86/ppro/fence.h) \
$(wildcard include/config/x86/numaq.h) \
include/asm-generic/iomap.h \
include/linux/vmalloc.h \
include/linux/rtc.h \
include/asm/mc146818rtc.h \
include/linux/poll.h \
include/asm/poll.h \
include/linux/mm.h \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/linux/prio_tree.h \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/err.h \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
include/linux/proc_fs.h \
$(wildcard include/config/proc/devicetree.h) \
$(wildcard include/config/proc/kcore.h) \
include/linux/sysctl.h \
include/linux/bcd.h \
include/asm/hpet.h \
$(wildcard include/config/hpet/timer.h) \
drivers/char/rtc.o: $(deps_drivers/char/rtc.o)
$(deps_drivers/char/rtc.o):

View File

@@ -0,0 +1,267 @@
cmd_drivers/char/selection.o := gcc -Wp,-MD,drivers/char/.selection.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=selection -DKBUILD_MODNAME=selection -c -o drivers/char/selection.o drivers/char/selection.c
deps_drivers/char/selection.o := \
drivers/char/selection.c \
include/linux/module.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/thread_info.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/prio_tree.h \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/err.h \
include/linux/major.h \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
include/linux/mm.h \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/x86/io/apic.h) \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
include/linux/vt_kern.h \
$(wildcard include/config/vga/console.h) \
include/linux/vt.h \
include/linux/kd.h \
include/linux/console_struct.h \
include/linux/consolemap.h \
include/linux/selection.h \
include/linux/tiocl.h \
include/linux/vt_buffer.h \
$(wildcard include/config/mda/console.h) \
include/asm/vga.h \
include/linux/console.h \
drivers/char/selection.o: $(deps_drivers/char/selection.o)
$(deps_drivers/char/selection.o):

View File

@@ -0,0 +1,308 @@
cmd_drivers/char/tty_io.o := gcc -Wp,-MD,drivers/char/.tty_io.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=tty_io -DKBUILD_MODNAME=tty_io -c -o drivers/char/tty_io.o drivers/char/tty_io.c
deps_drivers/char/tty_io.o := \
drivers/char/tty_io.c \
$(wildcard include/config/vt.h) \
$(wildcard include/config/unix98/ptys.h) \
$(wildcard include/config/early/printk.h) \
$(wildcard include/config/serial/68360.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/major.h \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/signal.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/processor.h \
$(wildcard include/config/smp.h) \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/cpufeature.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/spinlock.h \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/thread_info.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/linux/stringify.h \
include/asm/signal.h \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/string.h \
include/asm/string.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/interrupt.h \
$(wildcard include/config/generic/hardirqs.h) \
$(wildcard include/config/generic/irq/probe.h) \
include/linux/hardirq.h \
include/linux/smp_lock.h \
$(wildcard include/config/lock/kernel.h) \
include/asm/hardirq.h \
include/linux/irq.h \
$(wildcard include/config/arch/s390.h) \
include/asm/irq.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/irqbalance.h) \
include/asm-i386/mach-default/irq_vectors.h \
include/asm-i386/mach-default/irq_vectors_limits.h \
$(wildcard include/config/pci/msi.h) \
$(wildcard include/config/x86/io/apic.h) \
include/asm/hw_irq.h \
include/linux/profile.h \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/profiling.h) \
include/asm/sections.h \
include/asm-generic/sections.h \
include/linux/irq_cpustat.h \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/prio_tree.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/err.h \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/linux/module.h \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
include/linux/tty_flip.h \
include/linux/devpts_fs.h \
include/linux/file.h \
include/linux/console.h \
include/linux/ctype.h \
include/linux/kd.h \
include/linux/mm.h \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/linux/poll.h \
include/asm/poll.h \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
include/linux/proc_fs.h \
$(wildcard include/config/proc/devicetree.h) \
$(wildcard include/config/proc/kcore.h) \
include/linux/device.h \
include/linux/ioport.h \
include/linux/pm.h \
$(wildcard include/config/pm.h) \
include/linux/idr.h \
include/linux/kbd_kern.h \
include/linux/keyboard.h \
include/linux/vt_kern.h \
$(wildcard include/config/vga/console.h) \
include/linux/vt.h \
include/linux/console_struct.h \
include/linux/selection.h \
include/linux/tiocl.h \
include/linux/vt_buffer.h \
$(wildcard include/config/mda/console.h) \
include/asm/vga.h \
include/linux/devfs_fs_kernel.h \
$(wildcard include/config/devfs/fs.h) \
drivers/char/tty_io.o: $(deps_drivers/char/tty_io.o)
$(deps_drivers/char/tty_io.o):

View File

@@ -0,0 +1,260 @@
cmd_drivers/char/tty_ioctl.o := gcc -Wp,-MD,drivers/char/.tty_ioctl.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=tty_ioctl -DKBUILD_MODNAME=tty_ioctl -c -o drivers/char/tty_ioctl.o drivers/char/tty_ioctl.c
deps_drivers/char/tty_ioctl.o := \
drivers/char/tty_ioctl.c \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/asm/ioctl.h \
include/linux/module.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/thread_info.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/major.h \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/prio_tree.h \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/err.h \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
include/linux/mm.h \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/x86/io/apic.h) \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/asm/io.h \
$(wildcard include/config/x86/ppro/fence.h) \
$(wildcard include/config/x86/numaq.h) \
include/asm-generic/iomap.h \
include/linux/vmalloc.h \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
drivers/char/tty_ioctl.o: $(deps_drivers/char/tty_ioctl.o)
$(deps_drivers/char/tty_ioctl.o):

View File

@@ -0,0 +1,295 @@
cmd_drivers/char/vc_screen.o := gcc -Wp,-MD,drivers/char/.vc_screen.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=vc_screen -DKBUILD_MODNAME=vc_screen -c -o drivers/char/vc_screen.o drivers/char/vc_screen.c
deps_drivers/char/vc_screen.o := \
drivers/char/vc_screen.c \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/bitops.h \
include/asm/bitops.h \
$(wildcard include/config/smp.h) \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/major.h \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
$(wildcard include/config/security.h) \
include/linux/limits.h \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/thread_info.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/linux/stringify.h \
include/asm/current.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/rcupdate.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
$(wildcard include/config/numa.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/linux/smp.h \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/seqlock.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/time.h \
include/linux/prio_tree.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/asm/semaphore.h \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/err.h \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/linux/module.h \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
include/linux/devfs_fs_kernel.h \
$(wildcard include/config/devfs/fs.h) \
include/linux/interrupt.h \
$(wildcard include/config/generic/hardirqs.h) \
$(wildcard include/config/generic/irq/probe.h) \
include/linux/hardirq.h \
include/linux/smp_lock.h \
$(wildcard include/config/lock/kernel.h) \
include/asm/hardirq.h \
include/linux/irq.h \
$(wildcard include/config/arch/s390.h) \
include/asm/irq.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/irqbalance.h) \
include/asm-i386/mach-default/irq_vectors.h \
include/asm-i386/mach-default/irq_vectors_limits.h \
$(wildcard include/config/pci/msi.h) \
$(wildcard include/config/x86/io/apic.h) \
include/asm/hw_irq.h \
include/linux/profile.h \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/profiling.h) \
include/asm/sections.h \
include/asm-generic/sections.h \
include/linux/irq_cpustat.h \
include/linux/mm.h \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/linux/vt_kern.h \
$(wildcard include/config/vga/console.h) \
include/linux/vt.h \
include/linux/kd.h \
include/linux/console_struct.h \
include/linux/selection.h \
include/linux/tiocl.h \
include/linux/vt_buffer.h \
$(wildcard include/config/mda/console.h) \
include/asm/vga.h \
include/linux/kbd_kern.h \
include/linux/keyboard.h \
include/linux/console.h \
include/linux/device.h \
include/linux/ioport.h \
include/linux/pm.h \
$(wildcard include/config/pm.h) \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
include/asm/unaligned.h \
drivers/char/vc_screen.o: $(deps_drivers/char/vc_screen.o)
$(deps_drivers/char/vc_screen.o):

View File

@@ -0,0 +1,309 @@
cmd_drivers/char/vt.o := gcc -Wp,-MD,drivers/char/.vt.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=vt -DKBUILD_MODNAME=vt -c -o drivers/char/vt.o drivers/char/vt.c
deps_drivers/char/vt.o := \
drivers/char/vt.c \
$(wildcard include/config/prom/console.h) \
$(wildcard include/config/mda/console.h) \
$(wildcard include/config/vt/console.h) \
include/linux/module.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/thread_info.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/prio_tree.h \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/err.h \
include/linux/major.h \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
include/linux/tty_flip.h \
include/linux/kd.h \
include/linux/mm.h \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/x86/io/apic.h) \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/linux/console.h \
include/linux/devfs_fs_kernel.h \
$(wildcard include/config/devfs/fs.h) \
include/linux/vt_kern.h \
$(wildcard include/config/vga/console.h) \
include/linux/vt.h \
include/linux/console_struct.h \
include/linux/selection.h \
include/linux/tiocl.h \
include/linux/vt_buffer.h \
include/asm/vga.h \
include/linux/kbd_kern.h \
include/linux/interrupt.h \
$(wildcard include/config/generic/hardirqs.h) \
$(wildcard include/config/generic/irq/probe.h) \
include/linux/hardirq.h \
include/linux/smp_lock.h \
$(wildcard include/config/lock/kernel.h) \
include/asm/hardirq.h \
include/linux/irq.h \
$(wildcard include/config/arch/s390.h) \
include/asm/irq.h \
$(wildcard include/config/irqbalance.h) \
include/asm-i386/mach-default/irq_vectors.h \
include/asm-i386/mach-default/irq_vectors_limits.h \
$(wildcard include/config/pci/msi.h) \
include/asm/hw_irq.h \
include/linux/profile.h \
$(wildcard include/config/profiling.h) \
include/asm/sections.h \
include/asm-generic/sections.h \
include/linux/irq_cpustat.h \
include/linux/keyboard.h \
include/linux/consolemap.h \
include/linux/bootmem.h \
$(wildcard include/config/have/arch/bootmem/node.h) \
include/asm/dma.h \
$(wildcard include/config/pci.h) \
include/asm/io.h \
$(wildcard include/config/x86/ppro/fence.h) \
$(wildcard include/config/x86/numaq.h) \
include/asm-generic/iomap.h \
include/linux/vmalloc.h \
include/linux/delay.h \
include/asm/delay.h \
include/linux/pm.h \
$(wildcard include/config/pm.h) \
include/linux/font.h \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
drivers/char/console_macros.h \
drivers/char/vt.o: $(deps_drivers/char/vt.o)
$(deps_drivers/char/vt.o):

View File

@@ -0,0 +1,299 @@
cmd_drivers/char/vt_ioctl.o := gcc -Wp,-MD,drivers/char/.vt_ioctl.o.d -nostdinc -iwithprefix include -D__KERNEL__ -Iinclude -Wall -Wstrict-prototypes -Wno-trigraphs -fno-strict-aliasing -fno-common -O2 -fomit-frame-pointer -pipe -msoft-float -mpreferred-stack-boundary=2 -fno-unit-at-a-time -march=pentium-mmx -Iinclude/asm-i386/mach-default -Wdeclaration-after-statement -DKBUILD_BASENAME=vt_ioctl -DKBUILD_MODNAME=vt_ioctl -c -o drivers/char/vt_ioctl.o drivers/char/vt_ioctl.c
deps_drivers/char/vt_ioctl.o := \
drivers/char/vt_ioctl.c \
$(wildcard include/config/x86.h) \
include/linux/config.h \
$(wildcard include/config/h.h) \
include/linux/types.h \
$(wildcard include/config/uid16.h) \
include/linux/posix_types.h \
include/linux/stddef.h \
include/linux/compiler.h \
include/linux/compiler-gcc3.h \
include/linux/compiler-gcc.h \
include/asm/posix_types.h \
include/asm/types.h \
$(wildcard include/config/highmem64g.h) \
$(wildcard include/config/lbd.h) \
include/linux/errno.h \
include/asm/errno.h \
include/asm-generic/errno.h \
include/asm-generic/errno-base.h \
include/linux/sched.h \
$(wildcard include/config/keys.h) \
$(wildcard include/config/schedstats.h) \
$(wildcard include/config/smp.h) \
$(wildcard include/config/numa.h) \
$(wildcard include/config/security.h) \
$(wildcard include/config/preempt.h) \
$(wildcard include/config/magic/sysrq.h) \
include/asm/param.h \
include/linux/capability.h \
include/linux/spinlock.h \
$(wildcard include/config/debug/spinlock.h) \
$(wildcard include/config/lockmeter.h) \
include/linux/preempt.h \
include/linux/linkage.h \
include/asm/linkage.h \
$(wildcard include/config/regparm.h) \
$(wildcard include/config/x86/alignment/16.h) \
include/linux/thread_info.h \
include/linux/bitops.h \
include/asm/bitops.h \
include/asm/thread_info.h \
$(wildcard include/config/4kstacks.h) \
$(wildcard include/config/debug/stack/usage.h) \
include/asm/page.h \
$(wildcard include/config/x86/use/3dnow.h) \
$(wildcard include/config/x86/pae.h) \
$(wildcard include/config/hugetlb/page.h) \
$(wildcard include/config/highmem4g.h) \
$(wildcard include/config/discontigmem.h) \
include/asm/processor.h \
$(wildcard include/config/mk8.h) \
$(wildcard include/config/mk7.h) \
include/asm/vm86.h \
include/asm/math_emu.h \
include/asm/sigcontext.h \
include/asm/segment.h \
include/asm/cpufeature.h \
include/asm/msr.h \
include/asm/system.h \
$(wildcard include/config/x86/cmpxchg.h) \
$(wildcard include/config/x86/oostore.h) \
include/linux/kernel.h \
$(wildcard include/config/debug/spinlock/sleep.h) \
/usr/lib/gcc/i686-pc-linux-gnu/3.4.1/include/stdarg.h \
include/asm/byteorder.h \
$(wildcard include/config/x86/bswap.h) \
include/linux/byteorder/little_endian.h \
include/linux/byteorder/swab.h \
include/linux/byteorder/generic.h \
include/asm/bug.h \
include/asm-generic/bug.h \
include/linux/cache.h \
include/asm/cache.h \
$(wildcard include/config/x86/l1/cache/shift.h) \
include/linux/threads.h \
$(wildcard include/config/nr/cpus.h) \
include/asm/percpu.h \
include/asm-generic/percpu.h \
include/linux/stringify.h \
include/linux/timex.h \
$(wildcard include/config/time/interpolation.h) \
include/linux/time.h \
include/linux/seqlock.h \
include/asm/timex.h \
$(wildcard include/config/x86/elan.h) \
$(wildcard include/config/x86/tsc.h) \
$(wildcard include/config/x86/generic.h) \
include/linux/jiffies.h \
include/asm/div64.h \
include/linux/rbtree.h \
include/linux/cpumask.h \
$(wildcard include/config/hotplug/cpu.h) \
include/linux/bitmap.h \
include/linux/string.h \
include/asm/string.h \
include/asm/semaphore.h \
include/asm/atomic.h \
$(wildcard include/config/m386.h) \
include/linux/wait.h \
include/linux/list.h \
include/linux/prefetch.h \
include/asm/current.h \
include/linux/rwsem.h \
$(wildcard include/config/rwsem/generic/spinlock.h) \
include/asm/rwsem.h \
include/asm/ptrace.h \
$(wildcard include/config/frame/pointer.h) \
include/asm/mmu.h \
include/linux/smp.h \
include/linux/sem.h \
$(wildcard include/config/sysvipc.h) \
include/linux/ipc.h \
include/asm/ipcbuf.h \
include/asm/sembuf.h \
include/linux/signal.h \
include/asm/signal.h \
include/asm/siginfo.h \
include/asm-generic/siginfo.h \
include/linux/resource.h \
include/asm/resource.h \
include/linux/securebits.h \
include/linux/fs_struct.h \
include/linux/completion.h \
include/linux/pid.h \
include/linux/percpu.h \
include/linux/slab.h \
$(wildcard include/config/.h) \
include/linux/gfp.h \
include/linux/mmzone.h \
$(wildcard include/config/force/max/zoneorder.h) \
include/linux/numa.h \
include/linux/topology.h \
$(wildcard include/config/sched/smt.h) \
include/asm/topology.h \
include/asm-generic/topology.h \
include/linux/init.h \
$(wildcard include/config/modules.h) \
$(wildcard include/config/hotplug.h) \
include/linux/kmalloc_sizes.h \
$(wildcard include/config/mmu.h) \
$(wildcard include/config/large/allocs.h) \
include/linux/param.h \
include/linux/timer.h \
include/linux/aio.h \
include/linux/workqueue.h \
include/linux/aio_abi.h \
include/linux/tty.h \
$(wildcard include/config/legacy/pty/count.h) \
include/linux/fs.h \
$(wildcard include/config/dnotify.h) \
$(wildcard include/config/quota.h) \
$(wildcard include/config/epoll.h) \
$(wildcard include/config/auditsyscall.h) \
include/linux/limits.h \
include/linux/kdev_t.h \
include/linux/ioctl.h \
include/asm/ioctl.h \
include/linux/dcache.h \
include/linux/rcupdate.h \
include/linux/stat.h \
include/asm/stat.h \
include/linux/prio_tree.h \
include/linux/kobject.h \
include/linux/sysfs.h \
$(wildcard include/config/sysfs.h) \
include/linux/kref.h \
include/linux/kobject_uevent.h \
$(wildcard include/config/kobject/uevent.h) \
include/linux/radix-tree.h \
include/linux/audit.h \
$(wildcard include/config/audit.h) \
include/linux/quota.h \
include/linux/dqblk_xfs.h \
include/linux/dqblk_v1.h \
include/linux/dqblk_v2.h \
include/linux/nfs_fs_i.h \
include/linux/nfs.h \
include/linux/sunrpc/msg_prot.h \
include/linux/fcntl.h \
include/asm/fcntl.h \
include/linux/err.h \
include/linux/major.h \
include/linux/termios.h \
include/asm/termios.h \
include/asm/termbits.h \
include/asm/ioctls.h \
include/linux/module.h \
$(wildcard include/config/modversions.h) \
$(wildcard include/config/module/unload.h) \
$(wildcard include/config/kallsyms.h) \
include/linux/kmod.h \
$(wildcard include/config/kmod.h) \
include/linux/elf.h \
include/asm/elf.h \
include/asm/user.h \
include/linux/utsname.h \
include/linux/moduleparam.h \
include/asm/local.h \
include/asm/module.h \
$(wildcard include/config/m486.h) \
$(wildcard include/config/m586.h) \
$(wildcard include/config/m586tsc.h) \
$(wildcard include/config/m586mmx.h) \
$(wildcard include/config/m686.h) \
$(wildcard include/config/mpentiumii.h) \
$(wildcard include/config/mpentiumiii.h) \
$(wildcard include/config/mpentiumm.h) \
$(wildcard include/config/mpentium4.h) \
$(wildcard include/config/mk6.h) \
$(wildcard include/config/mcrusoe.h) \
$(wildcard include/config/mefficeon.h) \
$(wildcard include/config/mwinchipc6.h) \
$(wildcard include/config/mwinchip2.h) \
$(wildcard include/config/mwinchip3d.h) \
$(wildcard include/config/mcyrixiii.h) \
$(wildcard include/config/mviac3/2.h) \
include/linux/tty_driver.h \
include/linux/cdev.h \
include/linux/tty_ldisc.h \
include/linux/kd.h \
include/linux/vt.h \
include/linux/console.h \
include/asm/io.h \
$(wildcard include/config/x86/ppro/fence.h) \
$(wildcard include/config/x86/numaq.h) \
include/asm-generic/iomap.h \
include/linux/vmalloc.h \
include/asm/uaccess.h \
$(wildcard include/config/x86/intel/usercopy.h) \
$(wildcard include/config/x86/wp/works/ok.h) \
include/linux/kbd_kern.h \
include/linux/interrupt.h \
$(wildcard include/config/generic/hardirqs.h) \
$(wildcard include/config/generic/irq/probe.h) \
include/linux/hardirq.h \
include/linux/smp_lock.h \
$(wildcard include/config/lock/kernel.h) \
include/asm/hardirq.h \
include/linux/irq.h \
$(wildcard include/config/arch/s390.h) \
include/asm/irq.h \
$(wildcard include/config/x86/local/apic.h) \
$(wildcard include/config/irqbalance.h) \
include/asm-i386/mach-default/irq_vectors.h \
include/asm-i386/mach-default/irq_vectors_limits.h \
$(wildcard include/config/pci/msi.h) \
$(wildcard include/config/x86/io/apic.h) \
include/asm/hw_irq.h \
include/linux/profile.h \
$(wildcard include/config/proc/fs.h) \
$(wildcard include/config/profiling.h) \
include/asm/sections.h \
include/asm-generic/sections.h \
include/linux/irq_cpustat.h \
include/linux/keyboard.h \
include/linux/vt_kern.h \
$(wildcard include/config/vga/console.h) \
include/linux/console_struct.h \
include/linux/mm.h \
$(wildcard include/config/sysctl.h) \
$(wildcard include/config/stack/growsup.h) \
$(wildcard include/config/highmem.h) \
$(wildcard include/config/shmem.h) \
$(wildcard include/config/debug/pagealloc.h) \
$(wildcard include/config/arch/gate/area.h) \
include/asm/pgtable.h \
$(wildcard include/config/highpte.h) \
include/asm/fixmap.h \
$(wildcard include/config/x86/visws/apic.h) \
$(wildcard include/config/x86/f00f/bug.h) \
$(wildcard include/config/x86/cyclone/timer.h) \
$(wildcard include/config/acpi/boot.h) \
$(wildcard include/config/pci/mmconfig.h) \
include/asm/acpi.h \
$(wildcard include/config/acpi/pci.h) \
$(wildcard include/config/acpi/sleep.h) \
include/asm/apicdef.h \
include/asm/pgtable-2level-defs.h \
include/asm/pgtable-2level.h \
include/asm-generic/pgtable.h \
include/linux/page-flags.h \
$(wildcard include/config/swap.h) \
include/linux/kbd_diacr.h \
include/linux/selection.h \
include/linux/tiocl.h \
include/linux/vt_buffer.h \
$(wildcard include/config/mda/console.h) \
include/asm/vga.h \
include/linux/syscalls.h \
$(wildcard include/config/ia64.h) \
$(wildcard include/config/v850.h) \
include/linux/key.h \
drivers/char/vt_ioctl.o: $(deps_drivers/char/vt_ioctl.o)
$(deps_drivers/char/vt_ioctl.o):

View File

@@ -0,0 +1,775 @@
2001-08-11 Tim Waugh <twaugh@redhat.com>
* serial.c (get_pci_port): Deal with awkward Titan cards.
1998-08-26 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c (rs_open): Correctly decrement the module in-use count
on errors.
Thu Feb 19 14:24:08 1998 Theodore Ts'o <tytso@rsts-11.mit.edu>
* tty_io.c (tty_name): Remove the non-reentrant (and non-SMP safe)
version of tty_name, and rename the reentrant _tty_name
function to be tty_name.
(tty_open): Add a warning message stating callout devices
are deprecated.
Mon Dec 1 08:24:15 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
* tty_io.c (tty_get_baud_rate): Print a warning syslog if the
tty->alt_speed kludge is used; this means the system is
using the deprecated SPD_HI ioctls.
Mon Nov 24 10:37:49 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c, esp.c, rocket.c: Change drivers to take advantage of
tty_get_baud_rate().
* tty_io.c (tty_get_baud_rate): New function which computes the
correct baud rate for the tty. More factoring out of
common code out of the serial driver to the high-level tty
functions....
Sat Nov 22 07:53:36 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c, esp.c, rocket.c: Add tty->driver.break() routine, and
allow high-level tty code to handle the break and soft
carrier ioctls.
* tty_ioctl.c (n_tty_ioctl): Support TIOCGSOFTCAR and
TIOCSSOFTCAR, so that device drivers don't have to support
it.
* serial.c (autoconfig): Change 16750 test to hopefully eliminate
false results by people with strange 16550As being
detected as 16750s. Hopefully 16750s will still be
detected as 16750, and other weird UARTs won't get poorly
autodetected. If this doesn't work, I'll have to disable
the auto identification for the 16750.
* tty_io.c (tty_hangup): Now actually do the tty hangup
processing during the timer processing, and disable
interrupts while doing the hangup processing. This avoids
several nasty race conditions which happened when the
hangup processing was done asynchronously.
(tty_ioctl): Do break handling in the tty driver if
driver's break function is supported.
(tty_flip_buffer_push): New exported function which should
be used by drivers to push characters in the flip buffer
to the tty handler. This may either be done using a task
queue function for better CPU efficiency, or directly for
low latency operation.
* serial.c (rs_set_termios): Fix bug rs_set_termios when
transitioning away from B0, submitted by Stanislav
Voronyi.
Thu Jun 19 20:05:58 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c (begin_break, end_break, rs_ioctl): Applied patch
to support BSD ioctls to set and clear the break
condition explicitly.
* console.c (scrup, scrdown, insert_line, delete_line): Applied
fix suggested by Aaron Tiensivu to speed up block scrolls
up and down.
* n_tty.c (opost_block, write_chan): Added a modified "fast
console" patch which processes a block of text via
"cooking" efficiently.
Wed Jun 18 15:25:50 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
* tty_io.c (init_dev, release_dev): Applied fix suggested by Bill
Hawes to prevent race conditions in the tty code.
* n_tty.c (n_tty_chars_in_buffer): Applied fix suggested by Bill
Hawes so that n_tty_chars_in_buffer returns the correct
value in the case when the tty is in cannonical mode. (To
avoid a pty deadlock with telnetd.)
Thu Feb 27 01:53:08 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c (change_speed): Add support for the termios flag
CMSPAR, which allows the user to select stick parity.
(i.e, if PARODD is set, the parity bit is always 1; if
PARRODD is not set, then the parity bit is always 0).
Wed Feb 26 19:03:10 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c (cleanup_module): Fix memory leak when using the serial
driver as a module; make sure tmp_buf gets freed!
Tue Feb 25 11:01:59 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c (set_modem_info): Add support for setting and clearing
the OUT1 and OUT2 bits. (For special case UART's, usually
for half-duplex.)
(autoconfig, change_speed): Fix TI 16750 support.
Sun Feb 16 00:14:43 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
* tty_io.c (release_dev): Add sanity check to make sure there are
no waiters on tty->read_wait or tty->write_wait.
* serial.c (rs_init): Don't autoconfig a device if the I/O region
is already reserved.
* serial.c (serial_proc_info): Add support for /proc/serial.
Thu Feb 13 00:49:10 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c (receive_chars): When the UART repotrs an overrun
condition, it does so with a valid character. Changed to
not throw away the valid character, but instead report the
overrun after the valid character.
* serial.c: Added new #ifdef's for some of the advanced serial
driver features. A minimal driver that only supports COM
1/2/3/4 without sharing serial interrupts only takes 17k;
the full driver takes 32k.
Wed Feb 12 14:50:44 1997 Theodore Ts'o <tytso@rsts-11.mit.edu>
* vt.c:
* pty.c:
* tty_ioctl.c:
* serial.c: Update routines to use the new 2.1 memory access
routines.
Wed Dec 4 07:51:52 1996 Theodore Ts'o <tytso@localhost.mit.edu>
* serial.c (change_speed): Use save_flags(); cli() and
restore_flags() in order to ensure we don't accidentally
turn on interrupts when starting up the port.
(startup): Move the insertion of serial structure into the
IRQ chain earlier into the startup processing. Interrupts
should be off this whole time, but we eventually will want
to reduce this window.
Thu Nov 21 10:05:22 1996 Theodore Ts'o <tytso@localhost.mit.edu>
* tty_ioctl.c (tty_wait_until_sent): Always check the driver
wait_until_ready routine, even if there are no characters
in the xmit buffer. (There may be charactes in the device
FIFO.)
(n_tty_ioctl): Add new flag tty->flow_stopped which
indicates whether the tty is stopped due to a request by
the TCXONC ioctl (used by tcflow). If so, don't let an
incoming XOFF character restart the tty. The tty can only
be restarted by another TCXONC request.
* tty_io.c (start_tty): Don't allow the tty to be restarted if
tty->flow_stopped is true.
* n_tty.c (n_tty_receive_char): If tty->flow_stopped is true, and
IXANY is set, don't eat a character trying to restart the
tty.
* serial.c (startup): Remove need for MCR_noint from the
async_struct structure. Only turn on DTR and RTS if the
baud rate is not zero.
(change_speed): More accurately calculate the timeout
value based on the word size. Move responsibility of
hangup when speed becomes B0 to rs_set_termios()
(set_serial_info): When changing the UART type set the
current xmit_fifo_size as well as the permanent
xmit_fifo_size.
(rs_ioctl): Fix TCSBRK (used by tcdrain) and TCSBRKP
ioctls to return EINTR if interrupted by a signal.
(rs_set_termios): If the baud rate changes to or from B0,
this function is now responsible for setting or clearing
DTR and RTS. DTR and RTS are only be changed on the
transition to or from the B0 state.
(rs_close): Wait for the characters to drain based on
info->timeout. At low baud rates (50 bps), it may take a
long time for the FIFO to completely drain out!
(rs_wait_until_sent): Fixed timeout handling. Now
releases control to the scheduler, but checks frequently
enough so that the function is sensitive enough to pass
the timing requirements of the NIST-PCTS.
(block_til_ready): When opening the device, don't turn on
DTR and RTS if the baud rate is B0.
Thu Nov 14 00:06:09 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c (autoconfig): Fix autoconfiguration problems;
info->flags wasn't getting initialized from the state
structure. Put in more paranoid test for the 16750.
Fri Nov 8 20:19:50 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* n_tty.c (n_tty_flush_buffer): Only call driver->unthrottle() if
the tty was previous throttled.
(n_tty_set_termios, write_chan): Add changes suggested by
Simon P. Allen to allow hardware cooking.
* tty_ioctl.c (set_termios): If we get a signal while waiting for
the tty to drain, return -EINTR.
* serial.c (change_speed): Add support for CREAD, as required by
POSIX.
Sat Nov 2 20:43:10 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* serial.c: Wholesale changes. Added support for the Startech
16650 and 16650V2 chips. (WARNING: the new startech
16650A may or may not work!) Added support for the
TI16750 (not yet tested). Split async_struct into a
transient part (async_struct) and a permanent part
(serial_state) which contains the configuration
information for the ports. Added new driver routines
wait_until_sent() and send_xchar() to help with POSIX
compliance. Added support for radio clocks which waggle
the carrier detect line (CONFIG_HARD_PPS).
* tty_ioctl.c (tty_wait_until_sent): Added call to new driver
function tty->driver.wait_until_sent(), which returns when
the tty's device xmit buffers are drained. Needed for
full POSIX compliance.
(send_prio_char): New function, called by the ioctl's
TCIOFF and TCION; uses the new driver call send_xchar(),
which will send the XON or XOFF character at high priority
(and even if tty output is stopped).
Wed Jun 5 18:52:04 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* pty.c (pty_close): When closing a pty, make sure packet mode is
cleared.
Sun May 26 09:33:52 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* vesa_blank.c (set_vesa_blanking): Add missing verify_area() call.
* selection.c (set_selection): Add missing verify_area() call.
* tty_io.c (tty_ioctl): Add missing verify_area() calls.
* serial.c (rs_ioctl): Add missing verify_area() calls.
(rs_init): Allow initialization of serial driver
configuration from a module.
* random.c (extract_entropy): Add missing verify_area call.
Don't limit number of characters returned to
32,768. Extract entropy is now no longer a inlined
function.
(random_read): Check return value in case extract_entropy
returns an error.
(secure_tcp_sequence_number): New function which returns a
secure TCP sequence number. This is needed to prevent some
nasty TCP hijacking attacks.
(init_std_data): Initialize using gettimeofday() instead of
struct timeval xtime.
(fast_add_entropy_word, add_entropy_word): Rename the
inline function add_entropy_word() to
fast_add_entropy_word(). Make add_entropy_word() be the
non-inlined function which is used in non-timing critical
places, in order to save space.
(initialize_benchmark, begin_benchmark, end_benchmark): New
functions defined when RANDOM_BENCHMARK is defined. They
allow us to benchmark the speed of the
add_timer_randomness() call.
(int_ln, rotate_left): Add two new inline functions with
i386 optimized asm instructions. This speeds up the
critical add_entropy_word() and add_timer_randomness()
functions, which are called from interrupt handlers.
Tue May 7 22:51:11 1996 <tytso@rsts-11.mit.edu>
* random.c (add_timer_randomness): Limit the amount randomness
that we estimate to 12 bits. (An arbitrary amount).
(extract_entropy): To make it harder to analyze the hash
function, fold the hash function in half using XOR, and
use the folded result as the value to emit to the user.
Also, add timer randomness each pass through the
exact_entropy call, to increase the amount of unknown
values during the extraction process.
(random_ioctl): Use IOR/IOW definitions to define the
ioctl values used by the /dev/random driver. Allow the
old ioctl values to be used for backwards compatibility
(for a limited amount of time).
Wed Apr 24 14:02:04 1996 Theodore Ts'o <tytso@rsts-11.mit.edu>
* random.c (add_timer_randomness): Use 2nd derivative as well to
better estimate entropy.
(rand_initialize): Explicitly initialize all the pointers
to NULL. (Clearing pointers using memset isn't portable.)
Initialize the random pool with OS-dependent data.
(random_write): Add sanity checking to the arguments to
random_write(), so that bad arguments won't cause a kernel
SEGV.
(random_read): Update the access time of the device inode
when you return data to the user.
(random_ioctl): Wake up the random_wait channel when there
are only WAIT_INPUT_BITS available. Add more paranoia
checks to make sure entropy_count doesn't go beyond the
bounds of (0, POOLSIZE). Add a few missing verify_area
checks. Add support for the RNDCLEARPOOL ioctl, which
zaps the random pool.
(add_timer_randomness): Wake up the random_wait
channel only when there are WAIT_INPUT_BITS available.
(random_select): Allow a random refresh daemon process to
select on /dev/random for writing; wake up the daemon when
there are less than WAIT_OUTPUT_BITS bits of randomness
available.
Tue Apr 23 22:56:07 1996 <tytso@rsts-11.mit.edu>
* tty_io.c (init_dev): Change return code when user attempts to
open master pty which is already open from EAGAIN to EIO,
to match with BSD expectations. EIO is more correct
anyway, since EAGAIN implies that retrying will be
successful --- which it might be.... Eventually!!
* pty.c (pty_open, pty_close): Fix wait loop so that we don't
busy loop while waiting for the master side to open.
Fix tty opening/closing logic. TTY_SLAVE_CLOSED was
renamed to TTY_OTHER_CLOSED, so that the name is more
descriptive. Also fixed code so that the tty flag
actually works correctly now....
Mon Apr 1 10:22:01 1996 <tytso@rsts-11.mit.edu>
* serial.c (rs_close): Cleaned up modularization changes.
Remove code which forced line discipline back to N_TTY
this is done in the tty upper layers, and there's no
reason to do it here. (Making this change also
removed the requirement that the serial module access
the internal kernel symbol "ldiscs".)
* tty_io.c (tty_init): Formally register a tty_driver entry for
/dev/tty (device 4, 0) and /dev/console (device 5, 0).
This guarantees that major device numbers 4 and 5 will be
reserved for the tty subsystem (as they have to be because
of /dev/tty and /dev/console). Removed tty_regdev, as
this interface is no longer necessary.
Sun Mar 17 20:42:47 GMT 1996 <ah@doc.ic.ac.uk>
* serial.c : modularisation (changes in linux/fs/device.c allow
kerneld to automatically load the serial module).
* Makefile, Config.in : serial modularisation adds.
* tty_io.c : tty_init_ctty used by to register "cua" driver just
for the /dev/tty device (5,0). Added tty_regdev.
* serial.c (shutdown, rs_ioctl) : when port shuts down wakeup processes
waiting on delta_msr_wait. The TIOCMIWAIT ioctl returns EIO
if no change was done since the time of call.
Sat Mar 16 14:33:13 1996 <aeb@cwi.nl>
* tty_io.c (disassociate_ctty): If disassociate_ctty is called by
exit, do not perform an implicit vhangup on a pty.
Fri Feb 9 14:15:47 1996 <tytso@rsts-11.mit.edu>
* serial.c (block_til_ready): Fixed another race condition which
happens if a hangup happens during the open.
Wed Jan 10 10:08:00 1996 <tytso@rsts-11.mit.edu>
* serial.c (block_til_ready): Remove race condition which happened
if a hangup condition happened during the setup of the
UART, before rs_open() called block_til_ready(). This
caused the info->count counter to be erroneously
decremented.
* serial.c (startup, rs_open): Remove race condition that could
cause a memory leak of one page. (Fortunately, both race
conditions were relatively rare in practice.)
Tue Dec 5 13:21:27 1995 <tytso@rsts-11.mit.edu>
* serial.c (check_modem_status, rs_ioctl): Support the new
ioctl()'s TIOCGICOUNT, TIOCMIWAIT. These allow an
application program to wait on a modem serial register
status bit change, and to find out how many changes have
taken place for the MSR bits.
(rs_write): Eliminate a race condition which is introduced
if it is necessary to wait for the semaphore.
Sat Nov 4 17:14:45 1995 <tytso@rsts-11.mit.edu>
* tty_io.c (tty_init): Move registration of TTY_MAJOR and
TTY_AUX_MAJOR to the end, so that /proc/devices looks
prettier.
* pty.c (pty_init): Use new major numbers for PTY master and slave
devices. This allow us to have more than 64 pty's. We
register the old pty devices for backwards compatibility.
Note that a system should either be using the old pty
devices or the new pty devices --- in general, it should
try to use both, since they map into the same pty table.
The old pty devices are strictly for backwards compatibility.
Wed Oct 11 12:45:24 1995 <tytso@rsts-11.mit.edu>
* tty_io.c (disassociate_ctty): If disassociate_ctty is called by
exit, perform an implicit vhangup on the tty.
* pty.c (pty_close): When the master pty is closed, send a hangup
to the slave pty.
(pty_open): Use the flag TTY_SLAVE_CLOSED to test to see
if there are any open slave ptys, instead of using
tty->link->count. The old method got confused if there
were processes that had hung-up file descriptors on the
slave tty.
Tue May 2 00:53:25 1995 <tytso@rsx-11.mit.edu>
* tty_io.c (tty_set_ldisc): Wait until the output buffer is
drained before closing the old line discipline --- needed
in only one case: XON/XOFF processing.
* n_tty.c (n_tty_close): Don't bother waiting until the output
driver is closed; in general, the line discipline
shouldn't care if the hardware is finished
transmitting before the line discipline terminates.
* tty_io.c (release_dev): Shutdown the line discipline after
decrementing the tty count variable; but set the
TTY_CLOSING flag so that we know that this tty structure
isn't long for this world.
* tty_io.c (init_dev): Add sanity code to check to see if
TTY_CLOSING is set on a tty structure; if so, something
bad has happened (probably a line discipline close blocked
when it shouldn't have; so do a kernel printk and then
return an error).
Wed Apr 26 10:23:44 1995 Theodore Y. Ts'o <tytso@localhost>
* tty_io.c (release_dev): Try to shutdown the line discipline
*before* decrementing the tty count variable; this removes
a potential race condition which occurs when the line
discipline close blocks, and another process then tries
open the same serial port.
* serial.c (rs_hangup): When hanging up, flush the output buffer
before shutting down the UART. Otherwise the line
discipline close blocks waiting for the characters to get
flushed, which never happens until the serial port gets reused.
Wed Apr 12 08:06:16 1995 Theodore Y. Ts'o <tytso@localhost>
* serial.c (do_serial_hangup, do_softint, check_modem_status,
rs_init): Hangups are now scheduled via a separate tqueue
structure in the async_struct structure, tqueue_hangup.
This task is pushed on to the tq_schedule queue, so that
it is processed synchronously by the scheduler.
Sat Feb 18 12:13:51 1995 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (disassociate_ctty, tty_open, tty_ioctl): Clear
current->tty_old_pgrp field when a session leader
acquires a controlling tty, and after a session leader
has disassociated from a controlling tty.
Fri Feb 17 09:34:09 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_interrupt_single, rs_interrupt, rs_interrupt_multi):
Change the number of passes made from 64 to be 256,
configurable with the #define RS_ISR_PASS_LIMIT.
* serial.c (rs_init, set_serial_info, get_serial_info, rs_close):
Remove support for closing_wait2. Instead, set
tty->closing and rely on the line discipline to prevent
echo wars.
* n_tty.c (n_tty_receive_char): IEXTEN does not need to be
enabled in order for IXANY to be active.
If tty->closing is set, then only process XON and XOFF
characters.
Sun Feb 12 23:57:48 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_timer): Change the interrupt poll time from 60
seconds to 10 seconds, configurable with the #define
RS_STROBE_TIME.
* serial.c (rs_interrupt_multi, startup, shutdown, rs_ioctl,
set_multiport_struct, get_multiport_struct): Add
provisions for a new type of interrupt service routine,
which better supports multiple serial ports on a single
IRQ.
Sun Feb 5 19:35:11 1995 Theodore Y. Ts'o (tytso@rt-11)
* tty_ioctl.c (n_tty_ioctl, set_termios, tty_wait_until_sent):
* serial.c (rs_ioctl, rs_close):
* cyclades.c (cy_ioctl, cy_close):
* n_tty.c (n_tty_close): Rename wait_until_sent to
tty_wait_until_sent, so that it's a better name to export
in ksyms.c.
Sat Feb 4 23:36:20 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_close): Added missing check for closing_wait2 being
ASYNC_CLOSING_WAIT_NONE.
Thu Jan 26 09:02:49 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_init, set_serial_info, get_serial_info,
rs_close): Support close_wait in the serial driver.
This is helpful for slow devices (like serial
plotters) so that their outputs don't get flushed upon
device close. This has to be configurable because
normally we don't want ports to be hung up for long
periods of time during a close when they are not
connected to a device, or the device is powered off.
The default is to wait 30 seconds; in the case of a
very slow device, the close_wait timeout should be
lengthened. If it is set to 0, the kernel will wait
forever for all of the data to be transmitted.
Thu Jan 17 01:17:20 1995 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (startup, change_speed, rs_init): Add support to detect
the StarTech 16650 chip. Treat it as a 16450 for now,
because of its FIFO bugs.
Thu Jan 5 21:21:57 1995 <dahinds@users.sourceforge.net>
* serial.c: (receive_char): Added counter to prevent infinite loop
when a PCMCIA serial device is ejected.
Thu Dec 29 17:53:48 1994 <tytso@rsx-11.mit.edu>
* tty_io.c (check_tty_count): New procedure which checks
tty->count to make sure that it matches with the number of
open file descriptors which point at the structure. If
the number doesn't match, it prints a warning message.
Wed Dec 28 15:41:51 1994 <tytso@rsx-11.mit.edu>
* tty_io.c (do_tty_hangup, disassociate_ctty): At hangup time,
save the tty's current foreground process group in the
session leader's task structure. When the session leader
terminates, send a SIGHUP, SIGCONT to that process group.
This is not required by POSIX, but it's not prohibited
either, and it appears to be the least intrusive way
to fix a problem that dialup servers have with
orphaned process groups caused by modem hangups.
Thu Dec 8 14:52:11 1994 <tytso@rsx-11.mit.edu>
* serial.c (rs_ioctl): Don't allow most ioctl's if the serial port
isn't initialized.
* serial.c (rs_close): Don't clear the IER if the serial port
isn't initialized.
* serial.c (block_til_ready): Don't try to block on the dialin
port if the serial port isn't initialized.
Wed Dec 7 10:48:30 1994 Si Park (si@wimpol.demon.co.uk)
* tty_io.c (tty_register_driver): Fix bug when linking onto
the tty_drivers list. We now test that there are elements
already on the list before setting the back link from the
first element to the new driver.
* tty_io.c (tty_unregister_driver): Fix bug in unlinking the
specified driver from the tty_drivers list. We were not
setting the back link correctly. This used to result in
a dangling back link pointer and cause panics on the next
call to get_tty_driver().
Tue Nov 29 10:21:09 1994 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (tty_unregister_driver): Fix bug in
tty_unregister_driver where the pointer to the refcount is
tested, instead of the refcount itself. This caused
tty_unregister_driver to always return EBUSY.
Sat Nov 26 11:59:24 1994 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (tty_ioctl): Add support for the new ioctl
TIOCTTYGSTRUCT, which allow a kernel debugging program
direct read access to the tty and tty_driver structures.
Fri Nov 25 17:26:22 1994 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_set_termios): Don't wake up processes blocked in
open when the CLOCAL flag changes, since a blocking
open only samples the CLOCAL flag once when it blocks,
and doesn't check it again. (n.b. FreeBSD has a
different behavior for blocking opens; it's not clear
whether Linux or FreeBSD's interpretation is correct.
POSIX doesn't give clear guidance on this issue, so
this may change in the future....)
* serial.c (block_til_ready): Use the correct termios structure to
check the CLOCAL flag. If the cuaXX device is active,
then check the saved termios for the ttySXX device.
Otherwise, use the currently active termios structure.
Sun Nov 6 21:05:44 1994 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (change_speed): Add support for direct access of
57,600 and 115,200 bps.
Wed Nov 2 10:32:36 1994 Theodore Y. Ts'o (tytso@rt-11)
* n_tty.c (n_tty_receive_room): Only allow excess characters
through if we are in ICANON mode *and* there are other no
pending lines in the buffer. Otherwise cut and paste over
4k breaks.
Sat Oct 29 18:17:34 1994 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_ioctl, get_lsr_info): Added patch suggested by Arne
Riiber so that user mode programs can tell when the
transmitter shift register is empty.
Thu Oct 27 23:14:29 1994 Theodore Y. Ts'o (tytso@rt-11)
* tty_ioctl.c (wait_until_sent): Added debugging printk statements
(under the #ifdef TTY_DEBUG_WAIT_UNTIL_SENT)
* serial.c (rs_interrupt, rs_interrupt_single, receive_chars,
change_speed, rs_close): rs_close now disables receiver
interrupts when closing the serial port. This allows the
serial port to close quickly when Linux and a modem (or a
mouse) are engaged in an echo war; when closing the serial
port, we now first stop listening to incoming characters,
and *then* wait for the transmit buffer to drain.
In order to make this change, the info->read_status_mask
is now used to control what bits of the line status
register are looked at in the interrupt routine in all
cases; previously it was only used in receive_chars to
select a few of the status bits.
Mon Oct 24 23:36:21 1994 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_close): Add a timeout to the transmitter flush
loop; this is just a sanity check in case we have flaky
(or non-existent-but-configured-by-the-user) hardware.
Fri Oct 21 09:37:23 1994 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (tty_fasync): When asynchronous I/O is enabled, if the
process or process group has not be specified yet, set it
to be the tty's process group, or if that is not yet set,
to the current process's pid.
Thu Oct 20 23:17:28 1994 Theodore Y. Ts'o (tytso@rt-11)
* n_tty.c (n_tty_receive_room): If we are doing input
canonicalization, let as many characters through as
possible, so that the excess characters can be "beeped".
Tue Oct 18 10:02:43 1994 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_start): Removed an incorrect '!' that was
preventing transmit interrupts from being re-enabled in
rs_start(). Fortunately in most cases it would be
re-enabled elsewhere, but this still should be fixed
correctly.
Sun Oct 9 23:46:03 1994 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (do_tty_hangup): If the tty driver flags
TTY_DRIVER_RESET_TERMIOS is set, then reset the termios
settings back to the driver's initial configuration. This
allows the termios settings to be reset even if a process
has hung up file descriptors keeping a pty's termios from
being freed and reset.
* tty_io.c (release_dev): Fix memory leak. The pty's other
termios structure should also be freed.
* serial.c (rs_close, shutdown): Change how we wait for the
transmitter to completely drain before shutting down the
serial port. We now do it by scheduling in another
process instead of busy looping with the interrupts turned
on. This may eliminate some race condition problems that
some people seem to be reporting.
Sun Sep 25 14:18:14 1994 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (release_dev): When freeing a tty make sure that both
the tty and the o_tty (if present) aren't a process's
controlling tty. (Previously, we only checked the tty.)
* serial.c (change_speed): Only enable the Modem Status
Interrupt for a port if CLOCAL is not set or CRTSCTS
is set. If we're not checking the carrier detect and
CTS line, there's no point in enabling the modem
status interrupt. This will save spurious interrupts
from slowing down systems who have terminals that
don't support either line. (Of course, if you want
only one of CD and CTS support, you will need a
properly wired serial cable.)
Thu Sep 22 08:32:48 1994 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (do_SAK): Return if tty is null.
* tty_io.c (_tty_name): Return "NULL tty" if the passed in tty is
NULL.
Sat Sep 17 13:19:25 1994 Theodore Y. Ts'o (tytso@rt-11)
* tty_ioctl.c (n_tty_ioctl): Fix TIOCGLCKTRMIOS and
TIOCSLCKTRMIOS, which were totally broken. Remove
extra indirection from argument; it should be a struct
termios *, not a struct termios **.
&real_tty->termios_locked should have been
real_tty->termios_locked. This caused us to be
reading and writing the termios_locked structure to
random places in kernel memory.
* tty_io.c (release_dev): Oops! Forgot to delete a critical kfree
of the locked_termios. This leaves the locked_termios
structure pointed at a freed object.
Fri Sep 16 08:13:25 1994 Theodore Y. Ts'o (tytso@rt-11)
* tty_io.c (tty_open): Don't check for an exclusive open until
after the device specific open routine has been called.
Otherwise, the serial device ref counting will be screwed
up.
* serial.c (rs_open, block_til_ready): Don't set termios structure
until after block_til_ready has returned successfully.
Modify block_til_ready to check the normal_termios
structure directly, so it doesn't rely on termios being
set before it's called.
Thu Sep 15 23:34:01 1994 Theodore Y. Ts'o (tytso@rt-11)
* serial.c (rs_close): Turn off interrupts during rs_close() to
prevent a race condition with the hangup code (which
runs during a software interrupt).
* tty_io.c (release_dev): Don't free the locked_termios structure;
its state must be retained across device opens.
* tty_io.c (tty_unregister_driver): Added function to unregister a
tty driver. (For loadable device drivers.)

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,119 @@
#
# Makefile for the kernel character device drivers.
#
#
# This file contains the font map for the default (hardware) font
#
FONTMAPFILE = cp437.uni
obj-y += mem.o random.o tty_io.o n_tty.o tty_ioctl.o
obj-$(CONFIG_LEGACY_PTYS) += pty.o
obj-$(CONFIG_UNIX98_PTYS) += pty.o
obj-y += misc.o
obj-$(CONFIG_VT) += vt_ioctl.o vc_screen.o consolemap.o \
consolemap_deftbl.o selection.o keyboard.o
obj-$(CONFIG_HW_CONSOLE) += vt.o defkeymap.o
obj-$(CONFIG_MAGIC_SYSRQ) += sysrq.o
obj-$(CONFIG_ESPSERIAL) += esp.o
obj-$(CONFIG_MVME147_SCC) += generic_serial.o vme_scc.o
obj-$(CONFIG_MVME162_SCC) += generic_serial.o vme_scc.o
obj-$(CONFIG_BVME6000_SCC) += generic_serial.o vme_scc.o
obj-$(CONFIG_SERIAL_TX3912) += generic_serial.o serial_tx3912.o
obj-$(CONFIG_ROCKETPORT) += rocket.o
obj-$(CONFIG_SERIAL167) += serial167.o
obj-$(CONFIG_CYCLADES) += cyclades.o
obj-$(CONFIG_STALLION) += stallion.o
obj-$(CONFIG_ISTALLION) += istallion.o
obj-$(CONFIG_DIGI) += pcxx.o
obj-$(CONFIG_DIGIEPCA) += epca.o
obj-$(CONFIG_SPECIALIX) += specialix.o
obj-$(CONFIG_MOXA_INTELLIO) += moxa.o
obj-$(CONFIG_A2232) += ser_a2232.o generic_serial.o
obj-$(CONFIG_ATARI_DSP56K) += dsp56k.o
obj-$(CONFIG_MOXA_SMARTIO) += mxser.o
obj-$(CONFIG_COMPUTONE) += ip2.o ip2main.o
obj-$(CONFIG_RISCOM8) += riscom8.o
obj-$(CONFIG_ISI) += isicom.o
obj-$(CONFIG_SYNCLINK) += synclink.o
obj-$(CONFIG_SYNCLINKMP) += synclinkmp.o
obj-$(CONFIG_N_HDLC) += n_hdlc.o
obj-$(CONFIG_AMIGA_BUILTIN_SERIAL) += amiserial.o
obj-$(CONFIG_SX) += sx.o generic_serial.o
obj-$(CONFIG_RIO) += rio/ generic_serial.o
obj-$(CONFIG_HVC_CONSOLE) += hvc_console.o hvsi.o
obj-$(CONFIG_RAW_DRIVER) += raw.o
obj-$(CONFIG_SGI_SNSC) += snsc.o
obj-$(CONFIG_MMTIMER) += mmtimer.o
obj-$(CONFIG_VIOCONS) += viocons.o
obj-$(CONFIG_VIOTAPE) += viotape.o
obj-$(CONFIG_HVCS) += hvcs.o
obj-$(CONFIG_PRINTER) += lp.o
obj-$(CONFIG_TIPAR) += tipar.o
obj-$(CONFIG_DTLK) += dtlk.o
obj-$(CONFIG_R3964) += n_r3964.o
obj-$(CONFIG_APPLICOM) += applicom.o
obj-$(CONFIG_SONYPI) += sonypi.o
obj-$(CONFIG_RTC) += rtc.o
obj-$(CONFIG_HPET) += hpet.o
obj-$(CONFIG_GEN_RTC) += genrtc.o
obj-$(CONFIG_EFI_RTC) += efirtc.o
obj-$(CONFIG_SGI_DS1286) += ds1286.o
obj-$(CONFIG_SGI_IP27_RTC) += ip27-rtc.o
obj-$(CONFIG_DS1302) += ds1302.o
obj-$(CONFIG_S3C2410_RTC) += s3c2410-rtc.o
ifeq ($(CONFIG_GENERIC_NVRAM),y)
obj-$(CONFIG_NVRAM) += generic_nvram.o
else
obj-$(CONFIG_NVRAM) += nvram.o
endif
obj-$(CONFIG_TOSHIBA) += toshiba.o
obj-$(CONFIG_I8K) += i8k.o
obj-$(CONFIG_DS1620) += ds1620.o
obj-$(CONFIG_HW_RANDOM) += hw_random.o
obj-$(CONFIG_QIC02_TAPE) += tpqic02.o
obj-$(CONFIG_FTAPE) += ftape/
obj-$(CONFIG_COBALT_LCD) += lcd.o
obj-$(CONFIG_PPDEV) += ppdev.o
obj-$(CONFIG_NWBUTTON) += nwbutton.o
obj-$(CONFIG_NWFLASH) += nwflash.o
obj-$(CONFIG_SCx200_GPIO) += scx200_gpio.o
obj-$(CONFIG_WATCHDOG) += watchdog/
obj-$(CONFIG_MWAVE) += mwave/
obj-$(CONFIG_AGP) += agp/
obj-$(CONFIG_DRM) += drm/
obj-$(CONFIG_PCMCIA) += pcmcia/
obj-$(CONFIG_IPMI_HANDLER) += ipmi/
obj-$(CONFIG_HANGCHECK_TIMER) += hangcheck-timer.o
# Files generated that shall be removed upon make clean
clean-files := consolemap_deftbl.c defkeymap.c qtronixmap.c
quiet_cmd_conmk = CONMK $@
cmd_conmk = scripts/conmakehash $< > $@
$(obj)/consolemap_deftbl.c: $(src)/$(FONTMAPFILE)
$(call cmd,conmk)
$(obj)/defkeymap.o: $(obj)/defkeymap.c
$(obj)/qtronixmap.o: $(obj)/qtronixmap.c
# Uncomment if you're changing the keymap and have an appropriate
# loadkeys version for the map. By default, we'll use the shipped
# versions.
# GENERATE_KEYMAP := 1
ifdef GENERATE_KEYMAP
$(obj)/defkeymap.c $(obj)/qtronixmap.c: $(obj)/%.c: $(src)/%.map
loadkeys --mktable $< > $@.tmp
sed -e 's/^static *//' $@.tmp > $@
rm $@.tmp
endif

View File

@@ -0,0 +1,8 @@
The Cyclades-Z must have firmware loaded onto the card before it will
operate. This operation should be performed during system startup,
The firmware, loader program and the latest device driver code are
available from Cyclades at
ftp://ftp.cyclades.com/pub/cyclades/cyclades-z/linux/

View File

@@ -0,0 +1,173 @@
config AGP
tristate "/dev/agpgart (AGP Support)" if !GART_IOMMU && !M68K && !ARM
default y if GART_IOMMU
---help---
AGP (Accelerated Graphics Port) is a bus system mainly used to
connect graphics cards to the rest of the system.
If you have an AGP system and you say Y here, it will be possible to
use the AGP features of your 3D rendering video card. This code acts
as a sort of "AGP driver" for the motherboard's chipset.
If you need more texture memory than you can get with the AGP GART
(theoretically up to 256 MB, but in practice usually 64 or 128 MB
due to kernel allocation issues), you could use PCI accesses
and have up to a couple gigs of texture space.
Note that this is the only means to have XFree4/GLX use
write-combining with MTRR support on the AGP bus. Without it, OpenGL
direct rendering will be a lot slower but still faster than PIO.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N.
To compile this driver as a module, choose M here: the
module will be called agpgart.
config AGP_ALI
tristate "ALI chipset support"
depends on AGP && X86 && !X86_64
---help---
This option gives you AGP support for the GLX component of
XFree86 4.x on the following ALi chipsets. The supported chipsets
include M1541, M1621, M1631, M1632, M1641,M1647,and M1651.
For the ALi-chipset question, ALi suggests you refer to
<http://www.ali.com.tw/eng/support/index.shtml>.
The M1541 chipset can do AGP 1x and 2x, but note that there is an
acknowledged incompatibility with Matrox G200 cards. Due to
timing issues, this chipset cannot do AGP 2x with the G200.
This is a hardware limitation. AGP 1x seems to be fine, though.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N.
config AGP_ATI
tristate "ATI chipset support"
depends on AGP && X86 && !X86_64
---help---
This option gives you AGP support for the GLX component of
XFree86 4.x on the ATI RadeonIGP family of chipsets.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N.
config AGP_AMD
tristate "AMD Irongate, 761, and 762 chipset support"
depends on AGP && X86 && !X86_64
help
This option gives you AGP support for the GLX component of
XFree86 4.x on AMD Irongate, 761, and 762 chipsets.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N.
config AGP_AMD64
tristate "AMD Opteron/Athlon64 on-CPU GART support" if !GART_IOMMU
depends on AGP && X86
default y if GART_IOMMU
help
This option gives you AGP support for the GLX component of
XFree86 4.x using the on-CPU northbridge of the AMD Athlon64/Opteron CPUs.
You still need an external AGP bridge like the AMD 8151, VIA
K8T400M, SiS755. It may also support other AGP bridges when loaded
with agp_try_unsupported=1.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say Y
config AGP_INTEL
tristate "Intel 440LX/BX/GX, I8xx and E7x05 chipset support"
depends on AGP && X86 && !X86_64
help
This option gives you AGP support for the GLX component of XFree86 4.x
on Intel 440LX/BX/GX, 815, 820, 830, 840, 845, 850, 860, 875,
E7205 and E7505 chipsets and full support for the 810, 815, 830M, 845G,
852GM, 855GM, 865G and I915 integrated graphics chipsets.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI, or if you have any Intel integrated graphics
chipsets. If unsure, say Y.
config AGP_INTEL_MCH
tristate "Intel i865 chipset support"
depends on AGP && X86
help
This option gives you AGP support for the GLX component of XFree86 4.x
on Intel chipsets that support Intel EM64T processors.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say Y.
config AGP_NVIDIA
tristate "NVIDIA nForce/nForce2 chipset support"
depends on AGP && X86 && !X86_64
help
This option gives you AGP support for the GLX component of
XFree86 4.x on the following NVIDIA chipsets. The supported chipsets
include nForce and nForce2
config AGP_SIS
tristate "SiS chipset support"
depends on AGP && X86 && !X86_64
help
This option gives you AGP support for the GLX component of
XFree86 4.x on Silicon Integrated Systems [SiS] chipsets.
Note that 5591/5592 AGP chipsets are NOT supported.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N.
config AGP_SWORKS
tristate "Serverworks LE/HE chipset support"
depends on AGP && X86 && !X86_64
help
Say Y here to support the Serverworks AGP card. See
<http://www.serverworks.com/> for product descriptions and images.
config AGP_VIA
tristate "VIA chipset support"
depends on AGP && X86 && !X86_64
help
This option gives you AGP support for the GLX component of
XFree86 4.x on VIA MVP3/Apollo Pro chipsets.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say N.
config AGP_I460
tristate "Intel 460GX chipset support"
depends on AGP && (IA64_DIG || IA64_GENERIC)
help
This option gives you AGP GART support for the Intel 460GX chipset
for IA64 processors.
config AGP_HP_ZX1
tristate "HP ZX1 chipset AGP support"
depends on AGP && (IA64_HP_ZX1 || IA64_GENERIC)
help
This option gives you AGP GART support for the HP ZX1 chipset
for IA64 processors.
config AGP_ALPHA_CORE
tristate "Alpha AGP support"
depends on AGP && (ALPHA_GENERIC || ALPHA_TITAN || ALPHA_MARVEL)
default AGP
config AGP_UNINORTH
tristate "Apple UniNorth AGP support"
depends on AGP && PPC_PMAC
help
This option gives you AGP support for Apple machines with a
UniNorth bridge.
config AGP_EFFICEON
tristate "Transmeta Efficeon support"
depends on AGP && X86 && !X86_64
help
This option gives you AGP support for the Transmeta Efficeon
series processors with integrated northbridges.
You should say Y here if you use XFree86 3.3.6 or 4.x and want to
use GLX or DRI. If unsure, say Y.

View File

@@ -0,0 +1,19 @@
agpgart-y := backend.o frontend.o generic.o isoch.o
obj-$(CONFIG_AGP) += agpgart.o
obj-$(CONFIG_AGP_ALI) += ali-agp.o
obj-$(CONFIG_AGP_ATI) += ati-agp.o
obj-$(CONFIG_AGP_AMD) += amd-k7-agp.o
obj-$(CONFIG_AGP_AMD64) += amd64-agp.o
obj-$(CONFIG_AGP_ALPHA_CORE) += alpha-agp.o
obj-$(CONFIG_AGP_EFFICEON) += efficeon-agp.o
obj-$(CONFIG_AGP_HP_ZX1) += hp-agp.o
obj-$(CONFIG_AGP_I460) += i460-agp.o
obj-$(CONFIG_AGP_INTEL_MCH) += intel-mch-agp.o
obj-$(CONFIG_AGP_INTEL) += intel-agp.o
obj-$(CONFIG_AGP_NVIDIA) += nvidia-agp.o
obj-$(CONFIG_AGP_SIS) += sis-agp.o
obj-$(CONFIG_AGP_SWORKS) += sworks-agp.o
obj-$(CONFIG_AGP_UNINORTH) += uninorth-agp.o
obj-$(CONFIG_AGP_VIA) += via-agp.o

View File

@@ -0,0 +1,328 @@
/*
* AGPGART
* Copyright (C) 2002-2004 Dave Jones
* Copyright (C) 1999 Jeff Hartmann
* Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* JEFF HARTMANN, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
*/
#ifndef _AGP_BACKEND_PRIV_H
#define _AGP_BACKEND_PRIV_H 1
#include <asm/agp.h> /* for flush_agp_cache() */
#define PFX "agpgart: "
//#define AGP_DEBUG 1
#ifdef AGP_DEBUG
#define DBG(x,y...) printk (KERN_DEBUG PFX "%s: " x "\n", __FUNCTION__ , ## y)
#else
#define DBG(x,y...) do { } while (0)
#endif
extern struct agp_bridge_data *agp_bridge;
enum aper_size_type {
U8_APER_SIZE,
U16_APER_SIZE,
U32_APER_SIZE,
LVL2_APER_SIZE,
FIXED_APER_SIZE
};
struct gatt_mask {
unsigned long mask;
u32 type;
/* totally device specific, for integrated chipsets that
* might have different types of memory masks. For other
* devices this will probably be ignored */
};
struct aper_size_info_8 {
int size;
int num_entries;
int page_order;
u8 size_value;
};
struct aper_size_info_16 {
int size;
int num_entries;
int page_order;
u16 size_value;
};
struct aper_size_info_32 {
int size;
int num_entries;
int page_order;
u32 size_value;
};
struct aper_size_info_lvl2 {
int size;
int num_entries;
u32 size_value;
};
struct aper_size_info_fixed {
int size;
int num_entries;
int page_order;
};
struct agp_bridge_driver {
struct module *owner;
void *aperture_sizes;
int num_aperture_sizes;
enum aper_size_type size_type;
int cant_use_aperture;
int needs_scratch_page;
struct gatt_mask *masks;
int (*fetch_size)(void);
int (*configure)(void);
void (*agp_enable)(u32);
void (*cleanup)(void);
void (*tlb_flush)(struct agp_memory *);
unsigned long (*mask_memory)(unsigned long, int);
void (*cache_flush)(void);
int (*create_gatt_table)(void);
int (*free_gatt_table)(void);
int (*insert_memory)(struct agp_memory *, off_t, int);
int (*remove_memory)(struct agp_memory *, off_t, int);
struct agp_memory *(*alloc_by_type) (size_t, int);
void (*free_by_type)(struct agp_memory *);
void *(*agp_alloc_page)(void);
void (*agp_destroy_page)(void *);
};
struct agp_bridge_data {
struct agp_version *version;
struct agp_bridge_driver *driver;
struct vm_operations_struct *vm_ops;
void *previous_size;
void *current_size;
void *dev_private_data;
struct pci_dev *dev;
u32 __iomem *gatt_table;
u32 *gatt_table_real;
unsigned long scratch_page;
unsigned long scratch_page_real;
unsigned long gart_bus_addr;
unsigned long gatt_bus_addr;
u32 mode;
enum chipset_type type;
unsigned long *key_list;
atomic_t current_memory_agp;
atomic_t agp_in_use;
int max_memory_agp; /* in number of pages */
int aperture_size_idx;
int capndx;
char major_version;
char minor_version;
};
#define OUTREG64(mmap, addr, val) __raw_writeq((val), (mmap)+(addr))
#define OUTREG32(mmap, addr, val) __raw_writel((val), (mmap)+(addr))
#define OUTREG16(mmap, addr, val) __raw_writew((val), (mmap)+(addr))
#define OUTREG8(mmap, addr, val) __raw_writeb((val), (mmap)+(addr))
#define INREG64(mmap, addr) __raw_readq((mmap)+(addr))
#define INREG32(mmap, addr) __raw_readl((mmap)+(addr))
#define INREG16(mmap, addr) __raw_readw((mmap)+(addr))
#define INREG8(mmap, addr) __raw_readb((mmap)+(addr))
#define KB(x) ((x) * 1024)
#define MB(x) (KB (KB (x)))
#define GB(x) (MB (KB (x)))
#define A_SIZE_8(x) ((struct aper_size_info_8 *) x)
#define A_SIZE_16(x) ((struct aper_size_info_16 *) x)
#define A_SIZE_32(x) ((struct aper_size_info_32 *) x)
#define A_SIZE_LVL2(x) ((struct aper_size_info_lvl2 *) x)
#define A_SIZE_FIX(x) ((struct aper_size_info_fixed *) x)
#define A_IDX8(bridge) (A_SIZE_8((bridge)->driver->aperture_sizes) + i)
#define A_IDX16(bridge) (A_SIZE_16((bridge)->driver->aperture_sizes) + i)
#define A_IDX32(bridge) (A_SIZE_32((bridge)->driver->aperture_sizes) + i)
#define MAXKEY (4096 * 32)
#define PGE_EMPTY(b, p) (!(p) || (p) == (unsigned long) (b)->scratch_page)
/* Intel registers */
#define INTEL_APSIZE 0xb4
#define INTEL_ATTBASE 0xb8
#define INTEL_AGPCTRL 0xb0
#define INTEL_NBXCFG 0x50
#define INTEL_ERRSTS 0x91
/* Intel i830 registers */
#define I830_GMCH_CTRL 0x52
#define I830_GMCH_ENABLED 0x4
#define I830_GMCH_MEM_MASK 0x1
#define I830_GMCH_MEM_64M 0x1
#define I830_GMCH_MEM_128M 0
#define I830_GMCH_GMS_MASK 0x70
#define I830_GMCH_GMS_DISABLED 0x00
#define I830_GMCH_GMS_LOCAL 0x10
#define I830_GMCH_GMS_STOLEN_512 0x20
#define I830_GMCH_GMS_STOLEN_1024 0x30
#define I830_GMCH_GMS_STOLEN_8192 0x40
#define I830_RDRAM_CHANNEL_TYPE 0x03010
#define I830_RDRAM_ND(x) (((x) & 0x20) >> 5)
#define I830_RDRAM_DDT(x) (((x) & 0x18) >> 3)
/* This one is for I830MP w. an external graphic card */
#define INTEL_I830_ERRSTS 0x92
/* Intel 855GM/852GM registers */
#define I855_GMCH_GMS_STOLEN_0M 0x0
#define I855_GMCH_GMS_STOLEN_1M (0x1 << 4)
#define I855_GMCH_GMS_STOLEN_4M (0x2 << 4)
#define I855_GMCH_GMS_STOLEN_8M (0x3 << 4)
#define I855_GMCH_GMS_STOLEN_16M (0x4 << 4)
#define I855_GMCH_GMS_STOLEN_32M (0x5 << 4)
#define I85X_CAPID 0x44
#define I85X_VARIANT_MASK 0x7
#define I85X_VARIANT_SHIFT 5
#define I855_GME 0x0
#define I855_GM 0x4
#define I852_GME 0x2
#define I852_GM 0x5
/* Intel i845 registers */
#define INTEL_I845_AGPM 0x51
#define INTEL_I845_ERRSTS 0xc8
/* Intel i860 registers */
#define INTEL_I860_MCHCFG 0x50
#define INTEL_I860_ERRSTS 0xc8
/* Intel i810 registers */
#define I810_GMADDR 0x10
#define I810_MMADDR 0x14
#define I810_PTE_BASE 0x10000
#define I810_PTE_MAIN_UNCACHED 0x00000000
#define I810_PTE_LOCAL 0x00000002
#define I810_PTE_VALID 0x00000001
#define I810_SMRAM_MISCC 0x70
#define I810_GFX_MEM_WIN_SIZE 0x00010000
#define I810_GFX_MEM_WIN_32M 0x00010000
#define I810_GMS 0x000000c0
#define I810_GMS_DISABLE 0x00000000
#define I810_PGETBL_CTL 0x2020
#define I810_PGETBL_ENABLED 0x00000001
#define I810_DRAM_CTL 0x3000
#define I810_DRAM_ROW_0 0x00000001
#define I810_DRAM_ROW_0_SDRAM 0x00000001
struct agp_device_ids {
unsigned short device_id; /* first, to make table easier to read */
enum chipset_type chipset;
const char *chipset_name;
int (*chipset_setup) (struct pci_dev *pdev); /* used to override generic */
};
/* Driver registration */
struct agp_bridge_data *agp_alloc_bridge(void);
void agp_put_bridge(struct agp_bridge_data *bridge);
int agp_add_bridge(struct agp_bridge_data *bridge);
void agp_remove_bridge(struct agp_bridge_data *bridge);
/* Frontend routines. */
int agp_frontend_initialize(void);
void agp_frontend_cleanup(void);
/* Generic routines. */
void agp_generic_enable(u32 mode);
int agp_generic_create_gatt_table(void);
int agp_generic_free_gatt_table(void);
struct agp_memory *agp_create_memory(int scratch_pages);
int agp_generic_insert_memory(struct agp_memory *mem, off_t pg_start, int type);
int agp_generic_remove_memory(struct agp_memory *mem, off_t pg_start, int type);
struct agp_memory *agp_generic_alloc_by_type(size_t page_count, int type);
void agp_generic_free_by_type(struct agp_memory *curr);
void *agp_generic_alloc_page(void);
void agp_generic_destroy_page(void *addr);
void agp_free_key(int key);
int agp_num_entries(void);
u32 agp_collect_device_status(u32 mode, u32 command);
void agp_device_command(u32 command, int agp_v3);
int agp_3_5_enable(struct agp_bridge_data *bridge);
void global_cache_flush(void);
void get_agp_version(struct agp_bridge_data *bridge);
unsigned long agp_generic_mask_memory(unsigned long addr, int type);
/* generic routines for agp>=3 */
int agp3_generic_fetch_size(void);
void agp3_generic_tlbflush(struct agp_memory *mem);
int agp3_generic_configure(void);
void agp3_generic_cleanup(void);
/* aperture sizes have been standardised since v3 */
#define AGP_GENERIC_SIZES_ENTRIES 11
extern struct aper_size_info_16 agp3_generic_sizes[];
extern int agp_off;
extern int agp_try_unsupported_boot;
/* Chipset independant registers (from AGP Spec) */
#define AGP_APBASE 0x10
#define AGPSTAT 0x4
#define AGPCMD 0x8
#define AGPNISTAT 0xc
#define AGPCTRL 0x10
#define AGPAPSIZE 0x14
#define AGPNEPG 0x16
#define AGPGARTLO 0x18
#define AGPGARTHI 0x1c
#define AGPNICMD 0x20
#define AGP_MAJOR_VERSION_SHIFT (20)
#define AGP_MINOR_VERSION_SHIFT (16)
#define AGPSTAT_RQ_DEPTH (0xff000000)
#define AGPSTAT_RQ_DEPTH_SHIFT 24
#define AGPSTAT_CAL_MASK (1<<12|1<<11|1<<10)
#define AGPSTAT_ARQSZ (1<<15|1<<14|1<<13)
#define AGPSTAT_ARQSZ_SHIFT 13
#define AGPSTAT_SBA (1<<9)
#define AGPSTAT_AGP_ENABLE (1<<8)
#define AGPSTAT_FW (1<<4)
#define AGPSTAT_MODE_3_0 (1<<3)
#define AGPSTAT2_1X (1<<0)
#define AGPSTAT2_2X (1<<1)
#define AGPSTAT2_4X (1<<2)
#define AGPSTAT3_RSVD (1<<2)
#define AGPSTAT3_8X (1<<1)
#define AGPSTAT3_4X (1)
#define AGPCTRL_APERENB (1<<8)
#define AGPCTRL_GTLBEN (1<<7)
#endif /* _AGP_BACKEND_PRIV_H */

View File

@@ -0,0 +1,403 @@
/*
* ALi AGPGART routines.
*/
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include "agp.h"
#define ALI_AGPCTRL 0xb8
#define ALI_ATTBASE 0xbc
#define ALI_TLBCTRL 0xc0
#define ALI_TAGCTRL 0xc4
#define ALI_CACHE_FLUSH_CTRL 0xD0
#define ALI_CACHE_FLUSH_ADDR_MASK 0xFFFFF000
#define ALI_CACHE_FLUSH_EN 0x100
static int ali_fetch_size(void)
{
int i;
u32 temp;
struct aper_size_info_32 *values;
pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp);
temp &= ~(0xfffffff0);
values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
static void ali_tlbflush(struct agp_memory *mem)
{
u32 temp;
pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
temp &= 0xfffffff0;
temp |= (1<<0 | 1<<1);
pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL, temp);
}
static void ali_cleanup(void)
{
struct aper_size_info_32 *previous_size;
u32 temp;
previous_size = A_SIZE_32(agp_bridge->previous_size);
pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
// clear tag
pci_write_config_dword(agp_bridge->dev, ALI_TAGCTRL,
((temp & 0xffffff00) | 0x00000001|0x00000002));
pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp);
pci_write_config_dword(agp_bridge->dev, ALI_ATTBASE,
((temp & 0x00000ff0) | previous_size->size_value));
}
static int ali_configure(void)
{
u32 temp;
struct aper_size_info_32 *current_size;
current_size = A_SIZE_32(agp_bridge->current_size);
/* aperture size and gatt addr */
pci_read_config_dword(agp_bridge->dev, ALI_ATTBASE, &temp);
temp = (((temp & 0x00000ff0) | (agp_bridge->gatt_bus_addr & 0xfffff000))
| (current_size->size_value & 0xf));
pci_write_config_dword(agp_bridge->dev, ALI_ATTBASE, temp);
/* tlb control */
pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
pci_write_config_dword(agp_bridge->dev, ALI_TLBCTRL, ((temp & 0xffffff00) | 0x00000010));
/* address to map to */
pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
#if 0
if (agp_bridge->type == ALI_M1541) {
u32 nlvm_addr = 0;
switch (current_size->size_value) {
case 0: break;
case 1: nlvm_addr = 0x100000;break;
case 2: nlvm_addr = 0x200000;break;
case 3: nlvm_addr = 0x400000;break;
case 4: nlvm_addr = 0x800000;break;
case 6: nlvm_addr = 0x1000000;break;
case 7: nlvm_addr = 0x2000000;break;
case 8: nlvm_addr = 0x4000000;break;
case 9: nlvm_addr = 0x8000000;break;
case 10: nlvm_addr = 0x10000000;break;
default: break;
}
nlvm_addr--;
nlvm_addr&=0xfff00000;
nlvm_addr+= agp_bridge->gart_bus_addr;
nlvm_addr|=(agp_bridge->gart_bus_addr>>12);
printk(KERN_INFO PFX "nlvm top &base = %8x\n",nlvm_addr);
}
#endif
pci_read_config_dword(agp_bridge->dev, ALI_TLBCTRL, &temp);
temp &= 0xffffff7f; //enable TLB
pci_write_config_dword(agp_bridge->dev, ALI_TLBCTRL, temp);
return 0;
}
static void m1541_cache_flush(void)
{
int i, page_count;
u32 temp;
global_cache_flush();
page_count = 1 << A_SIZE_32(agp_bridge->current_size)->page_order;
for (i = 0; i < PAGE_SIZE * page_count; i += PAGE_SIZE) {
pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
&temp);
pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
(agp_bridge->gatt_bus_addr + i)) |
ALI_CACHE_FLUSH_EN));
}
}
static void *m1541_alloc_page(void)
{
void *addr = agp_generic_alloc_page();
u32 temp;
if (!addr)
return NULL;
pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN ));
return addr;
}
static void ali_destroy_page(void * addr)
{
if (addr) {
global_cache_flush(); /* is this really needed? --hch */
agp_generic_destroy_page(addr);
}
}
static void m1541_destroy_page(void * addr)
{
u32 temp;
if (addr == NULL)
return;
global_cache_flush();
pci_read_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL, &temp);
pci_write_config_dword(agp_bridge->dev, ALI_CACHE_FLUSH_CTRL,
(((temp & ALI_CACHE_FLUSH_ADDR_MASK) |
virt_to_phys(addr)) | ALI_CACHE_FLUSH_EN));
agp_generic_destroy_page(addr);
}
/* Setup function */
static struct aper_size_info_32 ali_generic_sizes[7] =
{
{256, 65536, 6, 10},
{128, 32768, 5, 9},
{64, 16384, 4, 8},
{32, 8192, 3, 7},
{16, 4096, 2, 6},
{8, 2048, 1, 4},
{4, 1024, 0, 3}
};
struct agp_bridge_driver ali_generic_bridge = {
.owner = THIS_MODULE,
.aperture_sizes = ali_generic_sizes,
.size_type = U32_APER_SIZE,
.num_aperture_sizes = 7,
.configure = ali_configure,
.fetch_size = ali_fetch_size,
.cleanup = ali_cleanup,
.tlb_flush = ali_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = NULL,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = agp_generic_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = ali_destroy_page,
};
struct agp_bridge_driver ali_m1541_bridge = {
.owner = THIS_MODULE,
.aperture_sizes = ali_generic_sizes,
.size_type = U32_APER_SIZE,
.num_aperture_sizes = 7,
.configure = ali_configure,
.fetch_size = ali_fetch_size,
.cleanup = ali_cleanup,
.tlb_flush = ali_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = NULL,
.agp_enable = agp_generic_enable,
.cache_flush = m1541_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = agp_generic_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = m1541_alloc_page,
.agp_destroy_page = m1541_destroy_page,
};
static struct agp_device_ids ali_agp_device_ids[] __devinitdata =
{
{
.device_id = PCI_DEVICE_ID_AL_M1541,
.chipset_name = "M1541",
},
{
.device_id = PCI_DEVICE_ID_AL_M1621,
.chipset_name = "M1621",
},
{
.device_id = PCI_DEVICE_ID_AL_M1631,
.chipset_name = "M1631",
},
{
.device_id = PCI_DEVICE_ID_AL_M1632,
.chipset_name = "M1632",
},
{
.device_id = PCI_DEVICE_ID_AL_M1641,
.chipset_name = "M1641",
},
{
.device_id = PCI_DEVICE_ID_AL_M1644,
.chipset_name = "M1644",
},
{
.device_id = PCI_DEVICE_ID_AL_M1647,
.chipset_name = "M1647",
},
{
.device_id = PCI_DEVICE_ID_AL_M1651,
.chipset_name = "M1651",
},
{
.device_id = PCI_DEVICE_ID_AL_M1671,
.chipset_name = "M1671",
},
{ }, /* dummy final entry, always present */
};
static int __devinit agp_ali_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_device_ids *devs = ali_agp_device_ids;
struct agp_bridge_data *bridge;
u8 hidden_1621_id, cap_ptr;
int j;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
/* probe for known chipsets */
for (j = 0; devs[j].chipset_name; j++) {
if (pdev->device == devs[j].device_id)
goto found;
}
printk(KERN_ERR PFX "Unsupported ALi chipset (device id: %04x)\n",
pdev->device);
return -ENODEV;
found:
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
switch (pdev->device) {
case PCI_DEVICE_ID_AL_M1541:
bridge->driver = &ali_m1541_bridge;
break;
case PCI_DEVICE_ID_AL_M1621:
pci_read_config_byte(pdev, 0xFB, &hidden_1621_id);
switch (hidden_1621_id) {
case 0x31:
devs[j].chipset_name = "M1631";
break;
case 0x32:
devs[j].chipset_name = "M1632";
break;
case 0x41:
devs[j].chipset_name = "M1641";
break;
case 0x43:
devs[j].chipset_name = "M????";
break;
case 0x47:
devs[j].chipset_name = "M1647";
break;
case 0x51:
devs[j].chipset_name = "M1651";
break;
default:
break;
}
/*FALLTHROUGH*/
default:
bridge->driver = &ali_generic_bridge;
}
printk(KERN_INFO PFX "Detected ALi %s chipset\n",
devs[j].chipset_name);
/* Fill in the mode register */
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_ali_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static struct pci_device_id agp_ali_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_AL,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_ali_pci_table);
static struct pci_driver agp_ali_pci_driver = {
.name = "agpgart-ali",
.id_table = agp_ali_pci_table,
.probe = agp_ali_probe,
.remove = agp_ali_remove,
};
static int __init agp_ali_init(void)
{
return pci_module_init(&agp_ali_pci_driver);
}
static void __exit agp_ali_cleanup(void)
{
pci_unregister_driver(&agp_ali_pci_driver);
}
module_init(agp_ali_init);
module_exit(agp_ali_cleanup);
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
MODULE_LICENSE("GPL and additional rights");

View File

@@ -0,0 +1,213 @@
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <asm/machvec.h>
#include <asm/agp_backend.h>
#include "../../../arch/alpha/kernel/pci_impl.h"
#include "agp.h"
static struct page *alpha_core_agp_vm_nopage(struct vm_area_struct *vma,
unsigned long address,
int *type)
{
alpha_agp_info *agp = agp_bridge->dev_private_data;
dma_addr_t dma_addr;
unsigned long pa;
struct page *page;
dma_addr = address - vma->vm_start + agp->aperture.bus_base;
pa = agp->ops->translate(agp, dma_addr);
if (pa == (unsigned long)-EINVAL) return NULL; /* no translation */
/*
* Get the page, inc the use count, and return it
*/
page = virt_to_page(__va(pa));
get_page(page);
if (type)
*type = VM_FAULT_MINOR;
return page;
}
static struct aper_size_info_fixed alpha_core_agp_sizes[] =
{
{ 0, 0, 0 }, /* filled in by alpha_core_agp_setup */
};
struct vm_operations_struct alpha_core_agp_vm_ops = {
.nopage = alpha_core_agp_vm_nopage,
};
static int alpha_core_agp_nop(void)
{
/* just return success */
return 0;
}
static int alpha_core_agp_fetch_size(void)
{
return alpha_core_agp_sizes[0].size;
}
static int alpha_core_agp_configure(void)
{
alpha_agp_info *agp = agp_bridge->dev_private_data;
agp_bridge->gart_bus_addr = agp->aperture.bus_base;
return 0;
}
static void alpha_core_agp_cleanup(void)
{
alpha_agp_info *agp = agp_bridge->dev_private_data;
agp->ops->cleanup(agp);
}
static void alpha_core_agp_tlbflush(struct agp_memory *mem)
{
alpha_agp_info *agp = agp_bridge->dev_private_data;
alpha_mv.mv_pci_tbi(agp->hose, 0, -1);
}
static void alpha_core_agp_enable(u32 mode)
{
alpha_agp_info *agp = agp_bridge->dev_private_data;
agp->mode.lw = agp_collect_device_status(mode, agp->capability.lw);
agp->mode.bits.enable = 1;
agp->ops->configure(agp);
agp_device_command(agp->mode.lw, 0);
}
static int alpha_core_agp_insert_memory(struct agp_memory *mem, off_t pg_start,
int type)
{
alpha_agp_info *agp = agp_bridge->dev_private_data;
int num_entries, status;
void *temp;
temp = agp_bridge->current_size;
num_entries = A_SIZE_FIX(temp)->num_entries;
if ((pg_start + mem->page_count) > num_entries) return -EINVAL;
status = agp->ops->bind(agp, pg_start, mem);
mb();
alpha_core_agp_tlbflush(mem);
return status;
}
static int alpha_core_agp_remove_memory(struct agp_memory *mem, off_t pg_start,
int type)
{
alpha_agp_info *agp = agp_bridge->dev_private_data;
int status;
status = agp->ops->unbind(agp, pg_start, mem);
alpha_core_agp_tlbflush(mem);
return status;
}
struct agp_bridge_driver alpha_core_agp_driver = {
.owner = THIS_MODULE,
.aperture_sizes = alpha_core_agp_sizes,
.num_aperture_sizes = 1,
.size_type = FIXED_APER_SIZE,
.cant_use_aperture = 1,
.masks = NULL,
.fetch_size = alpha_core_agp_fetch_size,
.configure = alpha_core_agp_configure,
.agp_enable = alpha_core_agp_enable,
.cleanup = alpha_core_agp_cleanup,
.tlb_flush = alpha_core_agp_tlbflush,
.mask_memory = agp_generic_mask_memory,
.cache_flush = global_cache_flush,
.create_gatt_table = alpha_core_agp_nop,
.free_gatt_table = alpha_core_agp_nop,
.insert_memory = alpha_core_agp_insert_memory,
.remove_memory = alpha_core_agp_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
struct agp_bridge_data *alpha_bridge;
int __init
alpha_core_agp_setup(void)
{
alpha_agp_info *agp = alpha_mv.agp_info();
struct pci_dev *pdev; /* faked */
struct aper_size_info_fixed *aper_size;
if (!agp)
return -ENODEV;
if (agp->ops->setup(agp))
return -ENODEV;
/*
* Build the aperture size descriptor
*/
aper_size = alpha_core_agp_sizes;
aper_size->size = agp->aperture.size / (1024 * 1024);
aper_size->num_entries = agp->aperture.size / PAGE_SIZE;
aper_size->page_order = __ffs(aper_size->num_entries / 1024);
/*
* Build a fake pci_dev struct
*/
pdev = kmalloc(sizeof(struct pci_dev), GFP_KERNEL);
if (!pdev)
return -ENOMEM;
pdev->vendor = 0xffff;
pdev->device = 0xffff;
pdev->sysdata = agp->hose;
alpha_bridge = agp_alloc_bridge();
if (!alpha_bridge)
goto fail;
alpha_bridge->driver = &alpha_core_agp_driver;
alpha_bridge->vm_ops = &alpha_core_agp_vm_ops;
alpha_bridge->current_size = aper_size; /* only 1 size */
alpha_bridge->dev_private_data = agp;
alpha_bridge->dev = pdev;
alpha_bridge->mode = agp->capability.lw;
printk(KERN_INFO PFX "Detected AGP on hose %d\n", agp->hose->index);
return agp_add_bridge(alpha_bridge);
fail:
kfree(pdev);
return -ENOMEM;
}
static int __init agp_alpha_core_init(void)
{
if (alpha_mv.agp_info)
return alpha_core_agp_setup();
return -ENODEV;
}
static void __exit agp_alpha_core_cleanup(void)
{
agp_remove_bridge(alpha_bridge);
agp_put_bridge(alpha_bridge);
}
module_init(agp_alpha_core_init);
module_exit(agp_alpha_core_cleanup);
MODULE_AUTHOR("Jeff Wiedemeier <Jeff.Wiedemeier@hp.com>");
MODULE_LICENSE("GPL and additional rights");

View File

@@ -0,0 +1,485 @@
/*
* AMD K7 AGPGART routines.
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <linux/gfp.h>
#include <linux/page-flags.h>
#include <linux/mm.h>
#include "agp.h"
#define AMD_MMBASE 0x14
#define AMD_APSIZE 0xac
#define AMD_MODECNTL 0xb0
#define AMD_MODECNTL2 0xb2
#define AMD_GARTENABLE 0x02 /* In mmio region (16-bit register) */
#define AMD_ATTBASE 0x04 /* In mmio region (32-bit register) */
#define AMD_TLBFLUSH 0x0c /* In mmio region (32-bit register) */
#define AMD_CACHEENTRY 0x10 /* In mmio region (32-bit register) */
static struct pci_device_id agp_amdk7_pci_table[];
struct amd_page_map {
unsigned long *real;
unsigned long __iomem *remapped;
};
static struct _amd_irongate_private {
volatile u8 __iomem *registers;
struct amd_page_map **gatt_pages;
int num_tables;
} amd_irongate_private;
static int amd_create_page_map(struct amd_page_map *page_map)
{
int i;
page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
if (page_map->real == NULL)
return -ENOMEM;
SetPageReserved(virt_to_page(page_map->real));
global_cache_flush();
page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
PAGE_SIZE);
if (page_map->remapped == NULL) {
ClearPageReserved(virt_to_page(page_map->real));
free_page((unsigned long) page_map->real);
page_map->real = NULL;
return -ENOMEM;
}
global_cache_flush();
for (i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++)
writel(agp_bridge->scratch_page, page_map->remapped+i);
return 0;
}
static void amd_free_page_map(struct amd_page_map *page_map)
{
iounmap(page_map->remapped);
ClearPageReserved(virt_to_page(page_map->real));
free_page((unsigned long) page_map->real);
}
static void amd_free_gatt_pages(void)
{
int i;
struct amd_page_map **tables;
struct amd_page_map *entry;
tables = amd_irongate_private.gatt_pages;
for (i = 0; i < amd_irongate_private.num_tables; i++) {
entry = tables[i];
if (entry != NULL) {
if (entry->real != NULL)
amd_free_page_map(entry);
kfree(entry);
}
}
kfree(tables);
amd_irongate_private.gatt_pages = NULL;
}
static int amd_create_gatt_pages(int nr_tables)
{
struct amd_page_map **tables;
struct amd_page_map *entry;
int retval = 0;
int i;
tables = kmalloc((nr_tables + 1) * sizeof(struct amd_page_map *),
GFP_KERNEL);
if (tables == NULL)
return -ENOMEM;
memset (tables, 0, sizeof(struct amd_page_map *) * (nr_tables + 1));
for (i = 0; i < nr_tables; i++) {
entry = kmalloc(sizeof(struct amd_page_map), GFP_KERNEL);
if (entry == NULL) {
retval = -ENOMEM;
break;
}
memset (entry, 0, sizeof(struct amd_page_map));
tables[i] = entry;
retval = amd_create_page_map(entry);
if (retval != 0)
break;
}
amd_irongate_private.num_tables = nr_tables;
amd_irongate_private.gatt_pages = tables;
if (retval != 0)
amd_free_gatt_pages();
return retval;
}
/* Since we don't need contigious memory we just try
* to get the gatt table once
*/
#define GET_PAGE_DIR_OFF(addr) (addr >> 22)
#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
#define GET_GATT(addr) (amd_irongate_private.gatt_pages[\
GET_PAGE_DIR_IDX(addr)]->remapped)
static int amd_create_gatt_table(void)
{
struct aper_size_info_lvl2 *value;
struct amd_page_map page_dir;
unsigned long addr;
int retval;
u32 temp;
int i;
value = A_SIZE_LVL2(agp_bridge->current_size);
retval = amd_create_page_map(&page_dir);
if (retval != 0)
return retval;
retval = amd_create_gatt_pages(value->num_entries / 1024);
if (retval != 0) {
amd_free_page_map(&page_dir);
return retval;
}
agp_bridge->gatt_table_real = (u32 *)page_dir.real;
agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
/* Get the address for the gart region.
* This is a bus address even on the alpha, b/c its
* used to program the agp master not the cpu
*/
pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
agp_bridge->gart_bus_addr = addr;
/* Calculate the agp offset */
for (i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
writel(virt_to_phys(amd_irongate_private.gatt_pages[i]->real) | 1,
page_dir.remapped+GET_PAGE_DIR_OFF(addr));
}
return 0;
}
static int amd_free_gatt_table(void)
{
struct amd_page_map page_dir;
page_dir.real = (unsigned long *)agp_bridge->gatt_table_real;
page_dir.remapped = (unsigned long __iomem *)agp_bridge->gatt_table;
amd_free_gatt_pages();
amd_free_page_map(&page_dir);
return 0;
}
static int amd_irongate_fetch_size(void)
{
int i;
u32 temp;
struct aper_size_info_lvl2 *values;
pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
temp = (temp & 0x0000000e);
values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
static int amd_irongate_configure(void)
{
struct aper_size_info_lvl2 *current_size;
u32 temp;
u16 enable_reg;
current_size = A_SIZE_LVL2(agp_bridge->current_size);
/* Get the memory mapped registers */
pci_read_config_dword(agp_bridge->dev, AMD_MMBASE, &temp);
temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
amd_irongate_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
/* Write out the address of the gatt table */
OUTREG32(amd_irongate_private.registers, AMD_ATTBASE,
agp_bridge->gatt_bus_addr);
/* Write the Sync register */
pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL, 0x80);
/* Set indexing mode */
pci_write_config_byte(agp_bridge->dev, AMD_MODECNTL2, 0x00);
/* Write the enable register */
enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
enable_reg = (enable_reg | 0x0004);
OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
/* Write out the size register */
pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
temp = (((temp & ~(0x0000000e)) | current_size->size_value)
| 0x00000001);
pci_write_config_dword(agp_bridge->dev, AMD_APSIZE, temp);
/* Flush the tlb */
OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
return 0;
}
static void amd_irongate_cleanup(void)
{
struct aper_size_info_lvl2 *previous_size;
u32 temp;
u16 enable_reg;
previous_size = A_SIZE_LVL2(agp_bridge->previous_size);
enable_reg = INREG16(amd_irongate_private.registers, AMD_GARTENABLE);
enable_reg = (enable_reg & ~(0x0004));
OUTREG16(amd_irongate_private.registers, AMD_GARTENABLE, enable_reg);
/* Write back the previous size and disable gart translation */
pci_read_config_dword(agp_bridge->dev, AMD_APSIZE, &temp);
temp = ((temp & ~(0x0000000f)) | previous_size->size_value);
pci_write_config_dword(agp_bridge->dev, AMD_APSIZE, temp);
iounmap((void __iomem *) amd_irongate_private.registers);
}
/*
* This routine could be implemented by taking the addresses
* written to the GATT, and flushing them individually. However
* currently it just flushes the whole table. Which is probably
* more efficent, since agp_memory blocks can be a large number of
* entries.
*/
static void amd_irongate_tlbflush(struct agp_memory *temp)
{
OUTREG32(amd_irongate_private.registers, AMD_TLBFLUSH, 0x00000001);
}
static int amd_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
{
int i, j, num_entries;
unsigned long __iomem *cur_gatt;
unsigned long addr;
num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
if (type != 0 || mem->type != 0)
return -EINVAL;
if ((pg_start + mem->page_count) > num_entries)
return -EINVAL;
j = pg_start;
while (j < (pg_start + mem->page_count)) {
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = GET_GATT(addr);
if (!PGE_EMPTY(agp_bridge, readl(cur_gatt+GET_GATT_OFF(addr))))
return -EBUSY;
j++;
}
if (mem->is_flushed == FALSE) {
global_cache_flush();
mem->is_flushed = TRUE;
}
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = GET_GATT(addr);
writel(agp_generic_mask_memory(mem->memory[i], mem->type), cur_gatt+GET_GATT_OFF(addr));
}
amd_irongate_tlbflush(mem);
return 0;
}
static int amd_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
{
int i;
unsigned long __iomem *cur_gatt;
unsigned long addr;
if (type != 0 || mem->type != 0)
return -EINVAL;
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = GET_GATT(addr);
writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr));
}
amd_irongate_tlbflush(mem);
return 0;
}
static struct aper_size_info_lvl2 amd_irongate_sizes[7] =
{
{2048, 524288, 0x0000000c},
{1024, 262144, 0x0000000a},
{512, 131072, 0x00000008},
{256, 65536, 0x00000006},
{128, 32768, 0x00000004},
{64, 16384, 0x00000002},
{32, 8192, 0x00000000}
};
static struct gatt_mask amd_irongate_masks[] =
{
{.mask = 1, .type = 0}
};
struct agp_bridge_driver amd_irongate_driver = {
.owner = THIS_MODULE,
.aperture_sizes = amd_irongate_sizes,
.size_type = LVL2_APER_SIZE,
.num_aperture_sizes = 7,
.configure = amd_irongate_configure,
.fetch_size = amd_irongate_fetch_size,
.cleanup = amd_irongate_cleanup,
.tlb_flush = amd_irongate_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = amd_irongate_masks,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = amd_create_gatt_table,
.free_gatt_table = amd_free_gatt_table,
.insert_memory = amd_insert_memory,
.remove_memory = amd_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
static struct agp_device_ids amd_agp_device_ids[] __devinitdata =
{
{
.device_id = PCI_DEVICE_ID_AMD_FE_GATE_7006,
.chipset_name = "Irongate",
},
{
.device_id = PCI_DEVICE_ID_AMD_FE_GATE_700E,
.chipset_name = "761",
},
{
.device_id = PCI_DEVICE_ID_AMD_FE_GATE_700C,
.chipset_name = "760MP",
},
{ }, /* dummy final entry, always present */
};
static int __devinit agp_amdk7_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
u8 cap_ptr;
int j;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
j = ent - agp_amdk7_pci_table;
printk(KERN_INFO PFX "Detected AMD %s chipset\n",
amd_agp_device_ids[j].chipset_name);
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &amd_irongate_driver;
bridge->dev_private_data = &amd_irongate_private,
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_amdk7_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
/* must be the same order as name table above */
static struct pci_device_id agp_amdk7_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_FE_GATE_7006,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_FE_GATE_700E,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_FE_GATE_700C,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_amdk7_pci_table);
static struct pci_driver agp_amdk7_pci_driver = {
.name = "agpgart-amdk7",
.id_table = agp_amdk7_pci_table,
.probe = agp_amdk7_probe,
.remove = agp_amdk7_remove,
};
static int __init agp_amdk7_init(void)
{
return pci_module_init(&agp_amdk7_pci_driver);
}
static void __exit agp_amdk7_cleanup(void)
{
pci_unregister_driver(&agp_amdk7_pci_driver);
}
module_init(agp_amdk7_init);
module_exit(agp_amdk7_cleanup);
MODULE_LICENSE("GPL and additional rights");

View File

@@ -0,0 +1,678 @@
/*
* Copyright 2001-2003 SuSE Labs.
* Distributed under the GNU public license, v2.
*
* This is a GART driver for the AMD Opteron/Athlon64 on-CPU northbridge.
* It also includes support for the AMD 8151 AGP bridge,
* although it doesn't actually do much, as all the real
* work is done in the northbridge(s).
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include "agp.h"
/* Will need to be increased if AMD64 ever goes >8-way. */
#define MAX_HAMMER_GARTS 8
/* PTE bits. */
#define GPTE_VALID 1
#define GPTE_COHERENT 2
/* Aperture control register bits. */
#define GARTEN (1<<0)
#define DISGARTCPU (1<<4)
#define DISGARTIO (1<<5)
/* GART cache control register bits. */
#define INVGART (1<<0)
#define GARTPTEERR (1<<1)
/* K8 On-cpu GART registers */
#define AMD64_GARTAPERTURECTL 0x90
#define AMD64_GARTAPERTUREBASE 0x94
#define AMD64_GARTTABLEBASE 0x98
#define AMD64_GARTCACHECTL 0x9c
#define AMD64_GARTEN (1<<0)
/* NVIDIA K8 registers */
#define NVIDIA_X86_64_0_APBASE 0x10
#define NVIDIA_X86_64_1_APBASE1 0x50
#define NVIDIA_X86_64_1_APLIMIT1 0x54
#define NVIDIA_X86_64_1_APSIZE 0xa8
#define NVIDIA_X86_64_1_APBASE2 0xd8
#define NVIDIA_X86_64_1_APLIMIT2 0xdc
static int nr_garts;
static struct pci_dev * hammers[MAX_HAMMER_GARTS];
static struct resource *aperture_resource;
static int __initdata agp_try_unsupported;
static int gart_iterator;
#define for_each_nb() for(gart_iterator=0;gart_iterator<nr_garts;gart_iterator++)
static void flush_amd64_tlb(struct pci_dev *dev)
{
u32 tmp;
pci_read_config_dword (dev, AMD64_GARTCACHECTL, &tmp);
tmp |= INVGART;
pci_write_config_dword (dev, AMD64_GARTCACHECTL, tmp);
}
static void amd64_tlbflush(struct agp_memory *temp)
{
for_each_nb()
flush_amd64_tlb(hammers[gart_iterator]);
}
static int amd64_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
{
int i, j, num_entries;
long long tmp;
u32 pte;
num_entries = agp_num_entries();
if (type != 0 || mem->type != 0)
return -EINVAL;
/* Make sure we can fit the range in the gatt table. */
/* FIXME: could wrap */
if (((unsigned long)pg_start + mem->page_count) > num_entries)
return -EINVAL;
j = pg_start;
/* gatt table should be empty. */
while (j < (pg_start + mem->page_count)) {
if (!PGE_EMPTY(agp_bridge, readl(agp_bridge->gatt_table+j)))
return -EBUSY;
j++;
}
if (mem->is_flushed == FALSE) {
global_cache_flush();
mem->is_flushed = TRUE;
}
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
tmp = agp_bridge->driver->mask_memory(mem->memory[i], mem->type);
BUG_ON(tmp & 0xffffff0000000ffcULL);
pte = (tmp & 0x000000ff00000000ULL) >> 28;
pte |=(tmp & 0x00000000fffff000ULL);
pte |= GPTE_VALID | GPTE_COHERENT;
writel(pte, agp_bridge->gatt_table+j);
}
amd64_tlbflush(mem);
return 0;
}
/*
* This hack alters the order element according
* to the size of a long. It sucks. I totally disown this, even
* though it does appear to work for the most part.
*/
static struct aper_size_info_32 amd64_aperture_sizes[7] =
{
{32, 8192, 3+(sizeof(long)/8), 0 },
{64, 16384, 4+(sizeof(long)/8), 1<<1 },
{128, 32768, 5+(sizeof(long)/8), 1<<2 },
{256, 65536, 6+(sizeof(long)/8), 1<<1 | 1<<2 },
{512, 131072, 7+(sizeof(long)/8), 1<<3 },
{1024, 262144, 8+(sizeof(long)/8), 1<<1 | 1<<3},
{2048, 524288, 9+(sizeof(long)/8), 1<<2 | 1<<3}
};
/*
* Get the current Aperture size from the x86-64.
* Note, that there may be multiple x86-64's, but we just return
* the value from the first one we find. The set_size functions
* keep the rest coherent anyway. Or at least should do.
*/
static int amd64_fetch_size(void)
{
struct pci_dev *dev;
int i;
u32 temp;
struct aper_size_info_32 *values;
dev = hammers[0];
if (dev==NULL)
return 0;
pci_read_config_dword(dev, AMD64_GARTAPERTURECTL, &temp);
temp = (temp & 0xe);
values = A_SIZE_32(amd64_aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
/*
* In a multiprocessor x86-64 system, this function gets
* called once for each CPU.
*/
static u64 amd64_configure (struct pci_dev *hammer, u64 gatt_table)
{
u64 aperturebase;
u32 tmp;
u64 addr, aper_base;
/* Address to map to */
pci_read_config_dword (hammer, AMD64_GARTAPERTUREBASE, &tmp);
aperturebase = tmp << 25;
aper_base = (aperturebase & PCI_BASE_ADDRESS_MEM_MASK);
/* address of the mappings table */
addr = (u64) gatt_table;
addr >>= 12;
tmp = (u32) addr<<4;
tmp &= ~0xf;
pci_write_config_dword (hammer, AMD64_GARTTABLEBASE, tmp);
/* Enable GART translation for this hammer. */
pci_read_config_dword(hammer, AMD64_GARTAPERTURECTL, &tmp);
tmp |= GARTEN;
tmp &= ~(DISGARTCPU | DISGARTIO);
pci_write_config_dword(hammer, AMD64_GARTAPERTURECTL, tmp);
/* keep CPU's coherent. */
flush_amd64_tlb (hammer);
return aper_base;
}
static struct aper_size_info_32 amd_8151_sizes[7] =
{
{2048, 524288, 9, 0x00000000 }, /* 0 0 0 0 0 0 */
{1024, 262144, 8, 0x00000400 }, /* 1 0 0 0 0 0 */
{512, 131072, 7, 0x00000600 }, /* 1 1 0 0 0 0 */
{256, 65536, 6, 0x00000700 }, /* 1 1 1 0 0 0 */
{128, 32768, 5, 0x00000720 }, /* 1 1 1 1 0 0 */
{64, 16384, 4, 0x00000730 }, /* 1 1 1 1 1 0 */
{32, 8192, 3, 0x00000738 } /* 1 1 1 1 1 1 */
};
static int amd_8151_configure(void)
{
unsigned long gatt_bus = virt_to_phys(agp_bridge->gatt_table_real);
/* Configure AGP regs in each x86-64 host bridge. */
for_each_nb() {
agp_bridge->gart_bus_addr =
amd64_configure(hammers[gart_iterator],gatt_bus);
}
return 0;
}
static void amd64_cleanup(void)
{
u32 tmp;
for_each_nb() {
/* disable gart translation */
pci_read_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, &tmp);
tmp &= ~AMD64_GARTEN;
pci_write_config_dword (hammers[gart_iterator], AMD64_GARTAPERTURECTL, tmp);
}
}
struct agp_bridge_driver amd_8151_driver = {
.owner = THIS_MODULE,
.aperture_sizes = amd_8151_sizes,
.size_type = U32_APER_SIZE,
.num_aperture_sizes = 7,
.configure = amd_8151_configure,
.fetch_size = amd64_fetch_size,
.cleanup = amd64_cleanup,
.tlb_flush = amd64_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = NULL,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = amd64_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
/* Some basic sanity checks for the aperture. */
static int __devinit aperture_valid(u64 aper, u32 size)
{
u32 pfn, c;
if (aper == 0) {
printk(KERN_ERR PFX "No aperture\n");
return 0;
}
if (size < 32*1024*1024) {
printk(KERN_ERR PFX "Aperture too small (%d MB)\n", size>>20);
return 0;
}
if (aper + size > 0xffffffff) {
printk(KERN_ERR PFX "Aperture out of bounds\n");
return 0;
}
pfn = aper >> PAGE_SHIFT;
for (c = 0; c < size/PAGE_SIZE; c++) {
if (!pfn_valid(pfn + c))
break;
if (!PageReserved(pfn_to_page(pfn + c))) {
printk(KERN_ERR PFX "Aperture pointing to RAM\n");
return 0;
}
}
/* Request the Aperture. This catches cases when someone else
already put a mapping in there - happens with some very broken BIOS
Maybe better to use pci_assign_resource/pci_enable_device instead
trusting the bridges? */
if (!aperture_resource &&
!(aperture_resource = request_mem_region(aper, size, "aperture"))) {
printk(KERN_ERR PFX "Aperture conflicts with PCI mapping.\n");
return 0;
}
return 1;
}
/*
* W*s centric BIOS sometimes only set up the aperture in the AGP
* bridge, not the northbridge. On AMD64 this is handled early
* in aperture.c, but when GART_IOMMU is not enabled or we run
* on a 32bit kernel this needs to be redone.
* Unfortunately it is impossible to fix the aperture here because it's too late
* to allocate that much memory. But at least error out cleanly instead of
* crashing.
*/
static __devinit int fix_northbridge(struct pci_dev *nb, struct pci_dev *agp,
u16 cap)
{
u32 aper_low, aper_hi;
u64 aper, nb_aper;
int order = 0;
u32 nb_order, nb_base;
u16 apsize;
pci_read_config_dword(nb, 0x90, &nb_order);
nb_order = (nb_order >> 1) & 7;
pci_read_config_dword(nb, 0x94, &nb_base);
nb_aper = nb_base << 25;
if (aperture_valid(nb_aper, (32*1024*1024)<<nb_order)) {
return 0;
}
/* Northbridge seems to contain crap. Try the AGP bridge. */
pci_read_config_word(agp, cap+0x14, &apsize);
if (apsize == 0xffff)
return -1;
apsize &= 0xfff;
/* Some BIOS use weird encodings not in the AGPv3 table. */
if (apsize & 0xff)
apsize |= 0xf00;
order = 7 - hweight16(apsize);
pci_read_config_dword(agp, 0x10, &aper_low);
pci_read_config_dword(agp, 0x14, &aper_hi);
aper = (aper_low & ~((1<<22)-1)) | ((u64)aper_hi << 32);
printk(KERN_INFO PFX "Aperture from AGP @ %Lx size %u MB\n", aper, 32 << order);
if (order < 0 || !aperture_valid(aper, (32*1024*1024)<<order))
return -1;
pci_write_config_dword(nb, 0x90, order << 1);
pci_write_config_dword(nb, 0x94, aper >> 25);
return 0;
}
static __devinit int cache_nbs (struct pci_dev *pdev, u32 cap_ptr)
{
struct pci_dev *loop_dev = NULL;
int i = 0;
/* cache pci_devs of northbridges. */
while ((loop_dev = pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, loop_dev))
!= NULL) {
if (i == MAX_HAMMER_GARTS) {
printk(KERN_ERR PFX "Too many northbridges for AGP\n");
return -1;
}
if (fix_northbridge(loop_dev, pdev, cap_ptr) < 0) {
printk(KERN_ERR PFX "No usable aperture found.\n");
#ifdef __x86_64__
/* should port this to i386 */
printk(KERN_ERR PFX "Consider rebooting with iommu=memaper=2 to get a good aperture.\n");
#endif
return -1;
}
hammers[i++] = loop_dev;
}
nr_garts = i;
return i == 0 ? -1 : 0;
}
/* Handle AMD 8151 quirks */
static void __devinit amd8151_init(struct pci_dev *pdev, struct agp_bridge_data *bridge)
{
char *revstring;
u8 rev_id;
pci_read_config_byte(pdev, PCI_REVISION_ID, &rev_id);
switch (rev_id) {
case 0x01: revstring="A0"; break;
case 0x02: revstring="A1"; break;
case 0x11: revstring="B0"; break;
case 0x12: revstring="B1"; break;
case 0x13: revstring="B2"; break;
case 0x14: revstring="B3"; break;
default: revstring="??"; break;
}
printk (KERN_INFO PFX "Detected AMD 8151 AGP Bridge rev %s\n", revstring);
/*
* Work around errata.
* Chips before B2 stepping incorrectly reporting v3.5
*/
if (rev_id < 0x13) {
printk (KERN_INFO PFX "Correcting AGP revision (reports 3.5, is really 3.0)\n");
bridge->major_version = 3;
bridge->minor_version = 0;
}
}
static struct aper_size_info_32 nforce3_sizes[5] =
{
{512, 131072, 7, 0x00000000 },
{256, 65536, 6, 0x00000008 },
{128, 32768, 5, 0x0000000C },
{64, 16384, 4, 0x0000000E },
{32, 8192, 3, 0x0000000F }
};
/* Handle shadow device of the Nvidia NForce3 */
/* CHECK-ME original 2.4 version set up some IORRs. Check if that is needed. */
static int __devinit nforce3_agp_init(struct pci_dev *pdev)
{
u32 tmp, apbase, apbar, aplimit;
struct pci_dev *dev1;
int i;
unsigned size = amd64_fetch_size();
printk(KERN_INFO PFX "Setting up Nforce3 AGP.\n");
dev1 = pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(11, 0));
if (dev1 == NULL) {
printk(KERN_INFO PFX "agpgart: Detected an NVIDIA "
"nForce3 chipset, but could not find "
"the secondary device.\n");
return -ENODEV;
}
for (i = 0; i < ARRAY_SIZE(nforce3_sizes); i++)
if (nforce3_sizes[i].size == size)
break;
if (i == ARRAY_SIZE(nforce3_sizes)) {
printk(KERN_INFO PFX "No NForce3 size found for %d\n", size);
return -ENODEV;
}
pci_read_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, &tmp);
tmp &= ~(0xf);
tmp |= nforce3_sizes[i].size_value;
pci_write_config_dword(dev1, NVIDIA_X86_64_1_APSIZE, tmp);
/* shadow x86-64 registers into NVIDIA registers */
pci_read_config_dword (hammers[0], AMD64_GARTAPERTUREBASE, &apbase);
/* if x86-64 aperture base is beyond 4G, exit here */
if ( (apbase & 0x7fff) >> (32 - 25) )
return -ENODEV;
apbase = (apbase & 0x7fff) << 25;
pci_read_config_dword(pdev, NVIDIA_X86_64_0_APBASE, &apbar);
apbar &= ~PCI_BASE_ADDRESS_MEM_MASK;
apbar |= apbase;
pci_write_config_dword(pdev, NVIDIA_X86_64_0_APBASE, apbar);
aplimit = apbase + (size * 1024 * 1024) - 1;
pci_write_config_dword(dev1, NVIDIA_X86_64_1_APBASE1, apbase);
pci_write_config_dword(dev1, NVIDIA_X86_64_1_APLIMIT1, aplimit);
pci_write_config_dword(dev1, NVIDIA_X86_64_1_APBASE2, apbase);
pci_write_config_dword(dev1, NVIDIA_X86_64_1_APLIMIT2, aplimit);
return 0;
}
static int __devinit agp_amd64_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
u8 cap_ptr;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
/* Could check for AGPv3 here */
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
if (pdev->vendor == PCI_VENDOR_ID_AMD &&
pdev->device == PCI_DEVICE_ID_AMD_8151_0) {
amd8151_init(pdev, bridge);
} else {
printk(KERN_INFO PFX "Detected AGP bridge %x\n", pdev->devfn);
}
bridge->driver = &amd_8151_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode);
if (cache_nbs(pdev, cap_ptr) == -1) {
agp_put_bridge(bridge);
return -ENODEV;
}
if (pdev->vendor == PCI_VENDOR_ID_NVIDIA) {
int ret = nforce3_agp_init(pdev);
if (ret) {
agp_put_bridge(bridge);
return ret;
}
}
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_amd64_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
release_mem_region(virt_to_phys(bridge->gatt_table_real),
amd64_aperture_sizes[bridge->aperture_size_idx].size);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static struct pci_device_id agp_amd64_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_AMD,
.device = PCI_DEVICE_ID_AMD_8151_0,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
/* VIA K8T800Pro */
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_K8T800PRO_0,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
/* VIA K8T800 */
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_8385_0,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
/* VIA K8M800 / K8N800 */
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_8380_0,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
/* VIA K8T890 */
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_3238_0,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
/* VIA K8T800/K8M800/K8N800 */
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_VIA,
.device = PCI_DEVICE_ID_VIA_838X_1,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
/* NForce3 */
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NFORCE3,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NFORCE3S,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
/* SIS 755 */
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_SI,
.device = PCI_DEVICE_ID_SI_755,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_amd64_pci_table);
static struct pci_driver agp_amd64_pci_driver = {
.name = "agpgart-amd64",
.id_table = agp_amd64_pci_table,
.probe = agp_amd64_probe,
.remove = agp_amd64_remove,
};
/* Not static due to IOMMU code calling it early. */
int __init agp_amd64_init(void)
{
int err = 0;
if (agp_off)
return -EINVAL;
if (pci_module_init(&agp_amd64_pci_driver) > 0) {
struct pci_dev *dev;
if (!agp_try_unsupported && !agp_try_unsupported_boot) {
printk(KERN_INFO PFX "No supported AGP bridge found.\n");
#ifdef MODULE
printk(KERN_INFO PFX "You can try agp_try_unsupported=1\n");
#else
printk(KERN_INFO PFX "You can boot with agp=try_unsupported\n");
#endif
return -ENODEV;
}
/* First check that we have at least one AMD64 NB */
if (!pci_find_device(PCI_VENDOR_ID_AMD, 0x1103, NULL))
return -ENODEV;
/* Look for any AGP bridge */
dev = NULL;
err = -ENODEV;
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev))) {
if (!pci_find_capability(dev, PCI_CAP_ID_AGP))
continue;
/* Only one bridge supported right now */
if (agp_amd64_probe(dev, NULL) == 0) {
err = 0;
break;
}
}
}
return err;
}
static void __exit agp_amd64_cleanup(void)
{
if (aperture_resource)
release_resource(aperture_resource);
pci_unregister_driver(&agp_amd64_pci_driver);
}
/* On AMD64 the PCI driver needs to initialize this driver early
for the IOMMU, so it has to be called via a backdoor. */
#ifndef CONFIG_GART_IOMMU
module_init(agp_amd64_init);
module_exit(agp_amd64_cleanup);
#endif
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>, Andi Kleen");
MODULE_PARM(agp_try_unsupported, "1i");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,541 @@
/*
* ATi AGPGART routines.
*/
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <asm/agp.h>
#include "agp.h"
#define ATI_GART_MMBASE_ADDR 0x14
#define ATI_RS100_APSIZE 0xac
#define ATI_RS100_IG_AGPMODE 0xb0
#define ATI_RS300_APSIZE 0xf8
#define ATI_RS300_IG_AGPMODE 0xfc
#define ATI_GART_FEATURE_ID 0x00
#define ATI_GART_BASE 0x04
#define ATI_GART_CACHE_SZBASE 0x08
#define ATI_GART_CACHE_CNTRL 0x0c
#define ATI_GART_CACHE_ENTRY_CNTRL 0x10
static struct aper_size_info_lvl2 ati_generic_sizes[7] =
{
{2048, 524288, 0x0000000c},
{1024, 262144, 0x0000000a},
{512, 131072, 0x00000008},
{256, 65536, 0x00000006},
{128, 32768, 0x00000004},
{64, 16384, 0x00000002},
{32, 8192, 0x00000000}
};
static struct gatt_mask ati_generic_masks[] =
{
{ .mask = 1, .type = 0}
};
typedef struct _ati_page_map {
unsigned long *real;
unsigned long __iomem *remapped;
} ati_page_map;
static struct _ati_generic_private {
volatile u8 __iomem *registers;
ati_page_map **gatt_pages;
int num_tables;
} ati_generic_private;
static int ati_create_page_map(ati_page_map *page_map)
{
int i, err = 0;
page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
if (page_map->real == NULL)
return -ENOMEM;
SetPageReserved(virt_to_page(page_map->real));
err = map_page_into_agp(virt_to_page(page_map->real));
/* CACHE_FLUSH(); */
global_cache_flush();
page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
PAGE_SIZE);
if (page_map->remapped == NULL || err) {
ClearPageReserved(virt_to_page(page_map->real));
free_page((unsigned long) page_map->real);
page_map->real = NULL;
return -ENOMEM;
}
/*CACHE_FLUSH();*/
global_cache_flush();
for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++)
writel(agp_bridge->scratch_page, page_map->remapped+i);
return 0;
}
static void ati_free_page_map(ati_page_map *page_map)
{
unmap_page_from_agp(virt_to_page(page_map->real));
iounmap(page_map->remapped);
ClearPageReserved(virt_to_page(page_map->real));
free_page((unsigned long) page_map->real);
}
static void ati_free_gatt_pages(void)
{
int i;
ati_page_map **tables;
ati_page_map *entry;
tables = ati_generic_private.gatt_pages;
for(i = 0; i < ati_generic_private.num_tables; i++) {
entry = tables[i];
if (entry != NULL) {
if (entry->real != NULL)
ati_free_page_map(entry);
kfree(entry);
}
}
kfree(tables);
}
static int ati_create_gatt_pages(int nr_tables)
{
ati_page_map **tables;
ati_page_map *entry;
int retval = 0;
int i;
tables = kmalloc((nr_tables + 1) * sizeof(ati_page_map *),
GFP_KERNEL);
if (tables == NULL)
return -ENOMEM;
memset(tables, 0, sizeof(ati_page_map *) * (nr_tables + 1));
for (i = 0; i < nr_tables; i++) {
entry = kmalloc(sizeof(ati_page_map), GFP_KERNEL);
if (entry == NULL) {
while (i>0) {
kfree (tables[i-1]);
i--;
}
kfree (tables);
tables = NULL;
retval = -ENOMEM;
break;
}
memset(entry, 0, sizeof(ati_page_map));
tables[i] = entry;
retval = ati_create_page_map(entry);
if (retval != 0) break;
}
ati_generic_private.num_tables = nr_tables;
ati_generic_private.gatt_pages = tables;
if (retval != 0) ati_free_gatt_pages();
return retval;
}
static int is_r200(void)
{
if ((agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS100) ||
(agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS200) ||
(agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS200_B) ||
(agp_bridge->dev->device == PCI_DEVICE_ID_ATI_RS250))
return 1;
return 0;
}
static int ati_fetch_size(void)
{
int i;
u32 temp;
struct aper_size_info_lvl2 *values;
if (is_r200())
pci_read_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, &temp);
else
pci_read_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, &temp);
temp = (temp & 0x0000000e);
values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
static void ati_tlbflush(struct agp_memory * mem)
{
OUTREG32(ati_generic_private.registers, ATI_GART_CACHE_CNTRL, 1);
}
static void ati_cleanup(void)
{
struct aper_size_info_lvl2 *previous_size;
u32 temp;
previous_size = A_SIZE_LVL2(agp_bridge->previous_size);
/* Write back the previous size and disable gart translation */
if (is_r200()) {
pci_read_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, &temp);
temp = ((temp & ~(0x0000000f)) | previous_size->size_value);
pci_write_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, temp);
} else {
pci_read_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, &temp);
temp = ((temp & ~(0x0000000f)) | previous_size->size_value);
pci_write_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, temp);
}
iounmap((volatile u8 __iomem *)ati_generic_private.registers);
}
static int ati_configure(void)
{
u32 temp;
/* Get the memory mapped registers */
pci_read_config_dword(agp_bridge->dev, ATI_GART_MMBASE_ADDR, &temp);
temp = (temp & 0xfffff000);
ati_generic_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
if (is_r200())
pci_write_config_dword(agp_bridge->dev, ATI_RS100_IG_AGPMODE, 0x20000);
else
pci_write_config_dword(agp_bridge->dev, ATI_RS300_IG_AGPMODE, 0x20000);
/* address to map too */
/*
pci_read_config_dword(agp_bridge.dev, AGP_APBASE, &temp);
agp_bridge.gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
printk(KERN_INFO PFX "IGP320 gart_bus_addr: %x\n", agp_bridge.gart_bus_addr);
*/
OUTREG32(ati_generic_private.registers, ATI_GART_FEATURE_ID, 0x60000);
/* SIGNALED_SYSTEM_ERROR @ NB_STATUS */
pci_read_config_dword(agp_bridge->dev, 4, &temp);
pci_write_config_dword(agp_bridge->dev, 4, temp | (1<<14));
/* Write out the address of the gatt table */
OUTREG32(ati_generic_private.registers, ATI_GART_BASE,
agp_bridge->gatt_bus_addr);
return 0;
}
/*
*Since we don't need contigious memory we just try
* to get the gatt table once
*/
#define GET_PAGE_DIR_OFF(addr) (addr >> 22)
#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
#undef GET_GATT
#define GET_GATT(addr) (ati_generic_private.gatt_pages[\
GET_PAGE_DIR_IDX(addr)]->remapped)
static int ati_insert_memory(struct agp_memory * mem,
off_t pg_start, int type)
{
int i, j, num_entries;
unsigned long __iomem *cur_gatt;
unsigned long addr;
num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
if (type != 0 || mem->type != 0)
return -EINVAL;
if ((pg_start + mem->page_count) > num_entries)
return -EINVAL;
j = pg_start;
while (j < (pg_start + mem->page_count)) {
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = GET_GATT(addr);
if (!PGE_EMPTY(agp_bridge,readl(cur_gatt+GET_GATT_OFF(addr))))
return -EBUSY;
j++;
}
if (mem->is_flushed == FALSE) {
/*CACHE_FLUSH(); */
global_cache_flush();
mem->is_flushed = TRUE;
}
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = GET_GATT(addr);
writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type), cur_gatt+GET_GATT_OFF(addr));
}
agp_bridge->driver->tlb_flush(mem);
return 0;
}
static int ati_remove_memory(struct agp_memory * mem, off_t pg_start,
int type)
{
int i;
unsigned long __iomem *cur_gatt;
unsigned long addr;
if (type != 0 || mem->type != 0) {
return -EINVAL;
}
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = GET_GATT(addr);
writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr));
}
agp_bridge->driver->tlb_flush(mem);
return 0;
}
static int ati_create_gatt_table(void)
{
struct aper_size_info_lvl2 *value;
ati_page_map page_dir;
unsigned long addr;
int retval;
u32 temp;
int i;
struct aper_size_info_lvl2 *current_size;
value = A_SIZE_LVL2(agp_bridge->current_size);
retval = ati_create_page_map(&page_dir);
if (retval != 0)
return retval;
retval = ati_create_gatt_pages(value->num_entries / 1024);
if (retval != 0) {
ati_free_page_map(&page_dir);
return retval;
}
agp_bridge->gatt_table_real = (u32 *)page_dir.real;
agp_bridge->gatt_table = (u32 __iomem *) page_dir.remapped;
agp_bridge->gatt_bus_addr = virt_to_bus(page_dir.real);
/* Write out the size register */
current_size = A_SIZE_LVL2(agp_bridge->current_size);
if (is_r200()) {
pci_read_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, &temp);
temp = (((temp & ~(0x0000000e)) | current_size->size_value)
| 0x00000001);
pci_write_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, temp);
pci_read_config_dword(agp_bridge->dev, ATI_RS100_APSIZE, &temp);
} else {
pci_read_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, &temp);
temp = (((temp & ~(0x0000000e)) | current_size->size_value)
| 0x00000001);
pci_write_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, temp);
pci_read_config_dword(agp_bridge->dev, ATI_RS300_APSIZE, &temp);
}
/*
* Get the address for the gart region.
* This is a bus address even on the alpha, b/c its
* used to program the agp master not the cpu
*/
pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
agp_bridge->gart_bus_addr = addr;
/* Calculate the agp offset */
for(i = 0; i < value->num_entries / 1024; i++, addr += 0x00400000) {
writel(virt_to_bus(ati_generic_private.gatt_pages[i]->real) | 1,
page_dir.remapped+GET_PAGE_DIR_OFF(addr));
}
return 0;
}
static int ati_free_gatt_table(void)
{
ati_page_map page_dir;
page_dir.real = (unsigned long *)agp_bridge->gatt_table_real;
page_dir.remapped = (unsigned long __iomem *)agp_bridge->gatt_table;
ati_free_gatt_pages();
ati_free_page_map(&page_dir);
return 0;
}
struct agp_bridge_driver ati_generic_bridge = {
.owner = THIS_MODULE,
.aperture_sizes = ati_generic_sizes,
.size_type = LVL2_APER_SIZE,
.num_aperture_sizes = 7,
.configure = ati_configure,
.fetch_size = ati_fetch_size,
.cleanup = ati_cleanup,
.tlb_flush = ati_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = ati_generic_masks,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = ati_create_gatt_table,
.free_gatt_table = ati_free_gatt_table,
.insert_memory = ati_insert_memory,
.remove_memory = ati_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
static struct agp_device_ids ati_agp_device_ids[] __devinitdata =
{
{
.device_id = PCI_DEVICE_ID_ATI_RS100,
.chipset_name = "IGP320/M",
},
{
.device_id = PCI_DEVICE_ID_ATI_RS200,
.chipset_name = "IGP330/340/345/350/M",
},
{
.device_id = PCI_DEVICE_ID_ATI_RS200_B,
.chipset_name = "IGP345M",
},
{
.device_id = PCI_DEVICE_ID_ATI_RS250,
.chipset_name = "IGP7000/M",
},
{
.device_id = PCI_DEVICE_ID_ATI_RS300_100,
.chipset_name = "IGP9100/M",
},
{
.device_id = PCI_DEVICE_ID_ATI_RS300_133,
.chipset_name = "IGP9100/M",
},
{
.device_id = PCI_DEVICE_ID_ATI_RS300_166,
.chipset_name = "IGP9100/M",
},
{
.device_id = PCI_DEVICE_ID_ATI_RS300_200,
.chipset_name = "IGP9100/M",
},
{ }, /* dummy final entry, always present */
};
static int __devinit agp_ati_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_device_ids *devs = ati_agp_device_ids;
struct agp_bridge_data *bridge;
u8 cap_ptr;
int j;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
/* probe for known chipsets */
for (j = 0; devs[j].chipset_name; j++) {
if (pdev->device == devs[j].device_id)
goto found;
}
printk(KERN_ERR PFX
"Unsupported Ati chipset (device id: %04x)\n", pdev->device);
return -ENODEV;
found:
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
bridge->driver = &ati_generic_bridge;
printk(KERN_INFO PFX "Detected Ati %s chipset\n",
devs[j].chipset_name);
/* Fill in the mode register */
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_ati_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static struct pci_device_id agp_ati_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_ATI,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_ati_pci_table);
static struct pci_driver agp_ati_pci_driver = {
.name = "agpgart-ati",
.id_table = agp_ati_pci_table,
.probe = agp_ati_probe,
.remove = agp_ati_remove,
};
static int __init agp_ati_init(void)
{
return pci_module_init(&agp_ati_pci_driver);
}
static void __exit agp_ati_cleanup(void)
{
pci_unregister_driver(&agp_ati_pci_driver);
}
module_init(agp_ati_init);
module_exit(agp_ati_cleanup);
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
MODULE_LICENSE("GPL and additional rights");

View File

@@ -0,0 +1,343 @@
/*
* AGPGART driver backend routines.
* Copyright (C) 2002-2003 Dave Jones.
* Copyright (C) 1999 Jeff Hartmann.
* Copyright (C) 1999 Precision Insight, Inc.
* Copyright (C) 1999 Xi Graphics, Inc.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included
* in all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
* OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* JEFF HARTMANN, DAVE JONES, OR ANY OTHER CONTRIBUTORS BE LIABLE FOR ANY CLAIM,
* DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
* OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE
* OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
*
* TODO:
* - Allocate more than order 0 pages to avoid too much linear map splitting.
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/pagemap.h>
#include <linux/miscdevice.h>
#include <linux/pm.h>
#include <linux/agp_backend.h>
#include <linux/agpgart.h>
#include <linux/vmalloc.h>
#include <asm/io.h>
#include "agp.h"
/* Due to XFree86 brain-damage, we can't go to 1.0 until they
* fix some real stupidity. It's only by chance we can bump
* past 0.99 at all due to some boolean logic error. */
#define AGPGART_VERSION_MAJOR 0
#define AGPGART_VERSION_MINOR 100
static struct agp_version agp_current_version =
{
.major = AGPGART_VERSION_MAJOR,
.minor = AGPGART_VERSION_MINOR,
};
static int agp_count=0;
struct agp_bridge_data agp_bridge_dummy = { .type = NOT_SUPPORTED };
struct agp_bridge_data *agp_bridge = &agp_bridge_dummy;
EXPORT_SYMBOL(agp_bridge);
/**
* agp_backend_acquire - attempt to acquire the agp backend.
*
* returns -EBUSY if agp is in use,
* returns 0 if the caller owns the agp backend
*/
int agp_backend_acquire(void)
{
if (agp_bridge->type == NOT_SUPPORTED)
return -EINVAL;
if (atomic_read(&agp_bridge->agp_in_use))
return -EBUSY;
atomic_inc(&agp_bridge->agp_in_use);
return 0;
}
EXPORT_SYMBOL(agp_backend_acquire);
/**
* agp_backend_release - release the lock on the agp backend.
*
* The caller must insure that the graphics aperture translation table
* is read for use by another entity.
*
* (Ensure that all memory it bound is unbound.)
*/
void agp_backend_release(void)
{
if (agp_bridge->type != NOT_SUPPORTED)
atomic_dec(&agp_bridge->agp_in_use);
}
EXPORT_SYMBOL(agp_backend_release);
struct { int mem, agp; } maxes_table[] = {
{0, 0},
{32, 4},
{64, 28},
{128, 96},
{256, 204},
{512, 440},
{1024, 942},
{2048, 1920},
{4096, 3932}
};
static int agp_find_max(void)
{
long memory, index, result;
#if PAGE_SHIFT < 20
memory = num_physpages >> (20 - PAGE_SHIFT);
#else
memory = num_physpages << (PAGE_SHIFT - 20);
#endif
index = 1;
while ((memory > maxes_table[index].mem) && (index < 8))
index++;
result = maxes_table[index - 1].agp +
( (memory - maxes_table[index - 1].mem) *
(maxes_table[index].agp - maxes_table[index - 1].agp)) /
(maxes_table[index].mem - maxes_table[index - 1].mem);
printk(KERN_INFO PFX "Maximum main memory to use for agp memory: %ldM\n", result);
result = result << (20 - PAGE_SHIFT);
return result;
}
static int agp_backend_initialize(struct agp_bridge_data *bridge)
{
int size_value, rc, got_gatt=0, got_keylist=0;
bridge->max_memory_agp = agp_find_max();
bridge->version = &agp_current_version;
if (bridge->driver->needs_scratch_page) {
void *addr = bridge->driver->agp_alloc_page();
if (!addr) {
printk(KERN_ERR PFX "unable to get memory for scratch page.\n");
return -ENOMEM;
}
bridge->scratch_page_real = virt_to_phys(addr);
bridge->scratch_page =
bridge->driver->mask_memory(bridge->scratch_page_real, 0);
}
size_value = bridge->driver->fetch_size();
if (size_value == 0) {
printk(KERN_ERR PFX "unable to determine aperture size.\n");
rc = -EINVAL;
goto err_out;
}
if (bridge->driver->create_gatt_table()) {
printk(KERN_ERR PFX
"unable to get memory for graphics translation table.\n");
rc = -ENOMEM;
goto err_out;
}
got_gatt = 1;
bridge->key_list = vmalloc(PAGE_SIZE * 4);
if (bridge->key_list == NULL) {
printk(KERN_ERR PFX "error allocating memory for key lists.\n");
rc = -ENOMEM;
goto err_out;
}
got_keylist = 1;
/* FIXME vmalloc'd memory not guaranteed contiguous */
memset(bridge->key_list, 0, PAGE_SIZE * 4);
if (bridge->driver->configure()) {
printk(KERN_ERR PFX "error configuring host chipset.\n");
rc = -EINVAL;
goto err_out;
}
printk(KERN_INFO PFX "AGP aperture is %dM @ 0x%lx\n",
size_value, bridge->gart_bus_addr);
return 0;
err_out:
if (bridge->driver->needs_scratch_page)
bridge->driver->agp_destroy_page(
phys_to_virt(bridge->scratch_page_real));
if (got_gatt)
bridge->driver->free_gatt_table();
if (got_keylist) {
vfree(bridge->key_list);
bridge->key_list = NULL;
}
return rc;
}
/* cannot be __exit b/c as it could be called from __init code */
static void agp_backend_cleanup(struct agp_bridge_data *bridge)
{
if (bridge->driver->cleanup)
bridge->driver->cleanup();
if (bridge->driver->free_gatt_table)
bridge->driver->free_gatt_table();
if (bridge->key_list) {
vfree(bridge->key_list);
bridge->key_list = NULL;
}
if (bridge->driver->agp_destroy_page &&
bridge->driver->needs_scratch_page)
bridge->driver->agp_destroy_page(
phys_to_virt(bridge->scratch_page_real));
}
static const drm_agp_t drm_agp = {
&agp_free_memory,
&agp_allocate_memory,
&agp_bind_memory,
&agp_unbind_memory,
&agp_enable,
&agp_backend_acquire,
&agp_backend_release,
&agp_copy_info
};
/* XXX Kludge alert: agpgart isn't ready for multiple bridges yet */
struct agp_bridge_data *agp_alloc_bridge(void)
{
return agp_bridge;
}
EXPORT_SYMBOL(agp_alloc_bridge);
void agp_put_bridge(struct agp_bridge_data *bridge)
{
}
EXPORT_SYMBOL(agp_put_bridge);
int agp_add_bridge(struct agp_bridge_data *bridge)
{
int error;
if (agp_off)
return -ENODEV;
if (!bridge->dev) {
printk (KERN_DEBUG PFX "Erk, registering with no pci_dev!\n");
return -EINVAL;
}
if (agp_count) {
printk (KERN_INFO PFX
"Only one agpgart device currently supported.\n");
return -ENODEV;
}
/* Grab reference on the chipset driver. */
if (!try_module_get(bridge->driver->owner)) {
printk (KERN_INFO PFX "Couldn't lock chipset driver.\n");
return -EINVAL;
}
bridge->type = SUPPORTED;
error = agp_backend_initialize(agp_bridge);
if (error) {
printk (KERN_INFO PFX "agp_backend_initialize() failed.\n");
goto err_out;
}
error = agp_frontend_initialize();
if (error) {
printk (KERN_INFO PFX "agp_frontend_initialize() failed.\n");
goto frontend_err;
}
/* FIXME: What to do with this? */
inter_module_register("drm_agp", THIS_MODULE, &drm_agp);
agp_count++;
return 0;
frontend_err:
agp_backend_cleanup(agp_bridge);
err_out:
bridge->type = NOT_SUPPORTED;
module_put(bridge->driver->owner);
return error;
}
EXPORT_SYMBOL_GPL(agp_add_bridge);
void agp_remove_bridge(struct agp_bridge_data *bridge)
{
bridge->type = NOT_SUPPORTED;
agp_frontend_cleanup();
agp_backend_cleanup(bridge);
inter_module_unregister("drm_agp");
agp_count--;
module_put(bridge->driver->owner);
}
EXPORT_SYMBOL_GPL(agp_remove_bridge);
int agp_off;
int agp_try_unsupported_boot;
EXPORT_SYMBOL(agp_off);
EXPORT_SYMBOL(agp_try_unsupported_boot);
static int __init agp_init(void)
{
if (!agp_off)
printk(KERN_INFO "Linux agpgart interface v%d.%d (c) Dave Jones\n",
AGPGART_VERSION_MAJOR, AGPGART_VERSION_MINOR);
return 0;
}
void __exit agp_exit(void)
{
}
#ifndef MODULE
static __init int agp_setup(char *s)
{
if (!strcmp(s,"off"))
agp_off = 1;
if (!strcmp(s,"try_unsupported"))
agp_try_unsupported_boot = 1;
return 1;
}
__setup("agp=", agp_setup);
#endif
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
MODULE_DESCRIPTION("AGP GART driver");
MODULE_LICENSE("GPL and additional rights");
MODULE_ALIAS_MISCDEV(AGPGART_MINOR);
module_init(agp_init);
module_exit(agp_exit);

View File

@@ -0,0 +1,460 @@
/*
* Transmeta's Efficeon AGPGART driver.
*
* Based upon a diff by Linus around November '02.
*
* Ported to the 2.6 kernel by Carlos Puchol <cpglinux@puchol.com>
* and H. Peter Anvin <hpa@transmeta.com>.
*/
/*
* NOTE-cpg-040217:
*
* - when compiled as a module, after loading the module,
* it will refuse to unload, indicating it is in use,
* when it is not.
* - no s3 (suspend to ram) testing.
* - tested on the efficeon integrated nothbridge for tens
* of iterations of starting x and glxgears.
* - tested with radeon 9000 and radeon mobility m9 cards
* - tested with c3/c4 enabled (with the mobility m9 card)
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <linux/gfp.h>
#include <linux/page-flags.h>
#include <linux/mm.h>
#include "agp.h"
/*
* The real differences to the generic AGP code is
* in the GART mappings - a two-level setup with the
* first level being an on-chip 64-entry table.
*
* The page array is filled through the ATTPAGE register
* (Aperture Translation Table Page Register) at 0xB8. Bits:
* 31:20: physical page address
* 11:9: Page Attribute Table Index (PATI)
* must match the PAT index for the
* mapped pages (the 2nd level page table pages
* themselves should be just regular WB-cacheable,
* so this is normally zero.)
* 8: Present
* 7:6: reserved, write as zero
* 5:0: GATT directory index: which 1st-level entry
*
* The Efficeon AGP spec requires pages to be WB-cacheable
* but to be explicitly CLFLUSH'd after any changes.
*/
#define EFFICEON_ATTPAGE 0xb8
#define EFFICEON_L1_SIZE 64 /* Number of PDE pages */
#define EFFICEON_PATI (0 << 9)
#define EFFICEON_PRESENT (1 << 8)
static struct _efficeon_private {
unsigned long l1_table[EFFICEON_L1_SIZE];
} efficeon_private;
static struct gatt_mask efficeon_generic_masks[] =
{
{.mask = 0x00000001, .type = 0}
};
static struct aper_size_info_lvl2 efficeon_generic_sizes[4] =
{
{256, 65536, 0},
{128, 32768, 32},
{64, 16384, 48},
{32, 8192, 56}
};
/*
* Control interfaces are largely identical to
* the legacy Intel 440BX..
*/
static int efficeon_fetch_size(void)
{
int i;
u16 temp;
struct aper_size_info_lvl2 *values;
pci_read_config_word(agp_bridge->dev, INTEL_APSIZE, &temp);
values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
static void efficeon_tlbflush(struct agp_memory * mem)
{
printk(KERN_DEBUG PFX "efficeon_tlbflush()\n");
pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2200);
pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
}
static void efficeon_cleanup(void)
{
u16 temp;
struct aper_size_info_lvl2 *previous_size;
printk(KERN_DEBUG PFX "efficeon_cleanup()\n");
previous_size = A_SIZE_LVL2(agp_bridge->previous_size);
pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
pci_write_config_word(agp_bridge->dev, INTEL_APSIZE,
previous_size->size_value);
}
static int efficeon_configure(void)
{
u32 temp;
u16 temp2;
struct aper_size_info_lvl2 *current_size;
printk(KERN_DEBUG PFX "efficeon_configure()\n");
current_size = A_SIZE_LVL2(agp_bridge->current_size);
/* aperture size */
pci_write_config_word(agp_bridge->dev, INTEL_APSIZE,
current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* agpctrl */
pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x2280);
/* paccfg/nbxcfg */
pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp2);
pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG,
(temp2 & ~(1 << 10)) | (1 << 9) | (1 << 11));
/* clear any possible error conditions */
pci_write_config_byte(agp_bridge->dev, INTEL_ERRSTS + 1, 7);
return 0;
}
static int efficeon_free_gatt_table(void)
{
int index, freed = 0;
for (index = 0; index < EFFICEON_L1_SIZE; index++) {
unsigned long page = efficeon_private.l1_table[index];
if (page) {
efficeon_private.l1_table[index] = 0;
ClearPageReserved(virt_to_page((char *)page));
free_page(page);
freed++;
}
printk(KERN_DEBUG PFX "efficeon_free_gatt_table(%p, %02x, %08x)\n",
agp_bridge->dev, EFFICEON_ATTPAGE, index);
pci_write_config_dword(agp_bridge->dev,
EFFICEON_ATTPAGE, index);
}
printk(KERN_DEBUG PFX "efficeon_free_gatt_table() freed %d pages\n", freed);
return 0;
}
/*
* Since we don't need contigious memory we just try
* to get the gatt table once
*/
#define GET_PAGE_DIR_OFF(addr) (addr >> 22)
#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
#undef GET_GATT
#define GET_GATT(addr) (efficeon_private.gatt_pages[\
GET_PAGE_DIR_IDX(addr)]->remapped)
static int efficeon_create_gatt_table(void)
{
int index;
const int pati = EFFICEON_PATI;
const int present = EFFICEON_PRESENT;
const int clflush_chunk = ((cpuid_ebx(1) >> 8) & 0xff) << 3;
int num_entries, l1_pages;
num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
printk(KERN_DEBUG PFX "efficeon_create_gatt_table(%d)\n", num_entries);
/* There are 2^10 PTE pages per PDE page */
BUG_ON(num_entries & 0x3ff);
l1_pages = num_entries >> 10;
for (index = 0 ; index < l1_pages ; index++) {
int offset;
unsigned long page;
unsigned long value;
page = efficeon_private.l1_table[index];
BUG_ON(page);
page = get_zeroed_page(GFP_KERNEL);
if (!page) {
efficeon_free_gatt_table();
return -ENOMEM;
}
SetPageReserved(virt_to_page((char *)page));
for (offset = 0; offset < PAGE_SIZE; offset += clflush_chunk)
asm volatile("clflush %0" : : "m" (*(char *)(page+offset)));
efficeon_private.l1_table[index] = page;
value = __pa(page) | pati | present | index;
pci_write_config_dword(agp_bridge->dev,
EFFICEON_ATTPAGE, value);
}
return 0;
}
static int efficeon_insert_memory(struct agp_memory * mem, off_t pg_start, int type)
{
int i, count = mem->page_count, num_entries;
unsigned int *page, *last_page;
const int clflush_chunk = ((cpuid_ebx(1) >> 8) & 0xff) << 3;
const unsigned long clflush_mask = ~(clflush_chunk-1);
printk(KERN_DEBUG PFX "efficeon_insert_memory(%lx, %d)\n", pg_start, count);
num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
if ((pg_start + mem->page_count) > num_entries)
return -EINVAL;
if (type != 0 || mem->type != 0)
return -EINVAL;
if (mem->is_flushed == FALSE) {
global_cache_flush();
mem->is_flushed = TRUE;
}
last_page = NULL;
for (i = 0; i < count; i++) {
int index = pg_start + i;
unsigned long insert = mem->memory[i];
page = (unsigned int *) efficeon_private.l1_table[index >> 10];
if (!page)
continue;
page += (index & 0x3ff);
*page = insert;
/* clflush is slow, so don't clflush until we have to */
if ( last_page &&
((unsigned long)page^(unsigned long)last_page) & clflush_mask )
asm volatile("clflush %0" : : "m" (*last_page));
last_page = page;
}
if ( last_page )
asm volatile("clflush %0" : : "m" (*last_page));
agp_bridge->driver->tlb_flush(mem);
return 0;
}
static int efficeon_remove_memory(struct agp_memory * mem, off_t pg_start, int type)
{
int i, count = mem->page_count, num_entries;
printk(KERN_DEBUG PFX "efficeon_remove_memory(%lx, %d)\n", pg_start, count);
num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
if ((pg_start + mem->page_count) > num_entries)
return -EINVAL;
if (type != 0 || mem->type != 0)
return -EINVAL;
for (i = 0; i < count; i++) {
int index = pg_start + i;
unsigned int *page = (unsigned int *) efficeon_private.l1_table[index >> 10];
if (!page)
continue;
page += (index & 0x3ff);
*page = 0;
}
agp_bridge->driver->tlb_flush(mem);
return 0;
}
struct agp_bridge_driver efficeon_driver = {
.owner = THIS_MODULE,
.aperture_sizes = efficeon_generic_sizes,
.size_type = LVL2_APER_SIZE,
.num_aperture_sizes = 4,
.configure = efficeon_configure,
.fetch_size = efficeon_fetch_size,
.cleanup = efficeon_cleanup,
.tlb_flush = efficeon_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = efficeon_generic_masks,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
// Efficeon-specific GATT table setup / populate / teardown
.create_gatt_table = efficeon_create_gatt_table,
.free_gatt_table = efficeon_free_gatt_table,
.insert_memory = efficeon_insert_memory,
.remove_memory = efficeon_remove_memory,
.cant_use_aperture = 0, // 1 might be faster?
// Generic
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
static int agp_efficeon_resume(struct pci_dev *pdev)
{
printk(KERN_DEBUG PFX "agp_efficeon_resume()\n");
return efficeon_configure();
}
static int __devinit agp_efficeon_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
u8 cap_ptr;
struct resource *r;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
/* Probe for Efficeon controller */
if (pdev->device != PCI_DEVICE_ID_EFFICEON) {
printk(KERN_ERR PFX "Unsupported Efficeon chipset (device id: %04x)\n",
pdev->device);
return -ENODEV;
}
printk(KERN_INFO PFX "Detected Transmeta Efficeon TM8000 series chipset\n");
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &efficeon_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/*
* The following fixes the case where the BIOS has "forgotten" to
* provide an address range for the GART.
* 20030610 - hamish@zot.org
*/
r = &pdev->resource[0];
if (!r->start && r->end) {
if(pci_assign_resource(pdev, 0)) {
printk(KERN_ERR PFX "could not assign resource 0\n");
return (-ENODEV);
}
}
/*
* If the device has not been properly setup, the following will catch
* the problem and should stop the system from crashing.
* 20030610 - hamish@zot.org
*/
if (pci_enable_device(pdev)) {
printk(KERN_ERR PFX "Unable to Enable PCI device\n");
return (-ENODEV);
}
/* Fill in the mode register */
if (cap_ptr) {
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
}
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_efficeon_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static int agp_efficeon_suspend(struct pci_dev *dev, u32 state)
{
return 0;
}
static struct pci_device_id agp_efficeon_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_TRANSMETA,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_efficeon_pci_table);
static struct pci_driver agp_efficeon_pci_driver = {
.name = "agpgart-efficeon",
.id_table = agp_efficeon_pci_table,
.probe = agp_efficeon_probe,
.remove = agp_efficeon_remove,
.suspend = agp_efficeon_suspend,
.resume = agp_efficeon_resume,
};
static int __init agp_efficeon_init(void)
{
static int agp_initialised=0;
if (agp_initialised == 1)
return 0;
agp_initialised=1;
return pci_module_init(&agp_efficeon_pci_driver);
}
static void __exit agp_efficeon_cleanup(void)
{
pci_unregister_driver(&agp_efficeon_pci_driver);
}
module_init(agp_efficeon_init);
module_exit(agp_efficeon_cleanup);
MODULE_AUTHOR("Carlos Puchol <cpglinux@puchol.com>");
MODULE_LICENSE("GPL and additional rights");

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,542 @@
/*
* HP zx1 AGPGART routines.
*
* (c) Copyright 2002, 2003 Hewlett-Packard Development Company, L.P.
* Bjorn Helgaas <bjorn.helgaas@hp.com>
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License version 2 as
* published by the Free Software Foundation.
*/
#include <linux/acpi.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <asm/acpi-ext.h>
#include "agp.h"
#ifndef log2
#define log2(x) ffz(~(x))
#endif
#define HP_ZX1_IOC_OFFSET 0x1000 /* ACPI reports SBA, we want IOC */
/* HP ZX1 IOC registers */
#define HP_ZX1_IBASE 0x300
#define HP_ZX1_IMASK 0x308
#define HP_ZX1_PCOM 0x310
#define HP_ZX1_TCNFG 0x318
#define HP_ZX1_PDIR_BASE 0x320
#define HP_ZX1_IOVA_BASE GB(1UL)
#define HP_ZX1_IOVA_SIZE GB(1UL)
#define HP_ZX1_GART_SIZE (HP_ZX1_IOVA_SIZE / 2)
#define HP_ZX1_SBA_IOMMU_COOKIE 0x0000badbadc0ffeeUL
#define HP_ZX1_PDIR_VALID_BIT 0x8000000000000000UL
#define HP_ZX1_IOVA_TO_PDIR(va) ((va - hp_private.iova_base) >> hp_private.io_tlb_shift)
#define AGP8X_MODE_BIT 3
#define AGP8X_MODE (1 << AGP8X_MODE_BIT)
/* AGP bridge need not be PCI device, but DRM thinks it is. */
static struct pci_dev fake_bridge_dev;
static int hp_zx1_gart_found;
static struct aper_size_info_fixed hp_zx1_sizes[] =
{
{0, 0, 0}, /* filled in by hp_zx1_fetch_size() */
};
static struct gatt_mask hp_zx1_masks[] =
{
{.mask = HP_ZX1_PDIR_VALID_BIT, .type = 0}
};
static struct _hp_private {
volatile u8 __iomem *ioc_regs;
volatile u8 __iomem *lba_regs;
int lba_cap_offset;
u64 *io_pdir; // PDIR for entire IOVA
u64 *gatt; // PDIR just for GART (subset of above)
u64 gatt_entries;
u64 iova_base;
u64 gart_base;
u64 gart_size;
u64 io_pdir_size;
int io_pdir_owner; // do we own it, or share it with sba_iommu?
int io_page_size;
int io_tlb_shift;
int io_tlb_ps; // IOC ps config
int io_pages_per_kpage;
} hp_private;
static int __init hp_zx1_ioc_shared(void)
{
struct _hp_private *hp = &hp_private;
printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR shared with sba_iommu\n");
/*
* IOC already configured by sba_iommu module; just use
* its setup. We assume:
* - IOVA space is 1Gb in size
* - first 512Mb is IOMMU, second 512Mb is GART
*/
hp->io_tlb_ps = INREG64(hp->ioc_regs, HP_ZX1_TCNFG);
switch (hp->io_tlb_ps) {
case 0: hp->io_tlb_shift = 12; break;
case 1: hp->io_tlb_shift = 13; break;
case 2: hp->io_tlb_shift = 14; break;
case 3: hp->io_tlb_shift = 16; break;
default:
printk(KERN_ERR PFX "Invalid IOTLB page size "
"configuration 0x%x\n", hp->io_tlb_ps);
hp->gatt = NULL;
hp->gatt_entries = 0;
return -ENODEV;
}
hp->io_page_size = 1 << hp->io_tlb_shift;
hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
hp->iova_base = INREG64(hp->ioc_regs, HP_ZX1_IBASE) & ~0x1;
hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - HP_ZX1_GART_SIZE;
hp->gart_size = HP_ZX1_GART_SIZE;
hp->gatt_entries = hp->gart_size / hp->io_page_size;
hp->io_pdir = phys_to_virt(INREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE));
hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
if (hp->gatt[0] != HP_ZX1_SBA_IOMMU_COOKIE) {
/* Normal case when no AGP device in system */
hp->gatt = NULL;
hp->gatt_entries = 0;
printk(KERN_ERR PFX "No reserved IO PDIR entry found; "
"GART disabled\n");
return -ENODEV;
}
return 0;
}
static int __init
hp_zx1_ioc_owner (void)
{
struct _hp_private *hp = &hp_private;
printk(KERN_INFO PFX "HP ZX1 IOC: IOPDIR dedicated to GART\n");
/*
* Select an IOV page size no larger than system page size.
*/
if (PAGE_SIZE >= KB(64)) {
hp->io_tlb_shift = 16;
hp->io_tlb_ps = 3;
} else if (PAGE_SIZE >= KB(16)) {
hp->io_tlb_shift = 14;
hp->io_tlb_ps = 2;
} else if (PAGE_SIZE >= KB(8)) {
hp->io_tlb_shift = 13;
hp->io_tlb_ps = 1;
} else {
hp->io_tlb_shift = 12;
hp->io_tlb_ps = 0;
}
hp->io_page_size = 1 << hp->io_tlb_shift;
hp->io_pages_per_kpage = PAGE_SIZE / hp->io_page_size;
hp->iova_base = HP_ZX1_IOVA_BASE;
hp->gart_size = HP_ZX1_GART_SIZE;
hp->gart_base = hp->iova_base + HP_ZX1_IOVA_SIZE - hp->gart_size;
hp->gatt_entries = hp->gart_size / hp->io_page_size;
hp->io_pdir_size = (HP_ZX1_IOVA_SIZE / hp->io_page_size) * sizeof(u64);
return 0;
}
static int __init
hp_zx1_ioc_init (u64 hpa)
{
struct _hp_private *hp = &hp_private;
hp->ioc_regs = ioremap(hpa, 1024);
if (!hp->ioc_regs)
return -ENOMEM;
/*
* If the IOTLB is currently disabled, we can take it over.
* Otherwise, we have to share with sba_iommu.
*/
hp->io_pdir_owner = (INREG64(hp->ioc_regs, HP_ZX1_IBASE) & 0x1) == 0;
if (hp->io_pdir_owner)
return hp_zx1_ioc_owner();
return hp_zx1_ioc_shared();
}
static int
hp_zx1_lba_find_capability (volatile u8 __iomem *hpa, int cap)
{
u16 status;
u8 pos, id;
int ttl = 48;
status = INREG16(hpa, PCI_STATUS);
if (!(status & PCI_STATUS_CAP_LIST))
return 0;
pos = INREG8(hpa, PCI_CAPABILITY_LIST);
while (ttl-- && pos >= 0x40) {
pos &= ~3;
id = INREG8(hpa, pos + PCI_CAP_LIST_ID);
if (id == 0xff)
break;
if (id == cap)
return pos;
pos = INREG8(hpa, pos + PCI_CAP_LIST_NEXT);
}
return 0;
}
static int __init
hp_zx1_lba_init (u64 hpa)
{
struct _hp_private *hp = &hp_private;
int cap;
hp->lba_regs = ioremap(hpa, 256);
if (!hp->lba_regs)
return -ENOMEM;
hp->lba_cap_offset = hp_zx1_lba_find_capability(hp->lba_regs, PCI_CAP_ID_AGP);
cap = INREG32(hp->lba_regs, hp->lba_cap_offset) & 0xff;
if (cap != PCI_CAP_ID_AGP) {
printk(KERN_ERR PFX "Invalid capability ID 0x%02x at 0x%x\n",
cap, hp->lba_cap_offset);
return -ENODEV;
}
return 0;
}
static int
hp_zx1_fetch_size(void)
{
int size;
size = hp_private.gart_size / MB(1);
hp_zx1_sizes[0].size = size;
agp_bridge->current_size = (void *) &hp_zx1_sizes[0];
return size;
}
static int
hp_zx1_configure (void)
{
struct _hp_private *hp = &hp_private;
agp_bridge->gart_bus_addr = hp->gart_base;
agp_bridge->capndx = hp->lba_cap_offset;
agp_bridge->mode = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
if (hp->io_pdir_owner) {
OUTREG64(hp->ioc_regs, HP_ZX1_PDIR_BASE, virt_to_phys(hp->io_pdir));
OUTREG64(hp->ioc_regs, HP_ZX1_TCNFG, hp->io_tlb_ps);
OUTREG64(hp->ioc_regs, HP_ZX1_IMASK, ~(HP_ZX1_IOVA_SIZE - 1));
OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, hp->iova_base | 0x1);
OUTREG64(hp->ioc_regs, HP_ZX1_PCOM, hp->iova_base | log2(HP_ZX1_IOVA_SIZE));
INREG64(hp->ioc_regs, HP_ZX1_PCOM);
}
return 0;
}
static void
hp_zx1_cleanup (void)
{
struct _hp_private *hp = &hp_private;
if (hp->ioc_regs) {
if (hp->io_pdir_owner)
OUTREG64(hp->ioc_regs, HP_ZX1_IBASE, 0);
iounmap(hp->ioc_regs);
}
if (hp->lba_regs)
iounmap(hp->lba_regs);
}
static void
hp_zx1_tlbflush (struct agp_memory *mem)
{
struct _hp_private *hp = &hp_private;
OUTREG64(hp->ioc_regs, HP_ZX1_PCOM, hp->gart_base | log2(hp->gart_size));
INREG64(hp->ioc_regs, HP_ZX1_PCOM);
}
static int
hp_zx1_create_gatt_table (void)
{
struct _hp_private *hp = &hp_private;
int i;
if (hp->io_pdir_owner) {
hp->io_pdir = (u64 *) __get_free_pages(GFP_KERNEL,
get_order(hp->io_pdir_size));
if (!hp->io_pdir) {
printk(KERN_ERR PFX "Couldn't allocate contiguous "
"memory for I/O PDIR\n");
hp->gatt = NULL;
hp->gatt_entries = 0;
return -ENOMEM;
}
memset(hp->io_pdir, 0, hp->io_pdir_size);
hp->gatt = &hp->io_pdir[HP_ZX1_IOVA_TO_PDIR(hp->gart_base)];
}
for (i = 0; i < hp->gatt_entries; i++) {
hp->gatt[i] = (unsigned long) agp_bridge->scratch_page;
}
return 0;
}
static int
hp_zx1_free_gatt_table (void)
{
struct _hp_private *hp = &hp_private;
if (hp->io_pdir_owner)
free_pages((unsigned long) hp->io_pdir,
get_order(hp->io_pdir_size));
else
hp->gatt[0] = HP_ZX1_SBA_IOMMU_COOKIE;
return 0;
}
static int
hp_zx1_insert_memory (struct agp_memory *mem, off_t pg_start, int type)
{
struct _hp_private *hp = &hp_private;
int i, k;
off_t j, io_pg_start;
int io_pg_count;
if (type != 0 || mem->type != 0) {
return -EINVAL;
}
io_pg_start = hp->io_pages_per_kpage * pg_start;
io_pg_count = hp->io_pages_per_kpage * mem->page_count;
if ((io_pg_start + io_pg_count) > hp->gatt_entries) {
return -EINVAL;
}
j = io_pg_start;
while (j < (io_pg_start + io_pg_count)) {
if (hp->gatt[j]) {
return -EBUSY;
}
j++;
}
if (mem->is_flushed == FALSE) {
global_cache_flush();
mem->is_flushed = TRUE;
}
for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
unsigned long paddr;
paddr = mem->memory[i];
for (k = 0;
k < hp->io_pages_per_kpage;
k++, j++, paddr += hp->io_page_size) {
hp->gatt[j] = agp_bridge->driver->mask_memory(paddr, type);
}
}
agp_bridge->driver->tlb_flush(mem);
return 0;
}
static int
hp_zx1_remove_memory (struct agp_memory *mem, off_t pg_start, int type)
{
struct _hp_private *hp = &hp_private;
int i, io_pg_start, io_pg_count;
if (type != 0 || mem->type != 0) {
return -EINVAL;
}
io_pg_start = hp->io_pages_per_kpage * pg_start;
io_pg_count = hp->io_pages_per_kpage * mem->page_count;
for (i = io_pg_start; i < io_pg_count + io_pg_start; i++) {
hp->gatt[i] = agp_bridge->scratch_page;
}
agp_bridge->driver->tlb_flush(mem);
return 0;
}
static unsigned long
hp_zx1_mask_memory (unsigned long addr, int type)
{
return HP_ZX1_PDIR_VALID_BIT | addr;
}
static void
hp_zx1_enable (u32 mode)
{
struct _hp_private *hp = &hp_private;
u32 command;
command = INREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_STATUS);
command = agp_collect_device_status(mode, command);
command |= 0x00000100;
OUTREG32(hp->lba_regs, hp->lba_cap_offset + PCI_AGP_COMMAND, command);
agp_device_command(command, (mode & AGP8X_MODE) != 0);
}
struct agp_bridge_driver hp_zx1_driver = {
.owner = THIS_MODULE,
.size_type = FIXED_APER_SIZE,
.configure = hp_zx1_configure,
.fetch_size = hp_zx1_fetch_size,
.cleanup = hp_zx1_cleanup,
.tlb_flush = hp_zx1_tlbflush,
.mask_memory = hp_zx1_mask_memory,
.masks = hp_zx1_masks,
.agp_enable = hp_zx1_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = hp_zx1_create_gatt_table,
.free_gatt_table = hp_zx1_free_gatt_table,
.insert_memory = hp_zx1_insert_memory,
.remove_memory = hp_zx1_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.cant_use_aperture = 1,
};
static int __init
hp_zx1_setup (u64 ioc_hpa, u64 lba_hpa)
{
struct agp_bridge_data *bridge;
int error = 0;
error = hp_zx1_ioc_init(ioc_hpa);
if (error)
goto fail;
error = hp_zx1_lba_init(lba_hpa);
if (error)
goto fail;
bridge = agp_alloc_bridge();
if (!bridge) {
error = -ENOMEM;
goto fail;
}
bridge->driver = &hp_zx1_driver;
fake_bridge_dev.vendor = PCI_VENDOR_ID_HP;
fake_bridge_dev.device = PCI_DEVICE_ID_HP_PCIX_LBA;
bridge->dev = &fake_bridge_dev;
error = agp_add_bridge(bridge);
fail:
if (error)
hp_zx1_cleanup();
return error;
}
static acpi_status __init
zx1_gart_probe (acpi_handle obj, u32 depth, void *context, void **ret)
{
acpi_handle handle, parent;
acpi_status status;
struct acpi_buffer buffer;
struct acpi_device_info *info;
u64 lba_hpa, sba_hpa, length;
int match;
status = hp_acpi_csr_space(obj, &lba_hpa, &length);
if (ACPI_FAILURE(status))
return AE_OK; /* keep looking for another bridge */
/* Look for an enclosing IOC scope and find its CSR space */
handle = obj;
do {
buffer.length = ACPI_ALLOCATE_LOCAL_BUFFER;
status = acpi_get_object_info(handle, &buffer);
if (ACPI_SUCCESS(status)) {
/* TBD check _CID also */
info = buffer.pointer;
info->hardware_id.value[sizeof(info->hardware_id)-1] = '\0';
match = (strcmp(info->hardware_id.value, "HWP0001") == 0);
ACPI_MEM_FREE(info);
if (match) {
status = hp_acpi_csr_space(handle, &sba_hpa, &length);
if (ACPI_SUCCESS(status))
break;
else {
printk(KERN_ERR PFX "Detected HP ZX1 "
"AGP LBA but no IOC.\n");
return AE_OK;
}
}
}
status = acpi_get_parent(handle, &parent);
handle = parent;
} while (ACPI_SUCCESS(status));
if (hp_zx1_setup(sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa))
return AE_OK;
printk(KERN_INFO PFX "Detected HP ZX1 %s AGP chipset (ioc=%lx, lba=%lx)\n",
(char *) context, sba_hpa + HP_ZX1_IOC_OFFSET, lba_hpa);
hp_zx1_gart_found = 1;
return AE_CTRL_TERMINATE; /* we only support one bridge; quit looking */
}
static int __init
agp_hp_init (void)
{
acpi_get_devices("HWP0003", zx1_gart_probe, "HWP0003", NULL);
if (hp_zx1_gart_found)
return 0;
acpi_get_devices("HWP0007", zx1_gart_probe, "HWP0007", NULL);
if (hp_zx1_gart_found)
return 0;
return -ENODEV;
}
static void __exit
agp_hp_cleanup (void)
{
}
module_init(agp_hp_init);
module_exit(agp_hp_cleanup);
MODULE_LICENSE("GPL and additional rights");

View File

@@ -0,0 +1,635 @@
/*
* For documentation on the i460 AGP interface, see Chapter 7 (AGP Subsystem) of
* the "Intel 460GTX Chipset Software Developer's Manual":
* http://developer.intel.com/design/itanium/downloads/24870401s.htm
*/
/*
* 460GX support by Chris Ahna <christopher.j.ahna@intel.com>
* Clean up & simplification by David Mosberger-Tang <davidm@hpl.hp.com>
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include "agp.h"
#define INTEL_I460_BAPBASE 0x98
#define INTEL_I460_GXBCTL 0xa0
#define INTEL_I460_AGPSIZ 0xa2
#define INTEL_I460_ATTBASE 0xfe200000
#define INTEL_I460_GATT_VALID (1UL << 24)
#define INTEL_I460_GATT_COHERENT (1UL << 25)
/*
* The i460 can operate with large (4MB) pages, but there is no sane way to support this
* within the current kernel/DRM environment, so we disable the relevant code for now.
* See also comments in ia64_alloc_page()...
*/
#define I460_LARGE_IO_PAGES 0
#if I460_LARGE_IO_PAGES
# define I460_IO_PAGE_SHIFT i460.io_page_shift
#else
# define I460_IO_PAGE_SHIFT 12
#endif
#define I460_IOPAGES_PER_KPAGE (PAGE_SIZE >> I460_IO_PAGE_SHIFT)
#define I460_KPAGES_PER_IOPAGE (1 << (I460_IO_PAGE_SHIFT - PAGE_SHIFT))
#define I460_SRAM_IO_DISABLE (1 << 4)
#define I460_BAPBASE_ENABLE (1 << 3)
#define I460_AGPSIZ_MASK 0x7
#define I460_4M_PS (1 << 1)
/* Control bits for Out-Of-GART coherency and Burst Write Combining */
#define I460_GXBCTL_OOG (1UL << 0)
#define I460_GXBCTL_BWC (1UL << 2)
/*
* gatt_table entries are 32-bits wide on the i460; the generic code ought to declare the
* gatt_table and gatt_table_real pointers a "void *"...
*/
#define RD_GATT(index) readl((u32 *) i460.gatt + (index))
#define WR_GATT(index, val) writel((val), (u32 *) i460.gatt + (index))
/*
* The 460 spec says we have to read the last location written to make sure that all
* writes have taken effect
*/
#define WR_FLUSH_GATT(index) RD_GATT(index)
#define log2(x) ffz(~(x))
static struct {
void *gatt; /* ioremap'd GATT area */
/* i460 supports multiple GART page sizes, so GART pageshift is dynamic: */
u8 io_page_shift;
/* BIOS configures chipset to one of 2 possible apbase values: */
u8 dynamic_apbase;
/* structure for tracking partial use of 4MB GART pages: */
struct lp_desc {
unsigned long *alloced_map; /* bitmap of kernel-pages in use */
int refcount; /* number of kernel pages using the large page */
u64 paddr; /* physical address of large page */
} *lp_desc;
} i460;
static struct aper_size_info_8 i460_sizes[3] =
{
/*
* The 32GB aperture is only available with a 4M GART page size. Due to the
* dynamic GART page size, we can't figure out page_order or num_entries until
* runtime.
*/
{32768, 0, 0, 4},
{1024, 0, 0, 2},
{256, 0, 0, 1}
};
static struct gatt_mask i460_masks[] =
{
{
.mask = INTEL_I460_GATT_VALID | INTEL_I460_GATT_COHERENT,
.type = 0
}
};
static int i460_fetch_size (void)
{
int i;
u8 temp;
struct aper_size_info_8 *values;
/* Determine the GART page size */
pci_read_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL, &temp);
i460.io_page_shift = (temp & I460_4M_PS) ? 22 : 12;
pr_debug("i460_fetch_size: io_page_shift=%d\n", i460.io_page_shift);
if (i460.io_page_shift != I460_IO_PAGE_SHIFT) {
printk(KERN_ERR PFX
"I/O (GART) page-size %ZuKB doesn't match expected size %ZuKB\n",
1UL << (i460.io_page_shift - 10), 1UL << (I460_IO_PAGE_SHIFT));
return 0;
}
values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
pci_read_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ, &temp);
/* Exit now if the IO drivers for the GART SRAMS are turned off */
if (temp & I460_SRAM_IO_DISABLE) {
printk(KERN_ERR PFX "GART SRAMS disabled on 460GX chipset\n");
printk(KERN_ERR PFX "AGPGART operation not possible\n");
return 0;
}
/* Make sure we don't try to create an 2 ^ 23 entry GATT */
if ((i460.io_page_shift == 0) && ((temp & I460_AGPSIZ_MASK) == 4)) {
printk(KERN_ERR PFX "We can't have a 32GB aperture with 4KB GART pages\n");
return 0;
}
/* Determine the proper APBASE register */
if (temp & I460_BAPBASE_ENABLE)
i460.dynamic_apbase = INTEL_I460_BAPBASE;
else
i460.dynamic_apbase = AGP_APBASE;
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
/*
* Dynamically calculate the proper num_entries and page_order values for
* the define aperture sizes. Take care not to shift off the end of
* values[i].size.
*/
values[i].num_entries = (values[i].size << 8) >> (I460_IO_PAGE_SHIFT - 12);
values[i].page_order = log2((sizeof(u32)*values[i].num_entries) >> PAGE_SHIFT);
}
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
/* Neglect control bits when matching up size_value */
if ((temp & I460_AGPSIZ_MASK) == values[i].size_value) {
agp_bridge->previous_size = agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
/* There isn't anything to do here since 460 has no GART TLB. */
static void i460_tlb_flush (struct agp_memory *mem)
{
return;
}
/*
* This utility function is needed to prevent corruption of the control bits
* which are stored along with the aperture size in 460's AGPSIZ register
*/
static void i460_write_agpsiz (u8 size_value)
{
u8 temp;
pci_read_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ, &temp);
pci_write_config_byte(agp_bridge->dev, INTEL_I460_AGPSIZ,
((temp & ~I460_AGPSIZ_MASK) | size_value));
}
static void i460_cleanup (void)
{
struct aper_size_info_8 *previous_size;
previous_size = A_SIZE_8(agp_bridge->previous_size);
i460_write_agpsiz(previous_size->size_value);
if (I460_IO_PAGE_SHIFT > PAGE_SHIFT)
kfree(i460.lp_desc);
}
static int i460_configure (void)
{
union {
u32 small[2];
u64 large;
} temp;
size_t size;
u8 scratch;
struct aper_size_info_8 *current_size;
temp.large = 0;
current_size = A_SIZE_8(agp_bridge->current_size);
i460_write_agpsiz(current_size->size_value);
/*
* Do the necessary rigmarole to read all eight bytes of APBASE.
* This has to be done since the AGP aperture can be above 4GB on
* 460 based systems.
*/
pci_read_config_dword(agp_bridge->dev, i460.dynamic_apbase, &(temp.small[0]));
pci_read_config_dword(agp_bridge->dev, i460.dynamic_apbase + 4, &(temp.small[1]));
/* Clear BAR control bits */
agp_bridge->gart_bus_addr = temp.large & ~((1UL << 3) - 1);
pci_read_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL, &scratch);
pci_write_config_byte(agp_bridge->dev, INTEL_I460_GXBCTL,
(scratch & 0x02) | I460_GXBCTL_OOG | I460_GXBCTL_BWC);
/*
* Initialize partial allocation trackers if a GART page is bigger than a kernel
* page.
*/
if (I460_IO_PAGE_SHIFT > PAGE_SHIFT) {
size = current_size->num_entries * sizeof(i460.lp_desc[0]);
i460.lp_desc = kmalloc(size, GFP_KERNEL);
if (!i460.lp_desc)
return -ENOMEM;
memset(i460.lp_desc, 0, size);
}
return 0;
}
static int i460_create_gatt_table (void)
{
int page_order, num_entries, i;
void *temp;
/*
* Load up the fixed address of the GART SRAMS which hold our GATT table.
*/
temp = agp_bridge->current_size;
page_order = A_SIZE_8(temp)->page_order;
num_entries = A_SIZE_8(temp)->num_entries;
i460.gatt = ioremap(INTEL_I460_ATTBASE, PAGE_SIZE << page_order);
/* These are no good, the should be removed from the agp_bridge strucure... */
agp_bridge->gatt_table_real = NULL;
agp_bridge->gatt_table = NULL;
agp_bridge->gatt_bus_addr = 0;
for (i = 0; i < num_entries; ++i)
WR_GATT(i, 0);
WR_FLUSH_GATT(i - 1);
return 0;
}
static int i460_free_gatt_table (void)
{
int num_entries, i;
void *temp;
temp = agp_bridge->current_size;
num_entries = A_SIZE_8(temp)->num_entries;
for (i = 0; i < num_entries; ++i)
WR_GATT(i, 0);
WR_FLUSH_GATT(num_entries - 1);
iounmap(i460.gatt);
return 0;
}
/*
* The following functions are called when the I/O (GART) page size is smaller than
* PAGE_SIZE.
*/
static int i460_insert_memory_small_io_page (struct agp_memory *mem,
off_t pg_start, int type)
{
unsigned long paddr, io_pg_start, io_page_size;
int i, j, k, num_entries;
void *temp;
pr_debug("i460_insert_memory_small_io_page(mem=%p, pg_start=%ld, type=%d, paddr0=0x%lx)\n",
mem, pg_start, type, mem->memory[0]);
io_pg_start = I460_IOPAGES_PER_KPAGE * pg_start;
temp = agp_bridge->current_size;
num_entries = A_SIZE_8(temp)->num_entries;
if ((io_pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count) > num_entries) {
printk(KERN_ERR PFX "Looks like we're out of AGP memory\n");
return -EINVAL;
}
j = io_pg_start;
while (j < (io_pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count)) {
if (!PGE_EMPTY(agp_bridge, RD_GATT(j))) {
pr_debug("i460_insert_memory_small_io_page: GATT[%d]=0x%x is busy\n",
j, RD_GATT(j));
return -EBUSY;
}
j++;
}
io_page_size = 1UL << I460_IO_PAGE_SHIFT;
for (i = 0, j = io_pg_start; i < mem->page_count; i++) {
paddr = mem->memory[i];
for (k = 0; k < I460_IOPAGES_PER_KPAGE; k++, j++, paddr += io_page_size)
WR_GATT(j, agp_bridge->driver->mask_memory(paddr, mem->type));
}
WR_FLUSH_GATT(j - 1);
return 0;
}
static int i460_remove_memory_small_io_page(struct agp_memory *mem,
off_t pg_start, int type)
{
int i;
pr_debug("i460_remove_memory_small_io_page(mem=%p, pg_start=%ld, type=%d)\n",
mem, pg_start, type);
pg_start = I460_IOPAGES_PER_KPAGE * pg_start;
for (i = pg_start; i < (pg_start + I460_IOPAGES_PER_KPAGE * mem->page_count); i++)
WR_GATT(i, 0);
WR_FLUSH_GATT(i - 1);
return 0;
}
#if I460_LARGE_IO_PAGES
/*
* These functions are called when the I/O (GART) page size exceeds PAGE_SIZE.
*
* This situation is interesting since AGP memory allocations that are smaller than a
* single GART page are possible. The i460.lp_desc array tracks partial allocation of the
* large GART pages to work around this issue.
*
* i460.lp_desc[pg_num].refcount tracks the number of kernel pages in use within GART page
* pg_num. i460.lp_desc[pg_num].paddr is the physical address of the large page and
* i460.lp_desc[pg_num].alloced_map is a bitmap of kernel pages that are in use (allocated).
*/
static int i460_alloc_large_page (struct lp_desc *lp)
{
unsigned long order = I460_IO_PAGE_SHIFT - PAGE_SHIFT;
size_t map_size;
void *lpage;
lpage = (void *) __get_free_pages(GFP_KERNEL, order);
if (!lpage) {
printk(KERN_ERR PFX "Couldn't alloc 4M GART page...\n");
return -ENOMEM;
}
map_size = ((I460_KPAGES_PER_IOPAGE + BITS_PER_LONG - 1) & -BITS_PER_LONG)/8;
lp->alloced_map = kmalloc(map_size, GFP_KERNEL);
if (!lp->alloced_map) {
free_pages((unsigned long) lpage, order);
printk(KERN_ERR PFX "Out of memory, we're in trouble...\n");
return -ENOMEM;
}
memset(lp->alloced_map, 0, map_size);
lp->paddr = virt_to_phys(lpage);
lp->refcount = 0;
atomic_add(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
return 0;
}
static void i460_free_large_page (struct lp_desc *lp)
{
kfree(lp->alloced_map);
lp->alloced_map = NULL;
free_pages((unsigned long) phys_to_virt(lp->paddr), I460_IO_PAGE_SHIFT - PAGE_SHIFT);
atomic_sub(I460_KPAGES_PER_IOPAGE, &agp_bridge->current_memory_agp);
}
static int i460_insert_memory_large_io_page (struct agp_memory *mem,
off_t pg_start, int type)
{
int i, start_offset, end_offset, idx, pg, num_entries;
struct lp_desc *start, *end, *lp;
void *temp;
temp = agp_bridge->current_size;
num_entries = A_SIZE_8(temp)->num_entries;
/* Figure out what pg_start means in terms of our large GART pages */
start = &i460.lp_desc[pg_start / I460_KPAGES_PER_IOPAGE];
end = &i460.lp_desc[(pg_start + mem->page_count - 1) / I460_KPAGES_PER_IOPAGE];
start_offset = pg_start % I460_KPAGES_PER_IOPAGE;
end_offset = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_IOPAGE;
if (end > i460.lp_desc + num_entries) {
printk(KERN_ERR PFX "Looks like we're out of AGP memory\n");
return -EINVAL;
}
/* Check if the requested region of the aperture is free */
for (lp = start; lp <= end; ++lp) {
if (!lp->alloced_map)
continue; /* OK, the entire large page is available... */
for (idx = ((lp == start) ? start_offset : 0);
idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE);
idx++)
{
if (test_bit(idx, lp->alloced_map))
return -EBUSY;
}
}
for (lp = start, i = 0; lp <= end; ++lp) {
if (!lp->alloced_map) {
/* Allocate new GART pages... */
if (i460_alloc_large_page(lp) < 0)
return -ENOMEM;
pg = lp - i460.lp_desc;
WR_GATT(pg, agp_bridge->driver->mask_memory(lp->paddr, 0));
WR_FLUSH_GATT(pg);
}
for (idx = ((lp == start) ? start_offset : 0);
idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE);
idx++, i++)
{
mem->memory[i] = lp->paddr + idx*PAGE_SIZE;
__set_bit(idx, lp->alloced_map);
++lp->refcount;
}
}
return 0;
}
static int i460_remove_memory_large_io_page (struct agp_memory *mem,
off_t pg_start, int type)
{
int i, pg, start_offset, end_offset, idx, num_entries;
struct lp_desc *start, *end, *lp;
void *temp;
temp = agp_bridge->driver->current_size;
num_entries = A_SIZE_8(temp)->num_entries;
/* Figure out what pg_start means in terms of our large GART pages */
start = &i460.lp_desc[pg_start / I460_KPAGES_PER_IOPAGE];
end = &i460.lp_desc[(pg_start + mem->page_count - 1) / I460_KPAGES_PER_IOPAGE];
start_offset = pg_start % I460_KPAGES_PER_IOPAGE;
end_offset = (pg_start + mem->page_count - 1) % I460_KPAGES_PER_IOPAGE;
for (i = 0, lp = start; lp <= end; ++lp) {
for (idx = ((lp == start) ? start_offset : 0);
idx < ((lp == end) ? (end_offset + 1) : I460_KPAGES_PER_IOPAGE);
idx++, i++)
{
mem->memory[i] = 0;
__clear_bit(idx, lp->alloced_map);
--lp->refcount;
}
/* Free GART pages if they are unused */
if (lp->refcount == 0) {
pg = lp - i460.lp_desc;
WR_GATT(pg, 0);
WR_FLUSH_GATT(pg);
i460_free_large_page(lp);
}
}
return 0;
}
/* Wrapper routines to call the approriate {small_io_page,large_io_page} function */
static int i460_insert_memory (struct agp_memory *mem,
off_t pg_start, int type)
{
if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
return i460_insert_memory_small_io_page(mem, pg_start, type);
else
return i460_insert_memory_large_io_page(mem, pg_start, type);
}
static int i460_remove_memory (struct agp_memory *mem,
off_t pg_start, int type)
{
if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
return i460_remove_memory_small_io_page(mem, pg_start, type);
else
return i460_remove_memory_large_io_page(mem, pg_start, type);
}
/*
* If the I/O (GART) page size is bigger than the kernel page size, we don't want to
* allocate memory until we know where it is to be bound in the aperture (a
* multi-kernel-page alloc might fit inside of an already allocated GART page).
*
* Let's just hope nobody counts on the allocated AGP memory being there before bind time
* (I don't think current drivers do)...
*/
static void *i460_alloc_page (void)
{
void *page;
if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
page = agp_generic_alloc_page();
else
/* Returning NULL would cause problems */
/* AK: really dubious code. */
page = (void *)~0UL;
return page;
}
static void i460_destroy_page (void *page)
{
if (I460_IO_PAGE_SHIFT <= PAGE_SHIFT)
agp_generic_destroy_page(page);
}
#endif /* I460_LARGE_IO_PAGES */
static unsigned long i460_mask_memory (unsigned long addr, int type)
{
/* Make sure the returned address is a valid GATT entry */
return (agp_bridge->driver->masks[0].mask
| (((addr & ~((1 << I460_IO_PAGE_SHIFT) - 1)) & 0xffffff000) >> 12));
}
struct agp_bridge_driver intel_i460_driver = {
.owner = THIS_MODULE,
.aperture_sizes = i460_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 3,
.configure = i460_configure,
.fetch_size = i460_fetch_size,
.cleanup = i460_cleanup,
.tlb_flush = i460_tlb_flush,
.mask_memory = i460_mask_memory,
.masks = i460_masks,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = i460_create_gatt_table,
.free_gatt_table = i460_free_gatt_table,
#if I460_LARGE_IO_PAGES
.insert_memory = i460_insert_memory,
.remove_memory = i460_remove_memory,
.agp_alloc_page = i460_alloc_page,
.agp_destroy_page = i460_destroy_page,
#else
.insert_memory = i460_insert_memory_small_io_page,
.remove_memory = i460_remove_memory_small_io_page,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
#endif
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.cant_use_aperture = 1,
};
static int __devinit agp_intel_i460_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
u8 cap_ptr;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &intel_i460_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_intel_i460_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static struct pci_device_id agp_intel_i460_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_84460GX,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_intel_i460_pci_table);
static struct pci_driver agp_intel_i460_pci_driver = {
.name = "agpgart-intel-i460",
.id_table = agp_intel_i460_pci_table,
.probe = agp_intel_i460_probe,
.remove = __devexit_p(agp_intel_i460_remove),
};
static int __init agp_intel_i460_init(void)
{
return pci_module_init(&agp_intel_i460_pci_driver);
}
static void __exit agp_intel_i460_cleanup(void)
{
pci_unregister_driver(&agp_intel_i460_pci_driver);
}
module_init(agp_intel_i460_init);
module_exit(agp_intel_i460_cleanup);
MODULE_AUTHOR("Chris Ahna <Christopher.J.Ahna@intel.com>");
MODULE_LICENSE("GPL and additional rights");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,637 @@
/*
* Intel MCH AGPGART routines.
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include "agp.h"
#define AGP_DCACHE_MEMORY 1
#define AGP_PHYS_MEMORY 2
static struct gatt_mask intel_i810_masks[] =
{
{.mask = I810_PTE_VALID, .type = 0},
{.mask = (I810_PTE_VALID | I810_PTE_LOCAL), .type = AGP_DCACHE_MEMORY},
{.mask = I810_PTE_VALID, .type = 0}
};
static void intel_i810_tlbflush(struct agp_memory *mem)
{
return;
}
static void intel_i810_agp_enable(u32 mode)
{
return;
}
/*
* The i810/i830 requires a physical address to program its mouse
* pointer into hardware.
* However the Xserver still writes to it through the agp aperture.
*/
static struct agp_memory *alloc_agpphysmem_i8xx(size_t pg_count, int type)
{
struct agp_memory *new;
void *addr;
if (pg_count != 1)
return NULL;
addr = agp_bridge->driver->agp_alloc_page();
if (addr == NULL)
return NULL;
new = agp_create_memory(1);
if (new == NULL)
return NULL;
new->memory[0] = agp_bridge->driver->mask_memory(virt_to_phys(addr), type);
new->page_count = 1;
new->num_scratch_pages = 1;
new->type = AGP_PHYS_MEMORY;
new->physical = new->memory[0];
return new;
}
static void intel_i810_free_by_type(struct agp_memory *curr)
{
agp_free_key(curr->key);
if(curr->type == AGP_PHYS_MEMORY) {
agp_bridge->driver->agp_destroy_page(phys_to_virt(curr->memory[0]));
vfree(curr->memory);
}
kfree(curr);
}
static unsigned long intel_i810_mask_memory(unsigned long addr, int type)
{
/* Type checking must be done elsewhere */
return addr | agp_bridge->driver->masks[type].mask;
}
static struct aper_size_info_fixed intel_i830_sizes[] =
{
{128, 32768, 5},
/* The 64M mode still requires a 128k gatt */
{64, 16384, 5}
};
static struct _intel_i830_private {
struct pci_dev *i830_dev; /* device one */
volatile u8 __iomem *registers;
int gtt_entries;
} intel_i830_private;
static void intel_i830_init_gtt_entries(void)
{
u16 gmch_ctrl;
int gtt_entries;
u8 rdct;
int local = 0;
static const int ddt[4] = { 0, 16, 32, 64 };
pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
if (agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82830_HB ||
agp_bridge->dev->device == PCI_DEVICE_ID_INTEL_82845G_HB) {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
case I830_GMCH_GMS_STOLEN_512:
gtt_entries = KB(512) - KB(132);
break;
case I830_GMCH_GMS_STOLEN_1024:
gtt_entries = MB(1) - KB(132);
break;
case I830_GMCH_GMS_STOLEN_8192:
gtt_entries = MB(8) - KB(132);
break;
case I830_GMCH_GMS_LOCAL:
rdct = INREG8(intel_i830_private.registers,
I830_RDRAM_CHANNEL_TYPE);
gtt_entries = (I830_RDRAM_ND(rdct) + 1) *
MB(ddt[I830_RDRAM_DDT(rdct)]);
local = 1;
break;
default:
gtt_entries = 0;
break;
}
} else {
switch (gmch_ctrl & I830_GMCH_GMS_MASK) {
case I855_GMCH_GMS_STOLEN_1M:
gtt_entries = MB(1) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_4M:
gtt_entries = MB(4) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_8M:
gtt_entries = MB(8) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_16M:
gtt_entries = MB(16) - KB(132);
break;
case I855_GMCH_GMS_STOLEN_32M:
gtt_entries = MB(32) - KB(132);
break;
default:
gtt_entries = 0;
break;
}
}
if (gtt_entries > 0)
printk(KERN_INFO PFX "Detected %dK %s memory.\n",
gtt_entries / KB(1), local ? "local" : "stolen");
else
printk(KERN_INFO PFX
"No pre-allocated video memory detected.\n");
gtt_entries /= KB(4);
intel_i830_private.gtt_entries = gtt_entries;
}
/* The intel i830 automatically initializes the agp aperture during POST.
* Use the memory already set aside for in the GTT.
*/
static int intel_i830_create_gatt_table(void)
{
int page_order;
struct aper_size_info_fixed *size;
int num_entries;
u32 temp;
size = agp_bridge->current_size;
page_order = size->page_order;
num_entries = size->num_entries;
agp_bridge->gatt_table_real = NULL;
pci_read_config_dword(intel_i830_private.i830_dev,I810_MMADDR,&temp);
temp &= 0xfff80000;
intel_i830_private.registers = (volatile u8 __iomem*) ioremap(temp,128 * 4096);
if (!intel_i830_private.registers)
return (-ENOMEM);
temp = INREG32(intel_i830_private.registers,I810_PGETBL_CTL) & 0xfffff000;
global_cache_flush();
/* we have to call this as early as possible after the MMIO base address is known */
intel_i830_init_gtt_entries();
agp_bridge->gatt_table = NULL;
agp_bridge->gatt_bus_addr = temp;
return(0);
}
/* Return the gatt table to a sane state. Use the top of stolen
* memory for the GTT.
*/
static int intel_i830_free_gatt_table(void)
{
return(0);
}
static int intel_i830_fetch_size(void)
{
u16 gmch_ctrl;
struct aper_size_info_fixed *values;
values = A_SIZE_FIX(agp_bridge->driver->aperture_sizes);
if (agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82830_HB &&
agp_bridge->dev->device != PCI_DEVICE_ID_INTEL_82845G_HB) {
/* 855GM/852GM/865G has 128MB aperture size */
agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
agp_bridge->aperture_size_idx = 0;
return(values[0].size);
}
pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
if ((gmch_ctrl & I830_GMCH_MEM_MASK) == I830_GMCH_MEM_128M) {
agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
agp_bridge->aperture_size_idx = 0;
return(values[0].size);
} else {
agp_bridge->previous_size = agp_bridge->current_size = (void *) values;
agp_bridge->aperture_size_idx = 1;
return(values[1].size);
}
return(0);
}
static int intel_i830_configure(void)
{
struct aper_size_info_fixed *current_size;
u32 temp;
u16 gmch_ctrl;
int i;
current_size = A_SIZE_FIX(agp_bridge->current_size);
pci_read_config_dword(intel_i830_private.i830_dev,I810_GMADDR,&temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
pci_read_config_word(agp_bridge->dev,I830_GMCH_CTRL,&gmch_ctrl);
gmch_ctrl |= I830_GMCH_ENABLED;
pci_write_config_word(agp_bridge->dev,I830_GMCH_CTRL,gmch_ctrl);
OUTREG32(intel_i830_private.registers,I810_PGETBL_CTL,agp_bridge->gatt_bus_addr | I810_PGETBL_ENABLED);
global_cache_flush();
if (agp_bridge->driver->needs_scratch_page)
for (i = intel_i830_private.gtt_entries; i < current_size->num_entries; i++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
return (0);
}
static void intel_i830_cleanup(void)
{
iounmap((void __iomem *) intel_i830_private.registers);
}
static int intel_i830_insert_entries(struct agp_memory *mem,off_t pg_start,
int type)
{
int i,j,num_entries;
void *temp;
temp = agp_bridge->current_size;
num_entries = A_SIZE_FIX(temp)->num_entries;
if (pg_start < intel_i830_private.gtt_entries) {
printk (KERN_DEBUG PFX "pg_start == 0x%.8lx,intel_i830_private.gtt_entries == 0x%.8x\n",
pg_start,intel_i830_private.gtt_entries);
printk (KERN_INFO PFX "Trying to insert into local/stolen memory\n");
return (-EINVAL);
}
if ((pg_start + mem->page_count) > num_entries)
return (-EINVAL);
/* The i830 can't check the GTT for entries since its read only,
* depend on the caller to make the correct offset decisions.
*/
if ((type != 0 && type != AGP_PHYS_MEMORY) ||
(mem->type != 0 && mem->type != AGP_PHYS_MEMORY))
return (-EINVAL);
global_cache_flush();
for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (j * 4),
agp_bridge->driver->mask_memory(mem->memory[i], mem->type));
global_cache_flush();
agp_bridge->driver->tlb_flush(mem);
return(0);
}
static int intel_i830_remove_entries(struct agp_memory *mem,off_t pg_start,
int type)
{
int i;
global_cache_flush();
if (pg_start < intel_i830_private.gtt_entries) {
printk (KERN_INFO PFX "Trying to disable local/stolen memory\n");
return (-EINVAL);
}
for (i = pg_start; i < (mem->page_count + pg_start); i++)
OUTREG32(intel_i830_private.registers,I810_PTE_BASE + (i * 4),agp_bridge->scratch_page);
global_cache_flush();
agp_bridge->driver->tlb_flush(mem);
return (0);
}
static struct agp_memory *intel_i830_alloc_by_type(size_t pg_count,int type)
{
if (type == AGP_PHYS_MEMORY)
return(alloc_agpphysmem_i8xx(pg_count, type));
/* always return NULL for other allocation types for now */
return(NULL);
}
static int intel_8xx_fetch_size(void)
{
u8 temp;
int i;
struct aper_size_info_8 *values;
pci_read_config_byte(agp_bridge->dev, INTEL_APSIZE, &temp);
values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
static void intel_8xx_tlbflush(struct agp_memory *mem)
{
u32 temp;
pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp & ~(1 << 7));
pci_read_config_dword(agp_bridge->dev, INTEL_AGPCTRL, &temp);
pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, temp | (1 << 7));
}
static void intel_8xx_cleanup(void)
{
u16 temp;
struct aper_size_info_8 *previous_size;
previous_size = A_SIZE_8(agp_bridge->previous_size);
pci_read_config_word(agp_bridge->dev, INTEL_NBXCFG, &temp);
pci_write_config_word(agp_bridge->dev, INTEL_NBXCFG, temp & ~(1 << 9));
pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, previous_size->size_value);
}
static int intel_845_configure(void)
{
u32 temp;
u8 temp2;
struct aper_size_info_8 *current_size;
current_size = A_SIZE_8(agp_bridge->current_size);
/* aperture size */
pci_write_config_byte(agp_bridge->dev, INTEL_APSIZE, current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* attbase - aperture base */
pci_write_config_dword(agp_bridge->dev, INTEL_ATTBASE, agp_bridge->gatt_bus_addr);
/* agpctrl */
pci_write_config_dword(agp_bridge->dev, INTEL_AGPCTRL, 0x0000);
/* agpm */
pci_read_config_byte(agp_bridge->dev, INTEL_I845_AGPM, &temp2);
pci_write_config_byte(agp_bridge->dev, INTEL_I845_AGPM, temp2 | (1 << 1));
/* clear any possible error conditions */
pci_write_config_word(agp_bridge->dev, INTEL_I845_ERRSTS, 0x001c);
return 0;
}
/* Setup function */
static struct gatt_mask intel_generic_masks[] =
{
{.mask = 0x00000017, .type = 0}
};
static struct aper_size_info_8 intel_8xx_sizes[7] =
{
{256, 65536, 6, 0},
{128, 32768, 5, 32},
{64, 16384, 4, 48},
{32, 8192, 3, 56},
{16, 4096, 2, 60},
{8, 2048, 1, 62},
{4, 1024, 0, 63}
};
static struct agp_bridge_driver intel_830_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_i830_sizes,
.size_type = FIXED_APER_SIZE,
.num_aperture_sizes = 2,
.needs_scratch_page = TRUE,
.configure = intel_i830_configure,
.fetch_size = intel_i830_fetch_size,
.cleanup = intel_i830_cleanup,
.tlb_flush = intel_i810_tlbflush,
.mask_memory = intel_i810_mask_memory,
.masks = intel_i810_masks,
.agp_enable = intel_i810_agp_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = intel_i830_create_gatt_table,
.free_gatt_table = intel_i830_free_gatt_table,
.insert_memory = intel_i830_insert_entries,
.remove_memory = intel_i830_remove_entries,
.alloc_by_type = intel_i830_alloc_by_type,
.free_by_type = intel_i810_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
static struct agp_bridge_driver intel_845_driver = {
.owner = THIS_MODULE,
.aperture_sizes = intel_8xx_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 7,
.configure = intel_845_configure,
.fetch_size = intel_8xx_fetch_size,
.cleanup = intel_8xx_cleanup,
.tlb_flush = intel_8xx_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = intel_generic_masks,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = agp_generic_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
static int find_i830(u16 device)
{
struct pci_dev *i830_dev;
i830_dev = pci_find_device(PCI_VENDOR_ID_INTEL, device, NULL);
if (i830_dev && PCI_FUNC(i830_dev->devfn) != 0) {
i830_dev = pci_find_device(PCI_VENDOR_ID_INTEL,
device, i830_dev);
}
if (!i830_dev)
return 0;
intel_i830_private.i830_dev = i830_dev;
return 1;
}
static int __devinit agp_intelmch_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
struct resource *r;
char *name = "(unknown)";
u8 cap_ptr = 0;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
switch (pdev->device) {
case PCI_DEVICE_ID_INTEL_82865_HB:
if (find_i830(PCI_DEVICE_ID_INTEL_82865_IG)) {
bridge->driver = &intel_830_driver;
} else {
bridge->driver = &intel_845_driver;
}
name = "865";
break;
case PCI_DEVICE_ID_INTEL_82875_HB:
bridge->driver = &intel_845_driver;
name = "i875";
break;
default:
printk(KERN_ERR PFX "Unsupported Intel chipset (device id: %04x)\n",
pdev->device);
return -ENODEV;
};
bridge->dev = pdev;
bridge->capndx = cap_ptr;
if (bridge->driver == &intel_830_driver)
bridge->dev_private_data = &intel_i830_private;
printk(KERN_INFO PFX "Detected an Intel %s Chipset.\n", name);
/*
* The following fixes the case where the BIOS has "forgotten" to
* provide an address range for the GART.
* 20030610 - hamish@zot.org
*/
r = &pdev->resource[0];
if (!r->start && r->end) {
if(pci_assign_resource(pdev, 0)) {
printk(KERN_ERR PFX "could not assign resource 0\n");
return (-ENODEV);
}
}
/*
* If the device has not been properly setup, the following will catch
* the problem and should stop the system from crashing.
* 20030610 - hamish@zot.org
*/
if (pci_enable_device(pdev)) {
printk(KERN_ERR PFX "Unable to Enable PCI device\n");
return (-ENODEV);
}
/* Fill in the mode register */
if (cap_ptr) {
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
}
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_intelmch_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static int agp_intelmch_resume(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
pci_restore_state(pdev);
if (bridge->driver == &intel_845_driver)
intel_845_configure();
return 0;
}
static struct pci_device_id agp_intelmch_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_82865_HB,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_INTEL,
.device = PCI_DEVICE_ID_INTEL_82875_HB,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_intelmch_pci_table);
static struct pci_driver agp_intelmch_pci_driver = {
.name = "agpgart-intel-mch",
.id_table = agp_intelmch_pci_table,
.probe = agp_intelmch_probe,
.remove = agp_intelmch_remove,
.resume = agp_intelmch_resume,
};
/* intel_agp_init() must not be declared static for explicit
early initialization to work (ie i810fb) */
int __init agp_intelmch_init(void)
{
static int agp_initialised=0;
if (agp_initialised == 1)
return 0;
agp_initialised=1;
return pci_module_init(&agp_intelmch_pci_driver);
}
static void __exit agp_intelmch_cleanup(void)
{
pci_unregister_driver(&agp_intelmch_pci_driver);
}
module_init(agp_intelmch_init);
module_exit(agp_intelmch_cleanup);
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,470 @@
/*
* Setup routines for AGP 3.5 compliant bridges.
*/
#include <linux/list.h>
#include <linux/pci.h>
#include <linux/agp_backend.h>
#include <linux/module.h>
#include "agp.h"
/* Generic AGP 3.5 enabling routines */
struct agp_3_5_dev {
struct list_head list;
u8 capndx;
u32 maxbw;
struct pci_dev *dev;
};
static void agp_3_5_dev_list_insert(struct list_head *head, struct list_head *new)
{
struct agp_3_5_dev *cur, *n = list_entry(new, struct agp_3_5_dev, list);
struct list_head *pos;
list_for_each(pos, head) {
cur = list_entry(pos, struct agp_3_5_dev, list);
if(cur->maxbw > n->maxbw)
break;
}
list_add_tail(new, pos);
}
static void agp_3_5_dev_list_sort(struct agp_3_5_dev *list, unsigned int ndevs)
{
struct agp_3_5_dev *cur;
struct pci_dev *dev;
struct list_head *pos, *tmp, *head = &list->list, *start = head->next;
u32 nistat;
INIT_LIST_HEAD(head);
for (pos=start; pos!=head; ) {
cur = list_entry(pos, struct agp_3_5_dev, list);
dev = cur->dev;
pci_read_config_dword(dev, cur->capndx+AGPNISTAT, &nistat);
cur->maxbw = (nistat >> 16) & 0xff;
tmp = pos;
pos = pos->next;
agp_3_5_dev_list_insert(head, tmp);
}
}
/*
* Initialize all isochronous transfer parameters for an AGP 3.0
* node (i.e. a host bridge in combination with the adapters
* lying behind it...)
*/
static int agp_3_5_isochronous_node_enable(struct agp_bridge_data *bridge,
struct agp_3_5_dev *dev_list, unsigned int ndevs)
{
/*
* Convenience structure to make the calculations clearer
* here. The field names come straight from the AGP 3.0 spec.
*/
struct isoch_data {
u32 maxbw;
u32 n;
u32 y;
u32 l;
u32 rq;
struct agp_3_5_dev *dev;
};
struct pci_dev *td = bridge->dev, *dev;
struct list_head *head = &dev_list->list, *pos;
struct agp_3_5_dev *cur;
struct isoch_data *master, target;
unsigned int cdev = 0;
u32 mnistat, tnistat, tstatus, mcmd;
u16 tnicmd, mnicmd;
u8 mcapndx;
u32 tot_bw = 0, tot_n = 0, tot_rq = 0, y_max, rq_isoch, rq_async;
u32 step, rem, rem_isoch, rem_async;
int ret = 0;
/*
* We'll work with an array of isoch_data's (one for each
* device in dev_list) throughout this function.
*/
if ((master = kmalloc(ndevs * sizeof(*master), GFP_KERNEL)) == NULL) {
ret = -ENOMEM;
goto get_out;
}
/*
* Sort the device list by maxbw. We need to do this because the
* spec suggests that the devices with the smallest requirements
* have their resources allocated first, with all remaining resources
* falling to the device with the largest requirement.
*
* We don't exactly do this, we divide target resources by ndevs
* and split them amongst the AGP 3.0 devices. The remainder of such
* division operations are dropped on the last device, sort of like
* the spec mentions it should be done.
*
* We can't do this sort when we initially construct the dev_list
* because we don't know until this function whether isochronous
* transfers are enabled and consequently whether maxbw will mean
* anything.
*/
agp_3_5_dev_list_sort(dev_list, ndevs);
pci_read_config_dword(td, bridge->capndx+AGPNISTAT, &tnistat);
pci_read_config_dword(td, bridge->capndx+AGPSTAT, &tstatus);
/* Extract power-on defaults from the target */
target.maxbw = (tnistat >> 16) & 0xff;
target.n = (tnistat >> 8) & 0xff;
target.y = (tnistat >> 6) & 0x3;
target.l = (tnistat >> 3) & 0x7;
target.rq = (tstatus >> 24) & 0xff;
y_max = target.y;
/*
* Extract power-on defaults for each device in dev_list. Along
* the way, calculate the total isochronous bandwidth required
* by these devices and the largest requested payload size.
*/
list_for_each(pos, head) {
cur = list_entry(pos, struct agp_3_5_dev, list);
dev = cur->dev;
mcapndx = cur->capndx;
pci_read_config_dword(dev, cur->capndx+AGPNISTAT, &mnistat);
master[cdev].maxbw = (mnistat >> 16) & 0xff;
master[cdev].n = (mnistat >> 8) & 0xff;
master[cdev].y = (mnistat >> 6) & 0x3;
master[cdev].dev = cur;
tot_bw += master[cdev].maxbw;
y_max = max(y_max, master[cdev].y);
cdev++;
}
/* Check if this configuration has any chance of working */
if (tot_bw > target.maxbw) {
printk(KERN_ERR PFX "isochronous bandwidth required "
"by AGP 3.0 devices exceeds that which is supported by "
"the AGP 3.0 bridge!\n");
ret = -ENODEV;
goto free_and_exit;
}
target.y = y_max;
/*
* Write the calculated payload size into the target's NICMD
* register. Doing this directly effects the ISOCH_N value
* in the target's NISTAT register, so we need to do this now
* to get an accurate value for ISOCH_N later.
*/
pci_read_config_word(td, bridge->capndx+AGPNICMD, &tnicmd);
tnicmd &= ~(0x3 << 6);
tnicmd |= target.y << 6;
pci_write_config_word(td, bridge->capndx+AGPNICMD, tnicmd);
/* Reread the target's ISOCH_N */
pci_read_config_dword(td, bridge->capndx+AGPNISTAT, &tnistat);
target.n = (tnistat >> 8) & 0xff;
/* Calculate the minimum ISOCH_N needed by each master */
for (cdev=0; cdev<ndevs; cdev++) {
master[cdev].y = target.y;
master[cdev].n = master[cdev].maxbw / (master[cdev].y + 1);
tot_n += master[cdev].n;
}
/* Exit if the minimal ISOCH_N allocation among the masters is more
* than the target can handle. */
if (tot_n > target.n) {
printk(KERN_ERR PFX "number of isochronous "
"transactions per period required by AGP 3.0 devices "
"exceeds that which is supported by the AGP 3.0 "
"bridge!\n");
ret = -ENODEV;
goto free_and_exit;
}
/* Calculate left over ISOCH_N capability in the target. We'll give
* this to the hungriest device (as per the spec) */
rem = target.n - tot_n;
/*
* Calculate the minimum isochronous RQ depth needed by each master.
* Along the way, distribute the extra ISOCH_N capability calculated
* above.
*/
for (cdev=0; cdev<ndevs; cdev++) {
/*
* This is a little subtle. If ISOCH_Y > 64B, then ISOCH_Y
* byte isochronous writes will be broken into 64B pieces.
* This means we need to budget more RQ depth to account for
* these kind of writes (each isochronous write is actually
* many writes on the AGP bus).
*/
master[cdev].rq = master[cdev].n;
if(master[cdev].y > 0x1)
master[cdev].rq *= (1 << (master[cdev].y - 1));
tot_rq += master[cdev].rq;
if (cdev == ndevs-1)
master[cdev].n += rem;
}
/* Figure the number of isochronous and asynchronous RQ slots the
* target is providing. */
rq_isoch = (target.y > 0x1) ? target.n * (1 << (target.y - 1)) : target.n;
rq_async = target.rq - rq_isoch;
/* Exit if the minimal RQ needs of the masters exceeds what the target
* can provide. */
if (tot_rq > rq_isoch) {
printk(KERN_ERR PFX "number of request queue slots "
"required by the isochronous bandwidth requested by "
"AGP 3.0 devices exceeds the number provided by the "
"AGP 3.0 bridge!\n");
ret = -ENODEV;
goto free_and_exit;
}
/* Calculate asynchronous RQ capability in the target (per master) as
* well as the total number of leftover isochronous RQ slots. */
step = rq_async / ndevs;
rem_async = step + (rq_async % ndevs);
rem_isoch = rq_isoch - tot_rq;
/* Distribute the extra RQ slots calculated above and write our
* isochronous settings out to the actual devices. */
for (cdev=0; cdev<ndevs; cdev++) {
cur = master[cdev].dev;
dev = cur->dev;
mcapndx = cur->capndx;
master[cdev].rq += (cdev == ndevs - 1)
? (rem_async + rem_isoch) : step;
pci_read_config_word(dev, cur->capndx+AGPNICMD, &mnicmd);
pci_read_config_dword(dev, cur->capndx+AGPCMD, &mcmd);
mnicmd &= ~(0xff << 8);
mnicmd &= ~(0x3 << 6);
mcmd &= ~(0xff << 24);
mnicmd |= master[cdev].n << 8;
mnicmd |= master[cdev].y << 6;
mcmd |= master[cdev].rq << 24;
pci_write_config_dword(dev, cur->capndx+AGPCMD, mcmd);
pci_write_config_word(dev, cur->capndx+AGPNICMD, mnicmd);
}
free_and_exit:
kfree(master);
get_out:
return ret;
}
/*
* This function basically allocates request queue slots among the
* AGP 3.0 systems in nonisochronous nodes. The algorithm is
* pretty stupid, divide the total number of RQ slots provided by the
* target by ndevs. Distribute this many slots to each AGP 3.0 device,
* giving any left over slots to the last device in dev_list.
*/
static void agp_3_5_nonisochronous_node_enable(struct agp_bridge_data *bridge,
struct agp_3_5_dev *dev_list, unsigned int ndevs)
{
struct agp_3_5_dev *cur;
struct list_head *head = &dev_list->list, *pos;
u32 tstatus, mcmd;
u32 trq, mrq, rem;
unsigned int cdev = 0;
pci_read_config_dword(bridge->dev, bridge->capndx+AGPSTAT, &tstatus);
trq = (tstatus >> 24) & 0xff;
mrq = trq / ndevs;
rem = mrq + (trq % ndevs);
for (pos=head->next; cdev<ndevs; cdev++, pos=pos->next) {
cur = list_entry(pos, struct agp_3_5_dev, list);
pci_read_config_dword(cur->dev, cur->capndx+AGPCMD, &mcmd);
mcmd &= ~(0xff << 24);
mcmd |= ((cdev == ndevs - 1) ? rem : mrq) << 24;
pci_write_config_dword(cur->dev, cur->capndx+AGPCMD, mcmd);
}
}
/*
* Fully configure and enable an AGP 3.0 host bridge and all the devices
* lying behind it.
*/
int agp_3_5_enable(struct agp_bridge_data *bridge)
{
struct pci_dev *td = bridge->dev, *dev = NULL;
u8 mcapndx;
u32 isoch, arqsz;
u32 tstatus, mstatus, ncapid;
u32 mmajor;
u16 mpstat;
struct agp_3_5_dev *dev_list, *cur;
struct list_head *head, *pos;
unsigned int ndevs = 0;
int ret = 0;
/* Extract some power-on defaults from the target */
pci_read_config_dword(td, bridge->capndx+AGPSTAT, &tstatus);
isoch = (tstatus >> 17) & 0x1;
if (isoch == 0) /* isoch xfers not available, bail out. */
return -ENODEV;
arqsz = (tstatus >> 13) & 0x7;
/*
* Allocate a head for our AGP 3.5 device list
* (multiple AGP v3 devices are allowed behind a single bridge).
*/
if ((dev_list = kmalloc(sizeof(*dev_list), GFP_KERNEL)) == NULL) {
ret = -ENOMEM;
goto get_out;
}
head = &dev_list->list;
INIT_LIST_HEAD(head);
/* Find all AGP devices, and add them to dev_list. */
while ((dev = pci_find_device(PCI_ANY_ID, PCI_ANY_ID, dev)) != NULL) {
mcapndx = pci_find_capability(dev, PCI_CAP_ID_AGP);
if (mcapndx == 0)
continue;
switch ((dev->class >>8) & 0xff00) {
case 0x0600: /* Bridge */
/* Skip bridges. We should call this function for each one. */
continue;
case 0x0001: /* Unclassified device */
/* Don't know what this is, but log it for investigation. */
if (mcapndx != 0) {
printk (KERN_INFO PFX "Wacky, found unclassified AGP device. %x:%x\n",
dev->vendor, dev->device);
}
continue;
case 0x0300: /* Display controller */
case 0x0400: /* Multimedia controller */
if((cur = kmalloc(sizeof(*cur), GFP_KERNEL)) == NULL) {
ret = -ENOMEM;
goto free_and_exit;
}
cur->dev = dev;
pos = &cur->list;
list_add(pos, head);
ndevs++;
continue;
default:
continue;
}
}
/*
* Take an initial pass through the devices lying behind our host
* bridge. Make sure each one is actually an AGP 3.0 device, otherwise
* exit with an error message. Along the way store the AGP 3.0
* cap_ptr for each device
*/
list_for_each(pos, head) {
cur = list_entry(pos, struct agp_3_5_dev, list);
dev = cur->dev;
pci_read_config_word(dev, PCI_STATUS, &mpstat);
if ((mpstat & PCI_STATUS_CAP_LIST) == 0)
continue;
pci_read_config_byte(dev, PCI_CAPABILITY_LIST, &mcapndx);
if (mcapndx != 0) {
do {
pci_read_config_dword(dev, mcapndx, &ncapid);
if ((ncapid & 0xff) != 2)
mcapndx = (ncapid >> 8) & 0xff;
}
while (((ncapid & 0xff) != 2) && (mcapndx != 0));
}
if (mcapndx == 0) {
printk(KERN_ERR PFX "woah! Non-AGP device "
"found on the secondary bus of an AGP 3.5 bridge!\n");
ret = -ENODEV;
goto free_and_exit;
}
mmajor = (ncapid >> AGP_MAJOR_VERSION_SHIFT) & 0xf;
if (mmajor < 3) {
printk(KERN_ERR PFX "woah! AGP 2.0 device "
"found on the secondary bus of an AGP 3.5 "
"bridge operating with AGP 3.0 electricals!\n");
ret = -ENODEV;
goto free_and_exit;
}
cur->capndx = mcapndx;
pci_read_config_dword(dev, cur->capndx+AGPSTAT, &mstatus);
if (((mstatus >> 3) & 0x1) == 0) {
printk(KERN_ERR PFX "woah! AGP 3.x device "
"not operating in AGP 3.x mode found on the "
"secondary bus of an AGP 3.5 bridge operating "
"with AGP 3.0 electricals!\n");
ret = -ENODEV;
goto free_and_exit;
}
}
/*
* Call functions to divide target resources amongst the AGP 3.0
* masters. This process is dramatically different depending on
* whether isochronous transfers are supported.
*/
if (isoch) {
ret = agp_3_5_isochronous_node_enable(bridge, dev_list, ndevs);
if (ret) {
printk(KERN_INFO PFX "Something bad happened setting "
"up isochronous xfers. Falling back to "
"non-isochronous xfer mode.\n");
} else {
goto free_and_exit;
}
}
agp_3_5_nonisochronous_node_enable(bridge, dev_list, ndevs);
free_and_exit:
/* Be sure to free the dev_list */
for (pos=head->next; pos!=head; ) {
cur = list_entry(pos, struct agp_3_5_dev, list);
pos = pos->next;
kfree(cur);
}
kfree(dev_list);
get_out:
return ret;
}

View File

@@ -0,0 +1,419 @@
/*
* Nvidia AGPGART routines.
* Based upon a 2.4 agpgart diff by the folks from NVIDIA, and hacked up
* to work in 2.5 by Dave Jones <davej@codemonkey.org.uk>
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <linux/gfp.h>
#include <linux/page-flags.h>
#include <linux/mm.h>
#include "agp.h"
/* NVIDIA registers */
#define NVIDIA_0_APSIZE 0x80
#define NVIDIA_1_WBC 0xf0
#define NVIDIA_2_GARTCTRL 0xd0
#define NVIDIA_2_APBASE 0xd8
#define NVIDIA_2_APLIMIT 0xdc
#define NVIDIA_2_ATTBASE(i) (0xe0 + (i) * 4)
#define NVIDIA_3_APBASE 0x50
#define NVIDIA_3_APLIMIT 0x54
static struct _nvidia_private {
struct pci_dev *dev_1;
struct pci_dev *dev_2;
struct pci_dev *dev_3;
volatile u32 __iomem *aperture;
int num_active_entries;
off_t pg_offset;
u32 wbc_mask;
} nvidia_private;
static int nvidia_fetch_size(void)
{
int i;
u8 size_value;
struct aper_size_info_8 *values;
pci_read_config_byte(agp_bridge->dev, NVIDIA_0_APSIZE, &size_value);
size_value &= 0x0f;
values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (size_value == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
#define SYSCFG 0xC0010010
#define IORR_BASE0 0xC0010016
#define IORR_MASK0 0xC0010017
#define AMD_K7_NUM_IORR 2
static int nvidia_init_iorr(u32 base, u32 size)
{
u32 base_hi, base_lo;
u32 mask_hi, mask_lo;
u32 sys_hi, sys_lo;
u32 iorr_addr, free_iorr_addr;
/* Find the iorr that is already used for the base */
/* If not found, determine the uppermost available iorr */
free_iorr_addr = AMD_K7_NUM_IORR;
for(iorr_addr = 0; iorr_addr < AMD_K7_NUM_IORR; iorr_addr++) {
rdmsr(IORR_BASE0 + 2 * iorr_addr, base_lo, base_hi);
rdmsr(IORR_MASK0 + 2 * iorr_addr, mask_lo, mask_hi);
if ((base_lo & 0xfffff000) == (base & 0xfffff000))
break;
if ((mask_lo & 0x00000800) == 0)
free_iorr_addr = iorr_addr;
}
if (iorr_addr >= AMD_K7_NUM_IORR) {
iorr_addr = free_iorr_addr;
if (iorr_addr >= AMD_K7_NUM_IORR)
return -EINVAL;
}
base_hi = 0x0;
base_lo = (base & ~0xfff) | 0x18;
mask_hi = 0xf;
mask_lo = ((~(size - 1)) & 0xfffff000) | 0x800;
wrmsr(IORR_BASE0 + 2 * iorr_addr, base_lo, base_hi);
wrmsr(IORR_MASK0 + 2 * iorr_addr, mask_lo, mask_hi);
rdmsr(SYSCFG, sys_lo, sys_hi);
sys_lo |= 0x00100000;
wrmsr(SYSCFG, sys_lo, sys_hi);
return 0;
}
static int nvidia_configure(void)
{
int i, rc, num_dirs;
u32 apbase, aplimit;
struct aper_size_info_8 *current_size;
u32 temp;
current_size = A_SIZE_8(agp_bridge->current_size);
/* aperture size */
pci_write_config_byte(agp_bridge->dev, NVIDIA_0_APSIZE,
current_size->size_value);
/* address to map to */
pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &apbase);
apbase &= PCI_BASE_ADDRESS_MEM_MASK;
agp_bridge->gart_bus_addr = apbase;
aplimit = apbase + (current_size->size * 1024 * 1024) - 1;
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_APBASE, apbase);
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_APLIMIT, aplimit);
pci_write_config_dword(nvidia_private.dev_3, NVIDIA_3_APBASE, apbase);
pci_write_config_dword(nvidia_private.dev_3, NVIDIA_3_APLIMIT, aplimit);
if (0 != (rc = nvidia_init_iorr(apbase, current_size->size * 1024 * 1024)))
return rc;
/* directory size is 64k */
num_dirs = current_size->size / 64;
nvidia_private.num_active_entries = current_size->num_entries;
nvidia_private.pg_offset = 0;
if (num_dirs == 0) {
num_dirs = 1;
nvidia_private.num_active_entries /= (64 / current_size->size);
nvidia_private.pg_offset = (apbase & (64 * 1024 * 1024 - 1) &
~(current_size->size * 1024 * 1024 - 1)) / PAGE_SIZE;
}
/* attbase */
for(i = 0; i < 8; i++) {
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_ATTBASE(i),
(agp_bridge->gatt_bus_addr + (i % num_dirs) * 64 * 1024) | 1);
}
/* gtlb control */
pci_read_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, &temp);
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, temp | 0x11);
/* gart control */
pci_read_config_dword(agp_bridge->dev, NVIDIA_0_APSIZE, &temp);
pci_write_config_dword(agp_bridge->dev, NVIDIA_0_APSIZE, temp | 0x100);
/* map aperture */
nvidia_private.aperture =
(volatile u32 __iomem *) ioremap(apbase, 33 * PAGE_SIZE);
return 0;
}
static void nvidia_cleanup(void)
{
struct aper_size_info_8 *previous_size;
u32 temp;
/* gart control */
pci_read_config_dword(agp_bridge->dev, NVIDIA_0_APSIZE, &temp);
pci_write_config_dword(agp_bridge->dev, NVIDIA_0_APSIZE, temp & ~(0x100));
/* gtlb control */
pci_read_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, &temp);
pci_write_config_dword(nvidia_private.dev_2, NVIDIA_2_GARTCTRL, temp & ~(0x11));
/* unmap aperture */
iounmap((void __iomem *) nvidia_private.aperture);
/* restore previous aperture size */
previous_size = A_SIZE_8(agp_bridge->previous_size);
pci_write_config_byte(agp_bridge->dev, NVIDIA_0_APSIZE,
previous_size->size_value);
/* restore iorr for previous aperture size */
nvidia_init_iorr(agp_bridge->gart_bus_addr,
previous_size->size * 1024 * 1024);
}
/*
* Note we can't use the generic routines, even though they are 99% the same.
* Aperture sizes <64M still requires a full 64k GART directory, but
* only use the portion of the TLB entries that correspond to the apertures
* alignment inside the surrounding 64M block.
*/
extern int agp_memory_reserved;
static int nvidia_insert_memory(struct agp_memory *mem, off_t pg_start, int type)
{
int i, j;
if ((type != 0) || (mem->type != 0))
return -EINVAL;
if ((pg_start + mem->page_count) >
(nvidia_private.num_active_entries - agp_memory_reserved/PAGE_SIZE))
return -EINVAL;
for(j = pg_start; j < (pg_start + mem->page_count); j++) {
if (!PGE_EMPTY(agp_bridge, readl(agp_bridge->gatt_table+nvidia_private.pg_offset+j)))
return -EBUSY;
}
if (mem->is_flushed == FALSE) {
global_cache_flush();
mem->is_flushed = TRUE;
}
for (i = 0, j = pg_start; i < mem->page_count; i++, j++)
writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type),
agp_bridge->gatt_table+nvidia_private.pg_offset+j);
agp_bridge->driver->tlb_flush(mem);
return 0;
}
static int nvidia_remove_memory(struct agp_memory *mem, off_t pg_start, int type)
{
int i;
if ((type != 0) || (mem->type != 0))
return -EINVAL;
for (i = pg_start; i < (mem->page_count + pg_start); i++)
writel(agp_bridge->scratch_page, agp_bridge->gatt_table+nvidia_private.pg_offset+i);
agp_bridge->driver->tlb_flush(mem);
return 0;
}
static void nvidia_tlbflush(struct agp_memory *mem)
{
unsigned long end;
u32 wbc_reg, temp;
int i;
/* flush chipset */
if (nvidia_private.wbc_mask) {
pci_read_config_dword(nvidia_private.dev_1, NVIDIA_1_WBC, &wbc_reg);
wbc_reg |= nvidia_private.wbc_mask;
pci_write_config_dword(nvidia_private.dev_1, NVIDIA_1_WBC, wbc_reg);
end = jiffies + 3*HZ;
do {
pci_read_config_dword(nvidia_private.dev_1,
NVIDIA_1_WBC, &wbc_reg);
if ((signed)(end - jiffies) <= 0) {
printk(KERN_ERR PFX
"TLB flush took more than 3 seconds.\n");
}
} while (wbc_reg & nvidia_private.wbc_mask);
}
/* flush TLB entries */
for(i = 0; i < 32 + 1; i++)
temp = readl(nvidia_private.aperture+(i * PAGE_SIZE / sizeof(u32)));
for(i = 0; i < 32 + 1; i++)
temp = readl(nvidia_private.aperture+(i * PAGE_SIZE / sizeof(u32)));
}
static struct aper_size_info_8 nvidia_generic_sizes[5] =
{
{512, 131072, 7, 0},
{256, 65536, 6, 8},
{128, 32768, 5, 12},
{64, 16384, 4, 14},
/* The 32M mode still requires a 64k gatt */
{32, 16384, 4, 15}
};
static struct gatt_mask nvidia_generic_masks[] =
{
{ .mask = 1, .type = 0}
};
struct agp_bridge_driver nvidia_driver = {
.owner = THIS_MODULE,
.aperture_sizes = nvidia_generic_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 5,
.configure = nvidia_configure,
.fetch_size = nvidia_fetch_size,
.cleanup = nvidia_cleanup,
.tlb_flush = nvidia_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = nvidia_generic_masks,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = nvidia_insert_memory,
.remove_memory = nvidia_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
static int __devinit agp_nvidia_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
u8 cap_ptr;
nvidia_private.dev_1 =
pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 1));
nvidia_private.dev_2 =
pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(0, 2));
nvidia_private.dev_3 =
pci_find_slot((unsigned int)pdev->bus->number, PCI_DEVFN(30, 0));
if (!nvidia_private.dev_1 || !nvidia_private.dev_2 || !nvidia_private.dev_3) {
printk(KERN_INFO PFX "Detected an NVIDIA nForce/nForce2 "
"chipset, but could not find the secondary devices.\n");
return -ENODEV;
}
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
switch (pdev->device) {
case PCI_DEVICE_ID_NVIDIA_NFORCE:
printk(KERN_INFO PFX "Detected NVIDIA nForce chipset\n");
nvidia_private.wbc_mask = 0x00010000;
break;
case PCI_DEVICE_ID_NVIDIA_NFORCE2:
printk(KERN_INFO PFX "Detected NVIDIA nForce2 chipset\n");
nvidia_private.wbc_mask = 0x80000000;
break;
default:
printk(KERN_ERR PFX "Unsupported NVIDIA chipset (device id: %04x)\n",
pdev->device);
return -ENODEV;
}
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &nvidia_driver;
bridge->dev_private_data = &nvidia_private,
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS,
&bridge->mode);
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_nvidia_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static struct pci_device_id agp_nvidia_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NFORCE,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_NVIDIA,
.device = PCI_DEVICE_ID_NVIDIA_NFORCE2,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_nvidia_pci_table);
static struct pci_driver agp_nvidia_pci_driver = {
.name = "agpgart-nvidia",
.id_table = agp_nvidia_pci_table,
.probe = agp_nvidia_probe,
.remove = agp_nvidia_remove,
};
static int __init agp_nvidia_init(void)
{
return pci_module_init(&agp_nvidia_pci_driver);
}
static void __exit agp_nvidia_cleanup(void)
{
pci_unregister_driver(&agp_nvidia_pci_driver);
}
module_init(agp_nvidia_init);
module_exit(agp_nvidia_cleanup);
MODULE_LICENSE("GPL and additional rights");
MODULE_AUTHOR("NVIDIA Corporation");

View File

@@ -0,0 +1,358 @@
/*
* SiS AGPGART routines.
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include <linux/delay.h>
#include "agp.h"
#define SIS_ATTBASE 0x90
#define SIS_APSIZE 0x94
#define SIS_TLBCNTRL 0x97
#define SIS_TLBFLUSH 0x98
static int __devinitdata agp_sis_force_delay = 0;
static int __devinitdata agp_sis_agp_spec = -1;
static int sis_fetch_size(void)
{
u8 temp_size;
int i;
struct aper_size_info_8 *values;
pci_read_config_byte(agp_bridge->dev, SIS_APSIZE, &temp_size);
values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if ((temp_size == values[i].size_value) ||
((temp_size & ~(0x03)) ==
(values[i].size_value & ~(0x03)))) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
static void sis_tlbflush(struct agp_memory *mem)
{
pci_write_config_byte(agp_bridge->dev, SIS_TLBFLUSH, 0x02);
}
static int sis_configure(void)
{
u32 temp;
struct aper_size_info_8 *current_size;
current_size = A_SIZE_8(agp_bridge->current_size);
pci_write_config_byte(agp_bridge->dev, SIS_TLBCNTRL, 0x05);
pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
pci_write_config_dword(agp_bridge->dev, SIS_ATTBASE,
agp_bridge->gatt_bus_addr);
pci_write_config_byte(agp_bridge->dev, SIS_APSIZE,
current_size->size_value);
return 0;
}
static void sis_cleanup(void)
{
struct aper_size_info_8 *previous_size;
previous_size = A_SIZE_8(agp_bridge->previous_size);
pci_write_config_byte(agp_bridge->dev, SIS_APSIZE,
(previous_size->size_value & ~(0x03)));
}
static void sis_delayed_enable(u32 mode)
{
struct pci_dev *device = NULL;
u32 command;
int rate;
printk(KERN_INFO PFX "Found an AGP %d.%d compliant device at %s.\n",
agp_bridge->major_version,
agp_bridge->minor_version,
agp_bridge->dev->slot_name);
pci_read_config_dword(agp_bridge->dev, agp_bridge->capndx + PCI_AGP_STATUS, &command);
command = agp_collect_device_status(mode, command);
command |= AGPSTAT_AGP_ENABLE;
rate = (command & 0x7) << 2;
for_each_pci_dev(device) {
u8 agp = pci_find_capability(device, PCI_CAP_ID_AGP);
if (!agp)
continue;
printk(KERN_INFO PFX "Putting AGP V3 device at %s into %dx mode\n",
pci_name(device), rate);
pci_write_config_dword(device, agp + PCI_AGP_COMMAND, command);
/*
* Weird: on some sis chipsets any rate change in the target
* command register triggers a 5ms screwup during which the master
* cannot be configured
*/
if (device->device == agp_bridge->dev->device) {
printk(KERN_INFO PFX "SiS delay workaround: giving bridge time to recover.\n");
msleep(10);
}
}
}
static struct aper_size_info_8 sis_generic_sizes[7] =
{
{256, 65536, 6, 99},
{128, 32768, 5, 83},
{64, 16384, 4, 67},
{32, 8192, 3, 51},
{16, 4096, 2, 35},
{8, 2048, 1, 19},
{4, 1024, 0, 3}
};
struct agp_bridge_driver sis_driver = {
.owner = THIS_MODULE,
.aperture_sizes = sis_generic_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 7,
.configure = sis_configure,
.fetch_size = sis_fetch_size,
.cleanup = sis_cleanup,
.tlb_flush = sis_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = NULL,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = agp_generic_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
static struct agp_device_ids sis_agp_device_ids[] __devinitdata =
{
{
.device_id = PCI_DEVICE_ID_SI_5591_AGP,
.chipset_name = "5591",
},
{
.device_id = PCI_DEVICE_ID_SI_530,
.chipset_name = "530",
},
{
.device_id = PCI_DEVICE_ID_SI_540,
.chipset_name = "540",
},
{
.device_id = PCI_DEVICE_ID_SI_550,
.chipset_name = "550",
},
{
.device_id = PCI_DEVICE_ID_SI_620,
.chipset_name = "620",
},
{
.device_id = PCI_DEVICE_ID_SI_630,
.chipset_name = "630",
},
{
.device_id = PCI_DEVICE_ID_SI_635,
.chipset_name = "635",
},
{
.device_id = PCI_DEVICE_ID_SI_645,
.chipset_name = "645",
},
{
.device_id = PCI_DEVICE_ID_SI_646,
.chipset_name = "646",
},
{
.device_id = PCI_DEVICE_ID_SI_648,
.chipset_name = "648",
},
{
.device_id = PCI_DEVICE_ID_SI_650,
.chipset_name = "650",
},
{
.device_id = PCI_DEVICE_ID_SI_651,
.chipset_name = "651",
},
{
.device_id = PCI_DEVICE_ID_SI_655,
.chipset_name = "655",
},
{
.device_id = PCI_DEVICE_ID_SI_661,
.chipset_name = "661",
},
{
.device_id = PCI_DEVICE_ID_SI_730,
.chipset_name = "730",
},
{
.device_id = PCI_DEVICE_ID_SI_735,
.chipset_name = "735",
},
{
.device_id = PCI_DEVICE_ID_SI_740,
.chipset_name = "740",
},
{
.device_id = PCI_DEVICE_ID_SI_741,
.chipset_name = "741",
},
{
.device_id = PCI_DEVICE_ID_SI_745,
.chipset_name = "745",
},
{
.device_id = PCI_DEVICE_ID_SI_746,
.chipset_name = "746",
},
{
.device_id = PCI_DEVICE_ID_SI_760,
.chipset_name = "760",
},
{ }, /* dummy final entry, always present */
};
// chipsets that require the 'delay hack'
static int sis_broken_chipsets[] __devinitdata = {
PCI_DEVICE_ID_SI_648,
PCI_DEVICE_ID_SI_746,
0 // terminator
};
static void __devinit sis_get_driver(struct agp_bridge_data *bridge)
{
int i;
for(i=0; sis_broken_chipsets[i]!=0; ++i)
if(bridge->dev->device==sis_broken_chipsets[i])
break;
if(sis_broken_chipsets[i] || agp_sis_force_delay)
sis_driver.agp_enable=sis_delayed_enable;
// sis chipsets that indicate less than agp3.5
// are not actually fully agp3 compliant
if ((agp_bridge->major_version == 3 && agp_bridge->minor_version >= 5
&& agp_sis_agp_spec!=0) || agp_sis_agp_spec==1) {
sis_driver.aperture_sizes = agp3_generic_sizes;
sis_driver.size_type = U16_APER_SIZE;
sis_driver.num_aperture_sizes = AGP_GENERIC_SIZES_ENTRIES;
sis_driver.configure = agp3_generic_configure;
sis_driver.fetch_size = agp3_generic_fetch_size;
sis_driver.cleanup = agp3_generic_cleanup;
sis_driver.tlb_flush = agp3_generic_tlbflush;
}
}
static int __devinit agp_sis_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_device_ids *devs = sis_agp_device_ids;
struct agp_bridge_data *bridge;
u8 cap_ptr;
int j;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
/* probe for known chipsets */
for (j = 0; devs[j].chipset_name; j++) {
if (pdev->device == devs[j].device_id) {
printk(KERN_INFO PFX "Detected SiS %s chipset\n",
devs[j].chipset_name);
goto found;
}
}
printk(KERN_ERR PFX "Unsupported SiS chipset (device id: %04x)\n",
pdev->device);
return -ENODEV;
found:
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &sis_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
get_agp_version(bridge);
/* Fill in the mode register */
pci_read_config_dword(pdev, bridge->capndx+PCI_AGP_STATUS, &bridge->mode);
sis_get_driver(bridge);
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_sis_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static struct pci_device_id agp_sis_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_SI,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_sis_pci_table);
static struct pci_driver agp_sis_pci_driver = {
.name = "agpgart-sis",
.id_table = agp_sis_pci_table,
.probe = agp_sis_probe,
.remove = agp_sis_remove,
};
static int __init agp_sis_init(void)
{
return pci_module_init(&agp_sis_pci_driver);
}
static void __exit agp_sis_cleanup(void)
{
pci_unregister_driver(&agp_sis_pci_driver);
}
module_init(agp_sis_init);
module_exit(agp_sis_cleanup);
MODULE_PARM(agp_sis_force_delay,"i");
MODULE_PARM_DESC(agp_sis_force_delay,"forces sis delay hack");
MODULE_PARM(agp_sis_agp_spec,"i");
MODULE_PARM_DESC(agp_sis_agp_spec,"0=force sis init, 1=force generic agp3 init, default: autodetect");
MODULE_LICENSE("GPL and additional rights");

View File

@@ -0,0 +1,554 @@
/*
* Serverworks AGPGART routines.
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include "agp.h"
#define SVWRKS_COMMAND 0x04
#define SVWRKS_APSIZE 0x10
#define SVWRKS_MMBASE 0x14
#define SVWRKS_CACHING 0x4b
#define SVWRKS_AGP_ENABLE 0x60
#define SVWRKS_FEATURE 0x68
#define SVWRKS_SIZE_MASK 0xfe000000
/* Memory mapped registers */
#define SVWRKS_GART_CACHE 0x02
#define SVWRKS_GATTBASE 0x04
#define SVWRKS_TLBFLUSH 0x10
#define SVWRKS_POSTFLUSH 0x14
#define SVWRKS_DIRFLUSH 0x0c
struct serverworks_page_map {
unsigned long *real;
unsigned long __iomem *remapped;
};
static struct _serverworks_private {
struct pci_dev *svrwrks_dev; /* device one */
volatile u8 __iomem *registers;
struct serverworks_page_map **gatt_pages;
int num_tables;
struct serverworks_page_map scratch_dir;
int gart_addr_ofs;
int mm_addr_ofs;
} serverworks_private;
static int serverworks_create_page_map(struct serverworks_page_map *page_map)
{
int i;
page_map->real = (unsigned long *) __get_free_page(GFP_KERNEL);
if (page_map->real == NULL) {
return -ENOMEM;
}
SetPageReserved(virt_to_page(page_map->real));
global_cache_flush();
page_map->remapped = ioremap_nocache(virt_to_phys(page_map->real),
PAGE_SIZE);
if (page_map->remapped == NULL) {
ClearPageReserved(virt_to_page(page_map->real));
free_page((unsigned long) page_map->real);
page_map->real = NULL;
return -ENOMEM;
}
global_cache_flush();
for(i = 0; i < PAGE_SIZE / sizeof(unsigned long); i++)
writel(agp_bridge->scratch_page, page_map->remapped+i);
return 0;
}
static void serverworks_free_page_map(struct serverworks_page_map *page_map)
{
iounmap(page_map->remapped);
ClearPageReserved(virt_to_page(page_map->real));
free_page((unsigned long) page_map->real);
}
static void serverworks_free_gatt_pages(void)
{
int i;
struct serverworks_page_map **tables;
struct serverworks_page_map *entry;
tables = serverworks_private.gatt_pages;
for(i = 0; i < serverworks_private.num_tables; i++) {
entry = tables[i];
if (entry != NULL) {
if (entry->real != NULL) {
serverworks_free_page_map(entry);
}
kfree(entry);
}
}
kfree(tables);
}
static int serverworks_create_gatt_pages(int nr_tables)
{
struct serverworks_page_map **tables;
struct serverworks_page_map *entry;
int retval = 0;
int i;
tables = kmalloc((nr_tables + 1) * sizeof(struct serverworks_page_map *),
GFP_KERNEL);
if (tables == NULL) {
return -ENOMEM;
}
memset(tables, 0, sizeof(struct serverworks_page_map *) * (nr_tables + 1));
for (i = 0; i < nr_tables; i++) {
entry = kmalloc(sizeof(struct serverworks_page_map), GFP_KERNEL);
if (entry == NULL) {
retval = -ENOMEM;
break;
}
memset(entry, 0, sizeof(struct serverworks_page_map));
tables[i] = entry;
retval = serverworks_create_page_map(entry);
if (retval != 0) break;
}
serverworks_private.num_tables = nr_tables;
serverworks_private.gatt_pages = tables;
if (retval != 0) serverworks_free_gatt_pages();
return retval;
}
#define SVRWRKS_GET_GATT(addr) (serverworks_private.gatt_pages[\
GET_PAGE_DIR_IDX(addr)]->remapped)
#ifndef GET_PAGE_DIR_OFF
#define GET_PAGE_DIR_OFF(addr) (addr >> 22)
#endif
#ifndef GET_PAGE_DIR_IDX
#define GET_PAGE_DIR_IDX(addr) (GET_PAGE_DIR_OFF(addr) - \
GET_PAGE_DIR_OFF(agp_bridge->gart_bus_addr))
#endif
#ifndef GET_GATT_OFF
#define GET_GATT_OFF(addr) ((addr & 0x003ff000) >> 12)
#endif
static int serverworks_create_gatt_table(void)
{
struct aper_size_info_lvl2 *value;
struct serverworks_page_map page_dir;
int retval;
u32 temp;
int i;
value = A_SIZE_LVL2(agp_bridge->current_size);
retval = serverworks_create_page_map(&page_dir);
if (retval != 0) {
return retval;
}
retval = serverworks_create_page_map(&serverworks_private.scratch_dir);
if (retval != 0) {
serverworks_free_page_map(&page_dir);
return retval;
}
/* Create a fake scratch directory */
for(i = 0; i < 1024; i++) {
writel(agp_bridge->scratch_page, serverworks_private.scratch_dir.remapped+i);
writel(virt_to_phys(serverworks_private.scratch_dir.real) | 1, page_dir.remapped+i);
}
retval = serverworks_create_gatt_pages(value->num_entries / 1024);
if (retval != 0) {
serverworks_free_page_map(&page_dir);
serverworks_free_page_map(&serverworks_private.scratch_dir);
return retval;
}
agp_bridge->gatt_table_real = (u32 *)page_dir.real;
agp_bridge->gatt_table = (u32 __iomem *)page_dir.remapped;
agp_bridge->gatt_bus_addr = virt_to_phys(page_dir.real);
/* Get the address for the gart region.
* This is a bus address even on the alpha, b/c its
* used to program the agp master not the cpu
*/
pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* Calculate the agp offset */
for(i = 0; i < value->num_entries / 1024; i++)
writel(virt_to_phys(serverworks_private.gatt_pages[i]->real)|1, page_dir.remapped+i);
return 0;
}
static int serverworks_free_gatt_table(void)
{
struct serverworks_page_map page_dir;
page_dir.real = (unsigned long *)agp_bridge->gatt_table_real;
page_dir.remapped = (unsigned long __iomem *)agp_bridge->gatt_table;
serverworks_free_gatt_pages();
serverworks_free_page_map(&page_dir);
serverworks_free_page_map(&serverworks_private.scratch_dir);
return 0;
}
static int serverworks_fetch_size(void)
{
int i;
u32 temp;
u32 temp2;
struct aper_size_info_lvl2 *values;
values = A_SIZE_LVL2(agp_bridge->driver->aperture_sizes);
pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp);
pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,
SVWRKS_SIZE_MASK);
pci_read_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,&temp2);
pci_write_config_dword(agp_bridge->dev,serverworks_private.gart_addr_ofs,temp);
temp2 &= SVWRKS_SIZE_MASK;
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp2 == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
/*
* This routine could be implemented by taking the addresses
* written to the GATT, and flushing them individually. However
* currently it just flushes the whole table. Which is probably
* more efficent, since agp_memory blocks can be a large number of
* entries.
*/
static void serverworks_tlbflush(struct agp_memory *temp)
{
OUTREG8(serverworks_private.registers, SVWRKS_POSTFLUSH, 1);
while(INREG8(serverworks_private.registers, SVWRKS_POSTFLUSH) == 1)
cpu_relax();
OUTREG32(serverworks_private.registers, SVWRKS_DIRFLUSH, 1);
while(INREG32(serverworks_private.registers, SVWRKS_DIRFLUSH) == 1)
cpu_relax();
}
static int serverworks_configure(void)
{
struct aper_size_info_lvl2 *current_size;
u32 temp;
u8 enable_reg;
u16 cap_reg;
current_size = A_SIZE_LVL2(agp_bridge->current_size);
/* Get the memory mapped registers */
pci_read_config_dword(agp_bridge->dev, serverworks_private.mm_addr_ofs, &temp);
temp = (temp & PCI_BASE_ADDRESS_MEM_MASK);
serverworks_private.registers = (volatile u8 __iomem *) ioremap(temp, 4096);
if (!serverworks_private.registers) {
printk (KERN_ERR PFX "Unable to ioremap() memory.\n");
return -ENOMEM;
}
OUTREG8(serverworks_private.registers, SVWRKS_GART_CACHE, 0x0a);
OUTREG32(serverworks_private.registers, SVWRKS_GATTBASE,
agp_bridge->gatt_bus_addr);
cap_reg = INREG16(serverworks_private.registers, SVWRKS_COMMAND);
cap_reg &= ~0x0007;
cap_reg |= 0x4;
OUTREG16(serverworks_private.registers, SVWRKS_COMMAND, cap_reg);
pci_read_config_byte(serverworks_private.svrwrks_dev,
SVWRKS_AGP_ENABLE, &enable_reg);
enable_reg |= 0x1; /* Agp Enable bit */
pci_write_config_byte(serverworks_private.svrwrks_dev,
SVWRKS_AGP_ENABLE, enable_reg);
serverworks_tlbflush(NULL);
agp_bridge->capndx = pci_find_capability(serverworks_private.svrwrks_dev, PCI_CAP_ID_AGP);
/* Fill in the mode register */
pci_read_config_dword(serverworks_private.svrwrks_dev,
agp_bridge->capndx+PCI_AGP_STATUS, &agp_bridge->mode);
pci_read_config_byte(agp_bridge->dev, SVWRKS_CACHING, &enable_reg);
enable_reg &= ~0x3;
pci_write_config_byte(agp_bridge->dev, SVWRKS_CACHING, enable_reg);
pci_read_config_byte(agp_bridge->dev, SVWRKS_FEATURE, &enable_reg);
enable_reg |= (1<<6);
pci_write_config_byte(agp_bridge->dev,SVWRKS_FEATURE, enable_reg);
return 0;
}
static void serverworks_cleanup(void)
{
iounmap((void __iomem *) serverworks_private.registers);
}
static int serverworks_insert_memory(struct agp_memory *mem,
off_t pg_start, int type)
{
int i, j, num_entries;
unsigned long __iomem *cur_gatt;
unsigned long addr;
num_entries = A_SIZE_LVL2(agp_bridge->current_size)->num_entries;
if (type != 0 || mem->type != 0) {
return -EINVAL;
}
if ((pg_start + mem->page_count) > num_entries) {
return -EINVAL;
}
j = pg_start;
while (j < (pg_start + mem->page_count)) {
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = SVRWRKS_GET_GATT(addr);
if (!PGE_EMPTY(agp_bridge, readl(cur_gatt+GET_GATT_OFF(addr))))
return -EBUSY;
j++;
}
if (mem->is_flushed == FALSE) {
global_cache_flush();
mem->is_flushed = TRUE;
}
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
addr = (j * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = SVRWRKS_GET_GATT(addr);
writel(agp_bridge->driver->mask_memory(mem->memory[i], mem->type), cur_gatt+GET_GATT_OFF(addr));
}
serverworks_tlbflush(mem);
return 0;
}
static int serverworks_remove_memory(struct agp_memory *mem, off_t pg_start,
int type)
{
int i;
unsigned long __iomem *cur_gatt;
unsigned long addr;
if (type != 0 || mem->type != 0) {
return -EINVAL;
}
global_cache_flush();
serverworks_tlbflush(mem);
for (i = pg_start; i < (mem->page_count + pg_start); i++) {
addr = (i * PAGE_SIZE) + agp_bridge->gart_bus_addr;
cur_gatt = SVRWRKS_GET_GATT(addr);
writel(agp_bridge->scratch_page, cur_gatt+GET_GATT_OFF(addr));
}
serverworks_tlbflush(mem);
return 0;
}
static struct gatt_mask serverworks_masks[] =
{
{.mask = 1, .type = 0}
};
static struct aper_size_info_lvl2 serverworks_sizes[7] =
{
{2048, 524288, 0x80000000},
{1024, 262144, 0xc0000000},
{512, 131072, 0xe0000000},
{256, 65536, 0xf0000000},
{128, 32768, 0xf8000000},
{64, 16384, 0xfc000000},
{32, 8192, 0xfe000000}
};
static void serverworks_agp_enable(u32 mode)
{
u32 command;
pci_read_config_dword(serverworks_private.svrwrks_dev,
agp_bridge->capndx + PCI_AGP_STATUS,
&command);
command = agp_collect_device_status(mode, command);
command &= ~0x10; /* disable FW */
command &= ~0x08;
command |= 0x100;
pci_write_config_dword(serverworks_private.svrwrks_dev,
agp_bridge->capndx + PCI_AGP_COMMAND,
command);
agp_device_command(command, 0);
}
struct agp_bridge_driver sworks_driver = {
.owner = THIS_MODULE,
.aperture_sizes = serverworks_sizes,
.size_type = LVL2_APER_SIZE,
.num_aperture_sizes = 7,
.configure = serverworks_configure,
.fetch_size = serverworks_fetch_size,
.cleanup = serverworks_cleanup,
.tlb_flush = serverworks_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = serverworks_masks,
.agp_enable = serverworks_agp_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = serverworks_create_gatt_table,
.free_gatt_table = serverworks_free_gatt_table,
.insert_memory = serverworks_insert_memory,
.remove_memory = serverworks_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
static int __devinit agp_serverworks_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_bridge_data *bridge;
struct pci_dev *bridge_dev;
u32 temp, temp2;
u8 cap_ptr = 0;
/* Everything is on func 1 here so we are hardcoding function one */
bridge_dev = pci_find_slot((unsigned int)pdev->bus->number,
PCI_DEVFN(0, 1));
if (!bridge_dev) {
printk(KERN_INFO PFX "Detected a Serverworks chipset "
"but could not find the secondary device.\n");
return -ENODEV;
}
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
switch (pdev->device) {
case 0x0006:
/* ServerWorks CNB20HE
Fail silently.*/
printk (KERN_ERR PFX "Detected ServerWorks CNB20HE chipset: No AGP present.\n");
return -ENODEV;
case PCI_DEVICE_ID_SERVERWORKS_HE:
case PCI_DEVICE_ID_SERVERWORKS_LE:
case 0x0007:
break;
default:
if (cap_ptr)
printk(KERN_ERR PFX "Unsupported Serverworks chipset "
"(device id: %04x)\n", pdev->device);
return -ENODEV;
}
serverworks_private.svrwrks_dev = bridge_dev;
serverworks_private.gart_addr_ofs = 0x10;
pci_read_config_dword(pdev, SVWRKS_APSIZE, &temp);
if (temp & PCI_BASE_ADDRESS_MEM_TYPE_64) {
pci_read_config_dword(pdev, SVWRKS_APSIZE + 4, &temp2);
if (temp2 != 0) {
printk(KERN_INFO PFX "Detected 64 bit aperture address, "
"but top bits are not zero. Disabling agp\n");
return -ENODEV;
}
serverworks_private.mm_addr_ofs = 0x18;
} else
serverworks_private.mm_addr_ofs = 0x14;
pci_read_config_dword(pdev, serverworks_private.mm_addr_ofs, &temp);
if (temp & PCI_BASE_ADDRESS_MEM_TYPE_64) {
pci_read_config_dword(pdev,
serverworks_private.mm_addr_ofs + 4, &temp2);
if (temp2 != 0) {
printk(KERN_INFO PFX "Detected 64 bit MMIO address, "
"but top bits are not zero. Disabling agp\n");
return -ENODEV;
}
}
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &sworks_driver;
bridge->dev_private_data = &serverworks_private,
bridge->dev = pdev;
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_serverworks_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static struct pci_device_id agp_serverworks_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_SERVERWORKS,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_serverworks_pci_table);
static struct pci_driver agp_serverworks_pci_driver = {
.name = "agpgart-serverworks",
.id_table = agp_serverworks_pci_table,
.probe = agp_serverworks_probe,
.remove = agp_serverworks_remove,
};
static int __init agp_serverworks_init(void)
{
return pci_module_init(&agp_serverworks_pci_driver);
}
static void __exit agp_serverworks_cleanup(void)
{
pci_unregister_driver(&agp_serverworks_pci_driver);
}
module_init(agp_serverworks_init);
module_exit(agp_serverworks_cleanup);
MODULE_LICENSE("GPL and additional rights");

View File

@@ -0,0 +1,388 @@
/*
* UniNorth AGPGART routines.
*/
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/pagemap.h>
#include <linux/agp_backend.h>
#include <asm/uninorth.h>
#include <asm/pci-bridge.h>
#include "agp.h"
static int uninorth_fetch_size(void)
{
int i;
u32 temp;
struct aper_size_info_32 *values;
pci_read_config_dword(agp_bridge->dev, UNI_N_CFG_GART_BASE, &temp);
temp &= ~(0xfffff000);
values = A_SIZE_32(agp_bridge->driver->aperture_sizes);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + 1);
agp_bridge->aperture_size_idx = 1;
return values[1].size;
return 0;
}
static void uninorth_tlbflush(struct agp_memory *mem)
{
pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_INVAL);
pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
UNI_N_CFG_GART_ENABLE);
pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_2xRESET);
pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
UNI_N_CFG_GART_ENABLE);
}
static void uninorth_cleanup(void)
{
pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
UNI_N_CFG_GART_ENABLE | UNI_N_CFG_GART_INVAL);
pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
0);
pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
UNI_N_CFG_GART_2xRESET);
pci_write_config_dword(agp_bridge->dev, UNI_N_CFG_GART_CTRL,
0);
}
static int uninorth_configure(void)
{
struct aper_size_info_32 *current_size;
current_size = A_SIZE_32(agp_bridge->current_size);
printk(KERN_INFO PFX "configuring for size idx: %d\n",
current_size->size_value);
/* aperture size and gatt addr */
pci_write_config_dword(agp_bridge->dev,
UNI_N_CFG_GART_BASE,
(agp_bridge->gatt_bus_addr & 0xfffff000)
| current_size->size_value);
/* HACK ALERT
* UniNorth seem to be buggy enough not to handle properly when
* the AGP aperture isn't mapped at bus physical address 0
*/
agp_bridge->gart_bus_addr = 0;
pci_write_config_dword(agp_bridge->dev,
UNI_N_CFG_AGP_BASE, agp_bridge->gart_bus_addr);
return 0;
}
static int uninorth_insert_memory(struct agp_memory *mem, off_t pg_start,
int type)
{
int i, j, num_entries;
void *temp;
temp = agp_bridge->current_size;
num_entries = A_SIZE_32(temp)->num_entries;
if (type != 0 || mem->type != 0)
/* We know nothing of memory types */
return -EINVAL;
if ((pg_start + mem->page_count) > num_entries)
return -EINVAL;
j = pg_start;
while (j < (pg_start + mem->page_count)) {
if (!PGE_EMPTY(agp_bridge, agp_bridge->gatt_table[j]))
return -EBUSY;
j++;
}
for (i = 0, j = pg_start; i < mem->page_count; i++, j++) {
agp_bridge->gatt_table[j] = cpu_to_le32((mem->memory[i] & 0xfffff000) | 0x00000001UL);
flush_dcache_range((unsigned long)__va(mem->memory[i]),
(unsigned long)__va(mem->memory[i])+0x1000);
}
(void)in_le32((volatile u32*)&agp_bridge->gatt_table[pg_start]);
mb();
flush_dcache_range((unsigned long)&agp_bridge->gatt_table[pg_start],
(unsigned long)&agp_bridge->gatt_table[pg_start + mem->page_count]);
uninorth_tlbflush(mem);
return 0;
}
static void uninorth_agp_enable(u32 mode)
{
u32 command, scratch;
int timeout;
pci_read_config_dword(agp_bridge->dev,
agp_bridge->capndx + PCI_AGP_STATUS,
&command);
command = agp_collect_device_status(mode, command);
command |= 0x100;
uninorth_tlbflush(NULL);
timeout = 0;
do {
pci_write_config_dword(agp_bridge->dev,
agp_bridge->capndx + PCI_AGP_COMMAND,
command);
pci_read_config_dword(agp_bridge->dev,
agp_bridge->capndx + PCI_AGP_COMMAND,
&scratch);
} while ((scratch & 0x100) == 0 && ++timeout < 1000);
if ((scratch & 0x100) == 0)
printk(KERN_ERR PFX "failed to write UniNorth AGP command reg\n");
agp_device_command(command, 0);
uninorth_tlbflush(NULL);
}
static int uninorth_create_gatt_table(void)
{
char *table;
char *table_end;
int size;
int page_order;
int num_entries;
int i;
void *temp;
struct page *page;
/* We can't handle 2 level gatt's */
if (agp_bridge->driver->size_type == LVL2_APER_SIZE)
return -EINVAL;
table = NULL;
i = agp_bridge->aperture_size_idx;
temp = agp_bridge->current_size;
size = page_order = num_entries = 0;
do {
size = A_SIZE_32(temp)->size;
page_order = A_SIZE_32(temp)->page_order;
num_entries = A_SIZE_32(temp)->num_entries;
table = (char *) __get_free_pages(GFP_KERNEL, page_order);
if (table == NULL) {
i++;
agp_bridge->current_size = A_IDX32(agp_bridge);
} else {
agp_bridge->aperture_size_idx = i;
}
} while (!table && (i < agp_bridge->driver->num_aperture_sizes));
if (table == NULL)
return -ENOMEM;
table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
SetPageReserved(page);
agp_bridge->gatt_table_real = (u32 *) table;
agp_bridge->gatt_table = (u32 *)table;
agp_bridge->gatt_bus_addr = virt_to_phys(table);
for (i = 0; i < num_entries; i++) {
agp_bridge->gatt_table[i] =
(unsigned long) agp_bridge->scratch_page;
}
flush_dcache_range((unsigned long)table, (unsigned long)table_end);
return 0;
}
static int uninorth_free_gatt_table(void)
{
int page_order;
char *table, *table_end;
void *temp;
struct page *page;
temp = agp_bridge->current_size;
page_order = A_SIZE_32(temp)->page_order;
/* Do not worry about freeing memory, because if this is
* called, then all agp memory is deallocated and removed
* from the table.
*/
table = (char *) agp_bridge->gatt_table_real;
table_end = table + ((PAGE_SIZE * (1 << page_order)) - 1);
for (page = virt_to_page(table); page <= virt_to_page(table_end); page++)
ClearPageReserved(page);
free_pages((unsigned long) agp_bridge->gatt_table_real, page_order);
return 0;
}
void null_cache_flush(void)
{
mb();
}
/* Setup function */
static struct aper_size_info_32 uninorth_sizes[7] =
{
#if 0 /* Not sure uninorth supports that high aperture sizes */
{256, 65536, 6, 64},
{128, 32768, 5, 32},
{64, 16384, 4, 16},
#endif
{32, 8192, 3, 8},
{16, 4096, 2, 4},
{8, 2048, 1, 2},
{4, 1024, 0, 1}
};
struct agp_bridge_driver uninorth_agp_driver = {
.owner = THIS_MODULE,
.aperture_sizes = (void *)uninorth_sizes,
.size_type = U32_APER_SIZE,
.num_aperture_sizes = 4,
.configure = uninorth_configure,
.fetch_size = uninorth_fetch_size,
.cleanup = uninorth_cleanup,
.tlb_flush = uninorth_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = NULL,
.cache_flush = null_cache_flush,
.agp_enable = uninorth_agp_enable,
.create_gatt_table = uninorth_create_gatt_table,
.free_gatt_table = uninorth_free_gatt_table,
.insert_memory = uninorth_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
.cant_use_aperture = 1,
};
static struct agp_device_ids uninorth_agp_device_ids[] __devinitdata = {
{
.device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP,
.chipset_name = "UniNorth",
},
{
.device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP_P,
.chipset_name = "UniNorth/Pangea",
},
{
.device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP15,
.chipset_name = "UniNorth 1.5",
},
{
.device_id = PCI_DEVICE_ID_APPLE_UNI_N_AGP2,
.chipset_name = "UniNorth 2",
},
};
static int __devinit agp_uninorth_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_device_ids *devs = uninorth_agp_device_ids;
struct agp_bridge_data *bridge;
u8 cap_ptr;
int j;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (cap_ptr == 0)
return -ENODEV;
/* probe for known chipsets */
for (j = 0; devs[j].chipset_name != NULL; ++j) {
if (pdev->device == devs[j].device_id) {
printk(KERN_INFO PFX "Detected Apple %s chipset\n",
devs[j].chipset_name);
goto found;
}
}
printk(KERN_ERR PFX "Unsupported Apple chipset (device id: %04x).\n",
pdev->device);
return -ENODEV;
found:
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->driver = &uninorth_agp_driver;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
/* Fill in the mode register */
pci_read_config_dword(pdev, cap_ptr+PCI_AGP_STATUS, &bridge->mode);
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_uninorth_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
static struct pci_device_id agp_uninorth_pci_table[] = {
{
.class = (PCI_CLASS_BRIDGE_HOST << 8),
.class_mask = ~0,
.vendor = PCI_VENDOR_ID_APPLE,
.device = PCI_ANY_ID,
.subvendor = PCI_ANY_ID,
.subdevice = PCI_ANY_ID,
},
{ }
};
MODULE_DEVICE_TABLE(pci, agp_uninorth_pci_table);
static struct pci_driver agp_uninorth_pci_driver = {
.name = "agpgart-uninorth",
.id_table = agp_uninorth_pci_table,
.probe = agp_uninorth_probe,
.remove = agp_uninorth_remove,
};
static int __init agp_uninorth_init(void)
{
return pci_module_init(&agp_uninorth_pci_driver);
}
static void __exit agp_uninorth_cleanup(void)
{
pci_unregister_driver(&agp_uninorth_pci_driver);
}
module_init(agp_uninorth_init);
module_exit(agp_uninorth_cleanup);
MODULE_AUTHOR("Ben Herrenschmidt & Paul Mackerras");
MODULE_LICENSE("GPL");

View File

@@ -0,0 +1,538 @@
/*
* VIA AGPGART routines.
*/
#include <linux/types.h>
#include <linux/module.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <linux/agp_backend.h>
#include "agp.h"
static struct pci_device_id agp_via_pci_table[];
#define VIA_GARTCTRL 0x80
#define VIA_APSIZE 0x84
#define VIA_ATTBASE 0x88
#define VIA_AGP3_GARTCTRL 0x90
#define VIA_AGP3_APSIZE 0x94
#define VIA_AGP3_ATTBASE 0x98
#define VIA_AGPSEL 0xfd
static int via_fetch_size(void)
{
int i;
u8 temp;
struct aper_size_info_8 *values;
values = A_SIZE_8(agp_bridge->driver->aperture_sizes);
pci_read_config_byte(agp_bridge->dev, VIA_APSIZE, &temp);
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
static int via_configure(void)
{
u32 temp;
struct aper_size_info_8 *current_size;
current_size = A_SIZE_8(agp_bridge->current_size);
/* aperture size */
pci_write_config_byte(agp_bridge->dev, VIA_APSIZE,
current_size->size_value);
/* address to map too */
pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* GART control register */
pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000000f);
/* attbase - aperture GATT base */
pci_write_config_dword(agp_bridge->dev, VIA_ATTBASE,
(agp_bridge->gatt_bus_addr & 0xfffff000) | 3);
return 0;
}
static void via_cleanup(void)
{
struct aper_size_info_8 *previous_size;
previous_size = A_SIZE_8(agp_bridge->previous_size);
pci_write_config_byte(agp_bridge->dev, VIA_APSIZE,
previous_size->size_value);
/* Do not disable by writing 0 to VIA_ATTBASE, it screws things up
* during reinitialization.
*/
}
static void via_tlbflush(struct agp_memory *mem)
{
pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000008f);
pci_write_config_dword(agp_bridge->dev, VIA_GARTCTRL, 0x0000000f);
}
static struct aper_size_info_8 via_generic_sizes[7] =
{
{256, 65536, 6, 0},
{128, 32768, 5, 128},
{64, 16384, 4, 192},
{32, 8192, 3, 224},
{16, 4096, 2, 240},
{8, 2048, 1, 248},
{4, 1024, 0, 252}
};
static int via_fetch_size_agp3(void)
{
int i;
u16 temp;
struct aper_size_info_16 *values;
values = A_SIZE_16(agp_bridge->driver->aperture_sizes);
pci_read_config_word(agp_bridge->dev, VIA_AGP3_APSIZE, &temp);
temp &= 0xfff;
for (i = 0; i < agp_bridge->driver->num_aperture_sizes; i++) {
if (temp == values[i].size_value) {
agp_bridge->previous_size =
agp_bridge->current_size = (void *) (values + i);
agp_bridge->aperture_size_idx = i;
return values[i].size;
}
}
return 0;
}
static int via_configure_agp3(void)
{
u32 temp;
struct aper_size_info_16 *current_size;
current_size = A_SIZE_16(agp_bridge->current_size);
/* address to map too */
pci_read_config_dword(agp_bridge->dev, AGP_APBASE, &temp);
agp_bridge->gart_bus_addr = (temp & PCI_BASE_ADDRESS_MEM_MASK);
/* attbase - aperture GATT base */
pci_write_config_dword(agp_bridge->dev, VIA_AGP3_ATTBASE,
agp_bridge->gatt_bus_addr & 0xfffff000);
/* 1. Enable GTLB in RX90<7>, all AGP aperture access needs to fetch
* translation table first.
* 2. Enable AGP aperture in RX91<0>. This bit controls the enabling of the
* graphics AGP aperture for the AGP3.0 port.
*/
pci_read_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, &temp);
pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp | (3<<7));
return 0;
}
static void via_cleanup_agp3(void)
{
struct aper_size_info_16 *previous_size;
previous_size = A_SIZE_16(agp_bridge->previous_size);
pci_write_config_byte(agp_bridge->dev, VIA_APSIZE, previous_size->size_value);
}
static void via_tlbflush_agp3(struct agp_memory *mem)
{
u32 temp;
pci_read_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, &temp);
pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp & ~(1<<7));
pci_write_config_dword(agp_bridge->dev, VIA_AGP3_GARTCTRL, temp);
}
struct agp_bridge_driver via_agp3_driver = {
.owner = THIS_MODULE,
.aperture_sizes = agp3_generic_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 10,
.configure = via_configure_agp3,
.fetch_size = via_fetch_size_agp3,
.cleanup = via_cleanup_agp3,
.tlb_flush = via_tlbflush_agp3,
.mask_memory = agp_generic_mask_memory,
.masks = NULL,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = agp_generic_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
struct agp_bridge_driver via_driver = {
.owner = THIS_MODULE,
.aperture_sizes = via_generic_sizes,
.size_type = U8_APER_SIZE,
.num_aperture_sizes = 7,
.configure = via_configure,
.fetch_size = via_fetch_size,
.cleanup = via_cleanup,
.tlb_flush = via_tlbflush,
.mask_memory = agp_generic_mask_memory,
.masks = NULL,
.agp_enable = agp_generic_enable,
.cache_flush = global_cache_flush,
.create_gatt_table = agp_generic_create_gatt_table,
.free_gatt_table = agp_generic_free_gatt_table,
.insert_memory = agp_generic_insert_memory,
.remove_memory = agp_generic_remove_memory,
.alloc_by_type = agp_generic_alloc_by_type,
.free_by_type = agp_generic_free_by_type,
.agp_alloc_page = agp_generic_alloc_page,
.agp_destroy_page = agp_generic_destroy_page,
};
static struct agp_device_ids via_agp_device_ids[] __devinitdata =
{
{
.device_id = PCI_DEVICE_ID_VIA_82C597_0,
.chipset_name = "Apollo VP3",
},
{
.device_id = PCI_DEVICE_ID_VIA_82C598_0,
.chipset_name = "Apollo MVP3",
},
{
.device_id = PCI_DEVICE_ID_VIA_8501_0,
.chipset_name = "Apollo MVP4",
},
/* VT8601 */
{
.device_id = PCI_DEVICE_ID_VIA_8601_0,
.chipset_name = "Apollo ProMedia/PLE133Ta",
},
/* VT82C693A / VT28C694T */
{
.device_id = PCI_DEVICE_ID_VIA_82C691_0,
.chipset_name = "Apollo Pro 133",
},
{
.device_id = PCI_DEVICE_ID_VIA_8371_0,
.chipset_name = "KX133",
},
/* VT8633 */
{
.device_id = PCI_DEVICE_ID_VIA_8633_0,
.chipset_name = "Pro 266",
},
{
.device_id = PCI_DEVICE_ID_VIA_XN266,
.chipset_name = "Apollo Pro266",
},
/* VT8361 */
{
.device_id = PCI_DEVICE_ID_VIA_8361,
.chipset_name = "KLE133",
},
/* VT8365 / VT8362 */
{
.device_id = PCI_DEVICE_ID_VIA_8363_0,
.chipset_name = "Twister-K/KT133x/KM133",
},
/* VT8753A */
{
.device_id = PCI_DEVICE_ID_VIA_8753_0,
.chipset_name = "P4X266",
},
/* VT8366 */
{
.device_id = PCI_DEVICE_ID_VIA_8367_0,
.chipset_name = "KT266/KY266x/KT333",
},
/* VT8633 (for CuMine/ Celeron) */
{
.device_id = PCI_DEVICE_ID_VIA_8653_0,
.chipset_name = "Pro266T",
},
/* KM266 / PM266 */
{
.device_id = PCI_DEVICE_ID_VIA_XM266,
.chipset_name = "PM266/KM266",
},
/* CLE266 */
{
.device_id = PCI_DEVICE_ID_VIA_862X_0,
.chipset_name = "CLE266",
},
{
.device_id = PCI_DEVICE_ID_VIA_8377_0,
.chipset_name = "KT400/KT400A/KT600",
},
/* VT8604 / VT8605 / VT8603
* (Apollo Pro133A chipset with S3 Savage4) */
{
.device_id = PCI_DEVICE_ID_VIA_8605_0,
.chipset_name = "ProSavage PM133/PL133/PN133"
},
/* P4M266x/P4N266 */
{
.device_id = PCI_DEVICE_ID_VIA_8703_51_0,
.chipset_name = "P4M266x/P4N266",
},
/* VT8754 */
{
.device_id = PCI_DEVICE_ID_VIA_8754C_0,
.chipset_name = "PT800",
},
/* P4X600 */
{
.device_id = PCI_DEVICE_ID_VIA_8763_0,
.chipset_name = "P4X600"
},
/* KM400 */
{
.device_id = PCI_DEVICE_ID_VIA_8378_0,
.chipset_name = "KM400/KM400A",
},
/* PT880 */
{
.device_id = PCI_DEVICE_ID_VIA_PT880,
.chipset_name = "PT880",
},
/* PT890 */
{
.device_id = PCI_DEVICE_ID_VIA_8783_0,
.chipset_name = "PT890",
},
/* PM800/PN800/PM880/PN880 */
{
.device_id = PCI_DEVICE_ID_VIA_PX8X0_0,
.chipset_name = "PM800/PN800/PM880/PN880",
},
/* KT880 */
{
.device_id = PCI_DEVICE_ID_VIA_3269_0,
.chipset_name = "KT880",
},
/* KTxxx/Px8xx */
{
.device_id = PCI_DEVICE_ID_VIA_83_87XX_1,
.chipset_name = "VT83xx/VT87xx/KTxxx/Px8xx",
},
/* P4M800 */
{
.device_id = PCI_DEVICE_ID_VIA_3296_0,
.chipset_name = "P4M800",
},
{ }, /* dummy final entry, always present */
};
/*
* VIA's AGP3 chipsets do magick to put the AGP bridge compliant
* with the same standards version as the graphics card.
*/
static void check_via_agp3 (struct agp_bridge_data *bridge)
{
u8 reg;
pci_read_config_byte(bridge->dev, VIA_AGPSEL, &reg);
/* Check AGP 2.0 compatibility mode. */
if ((reg & (1<<1))==0)
bridge->driver = &via_agp3_driver;
}
static int __devinit agp_via_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
struct agp_device_ids *devs = via_agp_device_ids;
struct agp_bridge_data *bridge;
int j = 0;
u8 cap_ptr;
cap_ptr = pci_find_capability(pdev, PCI_CAP_ID_AGP);
if (!cap_ptr)
return -ENODEV;
j = ent - agp_via_pci_table;
printk (KERN_INFO PFX "Detected VIA %s chipset\n", devs[j].chipset_name);
bridge = agp_alloc_bridge();
if (!bridge)
return -ENOMEM;
bridge->dev = pdev;
bridge->capndx = cap_ptr;
bridge->driver = &via_driver;
/*
* Garg, there are KT400s with KT266 IDs.
*/
if (pdev->device == PCI_DEVICE_ID_VIA_8367_0) {
/* Is there a KT400 subsystem ? */
if (pdev->subsystem_device == PCI_DEVICE_ID_VIA_8377_0) {
printk(KERN_INFO PFX "Found KT400 in disguise as a KT266.\n");
check_via_agp3(bridge);
}
}
/* If this is an AGP3 bridge, check which mode its in and adjust. */
get_agp_version(bridge);
if (bridge->major_version >= 3)
check_via_agp3(bridge);
/* Fill in the mode register */
pci_read_config_dword(pdev,
bridge->capndx+PCI_AGP_STATUS, &bridge->mode);
pci_set_drvdata(pdev, bridge);
return agp_add_bridge(bridge);
}
static void __devexit agp_via_remove(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
agp_remove_bridge(bridge);
agp_put_bridge(bridge);
}
#ifdef CONFIG_PM
static int agp_via_suspend(struct pci_dev *pdev, u32 state)
{
pci_save_state (pdev);
pci_set_power_state (pdev, 3);
return 0;
}
static int agp_via_resume(struct pci_dev *pdev)
{
struct agp_bridge_data *bridge = pci_get_drvdata(pdev);
pci_set_power_state (pdev, 0);
pci_restore_state(pdev);
if (bridge->driver == &via_agp3_driver)
return via_configure_agp3();
else if (bridge->driver == &via_driver)
return via_configure();
return 0;
}
#endif /* CONFIG_PM */
/* must be the same order as name table above */
static struct pci_device_id agp_via_pci_table[] = {
#define ID(x) \
{ \
.class = (PCI_CLASS_BRIDGE_HOST << 8), \
.class_mask = ~0, \
.vendor = PCI_VENDOR_ID_VIA, \
.device = x, \
.subvendor = PCI_ANY_ID, \
.subdevice = PCI_ANY_ID, \
}
ID(PCI_DEVICE_ID_VIA_82C597_0),
ID(PCI_DEVICE_ID_VIA_82C598_0),
ID(PCI_DEVICE_ID_VIA_8501_0),
ID(PCI_DEVICE_ID_VIA_8601_0),
ID(PCI_DEVICE_ID_VIA_82C691_0),
ID(PCI_DEVICE_ID_VIA_8371_0),
ID(PCI_DEVICE_ID_VIA_8633_0),
ID(PCI_DEVICE_ID_VIA_XN266),
ID(PCI_DEVICE_ID_VIA_8361),
ID(PCI_DEVICE_ID_VIA_8363_0),
ID(PCI_DEVICE_ID_VIA_8753_0),
ID(PCI_DEVICE_ID_VIA_8367_0),
ID(PCI_DEVICE_ID_VIA_8653_0),
ID(PCI_DEVICE_ID_VIA_XM266),
ID(PCI_DEVICE_ID_VIA_862X_0),
ID(PCI_DEVICE_ID_VIA_8377_0),
ID(PCI_DEVICE_ID_VIA_8605_0),
ID(PCI_DEVICE_ID_VIA_8703_51_0),
ID(PCI_DEVICE_ID_VIA_8754C_0),
ID(PCI_DEVICE_ID_VIA_8763_0),
ID(PCI_DEVICE_ID_VIA_8378_0),
ID(PCI_DEVICE_ID_VIA_PT880),
ID(PCI_DEVICE_ID_VIA_8783_0),
ID(PCI_DEVICE_ID_VIA_PX8X0_0),
ID(PCI_DEVICE_ID_VIA_3269_0),
ID(PCI_DEVICE_ID_VIA_83_87XX_1),
ID(PCI_DEVICE_ID_VIA_3296_0),
{ }
};
MODULE_DEVICE_TABLE(pci, agp_via_pci_table);
static struct pci_driver agp_via_pci_driver = {
.name = "agpgart-via",
.id_table = agp_via_pci_table,
.probe = agp_via_probe,
.remove = agp_via_remove,
#ifdef CONFIG_PM
.suspend = agp_via_suspend,
.resume = agp_via_resume,
#endif
};
static int __init agp_via_init(void)
{
return pci_module_init(&agp_via_pci_driver);
}
static void __exit agp_via_cleanup(void)
{
pci_unregister_driver(&agp_via_pci_driver);
}
module_init(agp_via_init);
module_exit(agp_via_cleanup);
MODULE_LICENSE("GPL");
MODULE_AUTHOR("Dave Jones <davej@codemonkey.org.uk>");

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,861 @@
/* Derived from Applicom driver ac.c for SCO Unix */
/* Ported by David Woodhouse, Axiom (Cambridge) Ltd. */
/* dwmw2@redhat.com 30/8/98 */
/* $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $ */
/* This module is for Linux 2.1 and 2.2 series kernels. */
/*****************************************************************************/
/* J PAGET 18/02/94 passage V2.4.2 ioctl avec code 2 reset to les interrupt */
/* ceci pour reseter correctement apres une sortie sauvage */
/* J PAGET 02/05/94 passage V2.4.3 dans le traitement de d'interruption, */
/* LoopCount n'etait pas initialise a 0. */
/* F LAFORSE 04/07/95 version V2.6.0 lecture bidon apres acces a une carte */
/* pour liberer le bus */
/* J.PAGET 19/11/95 version V2.6.1 Nombre, addresse,irq n'est plus configure */
/* et passe en argument a acinit, mais est scrute sur le bus pour s'adapter */
/* au nombre de cartes presentes sur le bus. IOCL code 6 affichait V2.4.3 */
/* F.LAFORSE 28/11/95 creation de fichiers acXX.o avec les differentes */
/* adresses de base des cartes, IOCTL 6 plus complet */
/* J.PAGET le 19/08/96 copie de la version V2.6 en V2.8.0 sans modification */
/* de code autre que le texte V2.6.1 en V2.8.0 */
/*****************************************************************************/
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
#include <linux/slab.h>
#include <linux/errno.h>
#include <linux/miscdevice.h>
#include <linux/pci.h>
#include <linux/wait.h>
#include <linux/init.h>
#include <linux/fs.h>
#include <asm/io.h>
#include <asm/uaccess.h>
#include "applicom.h"
/* NOTE: We use for loops with {write,read}b() instead of
memcpy_{from,to}io throughout this driver. This is because
the board doesn't correctly handle word accesses - only
bytes.
*/
#undef DEBUG
#define MAX_BOARD 8 /* maximum of pc board possible */
#define MAX_ISA_BOARD 4
#define LEN_RAM_IO 0x800
#define AC_MINOR 157
#ifndef PCI_VENDOR_ID_APPLICOM
#define PCI_VENDOR_ID_APPLICOM 0x1389
#define PCI_DEVICE_ID_APPLICOM_PCIGENERIC 0x0001
#define PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN 0x0002
#define PCI_DEVICE_ID_APPLICOM_PCI2000PFB 0x0003
#endif
#define MAX_PCI_DEVICE_NUM 3
static char *applicom_pci_devnames[] = {
"PCI board",
"PCI2000IBS / PCI2000CAN",
"PCI2000PFB"
};
static struct pci_device_id applicom_pci_tbl[] = {
{ PCI_VENDOR_ID_APPLICOM, PCI_DEVICE_ID_APPLICOM_PCIGENERIC,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_APPLICOM, PCI_DEVICE_ID_APPLICOM_PCI2000IBS_CAN,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ PCI_VENDOR_ID_APPLICOM, PCI_DEVICE_ID_APPLICOM_PCI2000PFB,
PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0 },
{ 0 }
};
MODULE_DEVICE_TABLE(pci, applicom_pci_tbl);
MODULE_AUTHOR("David Woodhouse & Applicom International");
MODULE_DESCRIPTION("Driver for Applicom Profibus card");
MODULE_LICENSE("GPL");
MODULE_PARM(irq, "i");
MODULE_PARM_DESC(irq, "IRQ of the Applicom board");
MODULE_PARM(mem, "i");
MODULE_PARM_DESC(mem, "Shared Memory Address of Applicom board");
MODULE_SUPPORTED_DEVICE("ac");
static struct applicom_board {
unsigned long PhysIO;
void __iomem *RamIO;
wait_queue_head_t FlagSleepSend;
long irq;
spinlock_t mutex;
} apbs[MAX_BOARD];
static unsigned int irq = 0; /* interrupt number IRQ */
static unsigned long mem = 0; /* physical segment of board */
static unsigned int numboards; /* number of installed boards */
static volatile unsigned char Dummy;
static DECLARE_WAIT_QUEUE_HEAD(FlagSleepRec);
static unsigned int WriteErrorCount; /* number of write error */
static unsigned int ReadErrorCount; /* number of read error */
static unsigned int DeviceErrorCount; /* number of device error */
static ssize_t ac_read (struct file *, char __user *, size_t, loff_t *);
static ssize_t ac_write (struct file *, const char __user *, size_t, loff_t *);
static int ac_ioctl(struct inode *, struct file *, unsigned int,
unsigned long);
static irqreturn_t ac_interrupt(int, void *, struct pt_regs *);
static struct file_operations ac_fops = {
.owner = THIS_MODULE,
.llseek = no_llseek,
.read = ac_read,
.write = ac_write,
.ioctl = ac_ioctl,
};
static struct miscdevice ac_miscdev = {
AC_MINOR,
"ac",
&ac_fops
};
static int dummy; /* dev_id for request_irq() */
static int ac_register_board(unsigned long physloc, void __iomem *loc,
unsigned char boardno)
{
volatile unsigned char byte_reset_it;
if((readb(loc + CONF_END_TEST) != 0x00) ||
(readb(loc + CONF_END_TEST + 1) != 0x55) ||
(readb(loc + CONF_END_TEST + 2) != 0xAA) ||
(readb(loc + CONF_END_TEST + 3) != 0xFF))
return 0;
if (!boardno)
boardno = readb(loc + NUMCARD_OWNER_TO_PC);
if (!boardno && boardno > MAX_BOARD) {
printk(KERN_WARNING "Board #%d (at 0x%lx) is out of range (1 <= x <= %d).\n",
boardno, physloc, MAX_BOARD);
return 0;
}
if (apbs[boardno - 1].RamIO) {
printk(KERN_WARNING "Board #%d (at 0x%lx) conflicts with previous board #%d (at 0x%lx)\n",
boardno, physloc, boardno, apbs[boardno-1].PhysIO);
return 0;
}
boardno--;
apbs[boardno].PhysIO = physloc;
apbs[boardno].RamIO = loc;
init_waitqueue_head(&apbs[boardno].FlagSleepSend);
spin_lock_init(&apbs[boardno].mutex);
byte_reset_it = readb(loc + RAM_IT_TO_PC);
numboards++;
return boardno + 1;
}
#ifdef MODULE
#define applicom_init init_module
void cleanup_module(void)
{
int i;
misc_deregister(&ac_miscdev);
for (i = 0; i < MAX_BOARD; i++) {
if (!apbs[i].RamIO)
continue;
if (apbs[i].irq)
free_irq(apbs[i].irq, &dummy);
iounmap(apbs[i].RamIO);
}
}
#endif /* MODULE */
int __init applicom_init(void)
{
int i, numisa = 0;
struct pci_dev *dev = NULL;
void __iomem *RamIO;
int boardno;
printk(KERN_INFO "Applicom driver: $Id: ac.c,v 1.30 2000/03/22 16:03:57 dwmw2 Exp $\n");
/* No mem and irq given - check for a PCI card */
while ( (dev = pci_get_class(PCI_CLASS_OTHERS << 16, dev))) {
if (dev->vendor != PCI_VENDOR_ID_APPLICOM)
continue;
if (dev->device > MAX_PCI_DEVICE_NUM || dev->device == 0)
continue;
if (pci_enable_device(dev))
return -EIO;
RamIO = ioremap(dev->resource[0].start, LEN_RAM_IO);
if (!RamIO) {
printk(KERN_INFO "ac.o: Failed to ioremap PCI memory space at 0x%lx\n", dev->resource[0].start);
pci_disable_device(dev);
return -EIO;
}
printk(KERN_INFO "Applicom %s found at mem 0x%lx, irq %d\n",
applicom_pci_devnames[dev->device-1], dev->resource[0].start,
dev->irq);
boardno = ac_register_board(dev->resource[0].start, RamIO,0);
if (!boardno) {
printk(KERN_INFO "ac.o: PCI Applicom device doesn't have correct signature.\n");
iounmap(RamIO);
pci_disable_device(dev);
continue;
}
if (request_irq(dev->irq, &ac_interrupt, SA_SHIRQ, "Applicom PCI", &dummy)) {
printk(KERN_INFO "Could not allocate IRQ %d for PCI Applicom device.\n", dev->irq);
iounmap(RamIO);
pci_disable_device(dev);
apbs[boardno - 1].RamIO = NULL;
continue;
}
/* Enable interrupts. */
writeb(0x40, apbs[boardno - 1].RamIO + RAM_IT_FROM_PC);
apbs[boardno - 1].irq = dev->irq;
}
/* Finished with PCI cards. If none registered,
* and there was no mem/irq specified, exit */
if (!mem || !irq) {
if (numboards)
goto fin;
else {
printk(KERN_INFO "ac.o: No PCI boards found.\n");
printk(KERN_INFO "ac.o: For an ISA board you must supply memory and irq parameters.\n");
return -ENXIO;
}
}
/* Now try the specified ISA cards */
for (i = 0; i < MAX_ISA_BOARD; i++) {
RamIO = ioremap(mem + (LEN_RAM_IO * i), LEN_RAM_IO);
if (!RamIO) {
printk(KERN_INFO "ac.o: Failed to ioremap the ISA card's memory space (slot #%d)\n", i + 1);
continue;
}
if (!(boardno = ac_register_board((unsigned long)mem+ (LEN_RAM_IO*i),
RamIO,i+1))) {
iounmap(RamIO);
continue;
}
printk(KERN_NOTICE "Applicom ISA card found at mem 0x%lx, irq %d\n", mem + (LEN_RAM_IO*i), irq);
if (!numisa) {
if (request_irq(irq, &ac_interrupt, SA_SHIRQ, "Applicom ISA", &dummy)) {
printk(KERN_WARNING "Could not allocate IRQ %d for ISA Applicom device.\n", irq);
iounmap(RamIO);
apbs[boardno - 1].RamIO = NULL;
}
else
apbs[boardno - 1].irq = irq;
}
else
apbs[boardno - 1].irq = 0;
numisa++;
}
if (!numisa)
printk(KERN_WARNING"ac.o: No valid ISA Applicom boards found at mem 0x%lx\n",mem);
fin:
init_waitqueue_head(&FlagSleepRec);
WriteErrorCount = 0;
ReadErrorCount = 0;
DeviceErrorCount = 0;
if (numboards) {
misc_register(&ac_miscdev);
for (i = 0; i < MAX_BOARD; i++) {
int serial;
char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1];
if (!apbs[i].RamIO)
continue;
for (serial = 0; serial < SERIAL_NUMBER - TYPE_CARD; serial++)
boardname[serial] = readb(apbs[i].RamIO + TYPE_CARD + serial);
boardname[serial] = 0;
printk(KERN_INFO "Applicom board %d: %s, PROM V%d.%d",
i+1, boardname,
(int)(readb(apbs[i].RamIO + VERS) >> 4),
(int)(readb(apbs[i].RamIO + VERS) & 0xF));
serial = (readb(apbs[i].RamIO + SERIAL_NUMBER) << 16) +
(readb(apbs[i].RamIO + SERIAL_NUMBER + 1) << 8) +
(readb(apbs[i].RamIO + SERIAL_NUMBER + 2) );
if (serial != 0)
printk(" S/N %d\n", serial);
else
printk("\n");
}
return 0;
}
else
return -ENXIO;
}
#ifndef MODULE
__initcall(applicom_init);
#endif
static ssize_t ac_write(struct file *file, const char __user *buf, size_t count, loff_t * ppos)
{
unsigned int NumCard; /* Board number 1 -> 8 */
unsigned int IndexCard; /* Index board number 0 -> 7 */
unsigned char TicCard; /* Board TIC to send */
unsigned long flags; /* Current priority */
struct st_ram_io st_loc;
struct mailbox tmpmailbox;
#ifdef DEBUG
int c;
#endif
DECLARE_WAITQUEUE(wait, current);
if (count != sizeof(struct st_ram_io) + sizeof(struct mailbox)) {
static int warncount = 5;
if (warncount) {
printk(KERN_INFO "Hmmm. write() of Applicom card, length %zd != expected %zd\n",
count, sizeof(struct st_ram_io) + sizeof(struct mailbox));
warncount--;
}
return -EINVAL;
}
if(copy_from_user(&st_loc, buf, sizeof(struct st_ram_io)))
return -EFAULT;
if(copy_from_user(&tmpmailbox, &buf[sizeof(struct st_ram_io)],
sizeof(struct mailbox)))
return -EFAULT;
NumCard = st_loc.num_card; /* board number to send */
TicCard = st_loc.tic_des_from_pc; /* tic number to send */
IndexCard = NumCard - 1;
if((NumCard < 1) || (NumCard > MAX_BOARD) || !apbs[IndexCard].RamIO)
return -EINVAL;
#ifdef DEBUG
printk("Write to applicom card #%d. struct st_ram_io follows:",
IndexCard+1);
for (c = 0; c < sizeof(struct st_ram_io);) {
printk("\n%5.5X: %2.2X", c, ((unsigned char *) &st_loc)[c]);
for (c++; c % 8 && c < sizeof(struct st_ram_io); c++) {
printk(" %2.2X", ((unsigned char *) &st_loc)[c]);
}
}
printk("\nstruct mailbox follows:");
for (c = 0; c < sizeof(struct mailbox);) {
printk("\n%5.5X: %2.2X", c, ((unsigned char *) &tmpmailbox)[c]);
for (c++; c % 8 && c < sizeof(struct mailbox); c++) {
printk(" %2.2X", ((unsigned char *) &tmpmailbox)[c]);
}
}
printk("\n");
#endif
spin_lock_irqsave(&apbs[IndexCard].mutex, flags);
/* Test octet ready correct */
if(readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY) > 2) {
Dummy = readb(apbs[IndexCard].RamIO + VERS);
spin_unlock_irqrestore(&apbs[IndexCard].mutex, flags);
printk(KERN_WARNING "APPLICOM driver write error board %d, DataFromPcReady = %d\n",
IndexCard,(int)readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY));
DeviceErrorCount++;
return -EIO;
}
/* Place ourselves on the wait queue */
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&apbs[IndexCard].FlagSleepSend, &wait);
/* Check whether the card is ready for us */
while (readb(apbs[IndexCard].RamIO + DATA_FROM_PC_READY) != 0) {
Dummy = readb(apbs[IndexCard].RamIO + VERS);
/* It's busy. Sleep. */
spin_unlock_irqrestore(&apbs[IndexCard].mutex, flags);
schedule();
if (signal_pending(current)) {
remove_wait_queue(&apbs[IndexCard].FlagSleepSend,
&wait);
return -EINTR;
}
spin_lock_irqsave(&apbs[IndexCard].mutex, flags);
set_current_state(TASK_INTERRUPTIBLE);
}
/* We may not have actually slept */
set_current_state(TASK_RUNNING);
remove_wait_queue(&apbs[IndexCard].FlagSleepSend, &wait);
writeb(1, apbs[IndexCard].RamIO + DATA_FROM_PC_READY);
/* Which is best - lock down the pages with rawio and then
copy directly, or use bounce buffers? For now we do the latter
because it works with 2.2 still */
{
unsigned char *from = (unsigned char *) &tmpmailbox;
void __iomem *to = apbs[IndexCard].RamIO + RAM_FROM_PC;
int c;
for (c = 0; c < sizeof(struct mailbox); c++)
writeb(*(from++), to++);
}
writeb(0x20, apbs[IndexCard].RamIO + TIC_OWNER_FROM_PC);
writeb(0xff, apbs[IndexCard].RamIO + NUMCARD_OWNER_FROM_PC);
writeb(TicCard, apbs[IndexCard].RamIO + TIC_DES_FROM_PC);
writeb(NumCard, apbs[IndexCard].RamIO + NUMCARD_DES_FROM_PC);
writeb(2, apbs[IndexCard].RamIO + DATA_FROM_PC_READY);
writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC);
Dummy = readb(apbs[IndexCard].RamIO + VERS);
spin_unlock_irqrestore(&apbs[IndexCard].mutex, flags);
return 0;
}
static int do_ac_read(int IndexCard, char __user *buf,
struct st_ram_io *st_loc, struct mailbox *mailbox)
{
void __iomem *from = apbs[IndexCard].RamIO + RAM_TO_PC;
unsigned char *to = (unsigned char *)&mailbox;
#ifdef DEBUG
int c;
#endif
st_loc->tic_owner_to_pc = readb(apbs[IndexCard].RamIO + TIC_OWNER_TO_PC);
st_loc->numcard_owner_to_pc = readb(apbs[IndexCard].RamIO + NUMCARD_OWNER_TO_PC);
{
int c;
for (c = 0; c < sizeof(struct mailbox); c++)
*(to++) = readb(from++);
}
writeb(1, apbs[IndexCard].RamIO + ACK_FROM_PC_READY);
writeb(1, apbs[IndexCard].RamIO + TYP_ACK_FROM_PC);
writeb(IndexCard+1, apbs[IndexCard].RamIO + NUMCARD_ACK_FROM_PC);
writeb(readb(apbs[IndexCard].RamIO + TIC_OWNER_TO_PC),
apbs[IndexCard].RamIO + TIC_ACK_FROM_PC);
writeb(2, apbs[IndexCard].RamIO + ACK_FROM_PC_READY);
writeb(0, apbs[IndexCard].RamIO + DATA_TO_PC_READY);
writeb(2, apbs[IndexCard].RamIO + RAM_IT_FROM_PC);
Dummy = readb(apbs[IndexCard].RamIO + VERS);
#ifdef DEBUG
printk("Read from applicom card #%d. struct st_ram_io follows:", NumCard);
for (c = 0; c < sizeof(struct st_ram_io);) {
printk("\n%5.5X: %2.2X", c, ((unsigned char *)st_loc)[c]);
for (c++; c % 8 && c < sizeof(struct st_ram_io); c++) {
printk(" %2.2X", ((unsigned char *)st_loc)[c]);
}
}
printk("\nstruct mailbox follows:");
for (c = 0; c < sizeof(struct mailbox);) {
printk("\n%5.5X: %2.2X", c, ((unsigned char *)mailbox)[c]);
for (c++; c % 8 && c < sizeof(struct mailbox); c++) {
printk(" %2.2X", ((unsigned char *)mailbox)[c]);
}
}
printk("\n");
#endif
return (sizeof(struct st_ram_io) + sizeof(struct mailbox));
}
static ssize_t ac_read (struct file *filp, char __user *buf, size_t count, loff_t *ptr)
{
unsigned long flags;
unsigned int i;
unsigned char tmp;
int ret = 0;
DECLARE_WAITQUEUE(wait, current);
#ifdef DEBUG
int loopcount=0;
#endif
/* No need to ratelimit this. Only root can trigger it anyway */
if (count != sizeof(struct st_ram_io) + sizeof(struct mailbox)) {
printk( KERN_WARNING "Hmmm. read() of Applicom card, length %zd != expected %zd\n",
count,sizeof(struct st_ram_io) + sizeof(struct mailbox));
return -EINVAL;
}
while(1) {
/* Stick ourself on the wait queue */
set_current_state(TASK_INTERRUPTIBLE);
add_wait_queue(&FlagSleepRec, &wait);
/* Scan each board, looking for one which has a packet for us */
for (i=0; i < MAX_BOARD; i++) {
if (!apbs[i].RamIO)
continue;
spin_lock_irqsave(&apbs[i].mutex, flags);
tmp = readb(apbs[i].RamIO + DATA_TO_PC_READY);
if (tmp == 2) {
struct st_ram_io st_loc;
struct mailbox mailbox;
/* Got a packet for us */
ret = do_ac_read(i, buf, &st_loc, &mailbox);
spin_unlock_irqrestore(&apbs[i].mutex, flags);
set_current_state(TASK_RUNNING);
remove_wait_queue(&FlagSleepRec, &wait);
if (copy_to_user(buf, &st_loc, sizeof(st_loc)))
return -EFAULT;
if (copy_to_user(buf + sizeof(st_loc), &mailbox, sizeof(mailbox)))
return -EFAULT;
return tmp;
}
if (tmp > 2) {
/* Got an error */
Dummy = readb(apbs[i].RamIO + VERS);
spin_unlock_irqrestore(&apbs[i].mutex, flags);
set_current_state(TASK_RUNNING);
remove_wait_queue(&FlagSleepRec, &wait);
printk(KERN_WARNING "APPLICOM driver read error board %d, DataToPcReady = %d\n",
i,(int)readb(apbs[i].RamIO + DATA_TO_PC_READY));
DeviceErrorCount++;
return -EIO;
}
/* Nothing for us. Try the next board */
Dummy = readb(apbs[i].RamIO + VERS);
spin_unlock_irqrestore(&apbs[i].mutex, flags);
} /* per board */
/* OK - No boards had data for us. Sleep now */
schedule();
remove_wait_queue(&FlagSleepRec, &wait);
if (signal_pending(current))
return -EINTR;
#ifdef DEBUG
if (loopcount++ > 2) {
printk("Looping in ac_read. loopcount %d\n", loopcount);
}
#endif
}
}
static irqreturn_t ac_interrupt(int vec, void *dev_instance, struct pt_regs *regs)
{
unsigned int i;
unsigned int FlagInt;
unsigned int LoopCount;
int handled = 0;
// printk("Applicom interrupt on IRQ %d occurred\n", vec);
LoopCount = 0;
do {
FlagInt = 0;
for (i = 0; i < MAX_BOARD; i++) {
/* Skip if this board doesn't exist */
if (!apbs[i].RamIO)
continue;
spin_lock(&apbs[i].mutex);
/* Skip if this board doesn't want attention */
if(readb(apbs[i].RamIO + RAM_IT_TO_PC) == 0) {
spin_unlock(&apbs[i].mutex);
continue;
}
handled = 1;
FlagInt = 1;
writeb(0, apbs[i].RamIO + RAM_IT_TO_PC);
if (readb(apbs[i].RamIO + DATA_TO_PC_READY) > 2) {
printk(KERN_WARNING "APPLICOM driver interrupt err board %d, DataToPcReady = %d\n",
i+1,(int)readb(apbs[i].RamIO + DATA_TO_PC_READY));
DeviceErrorCount++;
}
if((readb(apbs[i].RamIO + DATA_FROM_PC_READY) > 2) &&
(readb(apbs[i].RamIO + DATA_FROM_PC_READY) != 6)) {
printk(KERN_WARNING "APPLICOM driver interrupt err board %d, DataFromPcReady = %d\n",
i+1,(int)readb(apbs[i].RamIO + DATA_FROM_PC_READY));
DeviceErrorCount++;
}
if (readb(apbs[i].RamIO + DATA_TO_PC_READY) == 2) { /* mailbox sent by the card ? */
if (waitqueue_active(&FlagSleepRec)) {
wake_up_interruptible(&FlagSleepRec);
}
}
if (readb(apbs[i].RamIO + DATA_FROM_PC_READY) == 0) { /* ram i/o free for write by pc ? */
if (waitqueue_active(&apbs[i].FlagSleepSend)) { /* process sleep during read ? */
wake_up_interruptible(&apbs[i].FlagSleepSend);
}
}
Dummy = readb(apbs[i].RamIO + VERS);
if(readb(apbs[i].RamIO + RAM_IT_TO_PC)) {
/* There's another int waiting on this card */
spin_unlock(&apbs[i].mutex);
i--;
} else {
spin_unlock(&apbs[i].mutex);
}
}
if (FlagInt)
LoopCount = 0;
else
LoopCount++;
} while(LoopCount < 2);
return IRQ_RETVAL(handled);
}
static int ac_ioctl(struct inode *inode, struct file *file, unsigned int cmd, unsigned long arg)
{ /* @ ADG ou ATO selon le cas */
int i;
unsigned char IndexCard;
void __iomem *pmem;
int ret = 0;
volatile unsigned char byte_reset_it;
struct st_ram_io *adgl;
void __user *argp = (void __user *)arg;
/* In general, the device is only openable by root anyway, so we're not
particularly concerned that bogus ioctls can flood the console. */
adgl = kmalloc(sizeof(struct st_ram_io), GFP_KERNEL);
if (!adgl)
return -ENOMEM;
if (copy_from_user(adgl, argp, sizeof(struct st_ram_io))) {
kfree(adgl);
return -EFAULT;
}
IndexCard = adgl->num_card-1;
if(cmd != 0 && cmd != 6 &&
((IndexCard >= MAX_BOARD) || !apbs[IndexCard].RamIO)) {
static int warncount = 10;
if (warncount) {
printk( KERN_WARNING "APPLICOM driver IOCTL, bad board number %d\n",(int)IndexCard+1);
warncount--;
}
kfree(adgl);
return -EINVAL;
}
switch (cmd) {
case 0:
pmem = apbs[IndexCard].RamIO;
for (i = 0; i < sizeof(struct st_ram_io); i++)
((unsigned char *)adgl)[i]=readb(pmem++);
if (copy_to_user(argp, adgl, sizeof(struct st_ram_io)))
ret = -EFAULT;
break;
case 1:
pmem = apbs[IndexCard].RamIO + CONF_END_TEST;
for (i = 0; i < 4; i++)
adgl->conf_end_test[i] = readb(pmem++);
for (i = 0; i < 2; i++)
adgl->error_code[i] = readb(pmem++);
for (i = 0; i < 4; i++)
adgl->parameter_error[i] = readb(pmem++);
pmem = apbs[IndexCard].RamIO + VERS;
adgl->vers = readb(pmem);
pmem = apbs[IndexCard].RamIO + TYPE_CARD;
for (i = 0; i < 20; i++)
adgl->reserv1[i] = readb(pmem++);
*(int *)&adgl->reserv1[20] =
(readb(apbs[IndexCard].RamIO + SERIAL_NUMBER) << 16) +
(readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 1) << 8) +
(readb(apbs[IndexCard].RamIO + SERIAL_NUMBER + 2) );
if (copy_to_user(argp, adgl, sizeof(struct st_ram_io)))
ret = -EFAULT;
break;
case 2:
pmem = apbs[IndexCard].RamIO + CONF_END_TEST;
for (i = 0; i < 10; i++)
writeb(0xff, pmem++);
writeb(adgl->data_from_pc_ready,
apbs[IndexCard].RamIO + DATA_FROM_PC_READY);
writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC);
for (i = 0; i < MAX_BOARD; i++) {
if (apbs[i].RamIO) {
byte_reset_it = readb(apbs[i].RamIO + RAM_IT_TO_PC);
}
}
break;
case 3:
pmem = apbs[IndexCard].RamIO + TIC_DES_FROM_PC;
writeb(adgl->tic_des_from_pc, pmem);
break;
case 4:
pmem = apbs[IndexCard].RamIO + TIC_OWNER_TO_PC;
adgl->tic_owner_to_pc = readb(pmem++);
adgl->numcard_owner_to_pc = readb(pmem);
if (copy_to_user(argp, adgl,sizeof(struct st_ram_io)))
ret = -EFAULT;
break;
case 5:
writeb(adgl->num_card, apbs[IndexCard].RamIO + NUMCARD_OWNER_TO_PC);
writeb(adgl->num_card, apbs[IndexCard].RamIO + NUMCARD_DES_FROM_PC);
writeb(adgl->num_card, apbs[IndexCard].RamIO + NUMCARD_ACK_FROM_PC);
writeb(4, apbs[IndexCard].RamIO + DATA_FROM_PC_READY);
writeb(1, apbs[IndexCard].RamIO + RAM_IT_FROM_PC);
break;
case 6:
printk(KERN_INFO "APPLICOM driver release .... V2.8.0 ($Revision: 1.30 $)\n");
printk(KERN_INFO "Number of installed boards . %d\n", (int) numboards);
printk(KERN_INFO "Segment of board ........... %X\n", (int) mem);
printk(KERN_INFO "Interrupt IRQ number ....... %d\n", (int) irq);
for (i = 0; i < MAX_BOARD; i++) {
int serial;
char boardname[(SERIAL_NUMBER - TYPE_CARD) + 1];
if (!apbs[i].RamIO)
continue;
for (serial = 0; serial < SERIAL_NUMBER - TYPE_CARD; serial++)
boardname[serial] = readb(apbs[i].RamIO + TYPE_CARD + serial);
boardname[serial] = 0;
printk(KERN_INFO "Prom version board %d ....... V%d.%d %s",
i+1,
(int)(readb(apbs[IndexCard].RamIO + VERS) >> 4),
(int)(readb(apbs[IndexCard].RamIO + VERS) & 0xF),
boardname);
serial = (readb(apbs[i].RamIO + SERIAL_NUMBER) << 16) +
(readb(apbs[i].RamIO + SERIAL_NUMBER + 1) << 8) +
(readb(apbs[i].RamIO + SERIAL_NUMBER + 2) );
if (serial != 0)
printk(" S/N %d\n", serial);
else
printk("\n");
}
if (DeviceErrorCount != 0)
printk(KERN_INFO "DeviceErrorCount ........... %d\n", DeviceErrorCount);
if (ReadErrorCount != 0)
printk(KERN_INFO "ReadErrorCount ............. %d\n", ReadErrorCount);
if (WriteErrorCount != 0)
printk(KERN_INFO "WriteErrorCount ............ %d\n", WriteErrorCount);
if (waitqueue_active(&FlagSleepRec))
printk(KERN_INFO "Process in read pending\n");
for (i = 0; i < MAX_BOARD; i++) {
if (apbs[i].RamIO && waitqueue_active(&apbs[i].FlagSleepSend))
printk(KERN_INFO "Process in write pending board %d\n",i+1);
}
break;
default:
printk(KERN_INFO "APPLICOM driver ioctl, unknown function code %d\n",cmd) ;
ret = -EINVAL;
break;
}
Dummy = readb(apbs[IndexCard].RamIO + VERS);
kfree(adgl);
return 0;
}
#ifndef MODULE
static int __init applicom_setup(char *str)
{
int ints[4];
(void) get_options(str, 4, ints);
if (ints[0] > 2) {
printk(KERN_WARNING "Too many arguments to 'applicom=', expected mem,irq only.\n");
}
if (ints[0] < 2) {
printk(KERN_INFO"applicom numargs: %d\n", ints[0]);
return 0;
}
mem = ints[1];
irq = ints[2];
return 1;
}
__setup("applicom=", applicom_setup);
#endif /* MODULE */

View File

@@ -0,0 +1,85 @@
/* $Id: applicom.h,v 1.2 1999/08/28 15:09:49 dwmw2 Exp $ */
#ifndef __LINUX_APPLICOM_H__
#define __LINUX_APPLICOM_H__
#define DATA_TO_PC_READY 0x00
#define TIC_OWNER_TO_PC 0x01
#define NUMCARD_OWNER_TO_PC 0x02
#define TIC_DES_TO_PC 0x03
#define NUMCARD_DES_TO_PC 0x04
#define DATA_FROM_PC_READY 0x05
#define TIC_OWNER_FROM_PC 0x06
#define NUMCARD_OWNER_FROM_PC 0x07
#define TIC_DES_FROM_PC 0x08
#define NUMCARD_DES_FROM_PC 0x09
#define ACK_FROM_PC_READY 0x0E
#define TIC_ACK_FROM_PC 0x0F
#define NUMCARD_ACK_FROM_PC 0x010
#define TYP_ACK_FROM_PC 0x011
#define CONF_END_TEST 0x012
#define ERROR_CODE 0x016
#define PARAMETER_ERROR 0x018
#define VERS 0x01E
#define RAM_TO_PC 0x040
#define RAM_FROM_PC 0x0170
#define TYPE_CARD 0x03C0
#define SERIAL_NUMBER 0x03DA
#define RAM_IT_FROM_PC 0x03FE
#define RAM_IT_TO_PC 0x03FF
struct mailbox{
u16 stjb_codef; /* offset 00 */
s16 stjb_status; /* offset 02 */
u16 stjb_ticuser_root; /* offset 04 */
u8 stjb_piduser[4]; /* offset 06 */
u16 stjb_mode; /* offset 0A */
u16 stjb_time; /* offset 0C */
u16 stjb_stop; /* offset 0E */
u16 stjb_nfonc; /* offset 10 */
u16 stjb_ncard; /* offset 12 */
u16 stjb_nchan; /* offset 14 */
u16 stjb_nes; /* offset 16 */
u16 stjb_nb; /* offset 18 */
u16 stjb_typvar; /* offset 1A */
u32 stjb_adr; /* offset 1C */
u16 stjb_ticuser_dispcyc; /* offset 20 */
u16 stjb_ticuser_protocol; /* offset 22 */
u8 stjb_filler[12]; /* offset 24 */
u8 stjb_data[256]; /* offset 30 */
};
struct st_ram_io
{
unsigned char data_to_pc_ready;
unsigned char tic_owner_to_pc;
unsigned char numcard_owner_to_pc;
unsigned char tic_des_to_pc;
unsigned char numcard_des_to_pc;
unsigned char data_from_pc_ready;
unsigned char tic_owner_from_pc;
unsigned char numcard_owner_from_pc;
unsigned char tic_des_from_pc;
unsigned char numcard_des_from_pc;
unsigned char ack_to_pc_ready;
unsigned char tic_ack_to_pc;
unsigned char numcard_ack_to_pc;
unsigned char typ_ack_to_pc;
unsigned char ack_from_pc_ready;
unsigned char tic_ack_from_pc;
unsigned char numcard_ack_from_pc;
unsigned char typ_ack_from_pc;
unsigned char conf_end_test[4];
unsigned char error_code[2];
unsigned char parameter_error[4];
unsigned char time_base;
unsigned char nul_inc;
unsigned char vers;
unsigned char num_card;
unsigned char reserv1[32];
};
#endif /* __LINUX_APPLICOM_H__ */

Binary file not shown.

View File

@@ -0,0 +1,263 @@
/*
* linux/drivers/char/cd1865.h -- Definitions relating to the CD1865
* for the Specialix IO8+ multiport serial driver.
*
* Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl)
* Copyright (C) 1994-1996 Dmitry Gorodchanin (pgmdsg@ibi.com)
*
* Specialix pays for the development and support of this driver.
* Please DO contact io8-linux@specialix.co.uk if you require
* support.
*
* This driver was developped in the BitWizard linux device
* driver service. If you require a linux device driver for your
* product, please contact devices@BitWizard.nl for a quote.
*
*/
/*
* Definitions for Driving CD180/CD1864/CD1865 based eightport serial cards.
*/
/* Values of choice for Interrupt ACKs */
/* These values are "obligatory" if you use the register based
* interrupt acknowledgements. See page 99-101 of V2.0 of the CD1865
* databook */
#define SX_ACK_MINT 0x75 /* goes to PILR1 */
#define SX_ACK_TINT 0x76 /* goes to PILR2 */
#define SX_ACK_RINT 0x77 /* goes to PILR3 */
/* Chip ID (is used when chips ar daisy chained.) */
#define SX_ID 0x10
/* Definitions for Cirrus Logic CL-CD186x 8-port async mux chip */
#define CD186x_NCH 8 /* Total number of channels */
#define CD186x_TPC 16 /* Ticks per character */
#define CD186x_NFIFO 8 /* TX FIFO size */
/* Global registers */
#define CD186x_GIVR 0x40 /* Global Interrupt Vector Register */
#define CD186x_GICR 0x41 /* Global Interrupting Channel Register */
#define CD186x_PILR1 0x61 /* Priority Interrupt Level Register 1 */
#define CD186x_PILR2 0x62 /* Priority Interrupt Level Register 2 */
#define CD186x_PILR3 0x63 /* Priority Interrupt Level Register 3 */
#define CD186x_CAR 0x64 /* Channel Access Register */
#define CD186x_SRSR 0x65 /* Channel Access Register */
#define CD186x_GFRCR 0x6b /* Global Firmware Revision Code Register */
#define CD186x_PPRH 0x70 /* Prescaler Period Register High */
#define CD186x_PPRL 0x71 /* Prescaler Period Register Low */
#define CD186x_RDR 0x78 /* Receiver Data Register */
#define CD186x_RCSR 0x7a /* Receiver Character Status Register */
#define CD186x_TDR 0x7b /* Transmit Data Register */
#define CD186x_EOIR 0x7f /* End of Interrupt Register */
#define CD186x_MRAR 0x75 /* Modem Request Acknowledge register */
#define CD186x_TRAR 0x76 /* Transmit Request Acknowledge register */
#define CD186x_RRAR 0x77 /* Receive Request Acknowledge register */
#define CD186x_SRCR 0x66 /* Service Request Configuration register */
/* Channel Registers */
#define CD186x_CCR 0x01 /* Channel Command Register */
#define CD186x_IER 0x02 /* Interrupt Enable Register */
#define CD186x_COR1 0x03 /* Channel Option Register 1 */
#define CD186x_COR2 0x04 /* Channel Option Register 2 */
#define CD186x_COR3 0x05 /* Channel Option Register 3 */
#define CD186x_CCSR 0x06 /* Channel Control Status Register */
#define CD186x_RDCR 0x07 /* Receive Data Count Register */
#define CD186x_SCHR1 0x09 /* Special Character Register 1 */
#define CD186x_SCHR2 0x0a /* Special Character Register 2 */
#define CD186x_SCHR3 0x0b /* Special Character Register 3 */
#define CD186x_SCHR4 0x0c /* Special Character Register 4 */
#define CD186x_MCOR1 0x10 /* Modem Change Option 1 Register */
#define CD186x_MCOR2 0x11 /* Modem Change Option 2 Register */
#define CD186x_MCR 0x12 /* Modem Change Register */
#define CD186x_RTPR 0x18 /* Receive Timeout Period Register */
#define CD186x_MSVR 0x28 /* Modem Signal Value Register */
#define CD186x_MSVRTS 0x29 /* Modem Signal Value Register */
#define CD186x_MSVDTR 0x2a /* Modem Signal Value Register */
#define CD186x_RBPRH 0x31 /* Receive Baud Rate Period Register High */
#define CD186x_RBPRL 0x32 /* Receive Baud Rate Period Register Low */
#define CD186x_TBPRH 0x39 /* Transmit Baud Rate Period Register High */
#define CD186x_TBPRL 0x3a /* Transmit Baud Rate Period Register Low */
/* Global Interrupt Vector Register (R/W) */
#define GIVR_ITMASK 0x07 /* Interrupt type mask */
#define GIVR_IT_MODEM 0x01 /* Modem Signal Change Interrupt */
#define GIVR_IT_TX 0x02 /* Transmit Data Interrupt */
#define GIVR_IT_RCV 0x03 /* Receive Good Data Interrupt */
#define GIVR_IT_REXC 0x07 /* Receive Exception Interrupt */
/* Global Interrupt Channel Register (R/W) */
#define GICR_CHAN 0x1c /* Channel Number Mask */
#define GICR_CHAN_OFF 2 /* Channel Number shift */
/* Channel Address Register (R/W) */
#define CAR_CHAN 0x07 /* Channel Number Mask */
#define CAR_A7 0x08 /* A7 Address Extension (unused) */
/* Receive Character Status Register (R/O) */
#define RCSR_TOUT 0x80 /* Rx Timeout */
#define RCSR_SCDET 0x70 /* Special Character Detected Mask */
#define RCSR_NO_SC 0x00 /* No Special Characters Detected */
#define RCSR_SC_1 0x10 /* Special Char 1 (or 1 & 3) Detected */
#define RCSR_SC_2 0x20 /* Special Char 2 (or 2 & 4) Detected */
#define RCSR_SC_3 0x30 /* Special Char 3 Detected */
#define RCSR_SC_4 0x40 /* Special Char 4 Detected */
#define RCSR_BREAK 0x08 /* Break has been detected */
#define RCSR_PE 0x04 /* Parity Error */
#define RCSR_FE 0x02 /* Frame Error */
#define RCSR_OE 0x01 /* Overrun Error */
/* Channel Command Register (R/W) (commands in groups can be OR-ed) */
#define CCR_HARDRESET 0x81 /* Reset the chip */
#define CCR_SOFTRESET 0x80 /* Soft Channel Reset */
#define CCR_CORCHG1 0x42 /* Channel Option Register 1 Changed */
#define CCR_CORCHG2 0x44 /* Channel Option Register 2 Changed */
#define CCR_CORCHG3 0x48 /* Channel Option Register 3 Changed */
#define CCR_SSCH1 0x21 /* Send Special Character 1 */
#define CCR_SSCH2 0x22 /* Send Special Character 2 */
#define CCR_SSCH3 0x23 /* Send Special Character 3 */
#define CCR_SSCH4 0x24 /* Send Special Character 4 */
#define CCR_TXEN 0x18 /* Enable Transmitter */
#define CCR_RXEN 0x12 /* Enable Receiver */
#define CCR_TXDIS 0x14 /* Disable Transmitter */
#define CCR_RXDIS 0x11 /* Disable Receiver */
/* Interrupt Enable Register (R/W) */
#define IER_DSR 0x80 /* Enable interrupt on DSR change */
#define IER_CD 0x40 /* Enable interrupt on CD change */
#define IER_CTS 0x20 /* Enable interrupt on CTS change */
#define IER_RXD 0x10 /* Enable interrupt on Receive Data */
#define IER_RXSC 0x08 /* Enable interrupt on Receive Spec. Char */
#define IER_TXRDY 0x04 /* Enable interrupt on TX FIFO empty */
#define IER_TXEMPTY 0x02 /* Enable interrupt on TX completely empty */
#define IER_RET 0x01 /* Enable interrupt on RX Exc. Timeout */
/* Channel Option Register 1 (R/W) */
#define COR1_ODDP 0x80 /* Odd Parity */
#define COR1_PARMODE 0x60 /* Parity Mode mask */
#define COR1_NOPAR 0x00 /* No Parity */
#define COR1_FORCEPAR 0x20 /* Force Parity */
#define COR1_NORMPAR 0x40 /* Normal Parity */
#define COR1_IGNORE 0x10 /* Ignore Parity on RX */
#define COR1_STOPBITS 0x0c /* Number of Stop Bits */
#define COR1_1SB 0x00 /* 1 Stop Bit */
#define COR1_15SB 0x04 /* 1.5 Stop Bits */
#define COR1_2SB 0x08 /* 2 Stop Bits */
#define COR1_CHARLEN 0x03 /* Character Length */
#define COR1_5BITS 0x00 /* 5 bits */
#define COR1_6BITS 0x01 /* 6 bits */
#define COR1_7BITS 0x02 /* 7 bits */
#define COR1_8BITS 0x03 /* 8 bits */
/* Channel Option Register 2 (R/W) */
#define COR2_IXM 0x80 /* Implied XON mode */
#define COR2_TXIBE 0x40 /* Enable In-Band (XON/XOFF) Flow Control */
#define COR2_ETC 0x20 /* Embedded Tx Commands Enable */
#define COR2_LLM 0x10 /* Local Loopback Mode */
#define COR2_RLM 0x08 /* Remote Loopback Mode */
#define COR2_RTSAO 0x04 /* RTS Automatic Output Enable */
#define COR2_CTSAE 0x02 /* CTS Automatic Enable */
#define COR2_DSRAE 0x01 /* DSR Automatic Enable */
/* Channel Option Register 3 (R/W) */
#define COR3_XONCH 0x80 /* XON is a pair of characters (1 & 3) */
#define COR3_XOFFCH 0x40 /* XOFF is a pair of characters (2 & 4) */
#define COR3_FCT 0x20 /* Flow-Control Transparency Mode */
#define COR3_SCDE 0x10 /* Special Character Detection Enable */
#define COR3_RXTH 0x0f /* RX FIFO Threshold value (1-8) */
/* Channel Control Status Register (R/O) */
#define CCSR_RXEN 0x80 /* Receiver Enabled */
#define CCSR_RXFLOFF 0x40 /* Receive Flow Off (XOFF was sent) */
#define CCSR_RXFLON 0x20 /* Receive Flow On (XON was sent) */
#define CCSR_TXEN 0x08 /* Transmitter Enabled */
#define CCSR_TXFLOFF 0x04 /* Transmit Flow Off (got XOFF) */
#define CCSR_TXFLON 0x02 /* Transmit Flow On (got XON) */
/* Modem Change Option Register 1 (R/W) */
#define MCOR1_DSRZD 0x80 /* Detect 0->1 transition of DSR */
#define MCOR1_CDZD 0x40 /* Detect 0->1 transition of CD */
#define MCOR1_CTSZD 0x20 /* Detect 0->1 transition of CTS */
#define MCOR1_DTRTH 0x0f /* Auto DTR flow control Threshold (1-8) */
#define MCOR1_NODTRFC 0x0 /* Automatic DTR flow control disabled */
/* Modem Change Option Register 2 (R/W) */
#define MCOR2_DSROD 0x80 /* Detect 1->0 transition of DSR */
#define MCOR2_CDOD 0x40 /* Detect 1->0 transition of CD */
#define MCOR2_CTSOD 0x20 /* Detect 1->0 transition of CTS */
/* Modem Change Register (R/W) */
#define MCR_DSRCHG 0x80 /* DSR Changed */
#define MCR_CDCHG 0x40 /* CD Changed */
#define MCR_CTSCHG 0x20 /* CTS Changed */
/* Modem Signal Value Register (R/W) */
#define MSVR_DSR 0x80 /* Current state of DSR input */
#define MSVR_CD 0x40 /* Current state of CD input */
#define MSVR_CTS 0x20 /* Current state of CTS input */
#define MSVR_DTR 0x02 /* Current state of DTR output */
#define MSVR_RTS 0x01 /* Current state of RTS output */
/* Escape characters */
#define CD186x_C_ESC 0x00 /* Escape character */
#define CD186x_C_SBRK 0x81 /* Start sending BREAK */
#define CD186x_C_DELAY 0x82 /* Delay output */
#define CD186x_C_EBRK 0x83 /* Stop sending BREAK */
#define SRSR_RREQint 0x10 /* This chip wants "rec" serviced */
#define SRSR_TREQint 0x04 /* This chip wants "transmit" serviced */
#define SRSR_MREQint 0x01 /* This chip wants "mdm change" serviced */
#define SRCR_PKGTYPE 0x80
#define SRCR_REGACKEN 0x40
#define SRCR_DAISYEN 0x20
#define SRCR_GLOBPRI 0x10
#define SRCR_UNFAIR 0x08
#define SRCR_AUTOPRI 0x02
#define SRCR_PRISEL 0x01

View File

@@ -0,0 +1,71 @@
#define cons_num (vc_cons[currcons].d->vc_num)
#define video_scan_lines (vc_cons[currcons].d->vc_scan_lines)
#define sw (vc_cons[currcons].d->vc_sw)
#define screenbuf (vc_cons[currcons].d->vc_screenbuf)
#define screenbuf_size (vc_cons[currcons].d->vc_screenbuf_size)
#define origin (vc_cons[currcons].d->vc_origin)
#define scr_top (vc_cons[currcons].d->vc_scr_top)
#define visible_origin (vc_cons[currcons].d->vc_visible_origin)
#define scr_end (vc_cons[currcons].d->vc_scr_end)
#define pos (vc_cons[currcons].d->vc_pos)
#define top (vc_cons[currcons].d->vc_top)
#define bottom (vc_cons[currcons].d->vc_bottom)
#define x (vc_cons[currcons].d->vc_x)
#define y (vc_cons[currcons].d->vc_y)
#define vc_state (vc_cons[currcons].d->vc_state)
#define npar (vc_cons[currcons].d->vc_npar)
#define par (vc_cons[currcons].d->vc_par)
#define ques (vc_cons[currcons].d->vc_ques)
#define attr (vc_cons[currcons].d->vc_attr)
#define saved_x (vc_cons[currcons].d->vc_saved_x)
#define saved_y (vc_cons[currcons].d->vc_saved_y)
#define translate (vc_cons[currcons].d->vc_translate)
#define G0_charset (vc_cons[currcons].d->vc_G0_charset)
#define G1_charset (vc_cons[currcons].d->vc_G1_charset)
#define saved_G0 (vc_cons[currcons].d->vc_saved_G0)
#define saved_G1 (vc_cons[currcons].d->vc_saved_G1)
#define utf (vc_cons[currcons].d->vc_utf)
#define utf_count (vc_cons[currcons].d->vc_utf_count)
#define utf_char (vc_cons[currcons].d->vc_utf_char)
#define video_erase_char (vc_cons[currcons].d->vc_video_erase_char)
#define disp_ctrl (vc_cons[currcons].d->vc_disp_ctrl)
#define toggle_meta (vc_cons[currcons].d->vc_toggle_meta)
#define decscnm (vc_cons[currcons].d->vc_decscnm)
#define decom (vc_cons[currcons].d->vc_decom)
#define decawm (vc_cons[currcons].d->vc_decawm)
#define deccm (vc_cons[currcons].d->vc_deccm)
#define decim (vc_cons[currcons].d->vc_decim)
#define deccolm (vc_cons[currcons].d->vc_deccolm)
#define need_wrap (vc_cons[currcons].d->vc_need_wrap)
#define kmalloced (vc_cons[currcons].d->vc_kmalloced)
#define report_mouse (vc_cons[currcons].d->vc_report_mouse)
#define color (vc_cons[currcons].d->vc_color)
#define s_color (vc_cons[currcons].d->vc_s_color)
#define def_color (vc_cons[currcons].d->vc_def_color)
#define foreground (color & 0x0f)
#define background (color & 0xf0)
#define charset (vc_cons[currcons].d->vc_charset)
#define s_charset (vc_cons[currcons].d->vc_s_charset)
#define intensity (vc_cons[currcons].d->vc_intensity)
#define underline (vc_cons[currcons].d->vc_underline)
#define blink (vc_cons[currcons].d->vc_blink)
#define reverse (vc_cons[currcons].d->vc_reverse)
#define s_intensity (vc_cons[currcons].d->vc_s_intensity)
#define s_underline (vc_cons[currcons].d->vc_s_underline)
#define s_blink (vc_cons[currcons].d->vc_s_blink)
#define s_reverse (vc_cons[currcons].d->vc_s_reverse)
#define ulcolor (vc_cons[currcons].d->vc_ulcolor)
#define halfcolor (vc_cons[currcons].d->vc_halfcolor)
#define tab_stop (vc_cons[currcons].d->vc_tab_stop)
#define palette (vc_cons[currcons].d->vc_palette)
#define bell_pitch (vc_cons[currcons].d->vc_bell_pitch)
#define bell_duration (vc_cons[currcons].d->vc_bell_duration)
#define cursor_type (vc_cons[currcons].d->vc_cursor_type)
#define display_fg (vc_cons[currcons].d->vc_display_fg)
#define complement_mask (vc_cons[currcons].d->vc_complement_mask)
#define s_complement_mask (vc_cons[currcons].d->vc_s_complement_mask)
#define hi_font_mask (vc_cons[currcons].d->vc_hi_font_mask)
#define vcmode (vt_cons[currcons]->vc_mode)
#define structsize (sizeof(struct vc_data) + sizeof(struct vt_struct))

View File

@@ -0,0 +1,685 @@
/*
* consolemap.c
*
* Mapping from internal code (such as Latin-1 or Unicode or IBM PC code)
* to font positions.
*
* aeb, 950210
*
* Support for multiple unimaps by Jakub Jelinek <jj@ultra.linux.cz>, July 1998
*
* Fix bug in inverse translation. Stanislav Voronyi <stas@cnti.uanet.kharkov.ua>, Dec 1998
*/
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kd.h>
#include <linux/errno.h>
#include <linux/mm.h>
#include <linux/slab.h>
#include <linux/init.h>
#include <linux/tty.h>
#include <asm/uaccess.h>
#include <linux/consolemap.h>
#include <linux/vt_kern.h>
static unsigned short translations[][256] = {
/* 8-bit Latin-1 mapped to Unicode -- trivial mapping */
{
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x007f,
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
},
/* VT100 graphics mapped to Unicode */
{
0x0000, 0x0001, 0x0002, 0x0003, 0x0004, 0x0005, 0x0006, 0x0007,
0x0008, 0x0009, 0x000a, 0x000b, 0x000c, 0x000d, 0x000e, 0x000f,
0x0010, 0x0011, 0x0012, 0x0013, 0x0014, 0x0015, 0x0016, 0x0017,
0x0018, 0x0019, 0x001a, 0x001b, 0x001c, 0x001d, 0x001e, 0x001f,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x2192, 0x2190, 0x2191, 0x2193, 0x002f,
0x2588, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x00a0,
0x25c6, 0x2592, 0x2409, 0x240c, 0x240d, 0x240a, 0x00b0, 0x00b1,
0x2591, 0x240b, 0x2518, 0x2510, 0x250c, 0x2514, 0x253c, 0xf800,
0xf801, 0x2500, 0xf803, 0xf804, 0x251c, 0x2524, 0x2534, 0x252c,
0x2502, 0x2264, 0x2265, 0x03c0, 0x2260, 0x00a3, 0x00b7, 0x007f,
0x0080, 0x0081, 0x0082, 0x0083, 0x0084, 0x0085, 0x0086, 0x0087,
0x0088, 0x0089, 0x008a, 0x008b, 0x008c, 0x008d, 0x008e, 0x008f,
0x0090, 0x0091, 0x0092, 0x0093, 0x0094, 0x0095, 0x0096, 0x0097,
0x0098, 0x0099, 0x009a, 0x009b, 0x009c, 0x009d, 0x009e, 0x009f,
0x00a0, 0x00a1, 0x00a2, 0x00a3, 0x00a4, 0x00a5, 0x00a6, 0x00a7,
0x00a8, 0x00a9, 0x00aa, 0x00ab, 0x00ac, 0x00ad, 0x00ae, 0x00af,
0x00b0, 0x00b1, 0x00b2, 0x00b3, 0x00b4, 0x00b5, 0x00b6, 0x00b7,
0x00b8, 0x00b9, 0x00ba, 0x00bb, 0x00bc, 0x00bd, 0x00be, 0x00bf,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x00c4, 0x00c5, 0x00c6, 0x00c7,
0x00c8, 0x00c9, 0x00ca, 0x00cb, 0x00cc, 0x00cd, 0x00ce, 0x00cf,
0x00d0, 0x00d1, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x00d6, 0x00d7,
0x00d8, 0x00d9, 0x00da, 0x00db, 0x00dc, 0x00dd, 0x00de, 0x00df,
0x00e0, 0x00e1, 0x00e2, 0x00e3, 0x00e4, 0x00e5, 0x00e6, 0x00e7,
0x00e8, 0x00e9, 0x00ea, 0x00eb, 0x00ec, 0x00ed, 0x00ee, 0x00ef,
0x00f0, 0x00f1, 0x00f2, 0x00f3, 0x00f4, 0x00f5, 0x00f6, 0x00f7,
0x00f8, 0x00f9, 0x00fa, 0x00fb, 0x00fc, 0x00fd, 0x00fe, 0x00ff
},
/* IBM Codepage 437 mapped to Unicode */
{
0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x2663, 0x2660, 0x2022,
0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b, 0x263c,
0x25b6, 0x25c0, 0x2195, 0x203c, 0x00b6, 0x00a7, 0x25ac, 0x21a8,
0x2191, 0x2193, 0x2192, 0x2190, 0x221f, 0x2194, 0x25b2, 0x25bc,
0x0020, 0x0021, 0x0022, 0x0023, 0x0024, 0x0025, 0x0026, 0x0027,
0x0028, 0x0029, 0x002a, 0x002b, 0x002c, 0x002d, 0x002e, 0x002f,
0x0030, 0x0031, 0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037,
0x0038, 0x0039, 0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f,
0x0040, 0x0041, 0x0042, 0x0043, 0x0044, 0x0045, 0x0046, 0x0047,
0x0048, 0x0049, 0x004a, 0x004b, 0x004c, 0x004d, 0x004e, 0x004f,
0x0050, 0x0051, 0x0052, 0x0053, 0x0054, 0x0055, 0x0056, 0x0057,
0x0058, 0x0059, 0x005a, 0x005b, 0x005c, 0x005d, 0x005e, 0x005f,
0x0060, 0x0061, 0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067,
0x0068, 0x0069, 0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f,
0x0070, 0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077,
0x0078, 0x0079, 0x007a, 0x007b, 0x007c, 0x007d, 0x007e, 0x2302,
0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0, 0x00e5, 0x00e7,
0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec, 0x00c4, 0x00c5,
0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6, 0x00f2, 0x00fb, 0x00f9,
0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3, 0x00a5, 0x20a7, 0x0192,
0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1, 0x00d1, 0x00aa, 0x00ba,
0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc, 0x00a1, 0x00ab, 0x00bb,
0x2591, 0x2592, 0x2593, 0x2502, 0x2524, 0x2561, 0x2562, 0x2556,
0x2555, 0x2563, 0x2551, 0x2557, 0x255d, 0x255c, 0x255b, 0x2510,
0x2514, 0x2534, 0x252c, 0x251c, 0x2500, 0x253c, 0x255e, 0x255f,
0x255a, 0x2554, 0x2569, 0x2566, 0x2560, 0x2550, 0x256c, 0x2567,
0x2568, 0x2564, 0x2565, 0x2559, 0x2558, 0x2552, 0x2553, 0x256b,
0x256a, 0x2518, 0x250c, 0x2588, 0x2584, 0x258c, 0x2590, 0x2580,
0x03b1, 0x00df, 0x0393, 0x03c0, 0x03a3, 0x03c3, 0x00b5, 0x03c4,
0x03a6, 0x0398, 0x03a9, 0x03b4, 0x221e, 0x03c6, 0x03b5, 0x2229,
0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0x00a0
},
/* User mapping -- default to codes for direct font mapping */
{
0xf000, 0xf001, 0xf002, 0xf003, 0xf004, 0xf005, 0xf006, 0xf007,
0xf008, 0xf009, 0xf00a, 0xf00b, 0xf00c, 0xf00d, 0xf00e, 0xf00f,
0xf010, 0xf011, 0xf012, 0xf013, 0xf014, 0xf015, 0xf016, 0xf017,
0xf018, 0xf019, 0xf01a, 0xf01b, 0xf01c, 0xf01d, 0xf01e, 0xf01f,
0xf020, 0xf021, 0xf022, 0xf023, 0xf024, 0xf025, 0xf026, 0xf027,
0xf028, 0xf029, 0xf02a, 0xf02b, 0xf02c, 0xf02d, 0xf02e, 0xf02f,
0xf030, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036, 0xf037,
0xf038, 0xf039, 0xf03a, 0xf03b, 0xf03c, 0xf03d, 0xf03e, 0xf03f,
0xf040, 0xf041, 0xf042, 0xf043, 0xf044, 0xf045, 0xf046, 0xf047,
0xf048, 0xf049, 0xf04a, 0xf04b, 0xf04c, 0xf04d, 0xf04e, 0xf04f,
0xf050, 0xf051, 0xf052, 0xf053, 0xf054, 0xf055, 0xf056, 0xf057,
0xf058, 0xf059, 0xf05a, 0xf05b, 0xf05c, 0xf05d, 0xf05e, 0xf05f,
0xf060, 0xf061, 0xf062, 0xf063, 0xf064, 0xf065, 0xf066, 0xf067,
0xf068, 0xf069, 0xf06a, 0xf06b, 0xf06c, 0xf06d, 0xf06e, 0xf06f,
0xf070, 0xf071, 0xf072, 0xf073, 0xf074, 0xf075, 0xf076, 0xf077,
0xf078, 0xf079, 0xf07a, 0xf07b, 0xf07c, 0xf07d, 0xf07e, 0xf07f,
0xf080, 0xf081, 0xf082, 0xf083, 0xf084, 0xf085, 0xf086, 0xf087,
0xf088, 0xf089, 0xf08a, 0xf08b, 0xf08c, 0xf08d, 0xf08e, 0xf08f,
0xf090, 0xf091, 0xf092, 0xf093, 0xf094, 0xf095, 0xf096, 0xf097,
0xf098, 0xf099, 0xf09a, 0xf09b, 0xf09c, 0xf09d, 0xf09e, 0xf09f,
0xf0a0, 0xf0a1, 0xf0a2, 0xf0a3, 0xf0a4, 0xf0a5, 0xf0a6, 0xf0a7,
0xf0a8, 0xf0a9, 0xf0aa, 0xf0ab, 0xf0ac, 0xf0ad, 0xf0ae, 0xf0af,
0xf0b0, 0xf0b1, 0xf0b2, 0xf0b3, 0xf0b4, 0xf0b5, 0xf0b6, 0xf0b7,
0xf0b8, 0xf0b9, 0xf0ba, 0xf0bb, 0xf0bc, 0xf0bd, 0xf0be, 0xf0bf,
0xf0c0, 0xf0c1, 0xf0c2, 0xf0c3, 0xf0c4, 0xf0c5, 0xf0c6, 0xf0c7,
0xf0c8, 0xf0c9, 0xf0ca, 0xf0cb, 0xf0cc, 0xf0cd, 0xf0ce, 0xf0cf,
0xf0d0, 0xf0d1, 0xf0d2, 0xf0d3, 0xf0d4, 0xf0d5, 0xf0d6, 0xf0d7,
0xf0d8, 0xf0d9, 0xf0da, 0xf0db, 0xf0dc, 0xf0dd, 0xf0de, 0xf0df,
0xf0e0, 0xf0e1, 0xf0e2, 0xf0e3, 0xf0e4, 0xf0e5, 0xf0e6, 0xf0e7,
0xf0e8, 0xf0e9, 0xf0ea, 0xf0eb, 0xf0ec, 0xf0ed, 0xf0ee, 0xf0ef,
0xf0f0, 0xf0f1, 0xf0f2, 0xf0f3, 0xf0f4, 0xf0f5, 0xf0f6, 0xf0f7,
0xf0f8, 0xf0f9, 0xf0fa, 0xf0fb, 0xf0fc, 0xf0fd, 0xf0fe, 0xf0ff
}
};
/* The standard kernel character-to-font mappings are not invertible
-- this is just a best effort. */
#define MAX_GLYPH 512 /* Max possible glyph value */
static int inv_translate[MAX_NR_CONSOLES];
struct uni_pagedir {
u16 **uni_pgdir[32];
unsigned long refcount;
unsigned long sum;
unsigned char *inverse_translations[4];
int readonly;
};
static struct uni_pagedir *dflt;
static void set_inverse_transl(struct vc_data *conp, struct uni_pagedir *p, int i)
{
int j, glyph;
unsigned short *t = translations[i];
unsigned char *q;
if (!p) return;
q = p->inverse_translations[i];
if (!q) {
q = p->inverse_translations[i] = (unsigned char *)
kmalloc(MAX_GLYPH, GFP_KERNEL);
if (!q) return;
}
memset(q, 0, MAX_GLYPH);
for (j = 0; j < E_TABSZ; j++) {
glyph = conv_uni_to_pc(conp, t[j]);
if (glyph >= 0 && glyph < MAX_GLYPH && q[glyph] < 32) {
/* prefer '-' above SHY etc. */
q[glyph] = j;
}
}
}
unsigned short *set_translate(int m,int currcons)
{
inv_translate[currcons] = m;
return translations[m];
}
/*
* Inverse translation is impossible for several reasons:
* 1. The font<->character maps are not 1-1.
* 2. The text may have been written while a different translation map
* was active, or using Unicode.
* Still, it is now possible to a certain extent to cut and paste non-ASCII.
*/
unsigned char inverse_translate(struct vc_data *conp, int glyph)
{
struct uni_pagedir *p;
if (glyph < 0 || glyph >= MAX_GLYPH)
return 0;
else if (!(p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc) ||
!p->inverse_translations[inv_translate[conp->vc_num]])
return glyph;
else
return p->inverse_translations[inv_translate[conp->vc_num]][glyph];
}
static void update_user_maps(void)
{
int i;
struct uni_pagedir *p, *q = NULL;
for (i = 0; i < MAX_NR_CONSOLES; i++) {
if (!vc_cons_allocated(i))
continue;
p = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc;
if (p && p != q) {
set_inverse_transl(vc_cons[i].d, p, USER_MAP);
q = p;
}
}
}
/*
* Load customizable translation table
* arg points to a 256 byte translation table.
*
* The "old" variants are for translation directly to font (using the
* 0xf000-0xf0ff "transparent" Unicodes) whereas the "new" variants set
* Unicodes explicitly.
*/
int con_set_trans_old(unsigned char __user * arg)
{
int i;
unsigned short *p = translations[USER_MAP];
i = verify_area(VERIFY_READ, arg, E_TABSZ);
if (i)
return i;
for (i=0; i<E_TABSZ ; i++) {
unsigned char uc;
__get_user(uc, arg+i);
p[i] = UNI_DIRECT_BASE | uc;
}
update_user_maps();
return 0;
}
int con_get_trans_old(unsigned char __user * arg)
{
int i, ch;
unsigned short *p = translations[USER_MAP];
i = verify_area(VERIFY_WRITE, arg, E_TABSZ);
if (i)
return i;
for (i=0; i<E_TABSZ ; i++)
{
ch = conv_uni_to_pc(vc_cons[fg_console].d, p[i]);
__put_user((ch & ~0xff) ? 0 : ch, arg+i);
}
return 0;
}
int con_set_trans_new(ushort __user * arg)
{
int i;
unsigned short *p = translations[USER_MAP];
i = verify_area(VERIFY_READ, arg, E_TABSZ*sizeof(unsigned short));
if (i)
return i;
for (i=0; i<E_TABSZ ; i++) {
unsigned short us;
__get_user(us, arg+i);
p[i] = us;
}
update_user_maps();
return 0;
}
int con_get_trans_new(ushort __user * arg)
{
int i;
unsigned short *p = translations[USER_MAP];
i = verify_area(VERIFY_WRITE, arg, E_TABSZ*sizeof(unsigned short));
if (i)
return i;
for (i=0; i<E_TABSZ ; i++)
__put_user(p[i], arg+i);
return 0;
}
/*
* Unicode -> current font conversion
*
* A font has at most 512 chars, usually 256.
* But one font position may represent several Unicode chars.
* A hashtable is somewhat of a pain to deal with, so use a
* "paged table" instead. Simulation has shown the memory cost of
* this 3-level paged table scheme to be comparable to a hash table.
*/
extern u8 dfont_unicount[]; /* Defined in console_defmap.c */
extern u16 dfont_unitable[];
static void con_release_unimap(struct uni_pagedir *p)
{
u16 **p1;
int i, j;
if (p == dflt) dflt = NULL;
for (i = 0; i < 32; i++) {
if ((p1 = p->uni_pgdir[i]) != NULL) {
for (j = 0; j < 32; j++)
if (p1[j])
kfree(p1[j]);
kfree(p1);
}
p->uni_pgdir[i] = NULL;
}
for (i = 0; i < 4; i++)
if (p->inverse_translations[i]) {
kfree(p->inverse_translations[i]);
p->inverse_translations[i] = NULL;
}
}
void con_free_unimap(int con)
{
struct uni_pagedir *p;
struct vc_data *conp = vc_cons[con].d;
p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;
if (!p) return;
*conp->vc_uni_pagedir_loc = 0;
if (--p->refcount) return;
con_release_unimap(p);
kfree(p);
}
static int con_unify_unimap(struct vc_data *conp, struct uni_pagedir *p)
{
int i, j, k;
struct uni_pagedir *q;
for (i = 0; i < MAX_NR_CONSOLES; i++) {
if (!vc_cons_allocated(i))
continue;
q = (struct uni_pagedir *)*vc_cons[i].d->vc_uni_pagedir_loc;
if (!q || q == p || q->sum != p->sum)
continue;
for (j = 0; j < 32; j++) {
u16 **p1, **q1;
p1 = p->uni_pgdir[j]; q1 = q->uni_pgdir[j];
if (!p1 && !q1)
continue;
if (!p1 || !q1)
break;
for (k = 0; k < 32; k++) {
if (!p1[k] && !q1[k])
continue;
if (!p1[k] || !q1[k])
break;
if (memcmp(p1[k], q1[k], 64*sizeof(u16)))
break;
}
if (k < 32)
break;
}
if (j == 32) {
q->refcount++;
*conp->vc_uni_pagedir_loc = (unsigned long)q;
con_release_unimap(p);
kfree(p);
return 1;
}
}
return 0;
}
static int
con_insert_unipair(struct uni_pagedir *p, u_short unicode, u_short fontpos)
{
int i, n;
u16 **p1, *p2;
if (!(p1 = p->uni_pgdir[n = unicode >> 11])) {
p1 = p->uni_pgdir[n] = kmalloc(32*sizeof(u16 *), GFP_KERNEL);
if (!p1) return -ENOMEM;
for (i = 0; i < 32; i++)
p1[i] = NULL;
}
if (!(p2 = p1[n = (unicode >> 6) & 0x1f])) {
p2 = p1[n] = kmalloc(64*sizeof(u16), GFP_KERNEL);
if (!p2) return -ENOMEM;
memset(p2, 0xff, 64*sizeof(u16)); /* No glyphs for the characters (yet) */
}
p2[unicode & 0x3f] = fontpos;
p->sum += (fontpos << 20) + unicode;
return 0;
}
/* ui is a leftover from using a hashtable, but might be used again */
int con_clear_unimap(int con, struct unimapinit *ui)
{
struct uni_pagedir *p, *q;
struct vc_data *conp = vc_cons[con].d;
p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;
if (p && p->readonly) return -EIO;
if (!p || --p->refcount) {
q = (struct uni_pagedir *)kmalloc(sizeof(*p), GFP_KERNEL);
if (!q) {
if (p) p->refcount++;
return -ENOMEM;
}
memset(q, 0, sizeof(*q));
q->refcount=1;
*conp->vc_uni_pagedir_loc = (unsigned long)q;
} else {
if (p == dflt) dflt = NULL;
p->refcount++;
p->sum = 0;
con_release_unimap(p);
}
return 0;
}
int
con_set_unimap(int con, ushort ct, struct unipair __user *list)
{
int err = 0, err1, i;
struct uni_pagedir *p, *q;
struct vc_data *conp = vc_cons[con].d;
p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;
if (p->readonly) return -EIO;
if (!ct) return 0;
if (p->refcount > 1) {
int j, k;
u16 **p1, *p2, l;
err1 = con_clear_unimap(con, NULL);
if (err1) return err1;
q = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;
for (i = 0, l = 0; i < 32; i++)
if ((p1 = p->uni_pgdir[i]))
for (j = 0; j < 32; j++)
if ((p2 = p1[j]))
for (k = 0; k < 64; k++, l++)
if (p2[k] != 0xffff) {
err1 = con_insert_unipair(q, l, p2[k]);
if (err1) {
p->refcount++;
*conp->vc_uni_pagedir_loc = (unsigned long)p;
con_release_unimap(q);
kfree(q);
return err1;
}
}
p = q;
} else if (p == dflt)
dflt = NULL;
while (ct--) {
unsigned short unicode, fontpos;
__get_user(unicode, &list->unicode);
__get_user(fontpos, &list->fontpos);
if ((err1 = con_insert_unipair(p, unicode,fontpos)) != 0)
err = err1;
list++;
}
if (con_unify_unimap(conp, p))
return err;
for (i = 0; i <= 3; i++)
set_inverse_transl(conp, p, i); /* Update all inverse translations */
return err;
}
/* Loads the unimap for the hardware font, as defined in uni_hash.tbl.
The representation used was the most compact I could come up
with. This routine is executed at sys_setup time, and when the
PIO_FONTRESET ioctl is called. */
int
con_set_default_unimap(int con)
{
int i, j, err = 0, err1;
u16 *q;
struct uni_pagedir *p;
struct vc_data *conp = vc_cons[con].d;
if (dflt) {
p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;
if (p == dflt)
return 0;
dflt->refcount++;
*conp->vc_uni_pagedir_loc = (unsigned long)dflt;
if (p && --p->refcount) {
con_release_unimap(p);
kfree(p);
}
return 0;
}
/* The default font is always 256 characters */
err = con_clear_unimap(con,NULL);
if (err) return err;
p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;
q = dfont_unitable;
for (i = 0; i < 256; i++)
for (j = dfont_unicount[i]; j; j--) {
err1 = con_insert_unipair(p, *(q++), i);
if (err1)
err = err1;
}
if (con_unify_unimap(conp, p)) {
dflt = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;
return err;
}
for (i = 0; i <= 3; i++)
set_inverse_transl(conp, p, i); /* Update all inverse translations */
dflt = p;
return err;
}
EXPORT_SYMBOL(con_set_default_unimap);
int
con_copy_unimap(int dstcon, int srccon)
{
struct vc_data *sconp = vc_cons[srccon].d;
struct vc_data *dconp = vc_cons[dstcon].d;
struct uni_pagedir *q;
if (!vc_cons_allocated(srccon) || !*sconp->vc_uni_pagedir_loc)
return -EINVAL;
if (*dconp->vc_uni_pagedir_loc == *sconp->vc_uni_pagedir_loc)
return 0;
con_free_unimap(dstcon);
q = (struct uni_pagedir *)*sconp->vc_uni_pagedir_loc;
q->refcount++;
*dconp->vc_uni_pagedir_loc = (long)q;
return 0;
}
int
con_get_unimap(int con, ushort ct, ushort __user *uct, struct unipair __user *list)
{
int i, j, k, ect;
u16 **p1, *p2;
struct uni_pagedir *p;
struct vc_data *conp = vc_cons[con].d;
ect = 0;
if (*conp->vc_uni_pagedir_loc) {
p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;
for (i = 0; i < 32; i++)
if ((p1 = p->uni_pgdir[i]))
for (j = 0; j < 32; j++)
if ((p2 = *(p1++)))
for (k = 0; k < 64; k++) {
if (*p2 < MAX_GLYPH && ect++ < ct) {
__put_user((u_short)((i<<11)+(j<<6)+k),
&list->unicode);
__put_user((u_short) *p2,
&list->fontpos);
list++;
}
p2++;
}
}
__put_user(ect, uct);
return ((ect <= ct) ? 0 : -ENOMEM);
}
void con_protect_unimap(int con, int rdonly)
{
struct uni_pagedir *p = (struct uni_pagedir *)
*vc_cons[con].d->vc_uni_pagedir_loc;
if (p) p->readonly = rdonly;
}
int
conv_uni_to_pc(struct vc_data *conp, long ucs)
{
int h;
u16 **p1, *p2;
struct uni_pagedir *p;
/* Only 16-bit codes supported at this time */
if (ucs > 0xffff)
ucs = 0xfffd; /* U+FFFD: REPLACEMENT CHARACTER */
else if (ucs < 0x20 || ucs >= 0xfffe)
return -1; /* Not a printable character */
else if (ucs == 0xfeff || (ucs >= 0x200a && ucs <= 0x200f))
return -2; /* Zero-width space */
/*
* UNI_DIRECT_BASE indicates the start of the region in the User Zone
* which always has a 1:1 mapping to the currently loaded font. The
* UNI_DIRECT_MASK indicates the bit span of the region.
*/
else if ((ucs & ~UNI_DIRECT_MASK) == UNI_DIRECT_BASE)
return ucs & UNI_DIRECT_MASK;
if (!*conp->vc_uni_pagedir_loc)
return -3;
p = (struct uni_pagedir *)*conp->vc_uni_pagedir_loc;
if ((p1 = p->uni_pgdir[ucs >> 11]) &&
(p2 = p1[(ucs >> 6) & 0x1f]) &&
(h = p2[ucs & 0x3f]) < MAX_GLYPH)
return h;
return -4; /* not found */
}
/*
* This is called at sys_setup time, after memory and the console are
* initialized. It must be possible to call kmalloc(..., GFP_KERNEL)
* from this function, hence the call from sys_setup.
*/
void __init
console_map_init(void)
{
int i;
for (i = 0; i < MAX_NR_CONSOLES; i++)
if (vc_cons_allocated(i) && !*vc_cons[i].d->vc_uni_pagedir_loc)
con_set_default_unimap(i);
}
EXPORT_SYMBOL(con_copy_unimap);

Binary file not shown.

View File

@@ -0,0 +1,86 @@
/*
* Do not edit this file; it was automatically generated by
*
* conmakehash drivers/char/cp437.uni > [this file]
*
*/
#include <linux/types.h>
u8 dfont_unicount[256] =
{
1, 1, 1, 1, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 2, 1, 1, 1, 1, 1,
1, 1, 1, 1, 2, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 5, 1, 2, 1, 4, 1, 1,
1, 5, 1, 2, 1, 1, 1, 5,
1, 1, 2, 1, 1, 4, 1, 1,
1, 2, 1, 1, 1, 1, 1, 2,
1, 2, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2,
1, 1, 1, 1, 1, 1, 1, 1,
2, 2, 1, 1, 2, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 2,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 2, 1, 1, 1, 1, 2, 1,
2, 1, 2, 1, 1, 2, 1, 1,
1, 1, 1, 1, 1, 1, 1, 1,
1, 1, 1, 1, 1, 1, 2, 1
};
u16 dfont_unitable[297] =
{
0x0000, 0x263a, 0x263b, 0x2665, 0x2666, 0x25c6, 0x2663, 0x2660,
0x2022, 0x25d8, 0x25cb, 0x25d9, 0x2642, 0x2640, 0x266a, 0x266b,
0x263c, 0x25b6, 0x25ba, 0x25c0, 0x25c4, 0x2195, 0x203c, 0x00b6,
0x00a7, 0x25ac, 0x21a8, 0x2191, 0x2193, 0x2192, 0x2190, 0x221f,
0x2194, 0x25b2, 0x25bc, 0x0020, 0x0021, 0x0022, 0x00a8, 0x0023,
0x0024, 0x0025, 0x0026, 0x0027, 0x0028, 0x0029, 0x002a, 0x002b,
0x002c, 0x00b8, 0x002d, 0x00ad, 0x002e, 0x002f, 0x0030, 0x0031,
0x0032, 0x0033, 0x0034, 0x0035, 0x0036, 0x0037, 0x0038, 0x0039,
0x003a, 0x003b, 0x003c, 0x003d, 0x003e, 0x003f, 0x0040, 0x0041,
0x00c0, 0x00c1, 0x00c2, 0x00c3, 0x0042, 0x0043, 0x00a9, 0x0044,
0x0045, 0x00c8, 0x00ca, 0x00cb, 0x0046, 0x0047, 0x0048, 0x0049,
0x00cc, 0x00cd, 0x00ce, 0x00cf, 0x004a, 0x004b, 0x212a, 0x004c,
0x004d, 0x004e, 0x004f, 0x00d2, 0x00d3, 0x00d4, 0x00d5, 0x0050,
0x0051, 0x0052, 0x00ae, 0x0053, 0x0054, 0x0055, 0x00d9, 0x00da,
0x00db, 0x0056, 0x0057, 0x0058, 0x0059, 0x00dd, 0x005a, 0x005b,
0x005c, 0x005d, 0x005e, 0x005f, 0xf804, 0x0060, 0x0061, 0x00e3,
0x0062, 0x0063, 0x0064, 0x0065, 0x0066, 0x0067, 0x0068, 0x0069,
0x006a, 0x006b, 0x006c, 0x006d, 0x006e, 0x006f, 0x00f5, 0x0070,
0x0071, 0x0072, 0x0073, 0x0074, 0x0075, 0x0076, 0x0077, 0x0078,
0x00d7, 0x0079, 0x00fd, 0x007a, 0x007b, 0x007c, 0x00a5, 0x007d,
0x007e, 0x2302, 0x00c7, 0x00fc, 0x00e9, 0x00e2, 0x00e4, 0x00e0,
0x00e5, 0x00e7, 0x00ea, 0x00eb, 0x00e8, 0x00ef, 0x00ee, 0x00ec,
0x00c4, 0x00c5, 0x212b, 0x00c9, 0x00e6, 0x00c6, 0x00f4, 0x00f6,
0x00f2, 0x00fb, 0x00f9, 0x00ff, 0x00d6, 0x00dc, 0x00a2, 0x00a3,
0x00a5, 0x20a7, 0x0192, 0x00e1, 0x00ed, 0x00f3, 0x00fa, 0x00f1,
0x00d1, 0x00aa, 0x00ba, 0x00bf, 0x2310, 0x00ac, 0x00bd, 0x00bc,
0x00a1, 0x00ab, 0x00bb, 0x2591, 0x2592, 0x2593, 0x2502, 0x2524,
0x2561, 0x2562, 0x2556, 0x2555, 0x2563, 0x2551, 0x2557, 0x255d,
0x255c, 0x255b, 0x2510, 0x2514, 0x2534, 0x252c, 0x251c, 0x2500,
0x253c, 0x255e, 0x255f, 0x255a, 0x2554, 0x2569, 0x2566, 0x2560,
0x2550, 0x256c, 0x2567, 0x2568, 0x2564, 0x2565, 0x2559, 0x2558,
0x2552, 0x2553, 0x256b, 0x256a, 0x2518, 0x250c, 0x2588, 0x2584,
0x258c, 0x2590, 0x2580, 0x03b1, 0x03b2, 0x00df, 0x0393, 0x03c0,
0x03a3, 0x03c3, 0x00b5, 0x03bc, 0x03c4, 0x03a6, 0x00d8, 0x0398,
0x03a9, 0x2126, 0x03b4, 0x221e, 0x03c6, 0x00f8, 0x03b5, 0x2229,
0x2261, 0x00b1, 0x2265, 0x2264, 0x2320, 0x2321, 0x00f7, 0x2248,
0x00b0, 0x2219, 0x00b7, 0x221a, 0x207f, 0x00b2, 0x25a0, 0xfffd,
0x00a0
};

Binary file not shown.

View File

@@ -0,0 +1,291 @@
#
# Unicode table for IBM Codepage 437. Note that there are many more
# substitutions that could be conceived (for example, thick-line
# graphs probably should be replaced with double-line ones, accented
# Latin characters should replaced with their nonaccented versions,
# and some upper case Greek characters could be replaced by Latin), however,
# I have limited myself to the Unicodes used by the kernel ISO 8859-1,
# DEC VT, and IBM CP 437 tables.
#
# --------------------------------
#
# Basic IBM dingbats, some of which will never have a purpose clear
# to mankind
#
0x00 U+0000
0x01 U+263a
0x02 U+263b
0x03 U+2665
0x04 U+2666 U+25c6
0x05 U+2663
0x06 U+2660
0x07 U+2022
0x08 U+25d8
0x09 U+25cb
0x0a U+25d9
0x0b U+2642
0x0c U+2640
0x0d U+266a
0x0e U+266b
0x0f U+263c
0x10 U+25b6 U+25ba
0x11 U+25c0 U+25c4
0x12 U+2195
0x13 U+203c
0x14 U+00b6
0x15 U+00a7
0x16 U+25ac
0x17 U+21a8
0x18 U+2191
0x19 U+2193
0x1a U+2192
0x1b U+2190
0x1c U+221f
0x1d U+2194
0x1e U+25b2
0x1f U+25bc
#
# The ASCII range is identity-mapped, but some of the characters also
# have to act as substitutes, especially the upper-case characters.
#
0x20 U+0020
0x21 U+0021
0x22 U+0022 U+00a8
0x23 U+0023
0x24 U+0024
0x25 U+0025
0x26 U+0026
0x27 U+0027
0x28 U+0028
0x29 U+0029
0x2a U+002a
0x2b U+002b
0x2c U+002c U+00b8
0x2d U+002d U+00ad
0x2e U+002e
0x2f U+002f
0x30 U+0030
0x31 U+0031
0x32 U+0032
0x33 U+0033
0x34 U+0034
0x35 U+0035
0x36 U+0036
0x37 U+0037
0x38 U+0038
0x39 U+0039
0x3a U+003a
0x3b U+003b
0x3c U+003c
0x3d U+003d
0x3e U+003e
0x3f U+003f
0x40 U+0040
0x41 U+0041 U+00c0 U+00c1 U+00c2 U+00c3
0x42 U+0042
0x43 U+0043 U+00a9
0x44 U+0044
0x45 U+0045 U+00c8 U+00ca U+00cb
0x46 U+0046
0x47 U+0047
0x48 U+0048
0x49 U+0049 U+00cc U+00cd U+00ce U+00cf
0x4a U+004a
0x4b U+004b U+212a
0x4c U+004c
0x4d U+004d
0x4e U+004e
0x4f U+004f U+00d2 U+00d3 U+00d4 U+00d5
0x50 U+0050
0x51 U+0051
0x52 U+0052 U+00ae
0x53 U+0053
0x54 U+0054
0x55 U+0055 U+00d9 U+00da U+00db
0x56 U+0056
0x57 U+0057
0x58 U+0058
0x59 U+0059 U+00dd
0x5a U+005a
0x5b U+005b
0x5c U+005c
0x5d U+005d
0x5e U+005e
0x5f U+005f U+f804
0x60 U+0060
0x61 U+0061 U+00e3
0x62 U+0062
0x63 U+0063
0x64 U+0064
0x65 U+0065
0x66 U+0066
0x67 U+0067
0x68 U+0068
0x69 U+0069
0x6a U+006a
0x6b U+006b
0x6c U+006c
0x6d U+006d
0x6e U+006e
0x6f U+006f U+00f5
0x70 U+0070
0x71 U+0071
0x72 U+0072
0x73 U+0073
0x74 U+0074
0x75 U+0075
0x76 U+0076
0x77 U+0077
0x78 U+0078 U+00d7
0x79 U+0079 U+00fd
0x7a U+007a
0x7b U+007b
0x7c U+007c U+00a5
0x7d U+007d
0x7e U+007e
#
# Okay, what on Earth is this one supposed to be used for?
#
0x7f U+2302
#
# Non-English characters, mostly lower case letters...
#
0x80 U+00c7
0x81 U+00fc
0x82 U+00e9
0x83 U+00e2
0x84 U+00e4
0x85 U+00e0
0x86 U+00e5
0x87 U+00e7
0x88 U+00ea
0x89 U+00eb
0x8a U+00e8
0x8b U+00ef
0x8c U+00ee
0x8d U+00ec
0x8e U+00c4
0x8f U+00c5 U+212b
0x90 U+00c9
0x91 U+00e6
0x92 U+00c6
0x93 U+00f4
0x94 U+00f6
0x95 U+00f2
0x96 U+00fb
0x97 U+00f9
0x98 U+00ff
0x99 U+00d6
0x9a U+00dc
0x9b U+00a2
0x9c U+00a3
0x9d U+00a5
0x9e U+20a7
0x9f U+0192
0xa0 U+00e1
0xa1 U+00ed
0xa2 U+00f3
0xa3 U+00fa
0xa4 U+00f1
0xa5 U+00d1
0xa6 U+00aa
0xa7 U+00ba
0xa8 U+00bf
0xa9 U+2310
0xaa U+00ac
0xab U+00bd
0xac U+00bc
0xad U+00a1
0xae U+00ab
0xaf U+00bb
#
# Block graphics
#
0xb0 U+2591
0xb1 U+2592
0xb2 U+2593
0xb3 U+2502
0xb4 U+2524
0xb5 U+2561
0xb6 U+2562
0xb7 U+2556
0xb8 U+2555
0xb9 U+2563
0xba U+2551
0xbb U+2557
0xbc U+255d
0xbd U+255c
0xbe U+255b
0xbf U+2510
0xc0 U+2514
0xc1 U+2534
0xc2 U+252c
0xc3 U+251c
0xc4 U+2500
0xc5 U+253c
0xc6 U+255e
0xc7 U+255f
0xc8 U+255a
0xc9 U+2554
0xca U+2569
0xcb U+2566
0xcc U+2560
0xcd U+2550
0xce U+256c
0xcf U+2567
0xd0 U+2568
0xd1 U+2564
0xd2 U+2565
0xd3 U+2559
0xd4 U+2558
0xd5 U+2552
0xd6 U+2553
0xd7 U+256b
0xd8 U+256a
0xd9 U+2518
0xda U+250c
0xdb U+2588
0xdc U+2584
0xdd U+258c
0xde U+2590
0xdf U+2580
#
# Greek letters and mathematical symbols
#
0xe0 U+03b1
0xe1 U+03b2 U+00df
0xe2 U+0393
0xe3 U+03c0
0xe4 U+03a3
0xe5 U+03c3
0xe6 U+00b5 U+03bc
0xe7 U+03c4
0xe8 U+03a6 U+00d8
0xe9 U+0398
0xea U+03a9 U+2126
0xeb U+03b4
0xec U+221e
0xed U+03c6 U+00f8
0xee U+03b5
0xef U+2229
0xf0 U+2261
0xf1 U+00b1
0xf2 U+2265
0xf3 U+2264
0xf4 U+2320
0xf5 U+2321
0xf6 U+00f7
0xf7 U+2248
0xf8 U+00b0
0xf9 U+2219
0xfa U+00b7
0xfb U+221a
0xfc U+207f
0xfd U+00b2
#
# Square bullet, non-spacing blank
# Mapping U+fffd to the square bullet means it is the substitution
# character
#
0xfe U+25a0 U+fffd
0xff U+00a0

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,100 @@
/*
* sercons.c
* choose the right serial device at boot time
*
* triemer 6-SEP-1998
* sercons.c is designed to allow the three different kinds
* of serial devices under the decstation world to co-exist
* in the same kernel. The idea here is to abstract
* the pieces of the drivers that are common to this file
* so that they do not clash at compile time and runtime.
*
* HK 16-SEP-1998 v0.002
* removed the PROM console as this is not a real serial
* device. Added support for PROM console in drivers/char/tty_io.c
* instead. Although it may work to enable more than one
* console device I strongly recommend to use only one.
*/
#include <linux/config.h>
#include <linux/init.h>
#include <asm/dec/machtype.h>
#ifdef CONFIG_ZS
extern int zs_init(void);
#endif
#ifdef CONFIG_DZ
extern int dz_init(void);
#endif
#ifdef CONFIG_SERIAL_CONSOLE
#ifdef CONFIG_ZS
extern void zs_serial_console_init(void);
#endif
#ifdef CONFIG_DZ
extern void dz_serial_console_init(void);
#endif
#endif
/* rs_init - starts up the serial interface -
handle normal case of starting up the serial interface */
#ifdef CONFIG_SERIAL
int __init rs_init(void)
{
#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
if (IOASIC)
return zs_init();
else
return dz_init();
#else
#ifdef CONFIG_ZS
return zs_init();
#endif
#ifdef CONFIG_DZ
return dz_init();
#endif
#endif
}
__initcall(rs_init);
#endif
#ifdef CONFIG_SERIAL_CONSOLE
/* serial_console_init handles the special case of starting
* up the console on the serial port
*/
static int __init decserial_console_init(void)
{
#if defined(CONFIG_ZS) && defined(CONFIG_DZ)
if (IOASIC)
zs_serial_console_init();
else
dz_serial_console_init();
#else
#ifdef CONFIG_ZS
zs_serial_console_init();
#endif
#ifdef CONFIG_DZ
dz_serial_console_init();
#endif
#endif
return 0;
}
console_initcall(decserial_console_init);
#endif

View File

@@ -0,0 +1,262 @@
/* Do not edit this file! It was automatically generated by */
/* loadkeys --mktable defkeymap.map > defkeymap.c */
#include <linux/types.h>
#include <linux/keyboard.h>
#include <linux/kd.h>
u_short plain_map[NR_KEYS] = {
0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short shift_map[NR_KEYS] = {
0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short altgr_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short ctrl_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short shift_ctrl_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short alt_map[NR_KEYS] = {
0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short ctrl_alt_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
ushort *key_maps[MAX_NR_KEYMAPS] = {
plain_map, shift_map, altgr_map, NULL,
ctrl_map, shift_ctrl_map, NULL, NULL,
alt_map, NULL, NULL, NULL,
ctrl_alt_map, NULL
};
unsigned int keymap_count = 7;
/*
* Philosophy: most people do not define more strings, but they who do
* often want quite a lot of string space. So, we statically allocate
* the default and allocate dynamically in chunks of 512 bytes.
*/
char func_buf[] = {
'\033', '[', '[', 'A', 0,
'\033', '[', '[', 'B', 0,
'\033', '[', '[', 'C', 0,
'\033', '[', '[', 'D', 0,
'\033', '[', '[', 'E', 0,
'\033', '[', '1', '7', '~', 0,
'\033', '[', '1', '8', '~', 0,
'\033', '[', '1', '9', '~', 0,
'\033', '[', '2', '0', '~', 0,
'\033', '[', '2', '1', '~', 0,
'\033', '[', '2', '3', '~', 0,
'\033', '[', '2', '4', '~', 0,
'\033', '[', '2', '5', '~', 0,
'\033', '[', '2', '6', '~', 0,
'\033', '[', '2', '8', '~', 0,
'\033', '[', '2', '9', '~', 0,
'\033', '[', '3', '1', '~', 0,
'\033', '[', '3', '2', '~', 0,
'\033', '[', '3', '3', '~', 0,
'\033', '[', '3', '4', '~', 0,
'\033', '[', '1', '~', 0,
'\033', '[', '2', '~', 0,
'\033', '[', '3', '~', 0,
'\033', '[', '4', '~', 0,
'\033', '[', '5', '~', 0,
'\033', '[', '6', '~', 0,
'\033', '[', 'M', 0,
'\033', '[', 'P', 0,
};
char *funcbufptr = func_buf;
int funcbufsize = sizeof(func_buf);
int funcbufleft = 0; /* space left */
char *func_table[MAX_NR_FUNC] = {
func_buf + 0,
func_buf + 5,
func_buf + 10,
func_buf + 15,
func_buf + 20,
func_buf + 25,
func_buf + 31,
func_buf + 37,
func_buf + 43,
func_buf + 49,
func_buf + 55,
func_buf + 61,
func_buf + 67,
func_buf + 73,
func_buf + 79,
func_buf + 85,
func_buf + 91,
func_buf + 97,
func_buf + 103,
func_buf + 109,
func_buf + 115,
func_buf + 120,
func_buf + 125,
func_buf + 130,
func_buf + 135,
func_buf + 140,
func_buf + 145,
NULL,
NULL,
func_buf + 149,
NULL,
};
struct kbdiacr accent_table[MAX_DIACR] = {
{'`', 'A', '\300'}, {'`', 'a', '\340'},
{'\'', 'A', '\301'}, {'\'', 'a', '\341'},
{'^', 'A', '\302'}, {'^', 'a', '\342'},
{'~', 'A', '\303'}, {'~', 'a', '\343'},
{'"', 'A', '\304'}, {'"', 'a', '\344'},
{'O', 'A', '\305'}, {'o', 'a', '\345'},
{'0', 'A', '\305'}, {'0', 'a', '\345'},
{'A', 'A', '\305'}, {'a', 'a', '\345'},
{'A', 'E', '\306'}, {'a', 'e', '\346'},
{',', 'C', '\307'}, {',', 'c', '\347'},
{'`', 'E', '\310'}, {'`', 'e', '\350'},
{'\'', 'E', '\311'}, {'\'', 'e', '\351'},
{'^', 'E', '\312'}, {'^', 'e', '\352'},
{'"', 'E', '\313'}, {'"', 'e', '\353'},
{'`', 'I', '\314'}, {'`', 'i', '\354'},
{'\'', 'I', '\315'}, {'\'', 'i', '\355'},
{'^', 'I', '\316'}, {'^', 'i', '\356'},
{'"', 'I', '\317'}, {'"', 'i', '\357'},
{'-', 'D', '\320'}, {'-', 'd', '\360'},
{'~', 'N', '\321'}, {'~', 'n', '\361'},
{'`', 'O', '\322'}, {'`', 'o', '\362'},
{'\'', 'O', '\323'}, {'\'', 'o', '\363'},
{'^', 'O', '\324'}, {'^', 'o', '\364'},
{'~', 'O', '\325'}, {'~', 'o', '\365'},
{'"', 'O', '\326'}, {'"', 'o', '\366'},
{'/', 'O', '\330'}, {'/', 'o', '\370'},
{'`', 'U', '\331'}, {'`', 'u', '\371'},
{'\'', 'U', '\332'}, {'\'', 'u', '\372'},
{'^', 'U', '\333'}, {'^', 'u', '\373'},
{'"', 'U', '\334'}, {'"', 'u', '\374'},
{'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
{'T', 'H', '\336'}, {'t', 'h', '\376'},
{'s', 's', '\337'}, {'"', 'y', '\377'},
{'s', 'z', '\337'}, {'i', 'j', '\377'},
};
unsigned int accent_table_size = 68;

View File

@@ -0,0 +1,262 @@
/* Do not edit this file! It was automatically generated by */
/* loadkeys --mktable defkeymap.map > defkeymap.c */
#include <linux/types.h>
#include <linux/keyboard.h>
#include <linux/kd.h>
u_short plain_map[NR_KEYS] = {
0xf200, 0xf01b, 0xf031, 0xf032, 0xf033, 0xf034, 0xf035, 0xf036,
0xf037, 0xf038, 0xf039, 0xf030, 0xf02d, 0xf03d, 0xf07f, 0xf009,
0xfb71, 0xfb77, 0xfb65, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
0xfb6f, 0xfb70, 0xf05b, 0xf05d, 0xf201, 0xf702, 0xfb61, 0xfb73,
0xfb64, 0xfb66, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf03b,
0xf027, 0xf060, 0xf700, 0xf05c, 0xfb7a, 0xfb78, 0xfb63, 0xfb76,
0xfb62, 0xfb6e, 0xfb6d, 0xf02c, 0xf02e, 0xf02f, 0xf700, 0xf30c,
0xf703, 0xf020, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf209, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03c, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short shift_map[NR_KEYS] = {
0xf200, 0xf01b, 0xf021, 0xf040, 0xf023, 0xf024, 0xf025, 0xf05e,
0xf026, 0xf02a, 0xf028, 0xf029, 0xf05f, 0xf02b, 0xf07f, 0xf009,
0xfb51, 0xfb57, 0xfb45, 0xfb52, 0xfb54, 0xfb59, 0xfb55, 0xfb49,
0xfb4f, 0xfb50, 0xf07b, 0xf07d, 0xf201, 0xf702, 0xfb41, 0xfb53,
0xfb44, 0xfb46, 0xfb47, 0xfb48, 0xfb4a, 0xfb4b, 0xfb4c, 0xf03a,
0xf022, 0xf07e, 0xf700, 0xf07c, 0xfb5a, 0xfb58, 0xfb43, 0xfb56,
0xfb42, 0xfb4e, 0xfb4d, 0xf03c, 0xf03e, 0xf03f, 0xf700, 0xf30c,
0xf703, 0xf020, 0xf207, 0xf10a, 0xf10b, 0xf10c, 0xf10d, 0xf10e,
0xf10f, 0xf110, 0xf111, 0xf112, 0xf113, 0xf213, 0xf203, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf03e, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf20b, 0xf601, 0xf602, 0xf117, 0xf600, 0xf20a, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short altgr_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf040, 0xf200, 0xf024, 0xf200, 0xf200,
0xf07b, 0xf05b, 0xf05d, 0xf07d, 0xf05c, 0xf200, 0xf200, 0xf200,
0xfb71, 0xfb77, 0xf918, 0xfb72, 0xfb74, 0xfb79, 0xfb75, 0xfb69,
0xfb6f, 0xfb70, 0xf200, 0xf07e, 0xf201, 0xf702, 0xf914, 0xfb73,
0xf917, 0xf919, 0xfb67, 0xfb68, 0xfb6a, 0xfb6b, 0xfb6c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xfb7a, 0xfb78, 0xf916, 0xfb76,
0xf915, 0xfb6e, 0xfb6d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf50c, 0xf50d, 0xf50e, 0xf50f, 0xf510,
0xf511, 0xf512, 0xf513, 0xf514, 0xf515, 0xf208, 0xf202, 0xf911,
0xf912, 0xf913, 0xf30b, 0xf90e, 0xf90f, 0xf910, 0xf30a, 0xf90b,
0xf90c, 0xf90d, 0xf90a, 0xf310, 0xf206, 0xf200, 0xf07c, 0xf516,
0xf517, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short ctrl_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf000, 0xf01b, 0xf01c, 0xf01d, 0xf01e,
0xf01f, 0xf07f, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf008, 0xf200,
0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
0xf00f, 0xf010, 0xf01b, 0xf01d, 0xf201, 0xf702, 0xf001, 0xf013,
0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
0xf007, 0xf000, 0xf700, 0xf01c, 0xf01a, 0xf018, 0xf003, 0xf016,
0xf002, 0xf00e, 0xf00d, 0xf200, 0xf20e, 0xf07f, 0xf700, 0xf30c,
0xf703, 0xf000, 0xf207, 0xf100, 0xf101, 0xf102, 0xf103, 0xf104,
0xf105, 0xf106, 0xf107, 0xf108, 0xf109, 0xf208, 0xf204, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf10a,
0xf10b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short shift_ctrl_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf000, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf01f, 0xf200, 0xf200, 0xf200,
0xf011, 0xf017, 0xf005, 0xf012, 0xf014, 0xf019, 0xf015, 0xf009,
0xf00f, 0xf010, 0xf200, 0xf200, 0xf201, 0xf702, 0xf001, 0xf013,
0xf004, 0xf006, 0xf007, 0xf008, 0xf00a, 0xf00b, 0xf00c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xf01a, 0xf018, 0xf003, 0xf016,
0xf002, 0xf00e, 0xf00d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf208, 0xf200, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf310, 0xf206, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short alt_map[NR_KEYS] = {
0xf200, 0xf81b, 0xf831, 0xf832, 0xf833, 0xf834, 0xf835, 0xf836,
0xf837, 0xf838, 0xf839, 0xf830, 0xf82d, 0xf83d, 0xf87f, 0xf809,
0xf871, 0xf877, 0xf865, 0xf872, 0xf874, 0xf879, 0xf875, 0xf869,
0xf86f, 0xf870, 0xf85b, 0xf85d, 0xf80d, 0xf702, 0xf861, 0xf873,
0xf864, 0xf866, 0xf867, 0xf868, 0xf86a, 0xf86b, 0xf86c, 0xf83b,
0xf827, 0xf860, 0xf700, 0xf85c, 0xf87a, 0xf878, 0xf863, 0xf876,
0xf862, 0xf86e, 0xf86d, 0xf82c, 0xf82e, 0xf82f, 0xf700, 0xf30c,
0xf703, 0xf820, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf209, 0xf907,
0xf908, 0xf909, 0xf30b, 0xf904, 0xf905, 0xf906, 0xf30a, 0xf901,
0xf902, 0xf903, 0xf900, 0xf310, 0xf206, 0xf200, 0xf83c, 0xf50a,
0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf01c, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf210, 0xf211, 0xf117, 0xf600, 0xf119, 0xf115, 0xf116,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
u_short ctrl_alt_map[NR_KEYS] = {
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf811, 0xf817, 0xf805, 0xf812, 0xf814, 0xf819, 0xf815, 0xf809,
0xf80f, 0xf810, 0xf200, 0xf200, 0xf201, 0xf702, 0xf801, 0xf813,
0xf804, 0xf806, 0xf807, 0xf808, 0xf80a, 0xf80b, 0xf80c, 0xf200,
0xf200, 0xf200, 0xf700, 0xf200, 0xf81a, 0xf818, 0xf803, 0xf816,
0xf802, 0xf80e, 0xf80d, 0xf200, 0xf200, 0xf200, 0xf700, 0xf30c,
0xf703, 0xf200, 0xf207, 0xf500, 0xf501, 0xf502, 0xf503, 0xf504,
0xf505, 0xf506, 0xf507, 0xf508, 0xf509, 0xf208, 0xf200, 0xf307,
0xf308, 0xf309, 0xf30b, 0xf304, 0xf305, 0xf306, 0xf30a, 0xf301,
0xf302, 0xf303, 0xf300, 0xf20c, 0xf206, 0xf200, 0xf200, 0xf50a,
0xf50b, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
0xf30e, 0xf702, 0xf30d, 0xf200, 0xf701, 0xf205, 0xf114, 0xf603,
0xf118, 0xf601, 0xf602, 0xf117, 0xf600, 0xf119, 0xf115, 0xf20c,
0xf11a, 0xf10c, 0xf10d, 0xf11b, 0xf11c, 0xf110, 0xf311, 0xf11d,
0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200, 0xf200,
};
ushort *key_maps[MAX_NR_KEYMAPS] = {
plain_map, shift_map, altgr_map, NULL,
ctrl_map, shift_ctrl_map, NULL, NULL,
alt_map, NULL, NULL, NULL,
ctrl_alt_map, NULL
};
unsigned int keymap_count = 7;
/*
* Philosophy: most people do not define more strings, but they who do
* often want quite a lot of string space. So, we statically allocate
* the default and allocate dynamically in chunks of 512 bytes.
*/
char func_buf[] = {
'\033', '[', '[', 'A', 0,
'\033', '[', '[', 'B', 0,
'\033', '[', '[', 'C', 0,
'\033', '[', '[', 'D', 0,
'\033', '[', '[', 'E', 0,
'\033', '[', '1', '7', '~', 0,
'\033', '[', '1', '8', '~', 0,
'\033', '[', '1', '9', '~', 0,
'\033', '[', '2', '0', '~', 0,
'\033', '[', '2', '1', '~', 0,
'\033', '[', '2', '3', '~', 0,
'\033', '[', '2', '4', '~', 0,
'\033', '[', '2', '5', '~', 0,
'\033', '[', '2', '6', '~', 0,
'\033', '[', '2', '8', '~', 0,
'\033', '[', '2', '9', '~', 0,
'\033', '[', '3', '1', '~', 0,
'\033', '[', '3', '2', '~', 0,
'\033', '[', '3', '3', '~', 0,
'\033', '[', '3', '4', '~', 0,
'\033', '[', '1', '~', 0,
'\033', '[', '2', '~', 0,
'\033', '[', '3', '~', 0,
'\033', '[', '4', '~', 0,
'\033', '[', '5', '~', 0,
'\033', '[', '6', '~', 0,
'\033', '[', 'M', 0,
'\033', '[', 'P', 0,
};
char *funcbufptr = func_buf;
int funcbufsize = sizeof(func_buf);
int funcbufleft = 0; /* space left */
char *func_table[MAX_NR_FUNC] = {
func_buf + 0,
func_buf + 5,
func_buf + 10,
func_buf + 15,
func_buf + 20,
func_buf + 25,
func_buf + 31,
func_buf + 37,
func_buf + 43,
func_buf + 49,
func_buf + 55,
func_buf + 61,
func_buf + 67,
func_buf + 73,
func_buf + 79,
func_buf + 85,
func_buf + 91,
func_buf + 97,
func_buf + 103,
func_buf + 109,
func_buf + 115,
func_buf + 120,
func_buf + 125,
func_buf + 130,
func_buf + 135,
func_buf + 140,
func_buf + 145,
NULL,
NULL,
func_buf + 149,
NULL,
};
struct kbdiacr accent_table[MAX_DIACR] = {
{'`', 'A', '\300'}, {'`', 'a', '\340'},
{'\'', 'A', '\301'}, {'\'', 'a', '\341'},
{'^', 'A', '\302'}, {'^', 'a', '\342'},
{'~', 'A', '\303'}, {'~', 'a', '\343'},
{'"', 'A', '\304'}, {'"', 'a', '\344'},
{'O', 'A', '\305'}, {'o', 'a', '\345'},
{'0', 'A', '\305'}, {'0', 'a', '\345'},
{'A', 'A', '\305'}, {'a', 'a', '\345'},
{'A', 'E', '\306'}, {'a', 'e', '\346'},
{',', 'C', '\307'}, {',', 'c', '\347'},
{'`', 'E', '\310'}, {'`', 'e', '\350'},
{'\'', 'E', '\311'}, {'\'', 'e', '\351'},
{'^', 'E', '\312'}, {'^', 'e', '\352'},
{'"', 'E', '\313'}, {'"', 'e', '\353'},
{'`', 'I', '\314'}, {'`', 'i', '\354'},
{'\'', 'I', '\315'}, {'\'', 'i', '\355'},
{'^', 'I', '\316'}, {'^', 'i', '\356'},
{'"', 'I', '\317'}, {'"', 'i', '\357'},
{'-', 'D', '\320'}, {'-', 'd', '\360'},
{'~', 'N', '\321'}, {'~', 'n', '\361'},
{'`', 'O', '\322'}, {'`', 'o', '\362'},
{'\'', 'O', '\323'}, {'\'', 'o', '\363'},
{'^', 'O', '\324'}, {'^', 'o', '\364'},
{'~', 'O', '\325'}, {'~', 'o', '\365'},
{'"', 'O', '\326'}, {'"', 'o', '\366'},
{'/', 'O', '\330'}, {'/', 'o', '\370'},
{'`', 'U', '\331'}, {'`', 'u', '\371'},
{'\'', 'U', '\332'}, {'\'', 'u', '\372'},
{'^', 'U', '\333'}, {'^', 'u', '\373'},
{'"', 'U', '\334'}, {'"', 'u', '\374'},
{'\'', 'Y', '\335'}, {'\'', 'y', '\375'},
{'T', 'H', '\336'}, {'t', 'h', '\376'},
{'s', 's', '\337'}, {'"', 'y', '\377'},
{'s', 'z', '\337'}, {'i', 'j', '\377'},
};
unsigned int accent_table_size = 68;

View File

@@ -0,0 +1,357 @@
# Default kernel keymap. This uses 7 modifier combinations.
keymaps 0-2,4-5,8,12
# Change the above line into
# keymaps 0-2,4-6,8,12
# in case you want the entries
# altgr control keycode 83 = Boot
# altgr control keycode 111 = Boot
# below.
#
# In fact AltGr is used very little, and one more keymap can
# be saved by mapping AltGr to Alt (and adapting a few entries):
# keycode 100 = Alt
#
keycode 1 = Escape Escape
alt keycode 1 = Meta_Escape
keycode 2 = one exclam
alt keycode 2 = Meta_one
keycode 3 = two at at
control keycode 3 = nul
shift control keycode 3 = nul
alt keycode 3 = Meta_two
keycode 4 = three numbersign
control keycode 4 = Escape
alt keycode 4 = Meta_three
keycode 5 = four dollar dollar
control keycode 5 = Control_backslash
alt keycode 5 = Meta_four
keycode 6 = five percent
control keycode 6 = Control_bracketright
alt keycode 6 = Meta_five
keycode 7 = six asciicircum
control keycode 7 = Control_asciicircum
alt keycode 7 = Meta_six
keycode 8 = seven ampersand braceleft
control keycode 8 = Control_underscore
alt keycode 8 = Meta_seven
keycode 9 = eight asterisk bracketleft
control keycode 9 = Delete
alt keycode 9 = Meta_eight
keycode 10 = nine parenleft bracketright
alt keycode 10 = Meta_nine
keycode 11 = zero parenright braceright
alt keycode 11 = Meta_zero
keycode 12 = minus underscore backslash
control keycode 12 = Control_underscore
shift control keycode 12 = Control_underscore
alt keycode 12 = Meta_minus
keycode 13 = equal plus
alt keycode 13 = Meta_equal
keycode 14 = Delete Delete
control keycode 14 = BackSpace
alt keycode 14 = Meta_Delete
keycode 15 = Tab Tab
alt keycode 15 = Meta_Tab
keycode 16 = q
keycode 17 = w
keycode 18 = e
altgr keycode 18 = Hex_E
keycode 19 = r
keycode 20 = t
keycode 21 = y
keycode 22 = u
keycode 23 = i
keycode 24 = o
keycode 25 = p
keycode 26 = bracketleft braceleft
control keycode 26 = Escape
alt keycode 26 = Meta_bracketleft
keycode 27 = bracketright braceright asciitilde
control keycode 27 = Control_bracketright
alt keycode 27 = Meta_bracketright
keycode 28 = Return
alt keycode 28 = Meta_Control_m
keycode 29 = Control
keycode 30 = a
altgr keycode 30 = Hex_A
keycode 31 = s
keycode 32 = d
altgr keycode 32 = Hex_D
keycode 33 = f
altgr keycode 33 = Hex_F
keycode 34 = g
keycode 35 = h
keycode 36 = j
keycode 37 = k
keycode 38 = l
keycode 39 = semicolon colon
alt keycode 39 = Meta_semicolon
keycode 40 = apostrophe quotedbl
control keycode 40 = Control_g
alt keycode 40 = Meta_apostrophe
keycode 41 = grave asciitilde
control keycode 41 = nul
alt keycode 41 = Meta_grave
keycode 42 = Shift
keycode 43 = backslash bar
control keycode 43 = Control_backslash
alt keycode 43 = Meta_backslash
keycode 44 = z
keycode 45 = x
keycode 46 = c
altgr keycode 46 = Hex_C
keycode 47 = v
keycode 48 = b
altgr keycode 48 = Hex_B
keycode 49 = n
keycode 50 = m
keycode 51 = comma less
alt keycode 51 = Meta_comma
keycode 52 = period greater
control keycode 52 = Compose
alt keycode 52 = Meta_period
keycode 53 = slash question
control keycode 53 = Delete
alt keycode 53 = Meta_slash
keycode 54 = Shift
keycode 55 = KP_Multiply
keycode 56 = Alt
keycode 57 = space space
control keycode 57 = nul
alt keycode 57 = Meta_space
keycode 58 = Caps_Lock
keycode 59 = F1 F11 Console_13
control keycode 59 = F1
alt keycode 59 = Console_1
control alt keycode 59 = Console_1
keycode 60 = F2 F12 Console_14
control keycode 60 = F2
alt keycode 60 = Console_2
control alt keycode 60 = Console_2
keycode 61 = F3 F13 Console_15
control keycode 61 = F3
alt keycode 61 = Console_3
control alt keycode 61 = Console_3
keycode 62 = F4 F14 Console_16
control keycode 62 = F4
alt keycode 62 = Console_4
control alt keycode 62 = Console_4
keycode 63 = F5 F15 Console_17
control keycode 63 = F5
alt keycode 63 = Console_5
control alt keycode 63 = Console_5
keycode 64 = F6 F16 Console_18
control keycode 64 = F6
alt keycode 64 = Console_6
control alt keycode 64 = Console_6
keycode 65 = F7 F17 Console_19
control keycode 65 = F7
alt keycode 65 = Console_7
control alt keycode 65 = Console_7
keycode 66 = F8 F18 Console_20
control keycode 66 = F8
alt keycode 66 = Console_8
control alt keycode 66 = Console_8
keycode 67 = F9 F19 Console_21
control keycode 67 = F9
alt keycode 67 = Console_9
control alt keycode 67 = Console_9
keycode 68 = F10 F20 Console_22
control keycode 68 = F10
alt keycode 68 = Console_10
control alt keycode 68 = Console_10
keycode 69 = Num_Lock
shift keycode 69 = Bare_Num_Lock
keycode 70 = Scroll_Lock Show_Memory Show_Registers
control keycode 70 = Show_State
alt keycode 70 = Scroll_Lock
keycode 71 = KP_7
alt keycode 71 = Ascii_7
altgr keycode 71 = Hex_7
keycode 72 = KP_8
alt keycode 72 = Ascii_8
altgr keycode 72 = Hex_8
keycode 73 = KP_9
alt keycode 73 = Ascii_9
altgr keycode 73 = Hex_9
keycode 74 = KP_Subtract
keycode 75 = KP_4
alt keycode 75 = Ascii_4
altgr keycode 75 = Hex_4
keycode 76 = KP_5
alt keycode 76 = Ascii_5
altgr keycode 76 = Hex_5
keycode 77 = KP_6
alt keycode 77 = Ascii_6
altgr keycode 77 = Hex_6
keycode 78 = KP_Add
keycode 79 = KP_1
alt keycode 79 = Ascii_1
altgr keycode 79 = Hex_1
keycode 80 = KP_2
alt keycode 80 = Ascii_2
altgr keycode 80 = Hex_2
keycode 81 = KP_3
alt keycode 81 = Ascii_3
altgr keycode 81 = Hex_3
keycode 82 = KP_0
alt keycode 82 = Ascii_0
altgr keycode 82 = Hex_0
keycode 83 = KP_Period
# altgr control keycode 83 = Boot
control alt keycode 83 = Boot
keycode 84 = Last_Console
keycode 85 =
keycode 86 = less greater bar
alt keycode 86 = Meta_less
keycode 87 = F11 F11 Console_23
control keycode 87 = F11
alt keycode 87 = Console_11
control alt keycode 87 = Console_11
keycode 88 = F12 F12 Console_24
control keycode 88 = F12
alt keycode 88 = Console_12
control alt keycode 88 = Console_12
keycode 89 =
keycode 90 =
keycode 91 =
keycode 92 =
keycode 93 =
keycode 94 =
keycode 95 =
keycode 96 = KP_Enter
keycode 97 = Control
keycode 98 = KP_Divide
keycode 99 = Control_backslash
control keycode 99 = Control_backslash
alt keycode 99 = Control_backslash
keycode 100 = AltGr
keycode 101 = Break
keycode 102 = Find
keycode 103 = Up
keycode 104 = Prior
shift keycode 104 = Scroll_Backward
keycode 105 = Left
alt keycode 105 = Decr_Console
keycode 106 = Right
alt keycode 106 = Incr_Console
keycode 107 = Select
keycode 108 = Down
keycode 109 = Next
shift keycode 109 = Scroll_Forward
keycode 110 = Insert
keycode 111 = Remove
# altgr control keycode 111 = Boot
control alt keycode 111 = Boot
keycode 112 = Macro
keycode 113 = F13
keycode 114 = F14
keycode 115 = Help
keycode 116 = Do
keycode 117 = F17
keycode 118 = KP_MinPlus
keycode 119 = Pause
keycode 120 =
keycode 121 =
keycode 122 =
keycode 123 =
keycode 124 =
keycode 125 =
keycode 126 =
keycode 127 =
string F1 = "\033[[A"
string F2 = "\033[[B"
string F3 = "\033[[C"
string F4 = "\033[[D"
string F5 = "\033[[E"
string F6 = "\033[17~"
string F7 = "\033[18~"
string F8 = "\033[19~"
string F9 = "\033[20~"
string F10 = "\033[21~"
string F11 = "\033[23~"
string F12 = "\033[24~"
string F13 = "\033[25~"
string F14 = "\033[26~"
string F15 = "\033[28~"
string F16 = "\033[29~"
string F17 = "\033[31~"
string F18 = "\033[32~"
string F19 = "\033[33~"
string F20 = "\033[34~"
string Find = "\033[1~"
string Insert = "\033[2~"
string Remove = "\033[3~"
string Select = "\033[4~"
string Prior = "\033[5~"
string Next = "\033[6~"
string Macro = "\033[M"
string Pause = "\033[P"
compose '`' 'A' to 'À'
compose '`' 'a' to 'à'
compose '\'' 'A' to 'Á'
compose '\'' 'a' to 'á'
compose '^' 'A' to 'Â'
compose '^' 'a' to 'â'
compose '~' 'A' to 'Ã'
compose '~' 'a' to 'ã'
compose '"' 'A' to 'Ä'
compose '"' 'a' to 'ä'
compose 'O' 'A' to 'Å'
compose 'o' 'a' to 'å'
compose '0' 'A' to 'Å'
compose '0' 'a' to 'å'
compose 'A' 'A' to 'Å'
compose 'a' 'a' to 'å'
compose 'A' 'E' to 'Æ'
compose 'a' 'e' to 'æ'
compose ',' 'C' to 'Ç'
compose ',' 'c' to 'ç'
compose '`' 'E' to 'È'
compose '`' 'e' to 'è'
compose '\'' 'E' to 'É'
compose '\'' 'e' to 'é'
compose '^' 'E' to 'Ê'
compose '^' 'e' to 'ê'
compose '"' 'E' to 'Ë'
compose '"' 'e' to 'ë'
compose '`' 'I' to 'Ì'
compose '`' 'i' to 'ì'
compose '\'' 'I' to 'Í'
compose '\'' 'i' to 'í'
compose '^' 'I' to 'Î'
compose '^' 'i' to 'î'
compose '"' 'I' to 'Ï'
compose '"' 'i' to 'ï'
compose '-' 'D' to 'Ð'
compose '-' 'd' to 'ð'
compose '~' 'N' to 'Ñ'
compose '~' 'n' to 'ñ'
compose '`' 'O' to 'Ò'
compose '`' 'o' to 'ò'
compose '\'' 'O' to 'Ó'
compose '\'' 'o' to 'ó'
compose '^' 'O' to 'Ô'
compose '^' 'o' to 'ô'
compose '~' 'O' to 'Õ'
compose '~' 'o' to 'õ'
compose '"' 'O' to 'Ö'
compose '"' 'o' to 'ö'
compose '/' 'O' to 'Ø'
compose '/' 'o' to 'ø'
compose '`' 'U' to 'Ù'
compose '`' 'u' to 'ù'
compose '\'' 'U' to 'Ú'
compose '\'' 'u' to 'ú'
compose '^' 'U' to 'Û'
compose '^' 'u' to 'û'
compose '"' 'U' to 'Ü'
compose '"' 'u' to 'ü'
compose '\'' 'Y' to 'Ý'
compose '\'' 'y' to 'ý'
compose 'T' 'H' to 'Þ'
compose 't' 'h' to 'þ'
compose 's' 's' to 'ß'
compose '"' 'y' to 'ÿ'
compose 's' 'z' to 'ß'
compose 'i' 'j' to 'ÿ'

Binary file not shown.

View File

@@ -0,0 +1,71 @@
/* Definitions for DigiBoard ditty(1) command. */
#if !defined(TIOCMODG)
#define TIOCMODG (('d'<<8) | 250) /* get modem ctrl state */
#define TIOCMODS (('d'<<8) | 251) /* set modem ctrl state */
#endif
#if !defined(TIOCMSET)
#define TIOCMSET (('d'<<8) | 252) /* set modem ctrl state */
#define TIOCMGET (('d'<<8) | 253) /* set modem ctrl state */
#endif
#if !defined(TIOCMBIC)
#define TIOCMBIC (('d'<<8) | 254) /* set modem ctrl state */
#define TIOCMBIS (('d'<<8) | 255) /* set modem ctrl state */
#endif
#if !defined(TIOCSDTR)
#define TIOCSDTR (('e'<<8) | 0) /* set DTR */
#define TIOCCDTR (('e'<<8) | 1) /* clear DTR */
#endif
/************************************************************************
* Ioctl command arguments for DIGI parameters.
************************************************************************/
#define DIGI_GETA (('e'<<8) | 94) /* Read params */
#define DIGI_SETA (('e'<<8) | 95) /* Set params */
#define DIGI_SETAW (('e'<<8) | 96) /* Drain & set params */
#define DIGI_SETAF (('e'<<8) | 97) /* Drain, flush & set params */
#define DIGI_GETFLOW (('e'<<8) | 99) /* Get startc/stopc flow */
/* control characters */
#define DIGI_SETFLOW (('e'<<8) | 100) /* Set startc/stopc flow */
/* control characters */
#define DIGI_GETAFLOW (('e'<<8) | 101) /* Get Aux. startc/stopc */
/* flow control chars */
#define DIGI_SETAFLOW (('e'<<8) | 102) /* Set Aux. startc/stopc */
/* flow control chars */
struct digiflow_struct {
unsigned char startc; /* flow cntl start char */
unsigned char stopc; /* flow cntl stop char */
};
typedef struct digiflow_struct digiflow_t;
/************************************************************************
* Values for digi_flags
************************************************************************/
#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */
#define DIGI_FAST 0x0002 /* Fast baud rates */
#define RTSPACE 0x0004 /* RTS input flow control */
#define CTSPACE 0x0008 /* CTS output flow control */
#define DSRPACE 0x0010 /* DSR output flow control */
#define DCDPACE 0x0020 /* DCD output flow control */
#define DTRPACE 0x0040 /* DTR input flow control */
#define DIGI_FORCEDCD 0x0100 /* Force carrier */
#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */
#define DIGI_AIXON 0x0400 /* Aux flow control in fep */
/************************************************************************
* Structure used with ioctl commands for DIGI parameters.
************************************************************************/
struct digi_struct {
unsigned short digi_flags; /* Flags (see above) */
};
typedef struct digi_struct digi_t;

View File

@@ -0,0 +1,100 @@
/* Definitions for DigiBoard ditty(1) command. */
#if !defined(TIOCMODG)
#define TIOCMODG ('d'<<8) | 250 /* get modem ctrl state */
#define TIOCMODS ('d'<<8) | 251 /* set modem ctrl state */
#endif
#if !defined(TIOCMSET)
#define TIOCMSET ('d'<<8) | 252 /* set modem ctrl state */
#define TIOCMGET ('d'<<8) | 253 /* set modem ctrl state */
#endif
#if !defined(TIOCMBIC)
#define TIOCMBIC ('d'<<8) | 254 /* set modem ctrl state */
#define TIOCMBIS ('d'<<8) | 255 /* set modem ctrl state */
#endif
#if !defined(TIOCSDTR)
#define TIOCSDTR ('e'<<8) | 0 /* set DTR */
#define TIOCCDTR ('e'<<8) | 1 /* clear DTR */
#endif
/************************************************************************
* Ioctl command arguments for DIGI parameters.
************************************************************************/
#define DIGI_GETA ('e'<<8) | 94 /* Read params */
#define DIGI_SETA ('e'<<8) | 95 /* Set params */
#define DIGI_SETAW ('e'<<8) | 96 /* Drain & set params */
#define DIGI_SETAF ('e'<<8) | 97 /* Drain, flush & set params */
#define DIGI_GETFLOW ('e'<<8) | 99 /* Get startc/stopc flow */
/* control characters */
#define DIGI_SETFLOW ('e'<<8) | 100 /* Set startc/stopc flow */
/* control characters */
#define DIGI_GETAFLOW ('e'<<8) | 101 /* Get Aux. startc/stopc */
/* flow control chars */
#define DIGI_SETAFLOW ('e'<<8) | 102 /* Set Aux. startc/stopc */
/* flow control chars */
#define DIGI_GETINFO ('e'<<8) | 103 /* Fill in digi_info */
#define DIGI_POLLER ('e'<<8) | 104 /* Turn on/off poller */
#define DIGI_INIT ('e'<<8) | 105 /* Allow things to run. */
struct digiflow_struct
{
unsigned char startc; /* flow cntl start char */
unsigned char stopc; /* flow cntl stop char */
};
typedef struct digiflow_struct digiflow_t;
/************************************************************************
* Values for digi_flags
************************************************************************/
#define DIGI_IXON 0x0001 /* Handle IXON in the FEP */
#define DIGI_FAST 0x0002 /* Fast baud rates */
#define RTSPACE 0x0004 /* RTS input flow control */
#define CTSPACE 0x0008 /* CTS output flow control */
#define DSRPACE 0x0010 /* DSR output flow control */
#define DCDPACE 0x0020 /* DCD output flow control */
#define DTRPACE 0x0040 /* DTR input flow control */
#define DIGI_FORCEDCD 0x0100 /* Force carrier */
#define DIGI_ALTPIN 0x0200 /* Alternate RJ-45 pin config */
#define DIGI_AIXON 0x0400 /* Aux flow control in fep */
/************************************************************************
* Values for digiDload
************************************************************************/
#define NORMAL 0
#define PCI_CTL 1
#define SIZE8 0
#define SIZE16 1
#define SIZE32 2
/************************************************************************
* Structure used with ioctl commands for DIGI parameters.
************************************************************************/
struct digi_struct
{
unsigned short digi_flags; /* Flags (see above) */
};
typedef struct digi_struct digi_t;
struct digi_info
{
unsigned long board; /* Which board is this ? */
unsigned char status; /* Alive or dead */
unsigned char type; /* see epca.h */
unsigned char subtype; /* For future XEM, XR, etc ... */
unsigned short numports; /* Number of ports configured */
unsigned char *port; /* I/O Address */
unsigned char *membase; /* DPR Address */
unsigned char *version; /* For future ... */
unsigned short windowData; /* For future ... */
} ;

View File

@@ -0,0 +1,136 @@
#define CSTART 0x400L
#define CMAX 0x800L
#define ISTART 0x800L
#define IMAX 0xC00L
#define CIN 0xD10L
#define GLOBAL 0xD10L
#define EIN 0xD18L
#define FEPSTAT 0xD20L
#define CHANSTRUCT 0x1000L
#define RXTXBUF 0x4000L
struct global_data
{
volatile ushort cin;
volatile ushort cout;
volatile ushort cstart;
volatile ushort cmax;
volatile ushort ein;
volatile ushort eout;
volatile ushort istart;
volatile ushort imax;
};
struct board_chan
{
int filler1;
int filler2;
volatile ushort tseg;
volatile ushort tin;
volatile ushort tout;
volatile ushort tmax;
volatile ushort rseg;
volatile ushort rin;
volatile ushort rout;
volatile ushort rmax;
volatile ushort tlow;
volatile ushort rlow;
volatile ushort rhigh;
volatile ushort incr;
volatile ushort etime;
volatile ushort edelay;
volatile unchar *dev;
volatile ushort iflag;
volatile ushort oflag;
volatile ushort cflag;
volatile ushort gmask;
volatile ushort col;
volatile ushort delay;
volatile ushort imask;
volatile ushort tflush;
int filler3;
int filler4;
int filler5;
int filler6;
volatile unchar num;
volatile unchar ract;
volatile unchar bstat;
volatile unchar tbusy;
volatile unchar iempty;
volatile unchar ilow;
volatile unchar idata;
volatile unchar eflag;
volatile unchar tflag;
volatile unchar rflag;
volatile unchar xmask;
volatile unchar xval;
volatile unchar mstat;
volatile unchar mchange;
volatile unchar mint;
volatile unchar lstat;
volatile unchar mtran;
volatile unchar orun;
volatile unchar startca;
volatile unchar stopca;
volatile unchar startc;
volatile unchar stopc;
volatile unchar vnext;
volatile unchar hflow;
volatile unchar fillc;
volatile unchar ochar;
volatile unchar omask;
unchar filler7;
unchar filler8[28];
};
#define SRXLWATER 0xE0
#define SRXHWATER 0xE1
#define STOUT 0xE2
#define PAUSETX 0xE3
#define RESUMETX 0xE4
#define SAUXONOFFC 0xE6
#define SENDBREAK 0xE8
#define SETMODEM 0xE9
#define SETIFLAGS 0xEA
#define SONOFFC 0xEB
#define STXLWATER 0xEC
#define PAUSERX 0xEE
#define RESUMERX 0xEF
#define SETBUFFER 0xF2
#define SETCOOKED 0xF3
#define SETHFLOW 0xF4
#define SETCTRLFLAGS 0xF5
#define SETVNEXT 0xF6
#define BREAK_IND 0x01
#define LOWTX_IND 0x02
#define EMPTYTX_IND 0x04
#define DATA_IND 0x08
#define MODEMCHG_IND 0x20
#define FEP_HUPCL 0002000
#if 0
#define RTS 0x02
#define CD 0x08
#define DSR 0x10
#define CTS 0x20
#define RI 0x40
#define DTR 0x80
#endif

View File

@@ -0,0 +1,42 @@
/*************************************************************************
* Defines and structure definitions for PCI BIOS Interface
*************************************************************************/
#define PCIMAX 32 /* maximum number of PCI boards */
#define PCI_VENDOR_DIGI 0x114F
#define PCI_DEVICE_EPC 0x0002
#define PCI_DEVICE_RIGHTSWITCH 0x0003 /* For testing */
#define PCI_DEVICE_XEM 0x0004
#define PCI_DEVICE_XR 0x0005
#define PCI_DEVICE_CX 0x0006
#define PCI_DEVICE_XRJ 0x0009 /* Jupiter boards with */
#define PCI_DEVICE_EPCJ 0x000a /* PLX 9060 chip for PCI */
/*
* On the PCI boards, there is no IO space allocated
* The I/O registers will be in the first 3 bytes of the
* upper 2MB of the 4MB memory space. The board memory
* will be mapped into the low 2MB of the 4MB memory space
*/
/* Potential location of PCI Bios from E0000 to FFFFF*/
#define PCI_BIOS_SIZE 0x00020000
/* Size of Memory and I/O for PCI (4MB) */
#define PCI_RAM_SIZE 0x00400000
/* Size of Memory (2MB) */
#define PCI_MEM_SIZE 0x00200000
/* Offset of I/0 in Memory (2MB) */
#define PCI_IO_OFFSET 0x00200000
#define MEMOUTB(basemem, pnum, setmemval) *(caddr_t)((basemem) + ( PCI_IO_OFFSET | pnum << 4 | pnum )) = (setmemval)
#define MEMINB(basemem, pnum) *(caddr_t)((basemem) + (PCI_IO_OFFSET | pnum << 4 | pnum )) /* for PCI I/O */

View File

@@ -0,0 +1,177 @@
/* DigiBoard PCXX Bios */
static unsigned char pcxx_bios[] __initdata = {
0x28,0x43,0x29,0x20,0x43,0x6f,0x70,0x79,0x72,0x69,0x67,0x68,
0x74,0x20,0x31,0x39,0x39,0x34,0x2c,0x20,0x44,0x69,0x67,0x69,
0x42,0x6f,0x61,0x72,0x64,0x20,0x49,0x6e,0x63,0x2e,0x00,0x00,
0x8a,0xf8,0x8a,0xf8,0x15,0xf9,0x8a,0xf8,0x8a,0xf8,0x8a,0xf8,
0x8a,0xf8,0x8a,0xf8,0xbc,0xf8,0x8a,0xf8,0x96,0xf8,0x96,0xf8,
0x96,0xf8,0x96,0xf8,0x96,0xf8,0x96,0xf8,0x8a,0xf8,0x8a,0xf8,
0x96,0xf8,0x96,0xf8,0x8a,0xf8,0xad,0xf8,0xb0,0xf8,0x8a,0xf8,
0x8a,0xf8,0x8a,0xf8,0x8a,0xf8,0x8a,0xf8,0x8a,0xf8,0x8a,0xf8,
0x8a,0xf8,0x8a,0xf8,0x8a,0xf8,0x04,0x02,0x00,0x02,0x14,0x02,
0x10,0x02,0x24,0x02,0x20,0x02,0x34,0x02,0x30,0x02,0x44,0x02,
0x40,0x02,0x54,0x02,0x50,0x02,0x64,0x02,0x60,0x02,0x74,0x02,
0x70,0x02,0x04,0x01,0x00,0x01,0x1e,0x2e,0x8e,0x1e,0x22,0xf8,
0xfe,0x06,0x70,0x00,0x1f,0xcf,0x1e,0x50,0x52,0x2e,0x8e,0x1e,
0x22,0xf8,0xfe,0x06,0x71,0x00,0xb8,0x00,0x80,0xba,0x22,0xff,
0xef,0x5a,0x58,0x1f,0xcf,0xb4,0x80,0xcf,0x1e,0x2e,0x8e,0x1e,
0x22,0xf8,0xfe,0x06,0x2b,0x00,0x1f,0xcf,0x1e,0x52,0x50,0x2e,
0x8e,0x1e,0x22,0xf8,0xcd,0x16,0xfe,0x06,0x2a,0x00,0x80,0x3e,
0x2a,0x00,0x12,0x72,0x39,0xc6,0x06,0x2a,0x00,0x00,0xfe,0x06,
0x29,0x00,0x80,0x3e,0x29,0x00,0x3c,0x72,0x29,0xc6,0x06,0x29,
0x00,0x00,0xfe,0x06,0x28,0x00,0x80,0x3e,0x28,0x00,0x3c,0x72,
0x19,0xc6,0x06,0x28,0x00,0x00,0xfe,0x06,0x27,0x00,0x80,0x3e,
0x27,0x00,0x18,0x72,0x09,0xc6,0x06,0x27,0x00,0x00,0xff,0x06,
0x25,0x00,0xba,0x22,0xff,0xb8,0x00,0x80,0xef,0x58,0x5a,0x1f,
0xcf,0x60,0x1e,0x06,0xfc,0x2e,0x8e,0x06,0x22,0xf8,0x2e,0x8e,
0x1e,0x22,0xf8,0x8d,0x36,0x40,0x00,0xad,0x3c,0x3f,0x7f,0x22,
0x3c,0x1f,0x7f,0x22,0x32,0xe4,0xd1,0xe0,0x3d,0x16,0x00,0x90,
0x73,0x14,0xbb,0x56,0xf9,0x03,0xd8,0x2e,0xff,0x17,0x8d,0x36,
0x40,0x00,0xb0,0x00,0x89,0x04,0x07,0x1f,0x61,0xcf,0xb4,0x80,
0xeb,0xf0,0xcd,0x15,0xeb,0xec,0x6c,0xf9,0x79,0xf9,0xb9,0xf9,
0xd3,0xf9,0xd8,0xf9,0xe1,0xf9,0xe9,0xf9,0xf2,0xf9,0xfa,0xf9,
0xfd,0xf9,0x2a,0xfa,0xe4,0x00,0x24,0xf7,0xe6,0x00,0x0c,0x08,
0xe6,0x00,0xb4,0x00,0xc3,0x1e,0xad,0x8b,0xd8,0xad,0x8e,0xdb,
0x8b,0xf0,0x33,0xdb,0x8b,0x07,0x3d,0x4f,0x53,0x75,0x2a,0x8a,
0x47,0x02,0x32,0xe4,0x86,0xc4,0x8b,0xc8,0x32,0xc0,0x02,0x07,
0x43,0xe2,0xfb,0x0a,0xc0,0x75,0x16,0x8c,0xd9,0x1f,0x89,0x0e,
0x2e,0x00,0x89,0x36,0x2c,0x00,0x8d,0x1e,0x02,0x00,0xc7,0x07,
0x45,0x4d,0x32,0xe4,0xc3,0x1f,0xb4,0x80,0xc3,0xad,0x8b,0xd8,
0xad,0x8b,0xd0,0xad,0x8e,0xc0,0xad,0x8b,0xf8,0xad,0x8b,0xc8,
0x8b,0xf2,0x1e,0x8e,0xdb,0xf3,0xa4,0x1f,0x32,0xe4,0xc3,0xea,
0xf0,0xff,0x00,0xf0,0xad,0x8b,0xd0,0xec,0x88,0x04,0x32,0xe4,
0xc3,0xad,0x8b,0xd0,0xac,0xee,0x32,0xe4,0xc3,0xad,0x8b,0xd0,
0xed,0x89,0x04,0x32,0xe4,0xc3,0xad,0x8b,0xd0,0xad,0xef,0x32,
0xe4,0xc3,0xb4,0x80,0xc3,0xac,0x3c,0x12,0x7f,0x25,0xfe,0xc8,
0x32,0xe4,0xd1,0xe0,0x8d,0x1e,0x66,0xf8,0x03,0xd8,0x2e,0x8b,
0x17,0xec,0xac,0x3c,0x0f,0x7f,0x10,0x3c,0x00,0x74,0x03,0xee,
0x90,0x90,0xec,0x8b,0xfe,0x1e,0x07,0xaa,0x32,0xe4,0xc3,0xb4,
0x80,0xc3,0xac,0x3c,0x12,0x7f,0x1f,0xfe,0xc8,0x32,0xe4,0xd1,
0xe0,0x8d,0x1e,0x66,0xf8,0x03,0xd8,0x2e,0x8b,0x17,0xec,0xac,
0x3c,0x0f,0x7f,0x0a,0x3c,0x00,0x74,0x01,0xee,0xac,0xee,0x32,
0xe4,0xc3,0xb4,0x80,0xc3,0xfc,0x8e,0xc0,0xb8,0xff,0xff,0x8b,
0xcb,0x33,0xff,0xf3,0xab,0x8b,0xcb,0x33,0xff,0xf3,0xaf,0xe3,
0x01,0xc3,0x8b,0xcb,0xbf,0x00,0x00,0x26,0x89,0x3d,0x83,0xc7,
0x02,0xe2,0xf8,0xbe,0x00,0x00,0x8b,0xcb,0x26,0x8b,0x3c,0x3b,
0xfe,0x74,0x01,0xc3,0x83,0xc6,0x02,0x83,0xc7,0x02,0xe2,0xf0,
0x33,0xc0,0x8b,0xcb,0x33,0xff,0xf3,0xab,0x8b,0xcb,0x33,0xff,
0xf3,0xaf,0xc3,0x32,0xc0,0x26,0x80,0x3e,0x23,0x00,0x00,0x74,
0x02,0x0c,0x01,0x26,0xf7,0x06,0x20,0x00,0x0f,0x00,0x74,0x02,
0x0c,0x02,0x26,0xf7,0x06,0x20,0x00,0xf0,0x00,0x74,0x02,0x0c,
0x04,0x26,0xf7,0x06,0x20,0x00,0x00,0xff,0x74,0x02,0x0c,0x08,
0x26,0xa2,0x24,0x00,0xb8,0x00,0x40,0xba,0x5e,0xff,0xef,0xba,
0x66,0xff,0xef,0xba,0x52,0xff,0xb8,0x63,0x0e,0xef,0xba,0x56,
0xff,0xb8,0x05,0xe0,0xef,0xba,0x28,0xff,0xb8,0xfc,0x00,0xef,
0xb8,0x00,0x02,0x26,0xa3,0x2e,0x00,0xb8,0x04,0x00,0x26,0xa3,
0x2c,0x00,0xb0,0xc3,0xe6,0x08,0x8a,0xd8,0xe4,0x08,0x3a,0xc3,
0x75,0x06,0x26,0xc6,0x06,0xb4,0x00,0x01,0xb0,0x00,0xe6,0x00,
0xfc,0x8d,0x3e,0x00,0x00,0xb8,0x47,0x44,0xab,0xb8,0xff,0xff,
0xab,0xab,0xab,0xb8,0x42,0x49,0xab,0xb8,0x4f,0x53,0xab,0xb8,
0x58,0x69,0x26,0x80,0x3e,0x10,0x00,0x04,0x74,0x0e,0xb8,0x58,
0x65,0x26,0x80,0x3e,0x10,0x00,0x03,0x74,0x03,0xb8,0x58,0x74,
0xab,0x8d,0x36,0xfe,0xff,0x8a,0x04,0x8d,0x36,0xff,0xff,0x8a,
0x24,0xab,0xfb,0x26,0x81,0x0e,0x12,0x00,0x00,0x08,0x06,0x1f,
0xa1,0x00,0x00,0x8b,0x1e,0x02,0x00,0x3d,0x44,0x47,0x75,0x0b,
0x26,0x81,0x0e,0x12,0x00,0x00,0x10,0xff,0x2e,0x2c,0x00,0x81,
0xfb,0x45,0x4d,0x75,0xe3,0x26,0x81,0x0e,0x12,0x00,0x00,0x20,
0xff,0x2e,0x2c,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
0xff,0xff,0xff,0xff,0xfa,0xba,0xa8,0xff,0xb8,0xba,0x81,0xef,
0xba,0xa4,0xff,0xb8,0x3a,0x00,0xef,0x90,0xe4,0x00,0xa8,0x60,
0x75,0x0c,0x24,0x06,0x74,0x14,0x3c,0x02,0x74,0x1c,0x3c,0x04,
0x74,0x24,0xbb,0x38,0xc0,0xbe,0xf8,0x81,0xbf,0xba,0xa0,0xeb,
0x22,0x90,0xbb,0x38,0xf0,0xbe,0xf8,0x41,0xbf,0xba,0x81,0xeb,
0x16,0x90,0xbb,0x38,0xf0,0xbe,0xf8,0xe1,0xbf,0xba,0x88,0xeb,
0x0a,0x90,0xbb,0x38,0xc0,0xbe,0xf8,0x41,0xbf,0xba,0x81,0xba,
0xa0,0xff,0x8b,0xc3,0xef,0xba,0xa2,0xff,0xb8,0xf8,0x0f,0xef,
0xba,0xa6,0xff,0x8b,0xc6,0xef,0xba,0xa8,0xff,0x8b,0xc7,0xef,
0x8c,0xc8,0x8e,0xd8,0xe4,0x00,0x24,0x06,0x74,0x17,0xbb,0x00,
0x80,0xbd,0xc0,0xe0,0x3c,0x02,0x74,0x5a,0xbd,0xc0,0xc0,0x3c,
0x04,0x74,0x53,0xbd,0xc0,0x80,0xeb,0x4e,0x90,0xb9,0x08,0x00,
0xb8,0x00,0x80,0x8e,0xc0,0x26,0xa3,0x00,0x00,0x05,0x00,0x10,
0xe2,0xf5,0xbd,0xc0,0xf0,0xbb,0x00,0x7c,0xb8,0x00,0xe0,0x8e,
0xc0,0x26,0x8b,0x0e,0x00,0x00,0x3b,0xc8,0x75,0x28,0xbb,0x00,
0x80,0xbd,0xc0,0xe0,0xb8,0x00,0xc0,0x8e,0xc0,0x26,0x8b,0x0e,
0x00,0x00,0x3b,0xc8,0x75,0x14,0xbd,0xc0,0xc0,0xb8,0x00,0x80,
0x8e,0xc0,0x26,0x8b,0x0e,0x00,0x00,0x3b,0xc8,0x75,0x03,0xbd,
0xc0,0x80,0x8c,0xc8,0x8e,0xd0,0xbc,0xed,0xfc,0x8b,0xc5,0x25,
0x00,0xf0,0xe9,0x6c,0xfd,0xb4,0x00,0x74,0x06,0xb4,0xff,0xeb,
0x02,0xe5,0xfc,0x8e,0xc5,0x2e,0x89,0x2e,0x22,0xf8,0xe4,0x00,
0x24,0x16,0x26,0xa2,0x11,0x00,0x26,0x83,0x0e,0x12,0x00,0x01,
0x80,0xfc,0x00,0x74,0x06,0x26,0x83,0x0e,0x14,0x00,0x01,0x26,
0xc7,0x06,0x18,0x00,0x40,0x00,0x26,0xc6,0x06,0x10,0x00,0x03,
0xa8,0x10,0x74,0x06,0x26,0xc6,0x06,0x10,0x00,0x04,0xb8,0x00,
0x00,0x8e,0xc0,0xb8,0xaa,0x55,0x26,0xa3,0x00,0x00,0x26,0xc7,
0x06,0x02,0x00,0x00,0x00,0x26,0xc7,0x06,0x04,0x00,0x00,0x00,
0x8b,0xcd,0x81,0xe1,0x00,0xf0,0x8e,0xc1,0x26,0x8b,0x1e,0x00,
0x00,0x3b,0xc3,0x75,0x13,0x8e,0xc5,0x26,0xc6,0x06,0x10,0x00,
0x05,0xb8,0x40,0x00,0x8e,0xd0,0xbc,0x00,0x04,0xe9,0x99,0x00,
0x8c,0xc8,0x8e,0xd0,0xbc,0x7c,0xfd,0xb8,0x00,0x00,0xbb,0x00,
0x20,0xe9,0xdd,0xfc,0xb4,0x00,0x74,0x06,0xb4,0xff,0xeb,0x02,
0x74,0xfd,0x8e,0xc5,0x80,0xfc,0x00,0x74,0x08,0x26,0x83,0x0e,
0x14,0x00,0x02,0xeb,0x0d,0x26,0xc7,0x06,0x16,0x00,0x10,0x00,
0x26,0x83,0x0e,0x12,0x00,0x02,0xb8,0x40,0x00,0x8e,0xd0,0xbc,
0x00,0x04,0xe4,0x00,0xa8,0x60,0x75,0x07,0xba,0xa2,0xff,0xb8,
0xfc,0x0f,0xef,0xb8,0x00,0x04,0x8e,0xc0,0xb8,0xaa,0x55,0x26,
0xa3,0x00,0x00,0x26,0xc7,0x06,0x02,0x00,0x00,0x00,0x26,0xc7,
0x06,0x04,0x00,0x00,0x00,0xb9,0x00,0x00,0x8e,0xc1,0x26,0x8b,
0x1e,0x00,0x00,0x3b,0xc3,0x75,0x02,0xeb,0x24,0x8e,0xc5,0x26,
0x83,0x0e,0x12,0x00,0x04,0xb8,0x00,0x04,0xbb,0x00,0x60,0x06,
0xe8,0x66,0xfc,0x07,0x75,0x09,0x26,0xc7,0x06,0x16,0x00,0x40,
0x00,0xeb,0x06,0x26,0x83,0x0e,0x14,0x00,0x04,0x8e,0xc5,0x8c,
0xc0,0x3d,0xc0,0xf0,0x75,0x03,0xe9,0x9f,0x00,0x3d,0xc0,0x80,
0x74,0x62,0x3d,0xc0,0xc0,0x74,0x23,0x26,0x83,0x0e,0x12,0x00,
0x08,0xb8,0x00,0xf0,0xbb,0x00,0x7c,0x06,0xe8,0x2e,0xfc,0x07,
0x75,0x08,0x26,0x83,0x06,0x18,0x00,0x40,0xeb,0x06,0x26,0x83,
0x0e,0x14,0x00,0x08,0xeb,0x72,0xb9,0x03,0x00,0xb8,0x00,0xd0,
0xba,0x08,0x00,0xbb,0x00,0x80,0x3d,0x00,0xf0,0x75,0x03,0xbb,
0x00,0x7c,0x26,0x09,0x16,0x12,0x00,0x06,0x50,0x51,0xe8,0xfc,
0xfb,0x59,0x58,0x07,0x75,0x0f,0x26,0x83,0x06,0x18,0x00,0x40,
0xd1,0xe2,0x05,0x00,0x10,0xe2,0xd8,0xeb,0x05,0x26,0x09,0x16,
0x14,0x00,0xeb,0x38,0xb9,0x07,0x00,0xb8,0x00,0x90,0xba,0x08,
0x00,0xbb,0x00,0x80,0x3d,0x00,0xf0,0x75,0x03,0xbb,0x00,0x7c,
0x26,0x09,0x16,0x12,0x00,0x06,0x50,0x51,0xe8,0xc2,0xfb,0x59,
0x58,0x07,0x75,0x0f,0x26,0x83,0x06,0x18,0x00,0x40,0xd1,0xe2,
0x05,0x00,0x10,0xe2,0xd8,0xeb,0x05,0x26,0x09,0x16,0x14,0x00,
0x26,0xa1,0x18,0x00,0x2d,0x10,0x00,0x26,0xa3,0x1a,0x00,0x06,
0xfc,0x33,0xff,0x8e,0xc7,0xb9,0x00,0x02,0xb8,0x00,0xf0,0xf3,
0xab,0x33,0xff,0xbe,0x24,0xf8,0xb9,0x20,0x00,0xa5,0x47,0x47,
0xe2,0xfb,0xbe,0x64,0xf8,0xb9,0xe0,0x00,0x8b,0x1c,0x26,0x89,
0x1d,0x83,0xc7,0x04,0xe2,0xf8,0x07,0xba,0x28,0xff,0xb8,0xfd,
0x00,0xef,0xba,0x32,0xff,0xb8,0x0d,0x00,0xef,0xba,0x34,0xff,
0xb8,0x0f,0x00,0xef,0xba,0x36,0xff,0xb8,0x0e,0x00,0xef,0xba,
0x38,0xff,0xb8,0x19,0x00,0xef,0xba,0x3a,0xff,0xb8,0x18,0x00,
0xef,0xba,0x3c,0xff,0xb8,0x0b,0x00,0xef,0xba,0x3e,0xff,0xb8,
0x1a,0x00,0xef,0x8d,0x3e,0x90,0x00,0x8d,0x36,0x66,0xf8,0xb9,
0x10,0x00,0xf3,0xa5,0x8d,0x3e,0xb0,0x00,0x8d,0x36,0x86,0xf8,
0xb9,0x02,0x00,0xf3,0xa5,0xb9,0x10,0x00,0x8d,0x36,0x90,0x00,
0x83,0xc6,0x1e,0x26,0x8b,0x14,0xb3,0x10,0x32,0xc0,0xec,0xb0,
0x0c,0xee,0x8a,0xc3,0x8a,0xc3,0xee,0x83,0xee,0x02,0x26,0x8b,
0x14,0xfe,0xcb,0xe2,0xeb,0xb9,0x10,0x00,0x8d,0x36,0x90,0x00,
0x26,0x8b,0x14,0xb3,0x01,0xbf,0x00,0x80,0xb0,0x0c,0xee,0xf6,
0xe8,0xec,0x3a,0xc3,0x75,0x0e,0xd1,0xc7,0x26,0x09,0x3e,0x20,
0x00,0x26,0xfe,0x06,0x22,0x00,0xeb,0x07,0x33,0xc0,0x26,0x89,
0x04,0xd1,0xc7,0x83,0xc6,0x02,0x26,0x8b,0x14,0xfe,0xc3,0xe2,
0xd7,0x26,0xc6,0x06,0x23,0x00,0x01,0x8d,0x36,0xb0,0x00,0x26,
0x8b,0x14,0x32,0xc0,0xee,0xb0,0x0c,0xee,0xb0,0x5a,0xee,0xb0,
0x0c,0xee,0xf6,0xe8,0xec,0x3c,0x5a,0x74,0x14,0x26,0xc7,0x06,
0xb0,0x00,0x00,0x00,0x26,0xc7,0x06,0xb2,0x00,0x00,0x00,0x26,
0xc6,0x06,0x23,0x00,0x00,0xe9,0xd3,0xfa,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0xea,0x00,0xfc,0x00,0xf0,0x4d,0x2f,0x50,
0x43,0x2f,0x58,0x2a,0x39,0x34,0x34,0x31
};

View File

@@ -0,0 +1,517 @@
/* DigiBoard PCXX Bios */
static unsigned char pcxx_cook[] __initdata = {
0x4f,0x53,0x18,0x80,0xe9,0xbf,0x15,0x00,0x40,0x28,0x23,0x29,
0x46,0x45,0x50,0x4f,0x53,0x20,0x37,0x2e,0x30,0x38,0x20,0x34,
0x2f,0x32,0x30,0x2f,0x39,0x35,0x00,0x40,0x28,0x23,0x29,0x28,
0x43,0x29,0x43,0x6f,0x70,0x79,0x72,0x69,0x67,0x68,0x74,0x20,
0x31,0x39,0x38,0x39,0x2d,0x31,0x39,0x39,0x35,0x20,0x44,0x69,
0x67,0x69,0x42,0x6f,0x61,0x72,0x64,0x20,0x49,0x6e,0x63,0x2e,
0x00,0xcb,0x0c,0xcb,0x0c,0xe2,0x0c,0xcb,0x0c,0xcb,0x0c,0xcb,
0x0c,0xcb,0x0c,0xcb,0x0c,0x57,0x0c,0xcb,0x0c,0xcb,0x0c,0xcb,
0x0c,0x53,0x0b,0xcb,0x0c,0xcb,0x0c,0x42,0x0b,0xcb,0x0c,0xcb,
0x0c,0x12,0x0d,0xcb,0x0c,0xcb,0x0c,0xcb,0x0c,0xcb,0x0c,0xcb,
0x0c,0xcb,0x0c,0xcb,0x0c,0xcb,0x0c,0xcb,0x0c,0xcb,0x0c,0xcb,
0x0c,0xcb,0x0c,0xcb,0x0c,0x00,0x10,0x80,0x10,0x00,0x11,0x80,
0x11,0x00,0x12,0x80,0x12,0x00,0x13,0x80,0x13,0x00,0x14,0x80,
0x14,0x00,0x15,0x80,0x15,0x00,0x16,0x80,0x16,0x00,0x17,0x80,
0x17,0x78,0x0b,0xb9,0x0b,0x50,0x0c,0xb9,0x0b,0x8d,0x0b,0x8d,
0x0b,0x8d,0x0b,0x8d,0x0b,0xc0,0x0b,0xc0,0x0b,0xc0,0x0b,0xc0,
0x0b,0x8d,0x0b,0x8d,0x0b,0x8d,0x0b,0x8d,0x0b,0x50,0x0c,0xb9,
0x0b,0x50,0x0c,0xb9,0x0b,0x8d,0x0b,0x8d,0x0b,0x8d,0x0b,0x8d,
0x0b,0xc0,0x0b,0xc0,0x0b,0xc0,0x0b,0xc0,0x0b,0x8d,0x0b,0x8d,
0x0b,0x8d,0x0b,0x8d,0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,
0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,
0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,
0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,
0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,
0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x94,0x0b,0x16,0x00,0xfe,
0x11,0xfe,0x0b,0x2c,0x08,0xb5,0x06,0xfe,0x05,0x7e,0x04,0xfe,
0x02,0x7e,0x01,0xbe,0x00,0x7e,0x00,0x5e,0x00,0x2e,0x00,0x16,
0x00,0x0a,0x00,0x04,0x00,0x16,0x00,0x02,0x00,0x01,0x00,0x00,
0x00,0x0e,0x00,0x06,0x00,0x7e,0x04,0xfe,0x02,0x7e,0x01,0xbe,
0x00,0x7e,0x00,0x5e,0x00,0x2e,0x00,0x16,0x00,0x0a,0x00,0x04,
0x00,0x18,0x00,0x86,0x13,0x03,0x0d,0xdf,0x08,0x41,0x07,0x81,
0x06,0xe0,0x04,0x3f,0x03,0x9f,0x01,0xce,0x00,0x89,0x00,0x66,
0x00,0x32,0x00,0x18,0x00,0x0b,0x00,0x0b,0x00,0x18,0x00,0x0b,
0x00,0x0b,0x00,0x0b,0x00,0x41,0x07,0x81,0x06,0xe0,0x04,0x3f,
0x03,0x9f,0x01,0xce,0x00,0x89,0x00,0x66,0x00,0x32,0x00,0x18,
0x00,0x0b,0x00,0x0b,0x00,0x00,0x80,0x40,0xc0,0x1f,0x3f,0x7f,
0xff,0x00,0x04,0x02,0x06,0x08,0x0c,0x0a,0x0e,0x00,0x04,0x02,
0x06,0x08,0x0c,0x0a,0x0e,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,
0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0x1e,0x06,0x3e,
0x06,0xef,0x06,0xf8,0x05,0x0e,0x06,0x55,0x07,0xa0,0x08,0xa0,
0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,
0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,
0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0xa1,0x05,0xa1,0x05,0xa1,0x05,0xa1,0x05,0xa1,
0x05,0xa1,0x05,0xa1,0x05,0xa1,0x05,0xa1,0x05,0xa1,0x05,0xa1,
0x05,0xa1,0x05,0xa1,0x05,0xa1,0x05,0xa1,0x05,0xa1,0x05,0xa1,
0x05,0xa1,0x05,0xa1,0x05,0xa1,0x05,0xa1,0x05,0xa1,0x05,0xa1,
0x05,0xa1,0x05,0xa1,0x05,0xa1,0x05,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x5b,0x05,0xea,0x05,0xea,0x05,0xea,
0x05,0xea,0x05,0xea,0x05,0xea,0x05,0xea,0x05,0xea,0x05,0xea,
0x05,0xea,0x05,0xea,0x05,0xea,0x05,0xea,0x05,0xea,0x05,0xea,
0x05,0xea,0x05,0xea,0x05,0xea,0x05,0xea,0x05,0xea,0x05,0xea,
0x05,0xea,0x05,0xea,0x05,0xea,0x05,0xea,0x05,0xea,0x05,0x69,
0x05,0x77,0x05,0x85,0x05,0x93,0x05,0xa0,0x08,0xa0,0x08,0xa0,
0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,
0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,
0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,
0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,
0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,0x08,0xa0,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,0x08,0x9d,
0x08,0x00,0x00,0xfa,0x8a,0x5c,0x50,0xf6,0xc3,0x0e,0x75,0x3c,
0xf6,0xc3,0x40,0x75,0x16,0xf6,0xc3,0x10,0x74,0x26,0xf6,0xc3,
0x01,0x75,0x13,0xf6,0xc3,0x20,0x75,0x15,0xc7,0x04,0xb6,0x04,
0xe9,0xcf,0x00,0x8b,0x44,0x02,0x89,0x04,0xff,0xe0,0xc7,0x04,
0x03,0x05,0xe9,0x0e,0x01,0xc7,0x04,0x66,0x08,0xe9,0x6a,0x04,
0xf6,0xc3,0x20,0x74,0x1a,0xc7,0x04,0xb3,0x08,0xe9,0xab,0x04,
0x8b,0x54,0x20,0xec,0x8a,0xc8,0xf6,0xc3,0x02,0x75,0x42,0xf6,
0xc3,0x08,0x75,0x0e,0xeb,0x69,0x90,0xc7,0x04,0x20,0x04,0xfb,
0x81,0xc6,0x80,0x00,0xff,0x24,0xf6,0xc1,0x04,0x74,0x27,0x80,
0x64,0x50,0xf7,0xf6,0x44,0x51,0x02,0x74,0x13,0xf6,0x44,0x29,
0x10,0x74,0x0d,0x8a,0x44,0x5d,0x83,0xc2,0x02,0xee,0x83,0xea,
0x02,0xe9,0x49,0x04,0x8a,0x44,0x5c,0x83,0xc2,0x02,0xee,0x83,
0xea,0x02,0xe9,0x3c,0x04,0xf6,0x44,0x50,0x04,0x75,0x28,0x83,
0x7c,0x24,0xff,0x74,0x1f,0xa1,0x00,0x0e,0x2b,0x44,0x26,0x3d,
0x64,0x00,0x77,0x14,0xb0,0x05,0xee,0x8a,0x44,0x75,0x24,0xef,
0x88,0x44,0x75,0xee,0x80,0x64,0x50,0xfd,0x80,0x64,0x4b,0xfd,
0xe9,0x0e,0x04,0xb0,0x01,0xee,0x90,0x90,0x90,0xec,0xa8,0x01,
0x74,0x25,0xb0,0x05,0xee,0x8a,0x44,0x75,0x0c,0x10,0x88,0x44,
0x75,0xee,0xa1,0x00,0x0e,0x03,0x44,0x24,0x89,0x44,0x26,0x80,
0x64,0x50,0xfb,0x80,0x64,0x4b,0xfb,0x80,0x4c,0x50,0x02,0x80,
0x4c,0x4b,0x02,0xe9,0xdb,0x03,0xfa,0x8b,0x54,0x20,0xec,0x8a,
0xc8,0x22,0x44,0x52,0x3a,0x44,0x53,0x75,0x19,0x8b,0x7c,0x0c,
0x3b,0x7c,0x0a,0x74,0x18,0x8e,0x44,0x08,0x26,0x8a,0x05,0x47,
0x23,0x7c,0x0e,0x89,0x7c,0x0c,0x83,0xc2,0x02,0xee,0xfb,0x81,
0xc6,0x80,0x00,0xff,0x24,0xb0,0x01,0xee,0x90,0x90,0x90,0xec,
0xa8,0x01,0x74,0x0c,0x80,0x64,0x50,0xef,0x80,0x64,0x4b,0xef,
0xc7,0x04,0xc3,0x03,0xfb,0x81,0xc6,0x80,0x00,0xff,0x24,0xfa,
0x8b,0x54,0x20,0xec,0x8a,0xc8,0x22,0x44,0x52,0x3a,0x44,0x53,
0x75,0x3a,0x8b,0x7c,0x0c,0x3b,0x7c,0x0a,0x74,0x1b,0x8e,0x44,
0x08,0x26,0x8a,0x05,0x47,0x23,0x7c,0x0e,0x89,0x7c,0x0c,0x8a,
0xd8,0x22,0x5c,0x62,0x32,0xff,0x03,0xdb,0x2e,0xff,0xa7,0xc1,
0x01,0xb0,0x01,0xee,0x90,0x90,0x90,0xec,0xa8,0x01,0x74,0x0c,
0x80,0x64,0x50,0xef,0x80,0x64,0x4b,0xef,0xc7,0x04,0xc3,0x03,
0xf6,0xc1,0x01,0x75,0x07,0xfb,0x81,0xc6,0x80,0x00,0xff,0x24,
0xe9,0x61,0x03,0xf6,0x44,0x2a,0x01,0x75,0x03,0xe9,0x39,0x03,
0xb0,0x27,0xeb,0x42,0x90,0xf6,0x44,0x2a,0x01,0x75,0x03,0xe9,
0x2b,0x03,0xb0,0x28,0xeb,0x34,0x90,0xf6,0x44,0x2a,0x01,0x75,
0x03,0xe9,0x1d,0x03,0xb0,0x21,0xeb,0x26,0x90,0xf6,0x44,0x2a,
0x01,0x75,0x03,0xe9,0x0f,0x03,0xb0,0x29,0xeb,0x18,0x90,0xf6,
0x44,0x2a,0x01,0x75,0x03,0xe9,0x01,0x03,0xb0,0x5e,0xeb,0x0a,
0x90,0xf6,0x44,0x2a,0x01,0x75,0x03,0xe9,0xf3,0x02,0x88,0x44,
0x61,0xb0,0x5c,0x83,0xc2,0x02,0xee,0x83,0xea,0x02,0x80,0x4c,
0x50,0x40,0xc7,0x04,0xc6,0x05,0xc7,0x44,0x02,0xc6,0x05,0xe9,
0xcb,0x02,0xfa,0x8b,0x54,0x20,0xec,0x8a,0xc8,0x22,0x44,0x52,
0x3a,0x44,0x53,0x75,0x12,0x80,0x64,0x50,0xbf,0xc7,0x04,0x03,
0x05,0x83,0x44,0x30,0x02,0x8a,0x44,0x61,0xe9,0xb9,0x02,0xe9,
0xa7,0x02,0xf6,0x44,0x2a,0x02,0x75,0x03,0xe9,0xaa,0x02,0x2c,
0x20,0xe9,0xa5,0x02,0x83,0xc2,0x02,0xee,0x83,0xea,0x02,0xf6,
0x44,0x2b,0x40,0x75,0x03,0xe9,0x89,0x02,0xb8,0x7f,0x00,0xe9,
0x9b,0x01,0x83,0xc2,0x02,0xee,0x83,0xea,0x02,0xf6,0x44,0x2b,
0x80,0x75,0xed,0xe9,0x73,0x02,0x83,0xc2,0x02,0xee,0x83,0xea,
0x02,0xf7,0x44,0x30,0xff,0xff,0x74,0x03,0xff,0x4c,0x30,0xf6,
0x44,0x2b,0x20,0x75,0x03,0xe9,0x59,0x02,0xb8,0x02,0x00,0xe9,
0x6b,0x01,0xb3,0x18,0x22,0x5c,0x2b,0x75,0x16,0x83,0xc2,0x02,
0xee,0x83,0xea,0x02,0x8b,0x44,0x30,0x05,0x08,0x00,0x25,0xf8,
0xff,0x89,0x44,0x30,0xe9,0x36,0x02,0x80,0xfb,0x18,0x75,0x57,
0xb0,0x20,0x83,0xc2,0x02,0xee,0x83,0xea,0x02,0x8b,0x44,0x30,
0x8b,0xd8,0x05,0x08,0x00,0x25,0xf8,0xff,0x89,0x44,0x30,0x2b,
0xc3,0x48,0x74,0x38,0x89,0x44,0x32,0x80,0x4c,0x50,0x40,0xc7,
0x44,0x02,0x8f,0x06,0xc7,0x04,0x8f,0x06,0xe9,0x02,0x02,0xfa,
0x8b,0x54,0x20,0xec,0x8a,0xc8,0x22,0x44,0x52,0x3a,0x44,0x53,
0x75,0x16,0xb0,0x20,0x83,0xc2,0x02,0xee,0x83,0xea,0x02,0xff,
0x4c,0x32,0x75,0x08,0x80,0x64,0x50,0xbf,0xc7,0x04,0x03,0x05,
0xe9,0xda,0x01,0x83,0xc2,0x02,0xee,0x83,0xea,0x02,0x80,0xfb,
0x08,0x75,0x18,0x8b,0x44,0x30,0x8b,0xd8,0x05,0x08,0x00,0x25,
0xf8,0xff,0x89,0x44,0x30,0x2b,0xc3,0x3d,0x05,0x00,0x7c,0xdc,
0xe9,0xce,0x00,0x8b,0x44,0x30,0x8b,0xd8,0x05,0x08,0x00,0x25,
0xf8,0xff,0x89,0x44,0x30,0xb8,0x02,0x00,0xe9,0xba,0x00,0xf6,
0x44,0x2a,0x20,0x75,0x43,0xf6,0x44,0x2a,0x04,0x74,0x42,0xf6,
0x44,0x2a,0x10,0x74,0x07,0xf7,0x44,0x30,0xff,0xff,0x74,0x30,
0xb0,0x0d,0x83,0xc2,0x02,0xee,0x83,0xea,0x02,0x80,0x4c,0x50,
0x40,0xc7,0x04,0x21,0x07,0xc7,0x44,0x02,0x21,0x07,0xe9,0x70,
0x01,0xfa,0x8b,0x54,0x20,0xec,0x8a,0xc8,0x22,0x44,0x52,0x3a,
0x44,0x53,0x75,0x1c,0x80,0x64,0x50,0xbf,0xc7,0x04,0x03,0x05,
0xb0,0x0a,0xeb,0x2b,0x90,0xb0,0x0a,0x83,0xc2,0x02,0xee,0x83,
0xea,0x02,0xf6,0x44,0x2b,0x01,0x75,0x03,0xe9,0x42,0x01,0xb8,
0x05,0x00,0xeb,0x55,0x90,0xf6,0x44,0x2a,0x08,0x75,0xe2,0xf6,
0x44,0x2a,0x10,0x74,0x06,0x83,0x7c,0x30,0x00,0x74,0x13,0x83,
0xc2,0x02,0xee,0x83,0xea,0x02,0xb3,0x06,0x22,0x5c,0x2b,0x75,
0x08,0xc7,0x44,0x30,0x00,0x00,0xe9,0x14,0x01,0x80,0xfb,0x02,
0x75,0x14,0x8b,0x44,0x30,0xc1,0xe8,0x04,0x05,0x03,0x00,0x3d,
0x06,0x00,0x72,0x14,0xb8,0x06,0x00,0xeb,0x0f,0x90,0x80,0xfb,
0x04,0x75,0x06,0xb8,0x05,0x00,0xeb,0x04,0x90,0xb8,0x09,0x00,
0xc7,0x44,0x30,0x00,0x00,0xf6,0x44,0x2a,0x40,0x74,0x45,0x3d,
0x20,0x00,0x77,0x40,0xbb,0x01,0x00,0x3d,0x03,0x00,0x7e,0x03,
0xbb,0x02,0x00,0x89,0x5c,0x32,0x80,0x4c,0x50,0x40,0xc7,0x44,
0x02,0xd2,0x07,0xc7,0x04,0xd2,0x07,0xe9,0xbf,0x00,0xfa,0x8b,
0x54,0x20,0xec,0x8a,0xc8,0x22,0x44,0x52,0x3a,0x44,0x53,0x75,
0x10,0x8a,0x44,0x60,0x83,0xc2,0x02,0xee,0x83,0xea,0x02,0x83,
0x6c,0x32,0x01,0x7e,0x50,0xe9,0x9d,0x00,0x05,0x06,0x00,0x03,
0xc0,0x89,0x44,0x32,0x80,0x4c,0x50,0x40,0xc7,0x44,0x02,0x0c,
0x08,0xc7,0x04,0x0c,0x08,0xe9,0x85,0x00,0xfa,0x8b,0x54,0x20,
0xec,0x8a,0xc8,0xb0,0x01,0xee,0x90,0x90,0x90,0xec,0xa8,0x01,
0x74,0x0f,0xa1,0x00,0x0e,0x01,0x44,0x32,0xc7,0x44,0x02,0x30,
0x08,0xc7,0x04,0x30,0x08,0xeb,0x62,0x90,0x8b,0x54,0x20,0xec,
0x8a,0xc8,0xa1,0x00,0x0e,0x2b,0x44,0x32,0x3d,0xe8,0x03,0x77,
0xec,0x80,0x64,0x50,0xbf,0xc7,0x04,0x03,0x05,0xeb,0x46,0x90,
0xb0,0x01,0xee,0x90,0x90,0x90,0xec,0xa8,0x01,0x74,0x3a,0x80,
0x64,0x50,0xef,0x80,0x64,0x4b,0xef,0xc7,0x04,0xb3,0x08,0xeb,
0x2c,0x90,0xfa,0x8b,0x54,0x20,0xec,0x8a,0xc8,0x22,0x44,0x52,
0x3a,0x44,0x53,0x75,0x1c,0x8b,0x7c,0x0c,0x3b,0x7c,0x0a,0x74,
0xcf,0x8e,0x44,0x08,0x26,0x8a,0x05,0x47,0x23,0x7c,0x0e,0x89,
0x7c,0x0c,0x83,0xc2,0x02,0xee,0x83,0xea,0x02,0xf6,0xc1,0x01,
0x75,0x26,0xfb,0x81,0xc6,0x80,0x00,0xff,0x24,0xff,0x44,0x30,
0x83,0xc2,0x02,0xee,0x83,0xea,0x02,0xf6,0xc1,0x01,0x75,0x10,
0xfb,0x81,0xc6,0x80,0x00,0xff,0x24,0xfa,0x8b,0x54,0x20,0xec,
0xa8,0x01,0x74,0xda,0xc6,0x44,0x49,0x02,0x8b,0x7c,0x12,0x8e,
0x44,0x10,0xb0,0x01,0xee,0x90,0x90,0x90,0xec,0x8a,0xe0,0x90,
0xb0,0x30,0xee,0x83,0xc2,0x02,0x90,0xec,0x83,0xea,0x02,0x23,
0x44,0x34,0xff,0x64,0x06,0xb3,0x1c,0x22,0x5c,0x51,0x75,0x1a,
0xf6,0x44,0x29,0x04,0x74,0x21,0xf6,0x44,0x29,0x20,0x75,0x2b,
0x80,0x7c,0x5e,0x00,0x75,0x1d,0xc7,0x44,0x06,0x58,0x0a,0xe9,
0x56,0x01,0xf6,0xc3,0x10,0x75,0x2e,0xf6,0xc3,0x04,0x75,0x74,
0xeb,0x6b,0x90,0xc7,0x44,0x06,0x62,0x0a,0xe9,0x4b,0x01,0xc7,
0x44,0x06,0x53,0x0a,0xe9,0x34,0x01,0x80,0x7c,0x5e,0x00,0x75,
0x08,0xc7,0x44,0x06,0xca,0x09,0xe9,0x9d,0x00,0xc7,0x44,0x06,
0xc5,0x09,0xe9,0x90,0x00,0x0a,0xc0,0x74,0x2a,0xfe,0x4c,0x63,
0x74,0x1a,0x80,0xe3,0xef,0x75,0xc4,0xf6,0x44,0x29,0x04,0x74,
0x21,0xf6,0x44,0x29,0x20,0x75,0x21,0x80,0x7c,0x5e,0x00,0x75,
0x18,0xe9,0x00,0x01,0x80,0x64,0x51,0xef,0x80,0xe3,0xef,0x75,
0xa6,0xeb,0x85,0x80,0x64,0x51,0xef,0xe9,0x06,0x01,0xe9,0xf5,
0x00,0xe9,0xe3,0x00,0x80,0x7c,0x5e,0x00,0x75,0x4f,0xeb,0x52,
0x90,0x80,0x64,0x51,0xf7,0xe9,0xe2,0x00,0x80,0x64,0x53,0x3f,
0x80,0x64,0x54,0xfe,0x80,0x4c,0x58,0x01,0x80,0x64,0x51,0xfb,
0xf6,0x44,0x29,0x40,0x75,0x2c,0x3a,0x44,0x5d,0x74,0x27,0x3a,
0x44,0x5c,0x74,0x22,0xf6,0x44,0x29,0x20,0x74,0x0a,0x3a,0x44,
0x5a,0x74,0x17,0x3a,0x44,0x5b,0x74,0x12,0xf6,0x44,0x5e,0xff,
0x74,0x09,0x3a,0x44,0x5e,0x75,0x04,0x80,0x4c,0x51,0x08,0xe9,
0xa0,0x00,0xe9,0xab,0x00,0x3a,0x44,0x5e,0x74,0x7d,0x3a,0x44,
0x5c,0x74,0x3d,0x3a,0x44,0x5d,0x74,0x55,0x3a,0x44,0x5a,0x74,
0x08,0x3a,0x44,0x5b,0x74,0x18,0xe9,0x81,0x00,0xf6,0x44,0x53,
0x40,0x74,0x07,0x80,0x64,0x53,0xbf,0xe9,0x82,0x00,0x3a,0x44,
0x5b,0x74,0x03,0xeb,0x7b,0x90,0x80,0x4c,0x53,0x40,0xf6,0x44,
0x29,0x08,0x74,0x70,0x80,0x4c,0x51,0x04,0xc7,0x44,0x06,0xe1,
0x08,0xeb,0x65,0x90,0xf6,0x44,0x53,0x80,0x74,0x0f,0x80,0x64,
0x53,0x7f,0x80,0x64,0x54,0xfe,0x80,0x4c,0x58,0x01,0xeb,0x50,
0x90,0x3a,0x44,0x5d,0x74,0x03,0xeb,0x48,0x90,0x80,0x4c,0x53,
0x80,0x80,0x4c,0x54,0x01,0x80,0x4c,0x58,0x01,0xf6,0x44,0x29,
0x08,0x74,0x35,0x80,0x4c,0x51,0x04,0xc7,0x44,0x06,0xe1,0x08,
0xeb,0x2a,0x90,0x80,0x4c,0x51,0x08,0xc7,0x44,0x06,0xe1,0x08,
0xeb,0x10,0x90,0x3a,0x44,0x5e,0x74,0xef,0x3a,0x44,0x5c,0x74,
0xaf,0x3a,0x44,0x5d,0x74,0xc7,0x3d,0xff,0x00,0x73,0x26,0xaa,
0x23,0x7c,0x16,0x3b,0x7c,0x14,0x74,0x4f,0xec,0xa8,0x01,0x74,
0x03,0xe9,0x4e,0xfe,0x89,0x7c,0x12,0x2b,0x7c,0x14,0x23,0x7c,
0x16,0x3b,0x7c,0x1c,0x73,0x46,0xfb,0x81,0xc6,0x80,0x00,0xff,
0x24,0x0a,0xe4,0x75,0x1e,0xb3,0x0c,0x22,0x5c,0x28,0x80,0xfb,
0x08,0x75,0xcc,0xaa,0x23,0x7c,0x16,0x3b,0x7c,0x14,0x74,0x1b,
0xaa,0x23,0x7c,0x16,0x3b,0x7c,0x14,0x74,0x12,0xeb,0xc1,0xf6,
0x44,0x28,0x04,0x75,0xbb,0xf6,0x44,0x28,0x08,0x75,0x50,0x32,
0xc0,0xeb,0xa8,0x4f,0x23,0x7c,0x16,0x89,0x7c,0x12,0xc6,0x44,
0x59,0x01,0xeb,0xa4,0xf6,0x44,0x51,0x02,0x74,0x07,0xfb,0x81,
0xc6,0x80,0x00,0xff,0x24,0x80,0x4c,0x51,0x02,0xb0,0x05,0xee,
0xb0,0x82,0x22,0x44,0x5f,0xf6,0xd0,0x22,0x44,0x75,0x88,0x44,
0x75,0xee,0xf6,0x44,0x29,0x10,0x74,0x10,0x80,0x4c,0x54,0x04,
0x80,0x4c,0x58,0x04,0x80,0x74,0x50,0x08,0xc7,0x04,0xc3,0x03,
0xfb,0x81,0xc6,0x80,0x00,0xff,0x24,0x26,0xc6,0x05,0xff,0x47,
0x23,0x7c,0x16,0x3b,0x7c,0x14,0x74,0xa7,0x32,0xff,0xf6,0x44,
0x29,0x80,0x74,0x0a,0x8a,0xdc,0xc0,0xeb,0x04,0x2e,0x8a,0xbf,
0xb1,0x01,0x26,0x88,0x3d,0x47,0x23,0x7c,0x16,0x3b,0x7c,0x14,
0x74,0x89,0xaa,0x23,0x7c,0x16,0x3b,0x7c,0x14,0x74,0x80,0xe9,
0x2e,0xff,0x1e,0x2e,0x8e,0x1e,0xc1,0x03,0xff,0x06,0x1c,0x0e,
0x60,0xbe,0x00,0x14,0xeb,0x0f,0x90,0x1e,0x2e,0x8e,0x1e,0xc1,
0x03,0xff,0x06,0x1a,0x0e,0x60,0xbe,0x00,0x10,0xb9,0x08,0x00,
0x8b,0x54,0x20,0xb0,0x03,0xee,0x90,0x90,0x32,0xff,0xec,0x8a,
0xd8,0x02,0xd8,0x2e,0xff,0xa7,0xa9,0x00,0x81,0xc6,0x00,0x01,
0x8b,0x54,0x20,0x0b,0xd2,0xe0,0xe4,0xb8,0x00,0x80,0xba,0x22,
0xff,0xef,0x61,0x1f,0xcf,0x81,0xce,0x80,0x00,0x8b,0x54,0x20,
0xff,0x06,0x20,0x0e,0xb0,0x01,0xee,0x8a,0x44,0x71,0x24,0xe7,
0x88,0x44,0x71,0xee,0xc6,0x44,0x49,0x02,0x80,0x4c,0x50,0x20,
0xc7,0x04,0xc3,0x03,0x81,0xe6,0x7f,0xff,0x8b,0x54,0x20,0xeb,
0xae,0x81,0xce,0x80,0x00,0x8b,0x54,0x20,0xff,0x06,0x22,0x0e,
0xec,0x0a,0xc0,0x79,0x7a,0x80,0x4c,0x51,0x10,0xc7,0x44,0x06,
0xe1,0x08,0xc6,0x44,0x63,0x04,0xf6,0x44,0x51,0x04,0x74,0x08,
0x80,0x64,0x51,0xfb,0x80,0x64,0x53,0x3f,0xf6,0x44,0x28,0x01,
0x75,0x59,0xf6,0x44,0x28,0x02,0x75,0x4f,0x8b,0x7c,0x12,0x8c,
0xc3,0x8e,0x44,0x10,0xf6,0x44,0x28,0x08,0x74,0x1e,0xb0,0xff,
0xaa,0x23,0x7c,0x16,0x3b,0x7c,0x14,0x74,0x26,0x32,0xc0,0xf6,
0x44,0x29,0x80,0x74,0x02,0xb0,0x10,0xaa,0x23,0x7c,0x16,0x3b,
0x7c,0x14,0x74,0x13,0x32,0xc0,0xaa,0x23,0x7c,0x16,0x3b,0x7c,
0x14,0x74,0x08,0x8e,0xc3,0x89,0x7c,0x12,0xeb,0x15,0x90,0x8e,
0xc3,0x4f,0x23,0x7c,0x16,0x89,0x7c,0x12,0xc6,0x44,0x59,0x01,
0xeb,0x05,0x90,0x80,0x4c,0x4f,0x01,0xb0,0x10,0xee,0x81,0xe6,
0x7f,0xff,0x8b,0x54,0x20,0xe9,0x17,0xff,0xff,0x06,0x1e,0x0e,
0xe9,0x10,0xff,0x1e,0x2e,0x8e,0x1e,0xc1,0x03,0x50,0x52,0x55,
0x8b,0xec,0x8b,0x46,0x08,0xa3,0x12,0x0e,0x32,0xe4,0xa0,0x22,
0x0c,0xa3,0x10,0x0e,0xff,0x06,0x00,0x0e,0x83,0x06,0x0e,0x0e,
0x0a,0x83,0x3e,0x04,0x0e,0x00,0x74,0x31,0x8b,0x16,0x00,0x0e,
0x2b,0x16,0x02,0x0e,0x3b,0x16,0x04,0x0e,0x72,0x23,0x8b,0x16,
0x00,0x0e,0x89,0x16,0x02,0x0e,0x8b,0x16,0x18,0x0d,0x3b,0x16,
0x1a,0x0d,0x74,0x11,0x80,0x3e,0x10,0x0c,0x01,0x74,0x16,0xb0,
0x00,0x90,0xe6,0x00,0x0c,0x08,0x90,0xe6,0x00,0xb8,0x00,0x80,
0xba,0x22,0xff,0xef,0x5d,0x5a,0x58,0x1f,0xcf,0xb0,0x80,0xe6,
0x00,0xa0,0x11,0x0c,0x0c,0x10,0xa2,0x11,0x0c,0xeb,0xe6,0x1e,
0x2e,0x8e,0x1e,0xc1,0x03,0xff,0x06,0x28,0x0e,0x55,0x8b,0xec,
0x8b,0x6e,0x02,0x89,0x2e,0x16,0x0e,0x5d,0x1f,0xcf,0x1e,0x2e,
0x8e,0x1e,0xc1,0x03,0xff,0x06,0x24,0x0e,0x55,0x8b,0xec,0x8b,
0x6e,0x02,0x89,0x2e,0x14,0x0e,0x5d,0x80,0x3e,0x10,0x0c,0x01,
0x75,0x12,0x50,0xa0,0x11,0x0c,0x0c,0x01,0xa2,0x11,0x0c,0xe4,
0x00,0x90,0x90,0x24,0x7f,0xe6,0x00,0x58,0x1f,0xcf,0x1e,0x06,
0x60,0xb8,0x00,0x80,0xba,0x22,0xff,0xef,0x2e,0x8e,0x1e,0xc1,
0x03,0x2e,0x8e,0x06,0xc1,0x03,0x2e,0xff,0x06,0x30,0x0d,0xfc,
0xff,0x26,0x2e,0x0e,0x00,0x00,0xfb,0x40,0x43,0x41,0x42,0x46,
0x47,0x45,0xeb,0xf6,0xc3,0x00,0x00,0x8f,0x06,0x2e,0x0e,0x2e,
0xff,0x06,0x3d,0x0d,0xb8,0x00,0x00,0xba,0x58,0xff,0xef,0xb8,
0x00,0xe0,0xba,0x5e,0xff,0xef,0x61,0x07,0x1f,0xcf,0xc2,0xfe,
0xff,0x8b,0x7c,0x0a,0x2b,0x7c,0x0c,0x23,0x7c,0x0e,0x3b,0x7c,
0x18,0x77,0x2e,0xc6,0x44,0x4d,0x00,0x80,0x4c,0x4f,0x02,0xeb,
0x5a,0x90,0x8b,0x7c,0x0a,0x3b,0x7c,0x0c,0x75,0x1b,0x8b,0x3e,
0x10,0x0d,0x3b,0x3e,0x12,0x0d,0x75,0x53,0xf6,0x44,0x4b,0xff,
0x75,0x4d,0xc6,0x44,0x4c,0x00,0x80,0x4c,0x4f,0x04,0xeb,0x43,
0x90,0xf6,0x44,0x50,0x10,0x75,0x3c,0xeb,0x09,0x90,0x8b,0x7c,
0x0a,0x2b,0x7c,0x0c,0x74,0x31,0x80,0x4c,0x50,0x10,0x80,0x4c,
0x4b,0x10,0xc7,0x04,0xc3,0x03,0xeb,0x23,0x90,0xfa,0x8b,0x36,
0x08,0x0e,0x8b,0x54,0x20,0xec,0x8a,0xf8,0x8a,0x5c,0x54,0x32,
0xfb,0xf6,0x44,0x4d,0xff,0x75,0x8e,0xf6,0x44,0x4c,0xff,0x75,
0xa1,0xf6,0x44,0x50,0x10,0x74,0xc7,0xec,0x32,0xc3,0x22,0xf8,
0x83,0x2e,0x10,0x0e,0x01,0x78,0x05,0xd0,0x6c,0x49,0x72,0x45,
0x8b,0x7c,0x12,0x2b,0x7c,0x14,0x74,0x22,0x80,0x7c,0x4e,0x00,
0x74,0x1c,0x23,0x7c,0x16,0x03,0xff,0x3b,0x7c,0x16,0x73,0x43,
0x8b,0x0e,0x0e,0x0e,0x2b,0x4c,0x6e,0x3b,0x4c,0x22,0x73,0x37,
0x80,0x7c,0x49,0x00,0x74,0x31,0xf6,0x44,0x51,0x02,0x75,0x3c,
0xec,0x32,0xc3,0x22,0xf8,0x80,0xe7,0x38,0xfb,0x89,0x1e,0x30,
0x0e,0xbe,0x00,0x10,0xff,0x14,0xeb,0x61,0x90,0xb0,0x01,0xee,
0x8a,0x44,0x71,0x0c,0x10,0x88,0x44,0x71,0xee,0x80,0x64,0x50,
0xdf,0xc7,0x04,0xc3,0x03,0xeb,0xa5,0xc6,0x44,0x4e,0x00,0x8b,
0x0e,0x0e,0x0e,0x89,0x4c,0x6e,0x80,0x4c,0x4f,0x08,0xeb,0xbe,
0x8b,0x7c,0x12,0x2b,0x7c,0x14,0x23,0x7c,0x16,0x3b,0x7c,0x1a,
0x73,0xb6,0x80,0x64,0x51,0xfd,0xf6,0x44,0x29,0x10,0x74,0x10,
0x80,0x64,0x54,0xfb,0x80,0x4c,0x58,0x04,0x80,0x74,0x50,0x08,
0xc7,0x04,0xc3,0x03,0xb0,0x05,0xee,0xb0,0x82,0x22,0x44,0x5f,
0x0a,0x44,0x75,0x88,0x44,0x75,0xee,0xeb,0x8b,0xfa,0x8b,0x36,
0x08,0x0e,0x8b,0x1e,0x30,0x0e,0x8a,0xcb,0xe5,0x80,0x23,0x44,
0x2e,0x74,0x02,0xf6,0xd1,0x80,0xe1,0x40,0x0a,0xf9,0x8a,0xdf,
0x22,0x5c,0x55,0x30,0x5c,0x54,0x32,0xfb,0x88,0x7c,0x55,0x0a,
0x5c,0x58,0x88,0x5c,0x58,0x22,0x5c,0x56,0x75,0x24,0x80,0x7c,
0x4f,0x00,0x75,0x22,0xfb,0x03,0x74,0x1e,0x89,0x36,0x08,0x0e,
0xff,0x06,0x26,0x0e,0x8b,0x3e,0x12,0x0d,0x3b,0x3e,0x10,0x0d,
0x75,0x46,0xbe,0x00,0x10,0xff,0x14,0xe9,0xd3,0xfe,0x80,0x4c,
0x4f,0x20,0x8b,0x3e,0x18,0x0d,0x8a,0x44,0x48,0x8a,0x64,0x4f,
0x89,0x85,0x00,0x08,0x8a,0x44,0x54,0x8a,0x64,0x57,0x89,0x85,
0x02,0x08,0x83,0xc7,0x04,0x81,0xe7,0xfc,0x03,0x3b,0x3e,0x1a,
0x0d,0x74,0x13,0x88,0x44,0x57,0xc6,0x44,0x4f,0x00,0x8a,0x44,
0x56,0xf6,0xd0,0x20,0x44,0x58,0x89,0x3e,0x18,0x0d,0xeb,0xa4,
0xff,0x06,0x2c,0x0e,0xbe,0x00,0x10,0xff,0x14,0xfa,0x8b,0x3e,
0x12,0x0d,0x81,0xc7,0x00,0x04,0x8a,0x5d,0x01,0x83,0xe3,0x0f,
0x03,0xdb,0x2e,0x8b,0xb7,0x89,0x00,0x8b,0x54,0x20,0x0b,0xd2,
0x74,0x0d,0x8a,0x1d,0x83,0xe3,0x1f,0x03,0xdb,0xfa,0x2e,0xff,
0xa7,0x9c,0x0f,0xff,0x06,0x2a,0x0e,0x8b,0x3e,0x12,0x0d,0x8b,
0x36,0x18,0x0d,0x8b,0x9d,0x00,0x04,0x89,0x9c,0x00,0x08,0x8b,
0x9d,0x02,0x04,0x89,0x9c,0x02,0x08,0x83,0xc6,0x04,0x81,0xe6,
0xfc,0x03,0x3b,0x36,0x1a,0x0d,0x74,0x04,0x89,0x36,0x18,0x0d,
0xfb,0x8b,0x3e,0x12,0x0d,0x83,0xc7,0x04,0x81,0xe7,0xfc,0x03,
0x89,0x3e,0x12,0x0d,0xbe,0x00,0x10,0xff,0x14,0xe9,0x1d,0xfe,
0xdc,0x0f,0xe4,0x0f,0xec,0x0f,0x0d,0x10,0x1c,0x10,0x57,0x0f,
0x2f,0x10,0x57,0x0f,0x3b,0x10,0x54,0x10,0x83,0x10,0xcf,0x10,
0xdb,0x10,0xe4,0x10,0xeb,0x10,0x35,0x11,0x7d,0x11,0x83,0x11,
0xa1,0x11,0xb9,0x11,0xf2,0x11,0x38,0x12,0x03,0x13,0x0c,0x13,
0x57,0x0f,0x57,0x0f,0x57,0x0f,0x57,0x0f,0x57,0x0f,0x57,0x0f,
0x57,0x0f,0x57,0x0f,0x8b,0x45,0x02,0x89,0x44,0x1a,0xeb,0xa0,
0x8b,0x45,0x02,0x89,0x44,0x1c,0xeb,0x98,0x8b,0x45,0x02,0x8b,
0x5c,0x0a,0x2b,0x5c,0x0c,0x23,0x5c,0x0e,0x8b,0x4c,0x0a,0x2b,
0xc8,0x23,0x4c,0x0e,0x3b,0xd9,0x76,0x06,0x23,0x44,0x0e,0x89,
0x44,0x0c,0xe9,0x77,0xff,0x80,0x4c,0x53,0x80,0x80,0x4c,0x54,
0x01,0x80,0x4c,0x58,0x01,0xe9,0x68,0xff,0x80,0x64,0x53,0x3f,
0x80,0x64,0x54,0xfe,0x80,0x4c,0x58,0x01,0x80,0x64,0x51,0xfb,
0xe9,0x55,0xff,0x8b,0x45,0x02,0x88,0x44,0x5a,0x88,0x64,0x5b,
0xe9,0x49,0xff,0x8b,0x45,0x02,0x0b,0xc0,0x74,0x03,0x89,0x44,
0x24,0x80,0x4c,0x50,0x04,0x80,0x4c,0x4b,0x04,0xc7,0x04,0xc3,
0x03,0xe9,0x30,0xff,0x8b,0x5d,0x02,0xf6,0xd7,0x22,0x7c,0x54,
0x0a,0xdf,0x8a,0x44,0x54,0x32,0xc3,0x24,0x82,0x30,0x44,0x54,
0xb0,0x05,0xee,0x8a,0x44,0x75,0x32,0xd8,0x8a,0x7c,0x5f,0xf6,
0xd7,0x22,0xdf,0x80,0xe3,0x82,0x32,0xc3,0x88,0x44,0x75,0xee,
0xe9,0x01,0xff,0x8b,0x5d,0x02,0xf6,0xc7,0x04,0x75,0x08,0x80,
0x64,0x53,0x3f,0x80,0x64,0x51,0xfb,0x8a,0x44,0x29,0x32,0xc7,
0xa8,0x10,0x74,0x0e,0xf6,0x44,0x51,0x02,0x74,0x08,0x80,0x74,
0x50,0x08,0xc7,0x04,0xc3,0x03,0x88,0x5c,0x28,0x88,0x7c,0x29,
0xb4,0x60,0xf6,0xc3,0x10,0x74,0x03,0x80,0xcc,0x10,0x8a,0x44,
0x62,0xf6,0xc3,0x20,0x74,0x02,0x24,0x7f,0x89,0x44,0x34,0xc7,
0x44,0x06,0xe1,0x08,0xe9,0xb5,0xfe,0x8b,0x45,0x02,0x88,0x44,
0x5c,0x88,0x64,0x5d,0xe9,0xa9,0xfe,0x8b,0x45,0x02,0x89,0x44,
0x18,0xe9,0xa0,0xfe,0xff,0x1e,0x24,0x0d,0xe9,0x99,0xfe,0xf6,
0x44,0x51,0x02,0x75,0x41,0x8b,0x44,0x12,0x2b,0x44,0x14,0x23,
0x44,0x16,0x3b,0x44,0x1a,0x72,0x33,0x80,0x4c,0x51,0x02,0xf6,
0x44,0x29,0x10,0x74,0x10,0x80,0x4c,0x54,0x04,0x80,0x4c,0x58,
0x04,0x80,0x74,0x50,0x08,0xc7,0x04,0xc3,0x03,0xf6,0x44,0x5f,
0x82,0x74,0x13,0xb0,0x05,0xee,0x8a,0x44,0x75,0xb4,0x82,0x22,
0x64,0x5f,0xf6,0xd4,0x22,0xc4,0x88,0x44,0x75,0xee,0xe9,0x4f,
0xfe,0xf6,0x44,0x51,0x02,0x74,0x3f,0x8b,0x44,0x12,0x2b,0x44,
0x14,0x23,0x44,0x16,0x3b,0x44,0x1c,0x73,0xe9,0x80,0x64,0x51,
0xfd,0xf6,0x44,0x29,0x10,0x74,0x10,0x80,0x64,0x54,0xfb,0x80,
0x4c,0x58,0x04,0x80,0x74,0x50,0x08,0xc7,0x04,0xc3,0x03,0xf6,
0x44,0x5f,0x02,0x74,0x11,0xb0,0x05,0xee,0x8a,0x44,0x75,0xb4,
0x82,0x22,0x64,0x5f,0x0a,0xc4,0x88,0x44,0x75,0xee,0xe9,0x07,
0xfe,0xe8,0x8a,0x02,0xe9,0x01,0xfe,0x8b,0x45,0x02,0xbb,0x10,
0x27,0xf7,0xe3,0xbb,0x0f,0x00,0xf7,0xf3,0xa3,0x06,0x0e,0xba,
0x52,0xff,0xef,0xba,0x50,0xff,0xb8,0x00,0x00,0xef,0xe9,0xe3,
0xfd,0x8b,0x45,0x02,0x3a,0x06,0x22,0x0c,0x72,0x0c,0x3b,0x06,
0x1a,0x0c,0x77,0x06,0xe8,0xab,0x01,0xe9,0xce,0xfd,0xe9,0x9e,
0xfd,0x8b,0x45,0x02,0x88,0x44,0x2a,0x88,0x64,0x2b,0x0b,0xc0,
0x75,0x07,0x80,0x64,0x50,0xfe,0xeb,0x10,0x90,0xf6,0x44,0x50,
0x01,0x75,0x09,0x80,0x4c,0x50,0x01,0xc7,0x44,0x30,0x00,0x00,
0xa8,0x80,0x75,0x07,0xc6,0x44,0x60,0x00,0xeb,0x05,0x90,0xc6,
0x44,0x60,0x7f,0xc7,0x04,0xc3,0x03,0xe9,0x92,0xfd,0x8b,0x5d,
0x02,0xf6,0xd7,0x22,0x7c,0x5f,0x0a,0xdf,0x8a,0xfb,0x88,0x5c,
0x5f,0x8a,0x44,0x52,0x8a,0x64,0x53,0x8b,0xcb,0x33,0xc8,0x81,
0xe1,0x38,0x38,0x33,0xc1,0x88,0x44,0x52,0x88,0x64,0x53,0xb0,
0x05,0xee,0xf6,0xd3,0x22,0x5c,0x54,0xf6,0x44,0x51,0x02,0x75,
0x02,0x0a,0xdf,0x8a,0x44,0x75,0x32,0xd8,0x80,0xe3,0x82,0x32,
0xc3,0x88,0x44,0x75,0xee,0xe9,0x4c,0xfd,0x8b,0x5d,0x02,0x88,
0x5c,0x2c,0x88,0x7c,0x2d,0x8b,0xcb,0x83,0xe3,0x0f,0x03,0xdb,
0x80,0x3e,0x10,0x0c,0x01,0x75,0x1f,0xa1,0x0e,0x0c,0x86,0xe0,
0x3d,0x32,0x31,0x73,0x15,0xf6,0xc5,0x04,0x75,0x08,0x2e,0x8b,
0x9f,0x69,0x01,0xeb,0x1b,0x90,0x2e,0x8b,0x9f,0x89,0x01,0xeb,
0x13,0x90,0xf6,0xc5,0x04,0x75,0x08,0x2e,0x8b,0x9f,0x29,0x01,
0xeb,0x06,0x90,0x2e,0x8b,0x9f,0x49,0x01,0xb0,0x0c,0xee,0x8a,
0xc3,0x88,0x44,0x7c,0xee,0xb0,0x0d,0x90,0x90,0xee,0x8a,0xc7,
0x88,0x44,0x7d,0xee,0xb0,0x04,0xee,0xb0,0x44,0xf6,0xc1,0x40,
0x74,0x0c,0xf6,0xc1,0x80,0x74,0x05,0x04,0x04,0xeb,0x03,0x90,
0x0c,0x08,0xf6,0xc5,0x01,0x74,0x09,0x0c,0x01,0xf6,0xc5,0x02,
0x75,0x02,0x0c,0x02,0x88,0x44,0x74,0xee,0xb0,0x03,0x90,0x90,
0xee,0x8a,0xd9,0x80,0xe3,0x30,0xc0,0xeb,0x04,0x32,0xff,0x2e,
0x8a,0xa7,0xa9,0x01,0x8a,0x44,0x73,0x24,0x3f,0x0a,0xc4,0x88,
0x44,0x73,0xee,0x90,0x90,0xb0,0x05,0xee,0xd0,0xec,0x8a,0x44,
0x75,0x24,0x9f,0x0a,0xc4,0x88,0x44,0x75,0xee,0x2e,0x8a,0x87,
0xad,0x01,0x88,0x44,0x62,0xf6,0x44,0x28,0x20,0x74,0x02,0x24,
0x7f,0x88,0x44,0x34,0xe9,0x81,0xfc,0x8a,0x45,0x02,0x88,0x44,
0x5e,0xe9,0x78,0xfc,0x8b,0x45,0x02,0xba,0x5a,0xff,0xef,0x9c,
0xff,0x36,0x26,0x0d,0xff,0x36,0x24,0x0d,0x1e,0x06,0x60,0x8b,
0x36,0x0a,0x0e,0xc7,0x04,0x3f,0x0d,0xe9,0x5a,0xfc,0xb8,0x00,
0x00,0x8e,0xc0,0x8b,0xf0,0x8b,0xf8,0x2e,0x8b,0x9c,0x49,0x00,
0x83,0xc6,0x02,0x26,0x89,0x1d,0x26,0x8c,0x4d,0x02,0x83,0xc7,
0x04,0x81,0xff,0x80,0x00,0x72,0xe8,0x26,0xc7,0x05,0xcb,0x0c,
0x26,0x8c,0x4d,0x02,0x83,0xc7,0x04,0x81,0xff,0x00,0x04,0x72,
0xee,0xc3,0xc1,0xe0,0x06,0x8b,0xd8,0x8c,0xda,0x81,0xc2,0x00,
0x04,0x8b,0xfa,0x8a,0x0e,0x22,0x0c,0xb5,0x00,0xbe,0x00,0x10,
0x33,0xc0,0x89,0x44,0x0a,0x89,0x44,0x0c,0x89,0x44,0x12,0x89,
0x44,0x14,0x81,0xc6,0x80,0x00,0xe2,0xee,0x89,0x36,0x0a,0x0e,
0xb8,0x01,0x00,0x8b,0xd0,0xb3,0x00,0x8a,0x0e,0x22,0x0c,0xb5,
0x00,0xbe,0x00,0x10,0x2b,0xda,0x72,0x29,0x89,0x44,0x16,0x81,
0xc6,0x80,0x00,0xe2,0xf3,0x8a,0x0e,0x22,0x0c,0xb5,0x00,0xbe,
0x00,0x10,0x2b,0xda,0x72,0x13,0x89,0x44,0x0e,0x81,0xc6,0x80,
0x00,0xe2,0xf3,0x8b,0xd0,0x03,0xc0,0x81,0xfa,0x00,0x02,0x72,
0xca,0x8a,0x0e,0x22,0x0c,0xb5,0x00,0xbe,0x00,0x10,0x89,0x7c,
0x10,0x8b,0x44,0x16,0x03,0xf8,0x8b,0xd7,0xc1,0xe0,0x04,0x48,
0x89,0x44,0x16,0x81,0xc6,0x80,0x00,0xe2,0xe9,0x8a,0x0e,0x22,
0x0c,0xb5,0x00,0xbe,0x00,0x10,0x89,0x7c,0x08,0x8b,0x44,0x0e,
0x03,0xf8,0x8b,0xd7,0xc1,0xe0,0x04,0x48,0x89,0x44,0x0e,0x81,
0xc6,0x80,0x00,0xe2,0xe9,0xc3,0xc7,0x04,0x20,0x04,0xc7,0x44,
0x06,0xe1,0x08,0x8b,0xc6,0x2d,0x00,0x10,0xb1,0x80,0xf6,0xf1,
0x88,0x44,0x48,0xc7,0x44,0x0a,0x00,0x00,0xc7,0x44,0x0c,0x00,
0x00,0xc7,0x44,0x12,0x00,0x00,0xc7,0x44,0x14,0x00,0x00,0xc7,
0x44,0x18,0x00,0x00,0xc7,0x44,0x1a,0x00,0x00,0xc7,0x44,0x1c,
0xff,0xff,0x8a,0x5c,0x48,0x83,0xe3,0x0f,0x03,0xdb,0x8b,0x97,
0x90,0x0c,0x89,0x54,0x20,0xb8,0x01,0x00,0x8a,0x4c,0x48,0xd3,
0xe0,0x89,0x44,0x2e,0xc7,0x44,0x24,0x19,0x00,0xc7,0x44,0x26,
0x00,0x00,0xc6,0x44,0x4a,0x00,0xc7,0x44,0x30,0x00,0x00,0xc7,
0x44,0x32,0x00,0x00,0xc6,0x44,0x4c,0x00,0xc6,0x44,0x4d,0x00,
0xc6,0x44,0x4e,0x00,0xc6,0x44,0x4f,0x00,0xc6,0x44,0x50,0x00,
0xc6,0x44,0x4b,0x00,0xc6,0x44,0x51,0x00,0xc6,0x44,0x28,0x00,
0xc6,0x44,0x29,0x00,0xc6,0x44,0x2a,0x00,0xc6,0x44,0x2b,0x00,
0xc6,0x44,0x54,0x00,0xc6,0x44,0x57,0x00,0xc6,0x44,0x55,0x00,
0xc6,0x44,0x56,0x00,0xc6,0x44,0x58,0x00,0xc6,0x44,0x52,0x04,
0xc6,0x44,0x53,0x04,0xc6,0x44,0x5f,0x00,0xc6,0x44,0x2c,0x3d,
0xc6,0x44,0x2d,0x00,0xc7,0x44,0x34,0xff,0x60,0xc6,0x44,0x62,
0xff,0xc6,0x44,0x5d,0x13,0xc6,0x44,0x5c,0x11,0xc6,0x44,0x5e,
0x00,0xc6,0x44,0x60,0x23,0xc6,0x44,0x61,0x23,0x0b,0xd2,0x75,
0x03,0xe9,0xd9,0x00,0xb0,0x09,0xee,0x8a,0x4c,0x48,0xb0,0x80,
0xd2,0xe8,0xee,0xc6,0x44,0x70,0x00,0xb0,0x01,0xee,0xb0,0x11,
0x88,0x44,0x71,0xee,0xb0,0x02,0x90,0x90,0xee,0x8a,0x44,0x48,
0xc0,0xe0,0x03,0x24,0xf0,0x88,0x44,0x72,0xee,0xb0,0x03,0x90,
0x90,0xee,0xb0,0xc0,0x88,0x44,0x73,0xee,0xb0,0x04,0x90,0x90,
0xee,0xb0,0x44,0x88,0x44,0x74,0xee,0xb0,0x05,0x90,0xee,0xb0,
0x60,0x88,0x44,0x75,0xee,0xc6,0x44,0x76,0x00,0xc6,0x44,0x77,
0x00,0xc6,0x44,0x78,0x00,0xb0,0x09,0xee,0xb0,0x09,0x88,0x44,
0x79,0xee,0xc6,0x44,0x7a,0x00,0xb0,0x0b,0xee,0xb0,0x52,0x88,
0x44,0x7b,0xee,0x80,0x3e,0x10,0x0c,0x01,0x75,0x21,0xa1,0x0e,
0x0c,0x86,0xe0,0x3d,0x32,0x31,0x73,0x17,0xb0,0x0c,0xee,0xb0,
0x18,0x88,0x44,0x7c,0xee,0xb0,0x0d,0x90,0x90,0xee,0xb0,0x00,
0x88,0x44,0x7d,0xee,0xeb,0x15,0x90,0xb0,0x0c,0xee,0xb0,0x16,
0x88,0x44,0x7c,0xee,0xb0,0x0d,0x90,0x90,0xee,0xb0,0x00,0x88,
0x44,0x7d,0xee,0xb0,0x0e,0x90,0x90,0xee,0xb0,0x03,0x88,0x44,
0x7e,0xee,0xb0,0x0f,0x90,0x90,0xee,0xb0,0x80,0x88,0x44,0x7f,
0xee,0xb0,0x03,0x90,0x90,0xee,0x8a,0x44,0x73,0x0c,0x01,0x88,
0x44,0x73,0xee,0x90,0x90,0xb0,0x05,0xee,0x8a,0x44,0x75,0x0c,
0x08,0x88,0x44,0x75,0xee,0xc3,0xfa,0x8c,0xd8,0x25,0x00,0xf0,
0x8e,0xd0,0xbc,0xfe,0x1f,0x8c,0xd8,0x25,0x00,0xf0,0x8e,0xd8,
0x80,0x3e,0x40,0x0d,0x01,0x75,0x51,0xa1,0x0e,0x0c,0x86,0xe0,
0x3d,0x30,0x32,0x73,0x47,0x8b,0x1e,0x20,0x0c,0x8a,0x16,0x23,
0x0c,0xc6,0x06,0x23,0x0c,0x00,0x83,0xfb,0x00,0x74,0x07,0xfe,
0xca,0xc6,0x06,0x23,0x0c,0x01,0x88,0x16,0x22,0x0c,0xbe,0x10,
0x0c,0xbf,0x90,0x0c,0xb9,0x08,0x00,0x1e,0x07,0xfc,0xf3,0xa5,
0xbf,0xa0,0x0c,0xb8,0x00,0x00,0xb9,0x08,0x00,0xf3,0xab,0xc7,
0x06,0x1a,0x0c,0x70,0x00,0xa0,0x40,0x0d,0xa2,0x10,0x0c,0xc6,
0x06,0x11,0x0c,0x00,0x2e,0x8c,0x1e,0xc1,0x03,0xc7,0x06,0x18,
0x0e,0x02,0x00,0xe8,0xec,0xfc,0xc7,0x06,0x24,0x0d,0x5a,0x0d,
0x8c,0x0e,0x26,0x0d,0xc7,0x06,0x18,0x0e,0x06,0x00,0xa1,0x1a,
0x0c,0xe8,0x0a,0xfd,0xc7,0x06,0x18,0x0e,0x0a,0x00,0xbe,0x00,
0x10,0xc7,0x44,0x1e,0x80,0x00,0xe8,0xa5,0xfd,0x81,0xc6,0x80,
0x00,0x81,0xfe,0x00,0x18,0x72,0xee,0xa0,0x22,0x0c,0xb4,0x80,
0xf6,0xe4,0xbe,0x00,0x10,0x03,0xf0,0x89,0x36,0x0a,0x0e,0x29,
0x44,0x9e,0xc7,0x06,0x00,0x0e,0x00,0x00,0xc7,0x06,0x02,0x0e,
0x00,0x00,0xc7,0x06,0x04,0x0e,0x00,0x00,0xc7,0x06,0x06,0x0e,
0x9a,0x02,0xba,0x52,0xff,0xa1,0x06,0x0e,0xef,0xba,0x50,0xff,
0xb8,0x00,0x00,0xef,0xba,0x56,0xff,0xb8,0x05,0xe0,0xef,0xba,
0x5e,0xff,0xb8,0x00,0x40,0xef,0xba,0x66,0xff,0xb8,0x00,0x40,
0xef,0xc7,0x06,0x10,0x0d,0x00,0x00,0xc7,0x06,0x12,0x0d,0x00,
0x00,0xc7,0x06,0x14,0x0d,0x00,0x04,0xc7,0x06,0x16,0x0d,0xfc,
0x03,0xc7,0x06,0x18,0x0d,0x00,0x00,0xc7,0x06,0x1a,0x0d,0x00,
0x00,0xc7,0x06,0x1c,0x0d,0x00,0x08,0xc7,0x06,0x1e,0x0d,0xfc,
0x03,0xb0,0x00,0x90,0xe6,0x00,0xc7,0x06,0x18,0x0e,0x32,0x00,
0xba,0x38,0xff,0xb8,0x11,0x00,0xef,0xba,0x3a,0xff,0xb8,0x08,
0x00,0xef,0xba,0x3c,0xff,0xb8,0x08,0x00,0xef,0xba,0x3e,0xff,
0xb8,0x08,0x00,0x80,0x3e,0x22,0x0c,0x08,0x76,0x03,0xb8,0x12,
0x00,0xef,0xba,0x32,0xff,0xb8,0x05,0x00,0xef,0xba,0x28,0xff,
0xb8,0x6c,0x00,0xef,0xba,0x22,0xff,0xb8,0x00,0x80,0xef,0xc7,
0x06,0x18,0x0e,0x33,0x00,0xc7,0x06,0x20,0x0d,0x4f,0x00,0xc7,
0x06,0x21,0x0d,0x53,0x00,0x8b,0x36,0x0a,0x0e,0xc7,0x04,0x3c,
0x0d,0xc7,0x06,0x08,0x0e,0x00,0x10,0xe9,0x63,0xf6,0x40,0x28,
0x23,0x29,0x20,0x24,0x49,0x64,0x3a,0x20,0x78,0x61,0x63,0x6f,
0x6f,0x6b,0x2e,0x61,0x73,0x6d,0x2c,0x76,0x20,0x37,0x2e,0x32,
0x35,0x20,0x31,0x39,0x39,0x35,0x2f,0x30,0x31,0x2f,0x31,0x32,
0x20,0x32,0x30,0x3a,0x35,0x39,0x3a,0x32,0x31,0x20,0x6d,0x69,
0x6c,0x74,0x20,0x45,0x78,0x70,0x20,0x24,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
};

View File

@@ -0,0 +1,97 @@
#
# Drm device configuration
#
# This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
#
config DRM
bool "Direct Rendering Manager (XFree86 4.1.0 and higher DRI support)"
help
Kernel-level support for the Direct Rendering Infrastructure (DRI)
introduced in XFree86 4.0. If you say Y here, you need to select
the module that's right for your graphics card from the list below.
These modules provide support for synchronization, security, and
DMA transfers. Please see <http://dri.sourceforge.net/> for more
details. You should also select and configure AGP
(/dev/agpgart) support.
config DRM_TDFX
tristate "3dfx Banshee/Voodoo3+"
depends on DRM
help
Choose this option if you have a 3dfx Banshee or Voodoo3 (or later),
graphics card. If M is selected, the module will be called tdfx.
config DRM_GAMMA
tristate "3dlabs GMX 2000"
depends on DRM && BROKEN
help
This is the old gamma driver, please tell me if it might actually
work.
config DRM_R128
tristate "ATI Rage 128"
depends on DRM && PCI
help
Choose this option if you have an ATI Rage 128 graphics card. If M
is selected, the module will be called r128. AGP support for
this card is strongly suggested (unless you have a PCI version).
config DRM_RADEON
tristate "ATI Radeon"
depends on DRM && PCI
help
Choose this option if you have an ATI Radeon graphics card. There
are both PCI and AGP versions. You don't need to choose this to
run the Radeon in plain VGA mode. There is a product page at
<http://www.ati.com/na/pages/products/pc/radeon32/index.html>.
If M is selected, the module will be called radeon.
config DRM_I810
tristate "Intel I810"
depends on DRM && AGP && AGP_INTEL
help
Choose this option if you have an Intel I810 graphics card. If M is
selected, the module will be called i810. AGP support is required
for this driver to work.
choice
prompt "Intel 830M, 845G, 852GM, 855GM, 865G"
depends on DRM && AGP && AGP_INTEL
optional
config DRM_I830
tristate "i830 driver"
help
Choose this option if you have a system that has Intel 830M, 845G,
852GM, 855GM or 865G integrated graphics. If M is selected, the
module will be called i830. AGP support is required for this driver
to work. This driver will eventually be replaced by the i915 one.
config DRM_I915
tristate "i915 driver"
help
Choose this option if you have a system that has Intel 830M, 845G,
852GM, 855GM 865G or 915G integrated graphics. If M is selected, the
module will be called i915. AGP support is required for this driver
to work. This driver will eventually replace the I830 driver, when
later release of X start to use the new DDX and DRI.
endchoice
config DRM_MGA
tristate "Matrox g200/g400"
depends on DRM && AGP && (!X86_64 || BROKEN)
help
Choose this option if you have a Matrox G200, G400 or G450 graphics
card. If M is selected, the module will be called mga. AGP
support is required for this driver to work.
config DRM_SIS
tristate "SiS video cards"
depends on DRM && AGP
help
Choose this option if you have a SiS 630 or compatible video
chipset. If M is selected the module will be called sis. AGP
support is required for this driver to work.

View File

@@ -0,0 +1,26 @@
#
# Makefile for the drm device driver. This driver provides support for the
# Direct Rendering Infrastructure (DRI) in XFree86 4.1.0 and higher.
gamma-objs := gamma_drv.o gamma_dma.o
tdfx-objs := tdfx_drv.o
r128-objs := r128_drv.o r128_cce.o r128_state.o r128_irq.o
mga-objs := mga_drv.o mga_dma.o mga_state.o mga_warp.o mga_irq.o
i810-objs := i810_drv.o i810_dma.o
i830-objs := i830_drv.o i830_dma.o i830_irq.o
i915-objs := i915_drv.o i915_dma.o i915_irq.o i915_mem.o
radeon-objs := radeon_drv.o radeon_cp.o radeon_state.o radeon_mem.o radeon_irq.o
ffb-objs := ffb_drv.o ffb_context.o
sis-objs := sis_drv.o sis_ds.o sis_mm.o
obj-$(CONFIG_DRM_GAMMA) += gamma.o
obj-$(CONFIG_DRM_TDFX) += tdfx.o
obj-$(CONFIG_DRM_R128) += r128.o
obj-$(CONFIG_DRM_RADEON)+= radeon.o
obj-$(CONFIG_DRM_MGA) += mga.o
obj-$(CONFIG_DRM_I810) += i810.o
obj-$(CONFIG_DRM_I830) += i830.o
obj-$(CONFIG_DRM_I915) += i915.o
obj-$(CONFIG_DRM_FFB) += ffb.o
obj-$(CONFIG_DRM_SIS) += sis.o

View File

@@ -0,0 +1,46 @@
************************************************************
* For the very latest on DRI development, please see: *
* http://dri.sourceforge.net/ *
************************************************************
The Direct Rendering Manager (drm) is a device-independent kernel-level
device driver that provides support for the XFree86 Direct Rendering
Infrastructure (DRI).
The DRM supports the Direct Rendering Infrastructure (DRI) in four major
ways:
1. The DRM provides synchronized access to the graphics hardware via
the use of an optimized two-tiered lock.
2. The DRM enforces the DRI security policy for access to the graphics
hardware by only allowing authenticated X11 clients access to
restricted regions of memory.
3. The DRM provides a generic DMA engine, complete with multiple
queues and the ability to detect the need for an OpenGL context
switch.
4. The DRM is extensible via the use of small device-specific modules
that rely extensively on the API exported by the DRM module.
Documentation on the DRI is available from:
http://precisioninsight.com/piinsights.html
For specific information about kernel-level support, see:
The Direct Rendering Manager, Kernel Support for the Direct Rendering
Infrastructure
http://precisioninsight.com/dr/drm.html
Hardware Locking for the Direct Rendering Infrastructure
http://precisioninsight.com/dr/locking.html
A Security Analysis of the Direct Rendering Infrastructure
http://precisioninsight.com/dr/security.html
************************************************************
* For the very latest on DRI development, please see: *
* http://dri.sourceforge.net/ *
************************************************************

View File

@@ -0,0 +1,206 @@
/**
* \file ati_pcigart.h
* ATI PCI GART support
*
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Wed Dec 13 21:52:19 2000 by gareth@valinux.com
*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
#if PAGE_SIZE == 65536
# define ATI_PCIGART_TABLE_ORDER 0
# define ATI_PCIGART_TABLE_PAGES (1 << 0)
#elif PAGE_SIZE == 16384
# define ATI_PCIGART_TABLE_ORDER 1
# define ATI_PCIGART_TABLE_PAGES (1 << 1)
#elif PAGE_SIZE == 8192
# define ATI_PCIGART_TABLE_ORDER 2
# define ATI_PCIGART_TABLE_PAGES (1 << 2)
#elif PAGE_SIZE == 4096
# define ATI_PCIGART_TABLE_ORDER 3
# define ATI_PCIGART_TABLE_PAGES (1 << 3)
#else
# error - PAGE_SIZE not 64K, 16K, 8K or 4K
#endif
# define ATI_MAX_PCIGART_PAGES 8192 /**< 32 MB aperture, 4K pages */
# define ATI_PCIGART_PAGE_SIZE 4096 /**< PCI GART page size */
static unsigned long DRM(ati_alloc_pcigart_table)( void )
{
unsigned long address;
struct page *page;
int i;
DRM_DEBUG( "%s\n", __FUNCTION__ );
address = __get_free_pages( GFP_KERNEL, ATI_PCIGART_TABLE_ORDER );
if ( address == 0UL ) {
return 0;
}
page = virt_to_page( address );
for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
get_page(page);
SetPageReserved( page );
}
DRM_DEBUG( "%s: returning 0x%08lx\n", __FUNCTION__, address );
return address;
}
static void DRM(ati_free_pcigart_table)( unsigned long address )
{
struct page *page;
int i;
DRM_DEBUG( "%s\n", __FUNCTION__ );
page = virt_to_page( address );
for ( i = 0 ; i < ATI_PCIGART_TABLE_PAGES ; i++, page++ ) {
__put_page(page);
ClearPageReserved( page );
}
free_pages( address, ATI_PCIGART_TABLE_ORDER );
}
int DRM(ati_pcigart_init)( drm_device_t *dev,
unsigned long *addr,
dma_addr_t *bus_addr)
{
drm_sg_mem_t *entry = dev->sg;
unsigned long address = 0;
unsigned long pages;
u32 *pci_gart, page_base, bus_address = 0;
int i, j, ret = 0;
if ( !entry ) {
DRM_ERROR( "no scatter/gather memory!\n" );
goto done;
}
address = DRM(ati_alloc_pcigart_table)();
if ( !address ) {
DRM_ERROR( "cannot allocate PCI GART page!\n" );
goto done;
}
if ( !dev->pdev ) {
DRM_ERROR( "PCI device unknown!\n" );
goto done;
}
bus_address = pci_map_single(dev->pdev, (void *)address,
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
PCI_DMA_TODEVICE);
if (bus_address == 0) {
DRM_ERROR( "unable to map PCIGART pages!\n" );
DRM(ati_free_pcigart_table)( address );
address = 0;
goto done;
}
pci_gart = (u32 *)address;
pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
? entry->pages : ATI_MAX_PCIGART_PAGES;
memset( pci_gart, 0, ATI_MAX_PCIGART_PAGES * sizeof(u32) );
for ( i = 0 ; i < pages ; i++ ) {
/* we need to support large memory configurations */
entry->busaddr[i] = pci_map_single(dev->pdev,
page_address( entry->pagelist[i] ),
PAGE_SIZE,
PCI_DMA_TODEVICE);
if (entry->busaddr[i] == 0) {
DRM_ERROR( "unable to map PCIGART pages!\n" );
DRM(ati_pcigart_cleanup)( dev, address, bus_address );
address = 0;
bus_address = 0;
goto done;
}
page_base = (u32) entry->busaddr[i];
for (j = 0; j < (PAGE_SIZE / ATI_PCIGART_PAGE_SIZE); j++) {
*pci_gart++ = cpu_to_le32( page_base );
page_base += ATI_PCIGART_PAGE_SIZE;
}
}
ret = 1;
#if defined(__i386__) || defined(__x86_64__)
asm volatile ( "wbinvd" ::: "memory" );
#else
mb();
#endif
done:
*addr = address;
*bus_addr = bus_address;
return ret;
}
int DRM(ati_pcigart_cleanup)( drm_device_t *dev,
unsigned long addr,
dma_addr_t bus_addr)
{
drm_sg_mem_t *entry = dev->sg;
unsigned long pages;
int i;
/* we need to support large memory configurations */
if ( !entry ) {
DRM_ERROR( "no scatter/gather memory!\n" );
return 0;
}
if ( bus_addr ) {
pci_unmap_single(dev->pdev, bus_addr,
ATI_PCIGART_TABLE_PAGES * PAGE_SIZE,
PCI_DMA_TODEVICE);
pages = ( entry->pages <= ATI_MAX_PCIGART_PAGES )
? entry->pages : ATI_MAX_PCIGART_PAGES;
for ( i = 0 ; i < pages ; i++ ) {
if ( !entry->busaddr[i] ) break;
pci_unmap_single(dev->pdev, entry->busaddr[i],
PAGE_SIZE, PCI_DMA_TODEVICE);
}
}
if ( addr ) {
DRM(ati_free_pcigart_table)( addr );
}
return 1;
}

View File

@@ -0,0 +1,675 @@
/**
* \file drm.h
* Header for the Direct Rendering Manager
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
*
* \par Acknowledgments:
* Dec 1999, Richard Henderson <rth@twiddle.net>, move to generic \c cmpxchg.
*/
/*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _DRM_H_
#define _DRM_H_
#if defined(__linux__)
#include <linux/config.h>
#include <asm/ioctl.h> /* For _IO* macros */
#define DRM_IOCTL_NR(n) _IOC_NR(n)
#define DRM_IOC_VOID _IOC_NONE
#define DRM_IOC_READ _IOC_READ
#define DRM_IOC_WRITE _IOC_WRITE
#define DRM_IOC_READWRITE _IOC_READ|_IOC_WRITE
#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
#elif defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#if defined(__FreeBSD__) && defined(IN_MODULE)
/* Prevent name collision when including sys/ioccom.h */
#undef ioctl
#include <sys/ioccom.h>
#define ioctl(a,b,c) xf86ioctl(a,b,c)
#else
#include <sys/ioccom.h>
#endif /* __FreeBSD__ && xf86ioctl */
#define DRM_IOCTL_NR(n) ((n) & 0xff)
#define DRM_IOC_VOID IOC_VOID
#define DRM_IOC_READ IOC_OUT
#define DRM_IOC_WRITE IOC_IN
#define DRM_IOC_READWRITE IOC_INOUT
#define DRM_IOC(dir, group, nr, size) _IOC(dir, group, nr, size)
#endif
#define XFREE86_VERSION(major,minor,patch,snap) \
((major << 16) | (minor << 8) | patch)
#ifndef CONFIG_XFREE86_VERSION
#define CONFIG_XFREE86_VERSION XFREE86_VERSION(4,1,0,0)
#endif
#if CONFIG_XFREE86_VERSION < XFREE86_VERSION(4,1,0,0)
#define DRM_PROC_DEVICES "/proc/devices"
#define DRM_PROC_MISC "/proc/misc"
#define DRM_PROC_DRM "/proc/drm"
#define DRM_DEV_DRM "/dev/drm"
#define DRM_DEV_MODE (S_IRUSR|S_IWUSR|S_IRGRP|S_IWGRP)
#define DRM_DEV_UID 0
#define DRM_DEV_GID 0
#endif
#if CONFIG_XFREE86_VERSION >= XFREE86_VERSION(4,1,0,0)
#define DRM_MAJOR 226
#define DRM_MAX_MINOR 15
#endif
#define DRM_NAME "drm" /**< Name in kernel, /dev, and /proc */
#define DRM_MIN_ORDER 5 /**< At least 2^5 bytes = 32 bytes */
#define DRM_MAX_ORDER 22 /**< Up to 2^22 bytes = 4MB */
#define DRM_RAM_PERCENT 10 /**< How much system ram can we lock? */
#define _DRM_LOCK_HELD 0x80000000 /**< Hardware lock is held */
#define _DRM_LOCK_CONT 0x40000000 /**< Hardware lock is contended */
#define _DRM_LOCK_IS_HELD(lock) ((lock) & _DRM_LOCK_HELD)
#define _DRM_LOCK_IS_CONT(lock) ((lock) & _DRM_LOCK_CONT)
#define _DRM_LOCKING_CONTEXT(lock) ((lock) & ~(_DRM_LOCK_HELD|_DRM_LOCK_CONT))
typedef unsigned long drm_handle_t;
typedef unsigned int drm_context_t;
typedef unsigned int drm_drawable_t;
typedef unsigned int drm_magic_t;
/**
* Cliprect.
*
* \warning: If you change this structure, make sure you change
* XF86DRIClipRectRec in the server as well
*
* \note KW: Actually it's illegal to change either for
* backwards-compatibility reasons.
*/
typedef struct drm_clip_rect {
unsigned short x1;
unsigned short y1;
unsigned short x2;
unsigned short y2;
} drm_clip_rect_t;
/**
* Texture region,
*/
typedef struct drm_tex_region {
unsigned char next;
unsigned char prev;
unsigned char in_use;
unsigned char padding;
unsigned int age;
} drm_tex_region_t;
/**
* Hardware lock.
*
* The lock structure is a simple cache-line aligned integer. To avoid
* processor bus contention on a multiprocessor system, there should not be any
* other data stored in the same cache line.
*/
typedef struct drm_hw_lock {
__volatile__ unsigned int lock; /**< lock variable */
char padding[60]; /**< Pad to cache line */
} drm_hw_lock_t;
/**
* DRM_IOCTL_VERSION ioctl argument type.
*
* \sa drmGetVersion().
*/
typedef struct drm_version {
int version_major; /**< Major version */
int version_minor; /**< Minor version */
int version_patchlevel;/**< Patch level */
size_t name_len; /**< Length of name buffer */
char __user *name; /**< Name of driver */
size_t date_len; /**< Length of date buffer */
char __user *date; /**< User-space buffer to hold date */
size_t desc_len; /**< Length of desc buffer */
char __user *desc; /**< User-space buffer to hold desc */
} drm_version_t;
/**
* DRM_IOCTL_GET_UNIQUE ioctl argument type.
*
* \sa drmGetBusid() and drmSetBusId().
*/
typedef struct drm_unique {
size_t unique_len; /**< Length of unique */
char __user *unique; /**< Unique name for driver instantiation */
} drm_unique_t;
typedef struct drm_list {
int count; /**< Length of user-space structures */
drm_version_t __user *version;
} drm_list_t;
typedef struct drm_block {
int unused;
} drm_block_t;
/**
* DRM_IOCTL_CONTROL ioctl argument type.
*
* \sa drmCtlInstHandler() and drmCtlUninstHandler().
*/
typedef struct drm_control {
enum {
DRM_ADD_COMMAND,
DRM_RM_COMMAND,
DRM_INST_HANDLER,
DRM_UNINST_HANDLER
} func;
int irq;
} drm_control_t;
/**
* Type of memory to map.
*/
typedef enum drm_map_type {
_DRM_FRAME_BUFFER = 0, /**< WC (no caching), no core dump */
_DRM_REGISTERS = 1, /**< no caching, no core dump */
_DRM_SHM = 2, /**< shared, cached */
_DRM_AGP = 3, /**< AGP/GART */
_DRM_SCATTER_GATHER = 4 /**< Scatter/gather memory for PCI DMA */
} drm_map_type_t;
/**
* Memory mapping flags.
*/
typedef enum drm_map_flags {
_DRM_RESTRICTED = 0x01, /**< Cannot be mapped to user-virtual */
_DRM_READ_ONLY = 0x02,
_DRM_LOCKED = 0x04, /**< shared, cached, locked */
_DRM_KERNEL = 0x08, /**< kernel requires access */
_DRM_WRITE_COMBINING = 0x10, /**< use write-combining if available */
_DRM_CONTAINS_LOCK = 0x20, /**< SHM page that contains lock */
_DRM_REMOVABLE = 0x40 /**< Removable mapping */
} drm_map_flags_t;
typedef struct drm_ctx_priv_map {
unsigned int ctx_id; /**< Context requesting private mapping */
void *handle; /**< Handle of map */
} drm_ctx_priv_map_t;
/**
* DRM_IOCTL_GET_MAP, DRM_IOCTL_ADD_MAP and DRM_IOCTL_RM_MAP ioctls
* argument type.
*
* \sa drmAddMap().
*/
typedef struct drm_map {
unsigned long offset; /**< Requested physical address (0 for SAREA)*/
unsigned long size; /**< Requested physical size (bytes) */
drm_map_type_t type; /**< Type of memory to map */
drm_map_flags_t flags; /**< Flags */
void *handle; /**< User-space: "Handle" to pass to mmap() */
/**< Kernel-space: kernel-virtual address */
int mtrr; /**< MTRR slot used */
/* Private data */
} drm_map_t;
/**
* DRM_IOCTL_GET_CLIENT ioctl argument type.
*/
typedef struct drm_client {
int idx; /**< Which client desired? */
int auth; /**< Is client authenticated? */
unsigned long pid; /**< Process ID */
unsigned long uid; /**< User ID */
unsigned long magic; /**< Magic */
unsigned long iocs; /**< Ioctl count */
} drm_client_t;
typedef enum {
_DRM_STAT_LOCK,
_DRM_STAT_OPENS,
_DRM_STAT_CLOSES,
_DRM_STAT_IOCTLS,
_DRM_STAT_LOCKS,
_DRM_STAT_UNLOCKS,
_DRM_STAT_VALUE, /**< Generic value */
_DRM_STAT_BYTE, /**< Generic byte counter (1024bytes/K) */
_DRM_STAT_COUNT, /**< Generic non-byte counter (1000/k) */
_DRM_STAT_IRQ, /**< IRQ */
_DRM_STAT_PRIMARY, /**< Primary DMA bytes */
_DRM_STAT_SECONDARY, /**< Secondary DMA bytes */
_DRM_STAT_DMA, /**< DMA */
_DRM_STAT_SPECIAL, /**< Special DMA (e.g., priority or polled) */
_DRM_STAT_MISSED /**< Missed DMA opportunity */
/* Add to the *END* of the list */
} drm_stat_type_t;
/**
* DRM_IOCTL_GET_STATS ioctl argument type.
*/
typedef struct drm_stats {
unsigned long count;
struct {
unsigned long value;
drm_stat_type_t type;
} data[15];
} drm_stats_t;
/**
* Hardware locking flags.
*/
typedef enum drm_lock_flags {
_DRM_LOCK_READY = 0x01, /**< Wait until hardware is ready for DMA */
_DRM_LOCK_QUIESCENT = 0x02, /**< Wait until hardware quiescent */
_DRM_LOCK_FLUSH = 0x04, /**< Flush this context's DMA queue first */
_DRM_LOCK_FLUSH_ALL = 0x08, /**< Flush all DMA queues first */
/* These *HALT* flags aren't supported yet
-- they will be used to support the
full-screen DGA-like mode. */
_DRM_HALT_ALL_QUEUES = 0x10, /**< Halt all current and future queues */
_DRM_HALT_CUR_QUEUES = 0x20 /**< Halt all current queues */
} drm_lock_flags_t;
/**
* DRM_IOCTL_LOCK, DRM_IOCTL_UNLOCK and DRM_IOCTL_FINISH ioctl argument type.
*
* \sa drmGetLock() and drmUnlock().
*/
typedef struct drm_lock {
int context;
drm_lock_flags_t flags;
} drm_lock_t;
/**
* DMA flags
*
* \warning
* These values \e must match xf86drm.h.
*
* \sa drm_dma.
*/
typedef enum drm_dma_flags {
/* Flags for DMA buffer dispatch */
_DRM_DMA_BLOCK = 0x01, /**<
* Block until buffer dispatched.
*
* \note The buffer may not yet have
* been processed by the hardware --
* getting a hardware lock with the
* hardware quiescent will ensure
* that the buffer has been
* processed.
*/
_DRM_DMA_WHILE_LOCKED = 0x02, /**< Dispatch while lock held */
_DRM_DMA_PRIORITY = 0x04, /**< High priority dispatch */
/* Flags for DMA buffer request */
_DRM_DMA_WAIT = 0x10, /**< Wait for free buffers */
_DRM_DMA_SMALLER_OK = 0x20, /**< Smaller-than-requested buffers OK */
_DRM_DMA_LARGER_OK = 0x40 /**< Larger-than-requested buffers OK */
} drm_dma_flags_t;
/**
* DRM_IOCTL_ADD_BUFS and DRM_IOCTL_MARK_BUFS ioctl argument type.
*
* \sa drmAddBufs().
*/
typedef struct drm_buf_desc {
int count; /**< Number of buffers of this size */
int size; /**< Size in bytes */
int low_mark; /**< Low water mark */
int high_mark; /**< High water mark */
enum {
_DRM_PAGE_ALIGN = 0x01, /**< Align on page boundaries for DMA */
_DRM_AGP_BUFFER = 0x02, /**< Buffer is in AGP space */
_DRM_SG_BUFFER = 0x04 /**< Scatter/gather memory buffer */
} flags;
unsigned long agp_start; /**<
* Start address of where the AGP buffers are
* in the AGP aperture
*/
} drm_buf_desc_t;
/**
* DRM_IOCTL_INFO_BUFS ioctl argument type.
*/
typedef struct drm_buf_info {
int count; /**< Entries in list */
drm_buf_desc_t __user *list;
} drm_buf_info_t;
/**
* DRM_IOCTL_FREE_BUFS ioctl argument type.
*/
typedef struct drm_buf_free {
int count;
int __user *list;
} drm_buf_free_t;
/**
* Buffer information
*
* \sa drm_buf_map.
*/
typedef struct drm_buf_pub {
int idx; /**< Index into the master buffer list */
int total; /**< Buffer size */
int used; /**< Amount of buffer in use (for DMA) */
void __user *address; /**< Address of buffer */
} drm_buf_pub_t;
/**
* DRM_IOCTL_MAP_BUFS ioctl argument type.
*/
typedef struct drm_buf_map {
int count; /**< Length of the buffer list */
void __user *virtual; /**< Mmap'd area in user-virtual */
drm_buf_pub_t __user *list; /**< Buffer information */
} drm_buf_map_t;
/**
* DRM_IOCTL_DMA ioctl argument type.
*
* Indices here refer to the offset into the buffer list in drm_buf_get.
*
* \sa drmDMA().
*/
typedef struct drm_dma {
int context; /**< Context handle */
int send_count; /**< Number of buffers to send */
int __user *send_indices; /**< List of handles to buffers */
int __user *send_sizes; /**< Lengths of data to send */
drm_dma_flags_t flags; /**< Flags */
int request_count; /**< Number of buffers requested */
int request_size; /**< Desired size for buffers */
int __user *request_indices; /**< Buffer information */
int __user *request_sizes;
int granted_count; /**< Number of buffers granted */
} drm_dma_t;
typedef enum {
_DRM_CONTEXT_PRESERVED = 0x01,
_DRM_CONTEXT_2DONLY = 0x02
} drm_ctx_flags_t;
/**
* DRM_IOCTL_ADD_CTX ioctl argument type.
*
* \sa drmCreateContext() and drmDestroyContext().
*/
typedef struct drm_ctx {
drm_context_t handle;
drm_ctx_flags_t flags;
} drm_ctx_t;
/**
* DRM_IOCTL_RES_CTX ioctl argument type.
*/
typedef struct drm_ctx_res {
int count;
drm_ctx_t __user *contexts;
} drm_ctx_res_t;
/**
* DRM_IOCTL_ADD_DRAW and DRM_IOCTL_RM_DRAW ioctl argument type.
*/
typedef struct drm_draw {
drm_drawable_t handle;
} drm_draw_t;
/**
* DRM_IOCTL_GET_MAGIC and DRM_IOCTL_AUTH_MAGIC ioctl argument type.
*/
typedef struct drm_auth {
drm_magic_t magic;
} drm_auth_t;
/**
* DRM_IOCTL_IRQ_BUSID ioctl argument type.
*
* \sa drmGetInterruptFromBusID().
*/
typedef struct drm_irq_busid {
int irq; /**< IRQ number */
int busnum; /**< bus number */
int devnum; /**< device number */
int funcnum; /**< function number */
} drm_irq_busid_t;
typedef enum {
_DRM_VBLANK_ABSOLUTE = 0x0, /**< Wait for specific vblank sequence number */
_DRM_VBLANK_RELATIVE = 0x1, /**< Wait for given number of vblanks */
_DRM_VBLANK_SIGNAL = 0x40000000 /**< Send signal instead of blocking */
} drm_vblank_seq_type_t;
#define _DRM_VBLANK_FLAGS_MASK _DRM_VBLANK_SIGNAL
struct drm_wait_vblank_request {
drm_vblank_seq_type_t type;
unsigned int sequence;
unsigned long signal;
};
struct drm_wait_vblank_reply {
drm_vblank_seq_type_t type;
unsigned int sequence;
long tval_sec;
long tval_usec;
};
/**
* DRM_IOCTL_WAIT_VBLANK ioctl argument type.
*
* \sa drmWaitVBlank().
*/
typedef union drm_wait_vblank {
struct drm_wait_vblank_request request;
struct drm_wait_vblank_reply reply;
} drm_wait_vblank_t;
/**
* DRM_IOCTL_AGP_ENABLE ioctl argument type.
*
* \sa drmAgpEnable().
*/
typedef struct drm_agp_mode {
unsigned long mode; /**< AGP mode */
} drm_agp_mode_t;
/**
* DRM_IOCTL_AGP_ALLOC and DRM_IOCTL_AGP_FREE ioctls argument type.
*
* \sa drmAgpAlloc() and drmAgpFree().
*/
typedef struct drm_agp_buffer {
unsigned long size; /**< In bytes -- will round to page boundary */
unsigned long handle; /**< Used for binding / unbinding */
unsigned long type; /**< Type of memory to allocate */
unsigned long physical; /**< Physical used by i810 */
} drm_agp_buffer_t;
/**
* DRM_IOCTL_AGP_BIND and DRM_IOCTL_AGP_UNBIND ioctls argument type.
*
* \sa drmAgpBind() and drmAgpUnbind().
*/
typedef struct drm_agp_binding {
unsigned long handle; /**< From drm_agp_buffer */
unsigned long offset; /**< In bytes -- will round to page boundary */
} drm_agp_binding_t;
/**
* DRM_IOCTL_AGP_INFO ioctl argument type.
*
* \sa drmAgpVersionMajor(), drmAgpVersionMinor(), drmAgpGetMode(),
* drmAgpBase(), drmAgpSize(), drmAgpMemoryUsed(), drmAgpMemoryAvail(),
* drmAgpVendorId() and drmAgpDeviceId().
*/
typedef struct drm_agp_info {
int agp_version_major;
int agp_version_minor;
unsigned long mode;
unsigned long aperture_base; /* physical address */
unsigned long aperture_size; /* bytes */
unsigned long memory_allowed; /* bytes */
unsigned long memory_used;
/* PCI information */
unsigned short id_vendor;
unsigned short id_device;
} drm_agp_info_t;
/**
* DRM_IOCTL_SG_ALLOC ioctl argument type.
*/
typedef struct drm_scatter_gather {
unsigned long size; /**< In bytes -- will round to page boundary */
unsigned long handle; /**< Used for mapping / unmapping */
} drm_scatter_gather_t;
/**
* DRM_IOCTL_SET_VERSION ioctl argument type.
*/
typedef struct drm_set_version {
int drm_di_major;
int drm_di_minor;
int drm_dd_major;
int drm_dd_minor;
} drm_set_version_t;
#define DRM_IOCTL_BASE 'd'
#define DRM_IO(nr) _IO(DRM_IOCTL_BASE,nr)
#define DRM_IOR(nr,type) _IOR(DRM_IOCTL_BASE,nr,type)
#define DRM_IOW(nr,type) _IOW(DRM_IOCTL_BASE,nr,type)
#define DRM_IOWR(nr,type) _IOWR(DRM_IOCTL_BASE,nr,type)
#define DRM_IOCTL_VERSION DRM_IOWR(0x00, drm_version_t)
#define DRM_IOCTL_GET_UNIQUE DRM_IOWR(0x01, drm_unique_t)
#define DRM_IOCTL_GET_MAGIC DRM_IOR( 0x02, drm_auth_t)
#define DRM_IOCTL_IRQ_BUSID DRM_IOWR(0x03, drm_irq_busid_t)
#define DRM_IOCTL_GET_MAP DRM_IOWR(0x04, drm_map_t)
#define DRM_IOCTL_GET_CLIENT DRM_IOWR(0x05, drm_client_t)
#define DRM_IOCTL_GET_STATS DRM_IOR( 0x06, drm_stats_t)
#define DRM_IOCTL_SET_VERSION DRM_IOWR(0x07, drm_set_version_t)
#define DRM_IOCTL_SET_UNIQUE DRM_IOW( 0x10, drm_unique_t)
#define DRM_IOCTL_AUTH_MAGIC DRM_IOW( 0x11, drm_auth_t)
#define DRM_IOCTL_BLOCK DRM_IOWR(0x12, drm_block_t)
#define DRM_IOCTL_UNBLOCK DRM_IOWR(0x13, drm_block_t)
#define DRM_IOCTL_CONTROL DRM_IOW( 0x14, drm_control_t)
#define DRM_IOCTL_ADD_MAP DRM_IOWR(0x15, drm_map_t)
#define DRM_IOCTL_ADD_BUFS DRM_IOWR(0x16, drm_buf_desc_t)
#define DRM_IOCTL_MARK_BUFS DRM_IOW( 0x17, drm_buf_desc_t)
#define DRM_IOCTL_INFO_BUFS DRM_IOWR(0x18, drm_buf_info_t)
#define DRM_IOCTL_MAP_BUFS DRM_IOWR(0x19, drm_buf_map_t)
#define DRM_IOCTL_FREE_BUFS DRM_IOW( 0x1a, drm_buf_free_t)
#define DRM_IOCTL_RM_MAP DRM_IOW( 0x1b, drm_map_t)
#define DRM_IOCTL_SET_SAREA_CTX DRM_IOW( 0x1c, drm_ctx_priv_map_t)
#define DRM_IOCTL_GET_SAREA_CTX DRM_IOWR(0x1d, drm_ctx_priv_map_t)
#define DRM_IOCTL_ADD_CTX DRM_IOWR(0x20, drm_ctx_t)
#define DRM_IOCTL_RM_CTX DRM_IOWR(0x21, drm_ctx_t)
#define DRM_IOCTL_MOD_CTX DRM_IOW( 0x22, drm_ctx_t)
#define DRM_IOCTL_GET_CTX DRM_IOWR(0x23, drm_ctx_t)
#define DRM_IOCTL_SWITCH_CTX DRM_IOW( 0x24, drm_ctx_t)
#define DRM_IOCTL_NEW_CTX DRM_IOW( 0x25, drm_ctx_t)
#define DRM_IOCTL_RES_CTX DRM_IOWR(0x26, drm_ctx_res_t)
#define DRM_IOCTL_ADD_DRAW DRM_IOWR(0x27, drm_draw_t)
#define DRM_IOCTL_RM_DRAW DRM_IOWR(0x28, drm_draw_t)
#define DRM_IOCTL_DMA DRM_IOWR(0x29, drm_dma_t)
#define DRM_IOCTL_LOCK DRM_IOW( 0x2a, drm_lock_t)
#define DRM_IOCTL_UNLOCK DRM_IOW( 0x2b, drm_lock_t)
#define DRM_IOCTL_FINISH DRM_IOW( 0x2c, drm_lock_t)
#define DRM_IOCTL_AGP_ACQUIRE DRM_IO( 0x30)
#define DRM_IOCTL_AGP_RELEASE DRM_IO( 0x31)
#define DRM_IOCTL_AGP_ENABLE DRM_IOW( 0x32, drm_agp_mode_t)
#define DRM_IOCTL_AGP_INFO DRM_IOR( 0x33, drm_agp_info_t)
#define DRM_IOCTL_AGP_ALLOC DRM_IOWR(0x34, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_FREE DRM_IOW( 0x35, drm_agp_buffer_t)
#define DRM_IOCTL_AGP_BIND DRM_IOW( 0x36, drm_agp_binding_t)
#define DRM_IOCTL_AGP_UNBIND DRM_IOW( 0x37, drm_agp_binding_t)
#define DRM_IOCTL_SG_ALLOC DRM_IOW( 0x38, drm_scatter_gather_t)
#define DRM_IOCTL_SG_FREE DRM_IOW( 0x39, drm_scatter_gather_t)
#define DRM_IOCTL_WAIT_VBLANK DRM_IOWR(0x3a, drm_wait_vblank_t)
/**
* Device specific ioctls should only be in their respective headers
* The device specific ioctl range is from 0x40 to 0x79.
*
* \sa drmCommandNone(), drmCommandRead(), drmCommandWrite(), and
* drmCommandReadWrite().
*/
#define DRM_COMMAND_BASE 0x40
#endif

View File

@@ -0,0 +1,993 @@
/**
* \file drmP.h
* Private header for Direct Rendering Manager
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All rights reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _DRM_P_H_
#define _DRM_P_H_
#ifdef __KERNEL__
#ifdef __alpha__
/* add include of current.h so that "current" is defined
* before static inline funcs in wait.h. Doing this so we
* can build the DRM (part of PI DRI). 4/21/2000 S + B */
#include <asm/current.h>
#endif /* __alpha__ */
#include <linux/config.h>
#include <linux/module.h>
#include <linux/kernel.h>
#include <linux/miscdevice.h>
#include <linux/fs.h>
#include <linux/proc_fs.h>
#include <linux/init.h>
#include <linux/file.h>
#include <linux/pci.h>
#include <linux/version.h>
#include <linux/jiffies.h>
#include <linux/smp_lock.h> /* For (un)lock_kernel */
#include <linux/mm.h>
#if defined(__alpha__) || defined(__powerpc__)
#include <asm/pgtable.h> /* For pte_wrprotect */
#endif
#include <asm/io.h>
#include <asm/mman.h>
#include <asm/uaccess.h>
#ifdef CONFIG_MTRR
#include <asm/mtrr.h>
#endif
#if defined(CONFIG_AGP) || defined(CONFIG_AGP_MODULE)
#include <linux/types.h>
#include <linux/agp_backend.h>
#endif
#include <linux/workqueue.h>
#include <linux/poll.h>
#include <asm/pgalloc.h>
#include "drm.h"
#define __OS_HAS_AGP (defined(CONFIG_AGP) || (defined(CONFIG_AGP_MODULE) && defined(MODULE)))
#define __OS_HAS_MTRR (defined(CONFIG_MTRR))
#include "drm_os_linux.h"
/***********************************************************************/
/** \name DRM template customization defaults */
/*@{*/
/* driver capabilities and requirements mask */
#define DRIVER_USE_AGP 0x1
#define DRIVER_REQUIRE_AGP 0x2
#define DRIVER_USE_MTRR 0x4
#define DRIVER_PCI_DMA 0x8
#define DRIVER_SG 0x10
#define DRIVER_HAVE_DMA 0x20
#define DRIVER_HAVE_IRQ 0x40
#define DRIVER_IRQ_SHARED 0x80
#define DRIVER_IRQ_VBL 0x100
#define DRIVER_DMA_QUEUE 0x200
/***********************************************************************/
/** \name Begin the DRM... */
/*@{*/
#define DRM_DEBUG_CODE 2 /**< Include debugging code if > 1, then
also include looping detection. */
#define DRM_HASH_SIZE 16 /**< Size of key hash table. Must be power of 2. */
#define DRM_KERNEL_CONTEXT 0 /**< Change drm_resctx if changed */
#define DRM_RESERVED_CONTEXTS 1 /**< Change drm_resctx if changed */
#define DRM_LOOPING_LIMIT 5000000
#define DRM_BSZ 1024 /**< Buffer size for /dev/drm? output */
#define DRM_TIME_SLICE (HZ/20) /**< Time slice for GLXContexts */
#define DRM_LOCK_SLICE 1 /**< Time slice for lock, in jiffies */
#define DRM_FLAG_DEBUG 0x01
#define DRM_MEM_DMA 0
#define DRM_MEM_SAREA 1
#define DRM_MEM_DRIVER 2
#define DRM_MEM_MAGIC 3
#define DRM_MEM_IOCTLS 4
#define DRM_MEM_MAPS 5
#define DRM_MEM_VMAS 6
#define DRM_MEM_BUFS 7
#define DRM_MEM_SEGS 8
#define DRM_MEM_PAGES 9
#define DRM_MEM_FILES 10
#define DRM_MEM_QUEUES 11
#define DRM_MEM_CMDS 12
#define DRM_MEM_MAPPINGS 13
#define DRM_MEM_BUFLISTS 14
#define DRM_MEM_AGPLISTS 15
#define DRM_MEM_TOTALAGP 16
#define DRM_MEM_BOUNDAGP 17
#define DRM_MEM_CTXBITMAP 18
#define DRM_MEM_STUB 19
#define DRM_MEM_SGLISTS 20
#define DRM_MEM_CTXLIST 21
#define DRM_MAX_CTXBITMAP (PAGE_SIZE * 8)
/*@}*/
/***********************************************************************/
/** \name Backward compatibility section */
/*@{*/
#ifndef MODULE_LICENSE
#define MODULE_LICENSE(x)
#endif
#ifndef preempt_disable
#define preempt_disable()
#define preempt_enable()
#endif
#ifndef pte_offset_map
#define pte_offset_map pte_offset
#define pte_unmap(pte)
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,19)
static inline struct page * vmalloc_to_page(void * vmalloc_addr)
{
unsigned long addr = (unsigned long) vmalloc_addr;
struct page *page = NULL;
pgd_t *pgd = pgd_offset_k(addr);
pmd_t *pmd;
pte_t *ptep, pte;
if (!pgd_none(*pgd)) {
pmd = pmd_offset(pgd, addr);
if (!pmd_none(*pmd)) {
preempt_disable();
ptep = pte_offset_map(pmd, addr);
pte = *ptep;
if (pte_present(pte))
page = pte_page(pte);
pte_unmap(ptep);
preempt_enable();
}
}
return page;
}
#endif
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,5,0)
#define DRM_RPR_ARG(vma)
#else
#define DRM_RPR_ARG(vma) vma,
#endif
#define VM_OFFSET(vma) ((vma)->vm_pgoff << PAGE_SHIFT)
/*@}*/
/***********************************************************************/
/** \name Macros to make printk easier */
/*@{*/
/**
* Error output.
*
* \param fmt printf() like format string.
* \param arg arguments
*/
#define DRM_ERROR(fmt, arg...) \
printk(KERN_ERR "[" DRM_NAME ":%s] *ERROR* " fmt , __FUNCTION__ , ##arg)
/**
* Memory error output.
*
* \param area memory area where the error occurred.
* \param fmt printf() like format string.
* \param arg arguments
*/
#define DRM_MEM_ERROR(area, fmt, arg...) \
printk(KERN_ERR "[" DRM_NAME ":%s:%s] *ERROR* " fmt , __FUNCTION__, \
DRM(mem_stats)[area].name , ##arg)
#define DRM_INFO(fmt, arg...) printk(KERN_INFO "[" DRM_NAME "] " fmt , ##arg)
/**
* Debug output.
*
* \param fmt printf() like format string.
* \param arg arguments
*/
#if DRM_DEBUG_CODE
#define DRM_DEBUG(fmt, arg...) \
do { \
if ( DRM(flags) & DRM_FLAG_DEBUG ) \
printk(KERN_DEBUG \
"[" DRM_NAME ":%s] " fmt , \
__FUNCTION__ , ##arg); \
} while (0)
#else
#define DRM_DEBUG(fmt, arg...) do { } while (0)
#endif
#define DRM_PROC_LIMIT (PAGE_SIZE-80)
#define DRM_PROC_PRINT(fmt, arg...) \
len += sprintf(&buf[len], fmt , ##arg); \
if (len > DRM_PROC_LIMIT) { *eof = 1; return len - offset; }
#define DRM_PROC_PRINT_RET(ret, fmt, arg...) \
len += sprintf(&buf[len], fmt , ##arg); \
if (len > DRM_PROC_LIMIT) { ret; *eof = 1; return len - offset; }
/*@}*/
/***********************************************************************/
/** \name Internal types and structures */
/*@{*/
#define DRM_ARRAY_SIZE(x) (sizeof(x)/sizeof(x[0]))
#define DRM_MIN(a,b) ((a)<(b)?(a):(b))
#define DRM_MAX(a,b) ((a)>(b)?(a):(b))
#define DRM_LEFTCOUNT(x) (((x)->rp + (x)->count - (x)->wp) % ((x)->count + 1))
#define DRM_BUFCOUNT(x) ((x)->count - DRM_LEFTCOUNT(x))
#define DRM_WAITCOUNT(dev,idx) DRM_BUFCOUNT(&dev->queuelist[idx]->waitlist)
#define DRM_IF_VERSION(maj, min) (maj << 16 | min)
/**
* Get the private SAREA mapping.
*
* \param _dev DRM device.
* \param _ctx context number.
* \param _map output mapping.
*/
#define DRM_GET_PRIV_SAREA(_dev, _ctx, _map) do { \
(_map) = (_dev)->context_sareas[_ctx]; \
} while(0)
/**
* Test that the hardware lock is held by the caller, returning otherwise.
*
* \param dev DRM device.
* \param filp file pointer of the caller.
*/
#define LOCK_TEST_WITH_RETURN( dev, filp ) \
do { \
if ( !_DRM_LOCK_IS_HELD( dev->lock.hw_lock->lock ) || \
dev->lock.filp != filp ) { \
DRM_ERROR( "%s called without lock held\n", \
__FUNCTION__ ); \
return -EINVAL; \
} \
} while (0)
/**
* Ioctl function type.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg argument.
*/
typedef int drm_ioctl_t( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
typedef struct drm_ioctl_desc {
drm_ioctl_t *func;
int auth_needed;
int root_only;
} drm_ioctl_desc_t;
typedef struct drm_devstate {
pid_t owner; /**< X server pid holding x_lock */
} drm_devstate_t;
typedef struct drm_magic_entry {
drm_magic_t magic;
struct drm_file *priv;
struct drm_magic_entry *next;
} drm_magic_entry_t;
typedef struct drm_magic_head {
struct drm_magic_entry *head;
struct drm_magic_entry *tail;
} drm_magic_head_t;
typedef struct drm_vma_entry {
struct vm_area_struct *vma;
struct drm_vma_entry *next;
pid_t pid;
} drm_vma_entry_t;
/**
* DMA buffer.
*/
typedef struct drm_buf {
int idx; /**< Index into master buflist */
int total; /**< Buffer size */
int order; /**< log-base-2(total) */
int used; /**< Amount of buffer in use (for DMA) */
unsigned long offset; /**< Byte offset (used internally) */
void *address; /**< Address of buffer */
unsigned long bus_address; /**< Bus address of buffer */
struct drm_buf *next; /**< Kernel-only: used for free list */
__volatile__ int waiting; /**< On kernel DMA queue */
__volatile__ int pending; /**< On hardware DMA queue */
wait_queue_head_t dma_wait; /**< Processes waiting */
struct file *filp; /**< Pointer to holding file descr */
int context; /**< Kernel queue for this buffer */
int while_locked;/**< Dispatch this buffer while locked */
enum {
DRM_LIST_NONE = 0,
DRM_LIST_FREE = 1,
DRM_LIST_WAIT = 2,
DRM_LIST_PEND = 3,
DRM_LIST_PRIO = 4,
DRM_LIST_RECLAIM = 5
} list; /**< Which list we're on */
int dev_priv_size; /**< Size of buffer private storage */
void *dev_private; /**< Per-buffer private storage */
} drm_buf_t;
/** bufs is one longer than it has to be */
typedef struct drm_waitlist {
int count; /**< Number of possible buffers */
drm_buf_t **bufs; /**< List of pointers to buffers */
drm_buf_t **rp; /**< Read pointer */
drm_buf_t **wp; /**< Write pointer */
drm_buf_t **end; /**< End pointer */
spinlock_t read_lock;
spinlock_t write_lock;
} drm_waitlist_t;
typedef struct drm_freelist {
int initialized; /**< Freelist in use */
atomic_t count; /**< Number of free buffers */
drm_buf_t *next; /**< End pointer */
wait_queue_head_t waiting; /**< Processes waiting on free bufs */
int low_mark; /**< Low water mark */
int high_mark; /**< High water mark */
atomic_t wfh; /**< If waiting for high mark */
spinlock_t lock;
} drm_freelist_t;
/**
* Buffer entry. There is one of this for each buffer size order.
*/
typedef struct drm_buf_entry {
int buf_size; /**< size */
int buf_count; /**< number of buffers */
drm_buf_t *buflist; /**< buffer list */
int seg_count;
int page_order;
unsigned long *seglist;
drm_freelist_t freelist;
} drm_buf_entry_t;
/** File private data */
typedef struct drm_file {
int authenticated;
int minor;
pid_t pid;
uid_t uid;
drm_magic_t magic;
unsigned long ioctl_count;
struct drm_file *next;
struct drm_file *prev;
struct drm_device *dev;
int remove_auth_on_close;
unsigned long lock_count;
void *driver_priv;
} drm_file_t;
/** Wait queue */
typedef struct drm_queue {
atomic_t use_count; /**< Outstanding uses (+1) */
atomic_t finalization; /**< Finalization in progress */
atomic_t block_count; /**< Count of processes waiting */
atomic_t block_read; /**< Queue blocked for reads */
wait_queue_head_t read_queue; /**< Processes waiting on block_read */
atomic_t block_write; /**< Queue blocked for writes */
wait_queue_head_t write_queue; /**< Processes waiting on block_write */
#if 1
atomic_t total_queued; /**< Total queued statistic */
atomic_t total_flushed;/**< Total flushes statistic */
atomic_t total_locks; /**< Total locks statistics */
#endif
drm_ctx_flags_t flags; /**< Context preserving and 2D-only */
drm_waitlist_t waitlist; /**< Pending buffers */
wait_queue_head_t flush_queue; /**< Processes waiting until flush */
} drm_queue_t;
/**
* Lock data.
*/
typedef struct drm_lock_data {
drm_hw_lock_t *hw_lock; /**< Hardware lock */
struct file *filp; /**< File descr of lock holder (0=kernel) */
wait_queue_head_t lock_queue; /**< Queue of blocked processes */
unsigned long lock_time; /**< Time of last lock in jiffies */
} drm_lock_data_t;
/**
* DMA data.
*/
typedef struct drm_device_dma {
drm_buf_entry_t bufs[DRM_MAX_ORDER+1]; /**< buffers, grouped by their size order */
int buf_count; /**< total number of buffers */
drm_buf_t **buflist; /**< Vector of pointers into drm_device_dma::bufs */
int seg_count;
int page_count; /**< number of pages */
unsigned long *pagelist; /**< page list */
unsigned long byte_count;
enum {
_DRM_DMA_USE_AGP = 0x01,
_DRM_DMA_USE_SG = 0x02
} flags;
} drm_device_dma_t;
/**
* AGP memory entry. Stored as a doubly linked list.
*/
typedef struct drm_agp_mem {
unsigned long handle; /**< handle */
DRM_AGP_MEM *memory;
unsigned long bound; /**< address */
int pages;
struct drm_agp_mem *prev; /**< previous entry */
struct drm_agp_mem *next; /**< next entry */
} drm_agp_mem_t;
/**
* AGP data.
*
* \sa DRM(agp_init)() and drm_device::agp.
*/
typedef struct drm_agp_head {
DRM_AGP_KERN agp_info; /**< AGP device information */
drm_agp_mem_t *memory; /**< memory entries */
unsigned long mode; /**< AGP mode */
int enabled; /**< whether the AGP bus as been enabled */
int acquired; /**< whether the AGP device has been acquired */
unsigned long base;
int agp_mtrr;
int cant_use_aperture;
unsigned long page_mask;
} drm_agp_head_t;
/**
* Scatter-gather memory.
*/
typedef struct drm_sg_mem {
unsigned long handle;
void *virtual;
int pages;
struct page **pagelist;
dma_addr_t *busaddr;
} drm_sg_mem_t;
typedef struct drm_sigdata {
int context;
drm_hw_lock_t *lock;
} drm_sigdata_t;
/**
* Mappings list
*/
typedef struct drm_map_list {
struct list_head head; /**< list head */
drm_map_t *map; /**< mapping */
} drm_map_list_t;
typedef drm_map_t drm_local_map_t;
/**
* Context handle list
*/
typedef struct drm_ctx_list {
struct list_head head; /**< list head */
drm_context_t handle; /**< context handle */
drm_file_t *tag; /**< associated fd private data */
} drm_ctx_list_t;
typedef struct drm_vbl_sig {
struct list_head head;
unsigned int sequence;
struct siginfo info;
struct task_struct *task;
} drm_vbl_sig_t;
/**
* DRM device functions structure
*/
struct drm_device;
struct drm_driver_fn {
int (*preinit)(struct drm_device *);
int (*postinit)(struct drm_device *);
void (*prerelease)(struct drm_device *, struct file *filp);
void (*pretakedown)(struct drm_device *);
int (*postcleanup)(struct drm_device *);
int (*presetup)(struct drm_device *);
int (*postsetup)(struct drm_device *);
int (*open_helper)(struct drm_device *, drm_file_t *);
void (*free_filp_priv)(struct drm_device *, drm_file_t *);
void (*release)(struct drm_device *, struct file *filp);
void (*dma_ready)(struct drm_device *);
int (*dma_quiescent)(struct drm_device *);
int (*context_ctor)(struct drm_device *dev, int context);
int (*context_dtor)(struct drm_device *dev, int context);
int (*kernel_context_switch)(struct drm_device *dev, int old, int new);
void (*kernel_context_switch_unlock)(struct drm_device *dev, drm_lock_t *lock);
int (*vblank_wait)(struct drm_device *dev, unsigned int *sequence);
/* these have to be filled in */
irqreturn_t (*irq_handler)( DRM_IRQ_ARGS );
void (*irq_preinstall)(struct drm_device *dev);
void (*irq_postinstall)(struct drm_device *dev);
void (*irq_uninstall)(struct drm_device *dev);
void (*reclaim_buffers)(struct file *filp);
unsigned long (*get_map_ofs)(drm_map_t *map);
unsigned long (*get_reg_ofs)(struct drm_device *dev);
void (*set_version)(struct drm_device *dev, drm_set_version_t *sv);
};
/**
* DRM device structure.
*/
typedef struct drm_device {
const char *name; /**< Simple driver name */
char *unique; /**< Unique identifier: e.g., busid */
int unique_len; /**< Length of unique field */
dev_t device; /**< Device number for mknod */
char *devname; /**< For /proc/interrupts */
int minor; /**< Minor device number */
int if_version; /**< Highest interface version set */
int blocked; /**< Blocked due to VC switch? */
struct proc_dir_entry *root; /**< Root for this device's entries */
/** \name Locks */
/*@{*/
spinlock_t count_lock; /**< For inuse, drm_device::open_count, drm_device::buf_use */
struct semaphore struct_sem; /**< For others */
/*@}*/
/** \name Usage Counters */
/*@{*/
int open_count; /**< Outstanding files open */
atomic_t ioctl_count; /**< Outstanding IOCTLs pending */
atomic_t vma_count; /**< Outstanding vma areas open */
int buf_use; /**< Buffers in use -- cannot alloc */
atomic_t buf_alloc; /**< Buffer allocation in progress */
/*@}*/
/** \name Performance counters */
/*@{*/
unsigned long counters;
drm_stat_type_t types[15];
atomic_t counts[15];
/*@}*/
/** \name Authentication */
/*@{*/
drm_file_t *file_first; /**< file list head */
drm_file_t *file_last; /**< file list tail */
drm_magic_head_t magiclist[DRM_HASH_SIZE]; /**< magic hash table */
/*@}*/
/** \name Memory management */
/*@{*/
drm_map_list_t *maplist; /**< Linked list of regions */
int map_count; /**< Number of mappable regions */
/** \name Context handle management */
/*@{*/
drm_ctx_list_t *ctxlist; /**< Linked list of context handles */
int ctx_count; /**< Number of context handles */
struct semaphore ctxlist_sem; /**< For ctxlist */
drm_map_t **context_sareas; /**< per-context SAREA's */
int max_context;
drm_vma_entry_t *vmalist; /**< List of vmas (for debugging) */
drm_lock_data_t lock; /**< Information on hardware lock */
/*@}*/
/** \name DMA queues (contexts) */
/*@{*/
int queue_count; /**< Number of active DMA queues */
int queue_reserved; /**< Number of reserved DMA queues */
int queue_slots; /**< Actual length of queuelist */
drm_queue_t **queuelist; /**< Vector of pointers to DMA queues */
drm_device_dma_t *dma; /**< Optional pointer for DMA support */
/*@}*/
/** \name Context support */
/*@{*/
int irq; /**< Interrupt used by board */
int irq_enabled; /**< True if irq handler is enabled */
__volatile__ long context_flag; /**< Context swapping flag */
__volatile__ long interrupt_flag; /**< Interruption handler flag */
__volatile__ long dma_flag; /**< DMA dispatch flag */
struct timer_list timer; /**< Timer for delaying ctx switch */
wait_queue_head_t context_wait; /**< Processes waiting on ctx switch */
int last_checked; /**< Last context checked for DMA */
int last_context; /**< Last current context */
unsigned long last_switch; /**< jiffies at last context switch */
/*@}*/
struct work_struct work;
/** \name VBLANK IRQ support */
/*@{*/
wait_queue_head_t vbl_queue; /**< VBLANK wait queue */
atomic_t vbl_received;
spinlock_t vbl_lock;
drm_vbl_sig_t vbl_sigs; /**< signal list to send on VBLANK */
unsigned int vbl_pending;
/*@}*/
cycles_t ctx_start;
cycles_t lck_start;
char buf[DRM_BSZ]; /**< Output buffer */
char *buf_rp; /**< Read pointer */
char *buf_wp; /**< Write pointer */
char *buf_end; /**< End pointer */
struct fasync_struct *buf_async;/**< Processes waiting for SIGIO */
wait_queue_head_t buf_readers; /**< Processes waiting to read */
wait_queue_head_t buf_writers; /**< Processes waiting to ctx switch */
drm_agp_head_t *agp; /**< AGP data */
struct pci_dev *pdev; /**< PCI device structure */
int pci_domain; /**< PCI bus domain number */
int pci_bus; /**< PCI bus number */
int pci_slot; /**< PCI slot number */
int pci_func; /**< PCI function number */
#ifdef __alpha__
#if LINUX_VERSION_CODE < KERNEL_VERSION(2,4,3)
struct pci_controler *hose;
#else
struct pci_controller *hose;
#endif
#endif
drm_sg_mem_t *sg; /**< Scatter gather memory */
unsigned long *ctx_bitmap; /**< context bitmap */
void *dev_private; /**< device private data */
drm_sigdata_t sigdata; /**< For block_all_signals */
sigset_t sigmask;
struct drm_driver_fn fn_tbl;
drm_local_map_t *agp_buffer_map;
int dev_priv_size;
u32 driver_features;
} drm_device_t;
static __inline__ int drm_core_check_feature(struct drm_device *dev, int feature)
{
return ((dev->driver_features & feature) ? 1 : 0);
}
#if __OS_HAS_AGP
static inline int drm_core_has_AGP(struct drm_device *dev)
{
return drm_core_check_feature(dev, DRIVER_USE_AGP);
}
#else
#define drm_core_has_AGP(dev) (0)
#endif
#if __OS_HAS_MTRR
static inline int drm_core_has_MTRR(struct drm_device *dev)
{
return drm_core_check_feature(dev, DRIVER_USE_MTRR);
}
#else
#define drm_core_has_MTRR(dev) (0)
#endif
extern void DRM(driver_register_fns)(struct drm_device *dev);
/******************************************************************/
/** \name Internal function definitions */
/*@{*/
/* Misc. support (drm_init.h) */
extern int DRM(flags);
extern void DRM(parse_options)( char *s );
extern int DRM(cpu_valid)( void );
/* Driver support (drm_drv.h) */
extern int DRM(version)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(open)(struct inode *inode, struct file *filp);
extern int DRM(release)(struct inode *inode, struct file *filp);
extern int DRM(ioctl)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(lock)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(unlock)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/* Device support (drm_fops.h) */
extern int DRM(open_helper)(struct inode *inode, struct file *filp,
drm_device_t *dev);
extern int DRM(flush)(struct file *filp);
extern int DRM(fasync)(int fd, struct file *filp, int on);
/* Mapping support (drm_vm.h) */
extern void DRM(vm_open)(struct vm_area_struct *vma);
extern void DRM(vm_close)(struct vm_area_struct *vma);
extern void DRM(vm_shm_close)(struct vm_area_struct *vma);
extern int DRM(mmap_dma)(struct file *filp,
struct vm_area_struct *vma);
extern int DRM(mmap)(struct file *filp, struct vm_area_struct *vma);
extern unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait);
extern ssize_t DRM(read)(struct file *filp, char __user *buf, size_t count, loff_t *off);
/* Memory management support (drm_memory.h) */
extern void DRM(mem_init)(void);
extern int DRM(mem_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
extern void *DRM(alloc)(size_t size, int area);
extern void *DRM(calloc)(size_t nmemb, size_t size, int area);
extern void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size,
int area);
extern void DRM(free)(void *pt, size_t size, int area);
extern unsigned long DRM(alloc_pages)(int order, int area);
extern void DRM(free_pages)(unsigned long address, int order,
int area);
extern void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev);
extern void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size,
drm_device_t *dev);
extern void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev);
extern DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type);
extern int DRM(free_agp)(DRM_AGP_MEM *handle, int pages);
extern int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start);
extern int DRM(unbind_agp)(DRM_AGP_MEM *handle);
/* Misc. IOCTL support (drm_ioctl.h) */
extern int DRM(irq_by_busid)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(getunique)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(setunique)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(getmap)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(getclient)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(getstats)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(setversion)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/* Context IOCTL support (drm_context.h) */
extern int DRM(resctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(addctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(modctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(getctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(switchctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(newctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(rmctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(context_switch)(drm_device_t *dev, int old, int new);
extern int DRM(context_switch_complete)(drm_device_t *dev, int new);
extern int DRM(ctxbitmap_init)( drm_device_t *dev );
extern void DRM(ctxbitmap_cleanup)( drm_device_t *dev );
extern int DRM(setsareactx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(getsareactx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
/* Drawable IOCTL support (drm_drawable.h) */
extern int DRM(adddraw)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(rmdraw)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/* Authentication IOCTL support (drm_auth.h) */
extern int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv,
drm_magic_t magic);
extern int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic);
extern int DRM(getmagic)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(authmagic)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/* Placeholder for ioctls past */
extern int DRM(noop)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/* Locking IOCTL support (drm_lock.h) */
extern int DRM(lock_take)(__volatile__ unsigned int *lock,
unsigned int context);
extern int DRM(lock_transfer)(drm_device_t *dev,
__volatile__ unsigned int *lock,
unsigned int context);
extern int DRM(lock_free)(drm_device_t *dev,
__volatile__ unsigned int *lock,
unsigned int context);
extern int DRM(notifier)(void *priv);
/* Buffer management support (drm_bufs.h) */
extern int DRM(order)( unsigned long size );
extern int DRM(addmap)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(rmmap)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(addbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(infobufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(markbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(freebufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(mapbufs)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
/* DMA support (drm_dma.h) */
extern int DRM(dma_setup)(drm_device_t *dev);
extern void DRM(dma_takedown)(drm_device_t *dev);
extern void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf);
extern void DRM(reclaim_buffers)( struct file *filp );
/* IRQ support (drm_irq.h) */
extern int DRM(control)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg );
extern int DRM(irq_install)( drm_device_t *dev );
extern int DRM(irq_uninstall)( drm_device_t *dev );
extern irqreturn_t DRM(irq_handler)( DRM_IRQ_ARGS );
extern void DRM(driver_irq_preinstall)( drm_device_t *dev );
extern void DRM(driver_irq_postinstall)( drm_device_t *dev );
extern void DRM(driver_irq_uninstall)( drm_device_t *dev );
extern int DRM(wait_vblank)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(vblank_wait)(drm_device_t *dev, unsigned int *vbl_seq);
extern void DRM(vbl_send_signals)( drm_device_t *dev );
/* AGP/GART support (drm_agpsupport.h) */
extern drm_agp_head_t *DRM(agp_init)(void);
extern void DRM(agp_uninit)(void);
extern int DRM(agp_acquire)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern void DRM(agp_do_release)(void);
extern int DRM(agp_release)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(agp_enable)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(agp_info)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(agp_alloc)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(agp_free)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(agp_unbind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(agp_bind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern DRM_AGP_MEM *DRM(agp_allocate_memory)(size_t pages, u32 type);
extern int DRM(agp_free_memory)(DRM_AGP_MEM *handle);
extern int DRM(agp_bind_memory)(DRM_AGP_MEM *handle, off_t start);
extern int DRM(agp_unbind_memory)(DRM_AGP_MEM *handle);
/* Stub support (drm_stub.h) */
int DRM(stub_register)(const char *name,
struct file_operations *fops,
drm_device_t *dev);
int DRM(stub_unregister)(int minor);
/* Proc support (drm_proc.h) */
extern struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev,
int minor,
struct proc_dir_entry *root,
struct proc_dir_entry **dev_root);
extern int DRM(proc_cleanup)(int minor,
struct proc_dir_entry *root,
struct proc_dir_entry *dev_root);
/* Scatter Gather Support (drm_scatter.h) */
extern void DRM(sg_cleanup)(drm_sg_mem_t *entry);
extern int DRM(sg_alloc)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
extern int DRM(sg_free)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg);
/* ATI PCIGART support (ati_pcigart.h) */
extern int DRM(ati_pcigart_init)(drm_device_t *dev,
unsigned long *addr,
dma_addr_t *bus_addr);
extern int DRM(ati_pcigart_cleanup)(drm_device_t *dev,
unsigned long addr,
dma_addr_t bus_addr);
/* Inline replacements for DRM_IOREMAP macros */
static __inline__ void drm_core_ioremap(struct drm_map *map, struct drm_device *dev)
{
map->handle = DRM(ioremap)( map->offset, map->size, dev );
}
static __inline__ void drm_core_ioremap_nocache(struct drm_map *map, struct drm_device *dev)
{
map->handle = DRM(ioremap_nocache)(map->offset, map->size, dev);
}
static __inline__ void drm_core_ioremapfree(struct drm_map *map, struct drm_device *dev)
{
if ( map->handle && map->size )
DRM(ioremapfree)( map->handle, map->size, dev );
}
static __inline__ struct drm_map *drm_core_findmap(struct drm_device *dev, unsigned long offset)
{
struct list_head *_list;
list_for_each( _list, &dev->maplist->head ) {
drm_map_list_t *_entry = list_entry( _list, drm_map_list_t, head );
if ( _entry->map &&
_entry->map->offset == offset ) {
return _entry->map;
}
}
return NULL;
}
static __inline__ void drm_core_dropmap(struct drm_map *map)
{
}
/*@}*/
extern unsigned long DRM(core_get_map_ofs)(drm_map_t *map);
extern unsigned long DRM(core_get_reg_ofs)(struct drm_device *dev);
#endif /* __KERNEL__ */
#endif

View File

@@ -0,0 +1,468 @@
/**
* \file drm_agpsupport.h
* DRM support for AGP/GART backend
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
#include <linux/module.h>
#if __OS_HAS_AGP
#define DRM_AGP_GET (drm_agp_t *)inter_module_get("drm_agp")
#define DRM_AGP_PUT inter_module_put("drm_agp")
/**
* Pointer to the drm_agp_t structure made available by the agpgart module.
*/
static const drm_agp_t *drm_agp = NULL;
/**
* AGP information ioctl.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a (output) drm_agp_info structure.
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device has been initialized and acquired and fills in the
* drm_agp_info structure with the information in drm_agp_head::agp_info.
*/
int DRM(agp_info)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
DRM_AGP_KERN *kern;
drm_agp_info_t info;
if (!dev->agp || !dev->agp->acquired || !drm_agp->copy_info)
return -EINVAL;
kern = &dev->agp->agp_info;
info.agp_version_major = kern->version.major;
info.agp_version_minor = kern->version.minor;
info.mode = kern->mode;
info.aperture_base = kern->aper_base;
info.aperture_size = kern->aper_size * 1024 * 1024;
info.memory_allowed = kern->max_memory << PAGE_SHIFT;
info.memory_used = kern->current_memory << PAGE_SHIFT;
info.id_vendor = kern->device->vendor;
info.id_device = kern->device->device;
if (copy_to_user((drm_agp_info_t __user *)arg, &info, sizeof(info)))
return -EFAULT;
return 0;
}
/**
* Acquire the AGP device (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument.
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device hasn't been acquired before and calls
* drm_agp->acquire().
*/
int DRM(agp_acquire)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
int retcode;
if (!dev->agp)
return -ENODEV;
if (dev->agp->acquired)
return -EBUSY;
if (!drm_agp->acquire)
return -EINVAL;
if ((retcode = drm_agp->acquire()))
return retcode;
dev->agp->acquired = 1;
return 0;
}
/**
* Release the AGP device (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument.
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device has been acquired and calls drm_agp->release().
*/
int DRM(agp_release)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
if (!dev->agp || !dev->agp->acquired || !drm_agp->release)
return -EINVAL;
drm_agp->release();
dev->agp->acquired = 0;
return 0;
}
/**
* Release the AGP device.
*
* Calls drm_agp->release().
*/
void DRM(agp_do_release)(void)
{
if (drm_agp->release)
drm_agp->release();
}
/**
* Enable the AGP bus.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_agp_mode structure.
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device has been acquired but not enabled, and calls
* drm_agp->enable().
*/
int DRM(agp_enable)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_agp_mode_t mode;
if (!dev->agp || !dev->agp->acquired || !drm_agp->enable)
return -EINVAL;
if (copy_from_user(&mode, (drm_agp_mode_t __user *)arg, sizeof(mode)))
return -EFAULT;
dev->agp->mode = mode.mode;
drm_agp->enable(mode.mode);
dev->agp->base = dev->agp->agp_info.aper_base;
dev->agp->enabled = 1;
return 0;
}
/**
* Allocate AGP memory.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_agp_buffer structure.
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device is present and has been acquired, allocates the
* memory via alloc_agp() and creates a drm_agp_mem entry for it.
*/
int DRM(agp_alloc)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_agp_buffer_t request;
drm_agp_mem_t *entry;
DRM_AGP_MEM *memory;
unsigned long pages;
u32 type;
drm_agp_buffer_t __user *argp = (void __user *)arg;
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
if (copy_from_user(&request, argp, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(alloc)(sizeof(*entry), DRM_MEM_AGPLISTS)))
return -ENOMEM;
memset(entry, 0, sizeof(*entry));
pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
type = (u32) request.type;
if (!(memory = DRM(alloc_agp)(pages, type))) {
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return -ENOMEM;
}
entry->handle = (unsigned long)memory->key + 1;
entry->memory = memory;
entry->bound = 0;
entry->pages = pages;
entry->prev = NULL;
entry->next = dev->agp->memory;
if (dev->agp->memory)
dev->agp->memory->prev = entry;
dev->agp->memory = entry;
request.handle = entry->handle;
request.physical = memory->physical;
if (copy_to_user(argp, &request, sizeof(request))) {
dev->agp->memory = entry->next;
dev->agp->memory->prev = NULL;
DRM(free_agp)(memory, pages);
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return -EFAULT;
}
return 0;
}
/**
* Search for the AGP memory entry associated with a handle.
*
* \param dev DRM device structure.
* \param handle AGP memory handle.
* \return pointer to the drm_agp_mem structure associated with \p handle.
*
* Walks through drm_agp_head::memory until finding a matching handle.
*/
static drm_agp_mem_t *DRM(agp_lookup_entry)(drm_device_t *dev,
unsigned long handle)
{
drm_agp_mem_t *entry;
for (entry = dev->agp->memory; entry; entry = entry->next) {
if (entry->handle == handle)
return entry;
}
return NULL;
}
/**
* Unbind AGP memory from the GATT (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_agp_binding structure.
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device is present and acquired, looks-up the AGP memory
* entry and passes it to the unbind_agp() function.
*/
int DRM(agp_unbind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_agp_binding_t request;
drm_agp_mem_t *entry;
int ret;
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
if (!entry->bound)
return -EINVAL;
ret = DRM(unbind_agp)(entry->memory);
if (ret == 0)
entry->bound = 0;
return ret;
}
/**
* Bind AGP memory into the GATT (ioctl)
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_agp_binding structure.
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device is present and has been acquired and that no memory
* is currently bound into the GATT. Looks-up the AGP memory entry and passes
* it to bind_agp() function.
*/
int DRM(agp_bind)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_agp_binding_t request;
drm_agp_mem_t *entry;
int retcode;
int page;
if (!dev->agp || !dev->agp->acquired || !drm_agp->bind_memory)
return -EINVAL;
if (copy_from_user(&request, (drm_agp_binding_t __user *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
if (entry->bound)
return -EINVAL;
page = (request.offset + PAGE_SIZE - 1) / PAGE_SIZE;
if ((retcode = DRM(bind_agp)(entry->memory, page)))
return retcode;
entry->bound = dev->agp->base + (page << PAGE_SHIFT);
DRM_DEBUG("base = 0x%lx entry->bound = 0x%lx\n",
dev->agp->base, entry->bound);
return 0;
}
/**
* Free AGP memory (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_agp_buffer structure.
* \return zero on success or a negative number on failure.
*
* Verifies the AGP device is present and has been acquired and looks up the
* AGP memory entry. If the memory it's currently bound, unbind it via
* unbind_agp(). Frees it via free_agp() as well as the entry itself
* and unlinks from the doubly linked list it's inserted in.
*/
int DRM(agp_free)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_agp_buffer_t request;
drm_agp_mem_t *entry;
if (!dev->agp || !dev->agp->acquired)
return -EINVAL;
if (copy_from_user(&request, (drm_agp_buffer_t __user *)arg, sizeof(request)))
return -EFAULT;
if (!(entry = DRM(agp_lookup_entry)(dev, request.handle)))
return -EINVAL;
if (entry->bound)
DRM(unbind_agp)(entry->memory);
if (entry->prev)
entry->prev->next = entry->next;
else
dev->agp->memory = entry->next;
if (entry->next)
entry->next->prev = entry->prev;
DRM(free_agp)(entry->memory, entry->pages);
DRM(free)(entry, sizeof(*entry), DRM_MEM_AGPLISTS);
return 0;
}
/**
* Initialize the AGP resources.
*
* \return pointer to a drm_agp_head structure.
*
* Gets the drm_agp_t structure which is made available by the agpgart module
* via the inter_module_* functions. Creates and initializes a drm_agp_head
* structure.
*/
drm_agp_head_t *DRM(agp_init)(void)
{
drm_agp_head_t *head = NULL;
drm_agp = DRM_AGP_GET;
if (drm_agp) {
if (!(head = DRM(alloc)(sizeof(*head), DRM_MEM_AGPLISTS)))
return NULL;
memset((void *)head, 0, sizeof(*head));
drm_agp->copy_info(&head->agp_info);
if (head->agp_info.chipset == NOT_SUPPORTED) {
DRM(free)(head, sizeof(*head), DRM_MEM_AGPLISTS);
return NULL;
}
head->memory = NULL;
#if LINUX_VERSION_CODE <= 0x020408
head->cant_use_aperture = 0;
head->page_mask = ~(0xfff);
#else
head->cant_use_aperture = head->agp_info.cant_use_aperture;
head->page_mask = head->agp_info.page_mask;
#endif
}
return head;
}
/**
* Free the AGP resources.
*
* Releases the pointer in ::drm_agp.
*/
void DRM(agp_uninit)(void)
{
DRM_AGP_PUT;
drm_agp = NULL;
}
/** Calls drm_agp->allocate_memory() */
DRM_AGP_MEM *DRM(agp_allocate_memory)(size_t pages, u32 type)
{
if (!drm_agp->allocate_memory)
return NULL;
return drm_agp->allocate_memory(pages, type);
}
/** Calls drm_agp->free_memory() */
int DRM(agp_free_memory)(DRM_AGP_MEM *handle)
{
if (!handle || !drm_agp->free_memory)
return 0;
drm_agp->free_memory(handle);
return 1;
}
/** Calls drm_agp->bind_memory() */
int DRM(agp_bind_memory)(DRM_AGP_MEM *handle, off_t start)
{
if (!handle || !drm_agp->bind_memory)
return -EINVAL;
return drm_agp->bind_memory(handle, start);
}
/** Calls drm_agp->unbind_memory() */
int DRM(agp_unbind_memory)(DRM_AGP_MEM *handle)
{
if (!handle || !drm_agp->unbind_memory)
return -EINVAL;
return drm_agp->unbind_memory(handle);
}
#endif /* __OS_HAS_AGP */

View File

@@ -0,0 +1,230 @@
/**
* \file drm_auth.h
* IOCTLs for authentication
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
/**
* Generate a hash key from a magic.
*
* \param magic magic.
* \return hash key.
*
* The key is the modulus of the hash table size, #DRM_HASH_SIZE, which must be
* a power of 2.
*/
static int DRM(hash_magic)(drm_magic_t magic)
{
return magic & (DRM_HASH_SIZE-1);
}
/**
* Find the file with the given magic number.
*
* \param dev DRM device.
* \param magic magic number.
*
* Searches in drm_device::magiclist within all files with the same hash key
* the one with matching magic number, while holding the drm_device::struct_sem
* lock.
*/
static drm_file_t *DRM(find_file)(drm_device_t *dev, drm_magic_t magic)
{
drm_file_t *retval = NULL;
drm_magic_entry_t *pt;
int hash = DRM(hash_magic)(magic);
down(&dev->struct_sem);
for (pt = dev->magiclist[hash].head; pt; pt = pt->next) {
if (pt->magic == magic) {
retval = pt->priv;
break;
}
}
up(&dev->struct_sem);
return retval;
}
/**
* Adds a magic number.
*
* \param dev DRM device.
* \param priv file private data.
* \param magic magic number.
*
* Creates a drm_magic_entry structure and appends to the linked list
* associated the magic number hash key in drm_device::magiclist, while holding
* the drm_device::struct_sem lock.
*/
int DRM(add_magic)(drm_device_t *dev, drm_file_t *priv, drm_magic_t magic)
{
int hash;
drm_magic_entry_t *entry;
DRM_DEBUG("%d\n", magic);
hash = DRM(hash_magic)(magic);
entry = DRM(alloc)(sizeof(*entry), DRM_MEM_MAGIC);
if (!entry) return -ENOMEM;
memset(entry, 0, sizeof(*entry));
entry->magic = magic;
entry->priv = priv;
entry->next = NULL;
down(&dev->struct_sem);
if (dev->magiclist[hash].tail) {
dev->magiclist[hash].tail->next = entry;
dev->magiclist[hash].tail = entry;
} else {
dev->magiclist[hash].head = entry;
dev->magiclist[hash].tail = entry;
}
up(&dev->struct_sem);
return 0;
}
/**
* Remove a magic number.
*
* \param dev DRM device.
* \param magic magic number.
*
* Searches and unlinks the entry in drm_device::magiclist with the magic
* number hash key, while holding the drm_device::struct_sem lock.
*/
int DRM(remove_magic)(drm_device_t *dev, drm_magic_t magic)
{
drm_magic_entry_t *prev = NULL;
drm_magic_entry_t *pt;
int hash;
DRM_DEBUG("%d\n", magic);
hash = DRM(hash_magic)(magic);
down(&dev->struct_sem);
for (pt = dev->magiclist[hash].head; pt; prev = pt, pt = pt->next) {
if (pt->magic == magic) {
if (dev->magiclist[hash].head == pt) {
dev->magiclist[hash].head = pt->next;
}
if (dev->magiclist[hash].tail == pt) {
dev->magiclist[hash].tail = prev;
}
if (prev) {
prev->next = pt->next;
}
up(&dev->struct_sem);
return 0;
}
}
up(&dev->struct_sem);
DRM(free)(pt, sizeof(*pt), DRM_MEM_MAGIC);
return -EINVAL;
}
/**
* Get a unique magic number (ioctl).
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a resulting drm_auth structure.
* \return zero on success, or a negative number on failure.
*
* If there is a magic number in drm_file::magic then use it, otherwise
* searches an unique non-zero magic number and add it associating it with \p
* filp.
*/
int DRM(getmagic)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
static drm_magic_t sequence = 0;
static spinlock_t lock = SPIN_LOCK_UNLOCKED;
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_auth_t auth;
/* Find unique magic */
if (priv->magic) {
auth.magic = priv->magic;
} else {
do {
spin_lock(&lock);
if (!sequence) ++sequence; /* reserve 0 */
auth.magic = sequence++;
spin_unlock(&lock);
} while (DRM(find_file)(dev, auth.magic));
priv->magic = auth.magic;
DRM(add_magic)(dev, priv, auth.magic);
}
DRM_DEBUG("%u\n", auth.magic);
if (copy_to_user((drm_auth_t __user *)arg, &auth, sizeof(auth)))
return -EFAULT;
return 0;
}
/**
* Authenticate with a magic.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg pointer to a drm_auth structure.
* \return zero if authentication successed, or a negative number otherwise.
*
* Checks if \p filp is associated with the magic number passed in \arg.
*/
int DRM(authmagic)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_auth_t auth;
drm_file_t *file;
if (copy_from_user(&auth, (drm_auth_t __user *)arg, sizeof(auth)))
return -EFAULT;
DRM_DEBUG("%u\n", auth.magic);
if ((file = DRM(find_file)(dev, auth.magic))) {
file->authenticated = 1;
DRM(remove_magic)(dev, auth.magic);
return 0;
}
return -EINVAL;
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,578 @@
/**
* \file drm_context.h
* IOCTLs for generic contexts
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
/*
* ChangeLog:
* 2001-11-16 Torsten Duwe <duwe@caldera.de>
* added context constructor/destructor hooks,
* needed by SiS driver's memory management.
*/
#include "drmP.h"
/******************************************************************/
/** \name Context bitmap support */
/*@{*/
/**
* Free a handle from the context bitmap.
*
* \param dev DRM device.
* \param ctx_handle context handle.
*
* Clears the bit specified by \p ctx_handle in drm_device::ctx_bitmap and the entry
* in drm_device::context_sareas, while holding the drm_device::struct_sem
* lock.
*/
void DRM(ctxbitmap_free)( drm_device_t *dev, int ctx_handle )
{
if ( ctx_handle < 0 ) goto failed;
if ( !dev->ctx_bitmap ) goto failed;
if ( ctx_handle < DRM_MAX_CTXBITMAP ) {
down(&dev->struct_sem);
clear_bit( ctx_handle, dev->ctx_bitmap );
dev->context_sareas[ctx_handle] = NULL;
up(&dev->struct_sem);
return;
}
failed:
DRM_ERROR( "Attempt to free invalid context handle: %d\n",
ctx_handle );
return;
}
/**
* Context bitmap allocation.
*
* \param dev DRM device.
* \return (non-negative) context handle on success or a negative number on failure.
*
* Find the first zero bit in drm_device::ctx_bitmap and (re)allocates
* drm_device::context_sareas to accommodate the new entry while holding the
* drm_device::struct_sem lock.
*/
int DRM(ctxbitmap_next)( drm_device_t *dev )
{
int bit;
if(!dev->ctx_bitmap) return -1;
down(&dev->struct_sem);
bit = find_first_zero_bit( dev->ctx_bitmap, DRM_MAX_CTXBITMAP );
if ( bit < DRM_MAX_CTXBITMAP ) {
set_bit( bit, dev->ctx_bitmap );
DRM_DEBUG( "drm_ctxbitmap_next bit : %d\n", bit );
if((bit+1) > dev->max_context) {
dev->max_context = (bit+1);
if(dev->context_sareas) {
drm_map_t **ctx_sareas;
ctx_sareas = DRM(realloc)(dev->context_sareas,
(dev->max_context - 1) *
sizeof(*dev->context_sareas),
dev->max_context *
sizeof(*dev->context_sareas),
DRM_MEM_MAPS);
if(!ctx_sareas) {
clear_bit(bit, dev->ctx_bitmap);
up(&dev->struct_sem);
return -1;
}
dev->context_sareas = ctx_sareas;
dev->context_sareas[bit] = NULL;
} else {
/* max_context == 1 at this point */
dev->context_sareas = DRM(alloc)(
dev->max_context *
sizeof(*dev->context_sareas),
DRM_MEM_MAPS);
if(!dev->context_sareas) {
clear_bit(bit, dev->ctx_bitmap);
up(&dev->struct_sem);
return -1;
}
dev->context_sareas[bit] = NULL;
}
}
up(&dev->struct_sem);
return bit;
}
up(&dev->struct_sem);
return -1;
}
/**
* Context bitmap initialization.
*
* \param dev DRM device.
*
* Allocates and initialize drm_device::ctx_bitmap and drm_device::context_sareas, while holding
* the drm_device::struct_sem lock.
*/
int DRM(ctxbitmap_init)( drm_device_t *dev )
{
int i;
int temp;
down(&dev->struct_sem);
dev->ctx_bitmap = (unsigned long *) DRM(alloc)( PAGE_SIZE,
DRM_MEM_CTXBITMAP );
if ( dev->ctx_bitmap == NULL ) {
up(&dev->struct_sem);
return -ENOMEM;
}
memset( (void *)dev->ctx_bitmap, 0, PAGE_SIZE );
dev->context_sareas = NULL;
dev->max_context = -1;
up(&dev->struct_sem);
for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
temp = DRM(ctxbitmap_next)( dev );
DRM_DEBUG( "drm_ctxbitmap_init : %d\n", temp );
}
return 0;
}
/**
* Context bitmap cleanup.
*
* \param dev DRM device.
*
* Frees drm_device::ctx_bitmap and drm_device::context_sareas, while holding
* the drm_device::struct_sem lock.
*/
void DRM(ctxbitmap_cleanup)( drm_device_t *dev )
{
down(&dev->struct_sem);
if( dev->context_sareas ) DRM(free)( dev->context_sareas,
sizeof(*dev->context_sareas) *
dev->max_context,
DRM_MEM_MAPS );
DRM(free)( (void *)dev->ctx_bitmap, PAGE_SIZE, DRM_MEM_CTXBITMAP );
up(&dev->struct_sem);
}
/*@}*/
/******************************************************************/
/** \name Per Context SAREA Support */
/*@{*/
/**
* Get per-context SAREA.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx_priv_map structure.
* \return zero on success or a negative number on failure.
*
* Gets the map from drm_device::context_sareas with the handle specified and
* returns its handle.
*/
int DRM(getsareactx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_priv_map_t __user *argp = (void __user *)arg;
drm_ctx_priv_map_t request;
drm_map_t *map;
if (copy_from_user(&request, argp, sizeof(request)))
return -EFAULT;
down(&dev->struct_sem);
if (dev->max_context < 0 || request.ctx_id >= (unsigned) dev->max_context) {
up(&dev->struct_sem);
return -EINVAL;
}
map = dev->context_sareas[request.ctx_id];
up(&dev->struct_sem);
request.handle = map->handle;
if (copy_to_user(argp, &request, sizeof(request)))
return -EFAULT;
return 0;
}
/**
* Set per-context SAREA.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx_priv_map structure.
* \return zero on success or a negative number on failure.
*
* Searches the mapping specified in \p arg and update the entry in
* drm_device::context_sareas with it.
*/
int DRM(setsareactx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_priv_map_t request;
drm_map_t *map = NULL;
drm_map_list_t *r_list = NULL;
struct list_head *list;
if (copy_from_user(&request,
(drm_ctx_priv_map_t __user *)arg,
sizeof(request)))
return -EFAULT;
down(&dev->struct_sem);
list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head);
if(r_list->map &&
r_list->map->handle == request.handle)
goto found;
}
bad:
up(&dev->struct_sem);
return -EINVAL;
found:
map = r_list->map;
if (!map) goto bad;
if (dev->max_context < 0)
goto bad;
if (request.ctx_id >= (unsigned) dev->max_context)
goto bad;
dev->context_sareas[request.ctx_id] = map;
up(&dev->struct_sem);
return 0;
}
/*@}*/
/******************************************************************/
/** \name The actual DRM context handling routines */
/*@{*/
/**
* Switch context.
*
* \param dev DRM device.
* \param old old context handle.
* \param new new context handle.
* \return zero on success or a negative number on failure.
*
* Attempt to set drm_device::context_flag.
*/
int DRM(context_switch)( drm_device_t *dev, int old, int new )
{
if ( test_and_set_bit( 0, &dev->context_flag ) ) {
DRM_ERROR( "Reentering -- FIXME\n" );
return -EBUSY;
}
DRM_DEBUG( "Context switch from %d to %d\n", old, new );
if ( new == dev->last_context ) {
clear_bit( 0, &dev->context_flag );
return 0;
}
return 0;
}
/**
* Complete context switch.
*
* \param dev DRM device.
* \param new new context handle.
* \return zero on success or a negative number on failure.
*
* Updates drm_device::last_context and drm_device::last_switch. Verifies the
* hardware lock is held, clears the drm_device::context_flag and wakes up
* drm_device::context_wait.
*/
int DRM(context_switch_complete)( drm_device_t *dev, int new )
{
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
dev->last_switch = jiffies;
if ( !_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock) ) {
DRM_ERROR( "Lock isn't held after context switch\n" );
}
/* If a context switch is ever initiated
when the kernel holds the lock, release
that lock here. */
clear_bit( 0, &dev->context_flag );
wake_up( &dev->context_wait );
return 0;
}
/**
* Reserve contexts.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx_res structure.
* \return zero on success or a negative number on failure.
*/
int DRM(resctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_ctx_res_t res;
drm_ctx_t __user *argp = (void __user *)arg;
drm_ctx_t ctx;
int i;
if ( copy_from_user( &res, argp, sizeof(res) ) )
return -EFAULT;
if ( res.count >= DRM_RESERVED_CONTEXTS ) {
memset( &ctx, 0, sizeof(ctx) );
for ( i = 0 ; i < DRM_RESERVED_CONTEXTS ; i++ ) {
ctx.handle = i;
if ( copy_to_user( &res.contexts[i],
&i, sizeof(i) ) )
return -EFAULT;
}
}
res.count = DRM_RESERVED_CONTEXTS;
if ( copy_to_user( argp, &res, sizeof(res) ) )
return -EFAULT;
return 0;
}
/**
* Add context.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* Get a new handle for the context and copy to userspace.
*/
int DRM(addctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_list_t * ctx_entry;
drm_ctx_t __user *argp = (void __user *)arg;
drm_ctx_t ctx;
if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
return -EFAULT;
ctx.handle = DRM(ctxbitmap_next)( dev );
if ( ctx.handle == DRM_KERNEL_CONTEXT ) {
/* Skip kernel's context and get a new one. */
ctx.handle = DRM(ctxbitmap_next)( dev );
}
DRM_DEBUG( "%d\n", ctx.handle );
if ( ctx.handle == -1 ) {
DRM_DEBUG( "Not enough free contexts.\n" );
/* Should this return -EBUSY instead? */
return -ENOMEM;
}
if ( ctx.handle != DRM_KERNEL_CONTEXT )
{
if (dev->fn_tbl.context_ctor)
dev->fn_tbl.context_ctor(dev, ctx.handle);
}
ctx_entry = DRM(alloc)( sizeof(*ctx_entry), DRM_MEM_CTXLIST );
if ( !ctx_entry ) {
DRM_DEBUG("out of memory\n");
return -ENOMEM;
}
INIT_LIST_HEAD( &ctx_entry->head );
ctx_entry->handle = ctx.handle;
ctx_entry->tag = priv;
down( &dev->ctxlist_sem );
list_add( &ctx_entry->head, &dev->ctxlist->head );
++dev->ctx_count;
up( &dev->ctxlist_sem );
if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
return -EFAULT;
return 0;
}
int DRM(modctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
/* This does nothing */
return 0;
}
/**
* Get context.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*/
int DRM(getctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_ctx_t __user *argp = (void __user *)arg;
drm_ctx_t ctx;
if ( copy_from_user( &ctx, argp, sizeof(ctx) ) )
return -EFAULT;
/* This is 0, because we don't handle any context flags */
ctx.flags = 0;
if ( copy_to_user( argp, &ctx, sizeof(ctx) ) )
return -EFAULT;
return 0;
}
/**
* Switch context.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* Calls context_switch().
*/
int DRM(switchctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
return -EFAULT;
DRM_DEBUG( "%d\n", ctx.handle );
return DRM(context_switch)( dev, dev->last_context, ctx.handle );
}
/**
* New context.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* Calls context_switch_complete().
*/
int DRM(newctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
return -EFAULT;
DRM_DEBUG( "%d\n", ctx.handle );
DRM(context_switch_complete)( dev, ctx.handle );
return 0;
}
/**
* Remove context.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument pointing to a drm_ctx structure.
* \return zero on success or a negative number on failure.
*
* If not the special kernel context, calls ctxbitmap_free() to free the specified context.
*/
int DRM(rmctx)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
if ( copy_from_user( &ctx, (drm_ctx_t __user *)arg, sizeof(ctx) ) )
return -EFAULT;
DRM_DEBUG( "%d\n", ctx.handle );
if ( ctx.handle == DRM_KERNEL_CONTEXT + 1 ) {
priv->remove_auth_on_close = 1;
}
if ( ctx.handle != DRM_KERNEL_CONTEXT ) {
if (dev->fn_tbl.context_dtor)
dev->fn_tbl.context_dtor(dev, ctx.handle);
DRM(ctxbitmap_free)( dev, ctx.handle );
}
down( &dev->ctxlist_sem );
if ( !list_empty( &dev->ctxlist->head ) ) {
drm_ctx_list_t *pos, *n;
list_for_each_entry_safe( pos, n, &dev->ctxlist->head, head ) {
if ( pos->handle == ctx.handle ) {
list_del( &pos->head );
DRM(free)( pos, sizeof(*pos), DRM_MEM_CTXLIST );
--dev->ctx_count;
}
}
}
up( &dev->ctxlist_sem );
return 0;
}
/*@}*/

View File

@@ -0,0 +1,40 @@
/*
* Copyright 2004 Jon Smirl <jonsmirl@gmail.com>
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sub license,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) shall be included in all copies or substantial portions
* of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT. IN NO EVENT SHALL
* VIA, S3 GRAPHICS, AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "drm_auth.h"
#include "drm_agpsupport.h"
#include "drm_bufs.h"
#include "drm_context.h"
#include "drm_dma.h"
#include "drm_irq.h"
#include "drm_drawable.h"
#include "drm_drv.h"
#include "drm_fops.h"
#include "drm_init.h"
#include "drm_ioctl.h"
#include "drm_lock.h"
#include "drm_memory.h"
#include "drm_proc.h"
#include "drm_vm.h"
#include "drm_stub.h"
#include "drm_scatter.h"

View File

@@ -0,0 +1,181 @@
/**
* \file drm_dma.h
* DMA IOCTL and function support
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
/**
* Initialize the DMA data.
*
* \param dev DRM device.
* \return zero on success or a negative value on failure.
*
* Allocate and initialize a drm_device_dma structure.
*/
int DRM(dma_setup)( drm_device_t *dev )
{
int i;
dev->dma = DRM(alloc)( sizeof(*dev->dma), DRM_MEM_DRIVER );
if ( !dev->dma )
return -ENOMEM;
memset( dev->dma, 0, sizeof(*dev->dma) );
for ( i = 0 ; i <= DRM_MAX_ORDER ; i++ )
memset(&dev->dma->bufs[i], 0, sizeof(dev->dma->bufs[0]));
return 0;
}
/**
* Cleanup the DMA resources.
*
* \param dev DRM device.
*
* Free all pages associated with DMA buffers, the buffers and pages lists, and
* finally the the drm_device::dma structure itself.
*/
void DRM(dma_takedown)(drm_device_t *dev)
{
drm_device_dma_t *dma = dev->dma;
int i, j;
if (!dma) return;
/* Clear dma buffers */
for (i = 0; i <= DRM_MAX_ORDER; i++) {
if (dma->bufs[i].seg_count) {
DRM_DEBUG("order %d: buf_count = %d,"
" seg_count = %d\n",
i,
dma->bufs[i].buf_count,
dma->bufs[i].seg_count);
for (j = 0; j < dma->bufs[i].seg_count; j++) {
if (dma->bufs[i].seglist[j]) {
DRM(free_pages)(dma->bufs[i].seglist[j],
dma->bufs[i].page_order,
DRM_MEM_DMA);
}
}
DRM(free)(dma->bufs[i].seglist,
dma->bufs[i].seg_count
* sizeof(*dma->bufs[0].seglist),
DRM_MEM_SEGS);
}
if (dma->bufs[i].buf_count) {
for (j = 0; j < dma->bufs[i].buf_count; j++) {
if (dma->bufs[i].buflist[j].dev_private) {
DRM(free)(dma->bufs[i].buflist[j].dev_private,
dma->bufs[i].buflist[j].dev_priv_size,
DRM_MEM_BUFS);
}
}
DRM(free)(dma->bufs[i].buflist,
dma->bufs[i].buf_count *
sizeof(*dma->bufs[0].buflist),
DRM_MEM_BUFS);
}
}
if (dma->buflist) {
DRM(free)(dma->buflist,
dma->buf_count * sizeof(*dma->buflist),
DRM_MEM_BUFS);
}
if (dma->pagelist) {
DRM(free)(dma->pagelist,
dma->page_count * sizeof(*dma->pagelist),
DRM_MEM_PAGES);
}
DRM(free)(dev->dma, sizeof(*dev->dma), DRM_MEM_DRIVER);
dev->dma = NULL;
}
/**
* Free a buffer.
*
* \param dev DRM device.
* \param buf buffer to free.
*
* Resets the fields of \p buf.
*/
void DRM(free_buffer)(drm_device_t *dev, drm_buf_t *buf)
{
if (!buf) return;
buf->waiting = 0;
buf->pending = 0;
buf->filp = NULL;
buf->used = 0;
if (drm_core_check_feature(dev, DRIVER_DMA_QUEUE) && waitqueue_active(&buf->dma_wait)) {
wake_up_interruptible(&buf->dma_wait);
}
}
/**
* Reclaim the buffers.
*
* \param filp file pointer.
*
* Frees each buffer associated with \p filp not already on the hardware.
*/
void DRM(core_reclaim_buffers)( struct file *filp )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_device_dma_t *dma = dev->dma;
int i;
if (!dma) return;
for (i = 0; i < dma->buf_count; i++) {
if (dma->buflist[i]->filp == filp) {
switch (dma->buflist[i]->list) {
case DRM_LIST_NONE:
DRM(free_buffer)(dev, dma->buflist[i]);
break;
case DRM_LIST_WAIT:
dma->buflist[i]->list = DRM_LIST_RECLAIM;
break;
default:
/* Buffer already on hardware. */
break;
}
}
}
}

View File

@@ -0,0 +1,56 @@
/**
* \file drm_drawable.h
* IOCTLs for drawables
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
/** No-op. */
int DRM(adddraw)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_draw_t draw;
draw.handle = 0; /* NOOP */
DRM_DEBUG("%d\n", draw.handle);
if (copy_to_user((drm_draw_t __user *)arg, &draw, sizeof(draw)))
return -EFAULT;
return 0;
}
/** No-op. */
int DRM(rmdraw)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
return 0; /* NOOP */
}

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,156 @@
/**
* \file drm_fops.h
* File operations for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Daryll Strauss <daryll@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
#include <linux/poll.h>
/**
* Called whenever a process opens /dev/drm.
*
* \param inode device inode.
* \param filp file pointer.
* \param dev device.
* \return zero on success or a negative number on failure.
*
* Creates and initializes a drm_file structure for the file private data in \p
* filp and add it into the double linked list in \p dev.
*/
int DRM(open_helper)(struct inode *inode, struct file *filp, drm_device_t *dev)
{
int minor = iminor(inode);
drm_file_t *priv;
int ret;
if (filp->f_flags & O_EXCL) return -EBUSY; /* No exclusive opens */
if (!DRM(cpu_valid)()) return -EINVAL;
DRM_DEBUG("pid = %d, minor = %d\n", current->pid, minor);
priv = DRM(alloc)(sizeof(*priv), DRM_MEM_FILES);
if(!priv) return -ENOMEM;
memset(priv, 0, sizeof(*priv));
filp->private_data = priv;
priv->uid = current->euid;
priv->pid = current->pid;
priv->minor = minor;
priv->dev = dev;
priv->ioctl_count = 0;
priv->authenticated = capable(CAP_SYS_ADMIN);
priv->lock_count = 0;
if (dev->fn_tbl.open_helper) {
ret=dev->fn_tbl.open_helper(dev, priv);
if (ret < 0)
goto out_free;
}
down(&dev->struct_sem);
if (!dev->file_last) {
priv->next = NULL;
priv->prev = NULL;
dev->file_first = priv;
dev->file_last = priv;
} else {
priv->next = NULL;
priv->prev = dev->file_last;
dev->file_last->next = priv;
dev->file_last = priv;
}
up(&dev->struct_sem);
#ifdef __alpha__
/*
* Default the hose
*/
if (!dev->hose) {
struct pci_dev *pci_dev;
pci_dev = pci_get_class(PCI_CLASS_DISPLAY_VGA << 8, NULL);
if (pci_dev) {
dev->hose = pci_dev->sysdata;
pci_dev_put(pci_dev);
}
if (!dev->hose) {
struct pci_bus *b = pci_bus_b(pci_root_buses.next);
if (b) dev->hose = b->sysdata;
}
}
#endif
return 0;
out_free:
DRM(free)(priv, sizeof(*priv), DRM_MEM_FILES);
filp->private_data=NULL;
return ret;
}
/** No-op. */
int DRM(flush)(struct file *filp)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
DRM_DEBUG("pid = %d, device = 0x%lx, open_count = %d\n",
current->pid, (long)old_encode_dev(dev->device), dev->open_count);
return 0;
}
/** No-op. */
int DRM(fasync)(int fd, struct file *filp, int on)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
int retcode;
DRM_DEBUG("fd = %d, device = 0x%lx\n", fd, (long)old_encode_dev(dev->device));
retcode = fasync_helper(fd, filp, on, &dev->buf_async);
if (retcode < 0) return retcode;
return 0;
}
/** No-op. */
unsigned int DRM(poll)(struct file *filp, struct poll_table_struct *wait)
{
return 0;
}
/** No-op. */
ssize_t DRM(read)(struct file *filp, char __user *buf, size_t count, loff_t *off)
{
return 0;
}

View File

@@ -0,0 +1,128 @@
/**
* \file drm_init.h
* Setup/Cleanup for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
/** Debug flags. Set by parse_option(). */
#if 0
int DRM(flags) = DRM_FLAG_DEBUG;
#else
int DRM(flags) = 0;
#endif
/**
* Parse a single option.
*
* \param s option string.
*
* \sa See parse_options() for details.
*/
static void DRM(parse_option)(char *s)
{
char *c, *r;
DRM_DEBUG("\"%s\"\n", s);
if (!s || !*s) return;
for (c = s; *c && *c != ':'; c++); /* find : or \0 */
if (*c) r = c + 1; else r = NULL; /* remember remainder */
*c = '\0'; /* terminate */
if (!strcmp(s, "debug")) {
DRM(flags) |= DRM_FLAG_DEBUG;
DRM_INFO("Debug messages ON\n");
return;
}
DRM_ERROR("\"%s\" is not a valid option\n", s);
return;
}
/**
* Parse the insmod "drm_opts=" options, or the command-line
* options passed to the kernel via LILO.
*
* \param s contains option_list without the 'drm_opts=' part.
*
* The grammar of the format is as
* follows:
*
* \code
* drm ::= 'drm_opts=' option_list
* option_list ::= option [ ';' option_list ]
* option ::= 'device:' major
* | 'debug'
* | 'noctx'
* major ::= INTEGER
* \endcode
*
* - device=major,minor specifies the device number used for /dev/drm
* - if major == 0 then the misc device is used
* - if major == 0 and minor == 0 then dynamic misc allocation is used
* - debug=on specifies that debugging messages will be printk'd
* - debug=trace specifies that each function call will be logged via printk
* - debug=off turns off all debugging options
*
* \todo Actually only the \e presence of the 'debug' option is currently
* checked.
*/
void DRM(parse_options)(char *s)
{
char *h, *t, *n;
DRM_DEBUG("\"%s\"\n", s ?: "");
if (!s || !*s) return;
for (h = t = n = s; h && *h; h = n) {
for (; *t && *t != ';'; t++); /* find ; or \0 */
if (*t) n = t + 1; else n = NULL; /* remember next */
*t = '\0'; /* terminate */
DRM(parse_option)(h); /* parse */
}
}
/**
* Check whether DRI will run on this CPU.
*
* \return non-zero if the DRI will run on this CPU, or zero otherwise.
*/
int DRM(cpu_valid)(void)
{
#if defined(__i386__)
if (boot_cpu_data.x86 == 3) return 0; /* No cmpxchg on a 386 */
#endif
#if defined(__sparc__) && !defined(__sparc_v9__)
return 0; /* No cmpxchg before v9 sparc. */
#endif
return 1;
}

View File

@@ -0,0 +1,349 @@
/**
* \file drm_ioctl.h
* IOCTL processing for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Fri Jan 8 09:01:26 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
#include "linux/pci.h"
/**
* Get the bus id.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_unique structure.
* \return zero on success or a negative number on failure.
*
* Copies the bus id from drm_device::unique into user space.
*/
int DRM(getunique)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_unique_t __user *argp = (void __user *)arg;
drm_unique_t u;
if (copy_from_user(&u, argp, sizeof(u)))
return -EFAULT;
if (u.unique_len >= dev->unique_len) {
if (copy_to_user(u.unique, dev->unique, dev->unique_len))
return -EFAULT;
}
u.unique_len = dev->unique_len;
if (copy_to_user(argp, &u, sizeof(u)))
return -EFAULT;
return 0;
}
/**
* Set the bus id.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_unique structure.
* \return zero on success or a negative number on failure.
*
* Copies the bus id from userspace into drm_device::unique, and verifies that
* it matches the device this DRM is attached to (EINVAL otherwise). Deprecated
* in interface version 1.1 and will return EBUSY when setversion has requested
* version 1.1 or greater.
*/
int DRM(setunique)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_unique_t u;
int domain, bus, slot, func, ret;
if (dev->unique_len || dev->unique) return -EBUSY;
if (copy_from_user(&u, (drm_unique_t __user *)arg, sizeof(u)))
return -EFAULT;
if (!u.unique_len || u.unique_len > 1024) return -EINVAL;
dev->unique_len = u.unique_len;
dev->unique = DRM(alloc)(u.unique_len + 1, DRM_MEM_DRIVER);
if(!dev->unique) return -ENOMEM;
if (copy_from_user(dev->unique, u.unique, dev->unique_len))
return -EFAULT;
dev->unique[dev->unique_len] = '\0';
dev->devname = DRM(alloc)(strlen(dev->name) + strlen(dev->unique) + 2,
DRM_MEM_DRIVER);
if (!dev->devname)
return -ENOMEM;
sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
/* Return error if the busid submitted doesn't match the device's actual
* busid.
*/
ret = sscanf(dev->unique, "PCI:%d:%d:%d", &bus, &slot, &func);
if (ret != 3)
return DRM_ERR(EINVAL);
domain = bus >> 8;
bus &= 0xff;
if ((domain != dev->pci_domain) ||
(bus != dev->pci_bus) ||
(slot != dev->pci_slot) ||
(func != dev->pci_func))
return -EINVAL;
return 0;
}
static int
DRM(set_busid)(drm_device_t *dev)
{
if (dev->unique != NULL)
return EBUSY;
dev->unique_len = 20;
dev->unique = DRM(alloc)(dev->unique_len + 1, DRM_MEM_DRIVER);
if (dev->unique == NULL)
return ENOMEM;
snprintf(dev->unique, dev->unique_len, "pci:%04x:%02x:%02x.%d",
dev->pci_domain, dev->pci_bus, dev->pci_slot, dev->pci_func);
dev->devname = DRM(alloc)(strlen(dev->name) + dev->unique_len + 2,
DRM_MEM_DRIVER);
if (dev->devname == NULL)
return ENOMEM;
sprintf(dev->devname, "%s@%s", dev->name, dev->unique);
return 0;
}
/**
* Get a mapping information.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_map structure.
*
* \return zero on success or a negative number on failure.
*
* Searches for the mapping with the specified offset and copies its information
* into userspace
*/
int DRM(getmap)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_map_t __user *argp = (void __user *)arg;
drm_map_t map;
drm_map_list_t *r_list = NULL;
struct list_head *list;
int idx;
int i;
if (copy_from_user(&map, argp, sizeof(map)))
return -EFAULT;
idx = map.offset;
down(&dev->struct_sem);
if (idx < 0) {
up(&dev->struct_sem);
return -EINVAL;
}
i = 0;
list_for_each(list, &dev->maplist->head) {
if(i == idx) {
r_list = list_entry(list, drm_map_list_t, head);
break;
}
i++;
}
if(!r_list || !r_list->map) {
up(&dev->struct_sem);
return -EINVAL;
}
map.offset = r_list->map->offset;
map.size = r_list->map->size;
map.type = r_list->map->type;
map.flags = r_list->map->flags;
map.handle = r_list->map->handle;
map.mtrr = r_list->map->mtrr;
up(&dev->struct_sem);
if (copy_to_user(argp, &map, sizeof(map))) return -EFAULT;
return 0;
}
/**
* Get client information.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_client structure.
*
* \return zero on success or a negative number on failure.
*
* Searches for the client with the specified index and copies its information
* into userspace
*/
int DRM(getclient)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_client_t __user *argp = (void __user *)arg;
drm_client_t client;
drm_file_t *pt;
int idx;
int i;
if (copy_from_user(&client, argp, sizeof(client)))
return -EFAULT;
idx = client.idx;
down(&dev->struct_sem);
for (i = 0, pt = dev->file_first; i < idx && pt; i++, pt = pt->next)
;
if (!pt) {
up(&dev->struct_sem);
return -EINVAL;
}
client.auth = pt->authenticated;
client.pid = pt->pid;
client.uid = pt->uid;
client.magic = pt->magic;
client.iocs = pt->ioctl_count;
up(&dev->struct_sem);
if (copy_to_user((drm_client_t __user *)arg, &client, sizeof(client)))
return -EFAULT;
return 0;
}
/**
* Get statistics information.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_stats structure.
*
* \return zero on success or a negative number on failure.
*/
int DRM(getstats)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_stats_t stats;
int i;
memset(&stats, 0, sizeof(stats));
down(&dev->struct_sem);
for (i = 0; i < dev->counters; i++) {
if (dev->types[i] == _DRM_STAT_LOCK)
stats.data[i].value
= (dev->lock.hw_lock
? dev->lock.hw_lock->lock : 0);
else
stats.data[i].value = atomic_read(&dev->counts[i]);
stats.data[i].type = dev->types[i];
}
stats.count = dev->counters;
up(&dev->struct_sem);
if (copy_to_user((drm_stats_t __user *)arg, &stats, sizeof(stats)))
return -EFAULT;
return 0;
}
#define DRM_IF_MAJOR 1
#define DRM_IF_MINOR 2
int DRM(setversion)(DRM_IOCTL_ARGS)
{
DRM_DEVICE;
drm_set_version_t sv;
drm_set_version_t retv;
int if_version;
drm_set_version_t __user *argp = (void __user *)data;
DRM_COPY_FROM_USER_IOCTL(sv, argp, sizeof(sv));
retv.drm_di_major = DRM_IF_MAJOR;
retv.drm_di_minor = DRM_IF_MINOR;
retv.drm_dd_major = DRIVER_MAJOR;
retv.drm_dd_minor = DRIVER_MINOR;
DRM_COPY_TO_USER_IOCTL(argp, retv, sizeof(sv));
if (sv.drm_di_major != -1) {
if (sv.drm_di_major != DRM_IF_MAJOR ||
sv.drm_di_minor < 0 || sv.drm_di_minor > DRM_IF_MINOR)
return EINVAL;
if_version = DRM_IF_VERSION(sv.drm_di_major, sv.drm_dd_minor);
dev->if_version = DRM_MAX(if_version, dev->if_version);
if (sv.drm_di_minor >= 1) {
/*
* Version 1.1 includes tying of DRM to specific device
*/
DRM(set_busid)(dev);
}
}
if (sv.drm_dd_major != -1) {
if (sv.drm_dd_major != DRIVER_MAJOR ||
sv.drm_dd_minor < 0 || sv.drm_dd_minor > DRIVER_MINOR)
return EINVAL;
if (dev->fn_tbl.set_version)
dev->fn_tbl.set_version(dev, &sv);
}
return 0;
}

View File

@@ -0,0 +1,368 @@
/**
* \file drm_irq.h
* IRQ support
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Fri Mar 19 14:30:16 1999 by faith@valinux.com
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
#include <linux/interrupt.h> /* For task queue support */
/**
* Get interrupt from bus id.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_irq_busid structure.
* \return zero on success or a negative number on failure.
*
* Finds the PCI device with the specified bus id and gets its IRQ number.
* This IOCTL is deprecated, and will now return EINVAL for any busid not equal
* to that of the device that this DRM instance attached to.
*/
int DRM(irq_by_busid)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_irq_busid_t __user *argp = (void __user *)arg;
drm_irq_busid_t p;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
if (copy_from_user(&p, argp, sizeof(p)))
return -EFAULT;
if ((p.busnum >> 8) != dev->pci_domain ||
(p.busnum & 0xff) != dev->pci_bus ||
p.devnum != dev->pci_slot ||
p.funcnum != dev->pci_func)
return -EINVAL;
p.irq = dev->irq;
DRM_DEBUG("%d:%d:%d => IRQ %d\n",
p.busnum, p.devnum, p.funcnum, p.irq);
if (copy_to_user(argp, &p, sizeof(p)))
return -EFAULT;
return 0;
}
/**
* Install IRQ handler.
*
* \param dev DRM device.
* \param irq IRQ number.
*
* Initializes the IRQ related data, and setups drm_device::vbl_queue. Installs the handler, calling the driver
* \c DRM(driver_irq_preinstall)() and \c DRM(driver_irq_postinstall)() functions
* before and after the installation.
*/
int DRM(irq_install)( drm_device_t *dev )
{
int ret;
unsigned long sh_flags=0;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
if ( dev->irq == 0 )
return -EINVAL;
down( &dev->struct_sem );
/* Driver must have been initialized */
if ( !dev->dev_private ) {
up( &dev->struct_sem );
return -EINVAL;
}
if ( dev->irq_enabled ) {
up( &dev->struct_sem );
return -EBUSY;
}
dev->irq_enabled = 1;
up( &dev->struct_sem );
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
if (drm_core_check_feature(dev, DRIVER_IRQ_VBL)) {
init_waitqueue_head(&dev->vbl_queue);
spin_lock_init( &dev->vbl_lock );
INIT_LIST_HEAD( &dev->vbl_sigs.head );
dev->vbl_pending = 0;
}
/* Before installing handler */
dev->fn_tbl.irq_preinstall(dev);
/* Install handler */
if (drm_core_check_feature(dev, DRIVER_IRQ_SHARED))
sh_flags = SA_SHIRQ;
ret = request_irq( dev->irq, dev->fn_tbl.irq_handler,
sh_flags, dev->devname, dev );
if ( ret < 0 ) {
down( &dev->struct_sem );
dev->irq_enabled = 0;
up( &dev->struct_sem );
return ret;
}
/* After installing handler */
dev->fn_tbl.irq_postinstall(dev);
return 0;
}
/**
* Uninstall the IRQ handler.
*
* \param dev DRM device.
*
* Calls the driver's \c DRM(driver_irq_uninstall)() function, and stops the irq.
*/
int DRM(irq_uninstall)( drm_device_t *dev )
{
int irq_enabled;
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return -EINVAL;
down( &dev->struct_sem );
irq_enabled = dev->irq_enabled;
dev->irq_enabled = 0;
up( &dev->struct_sem );
if ( !irq_enabled )
return -EINVAL;
DRM_DEBUG( "%s: irq=%d\n", __FUNCTION__, dev->irq );
dev->fn_tbl.irq_uninstall(dev);
free_irq( dev->irq, dev );
return 0;
}
/**
* IRQ control ioctl.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param arg user argument, pointing to a drm_control structure.
* \return zero on success or a negative number on failure.
*
* Calls irq_install() or irq_uninstall() according to \p arg.
*/
int DRM(control)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_control_t ctl;
/* if we haven't irq we fallback for compatibility reasons - this used to be a separate function in drm_dma.h */
if ( copy_from_user( &ctl, (drm_control_t __user *)arg, sizeof(ctl) ) )
return -EFAULT;
switch ( ctl.func ) {
case DRM_INST_HANDLER:
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return 0;
if (dev->if_version < DRM_IF_VERSION(1, 2) &&
ctl.irq != dev->irq)
return -EINVAL;
return DRM(irq_install)( dev );
case DRM_UNINST_HANDLER:
if (!drm_core_check_feature(dev, DRIVER_HAVE_IRQ))
return 0;
return DRM(irq_uninstall)( dev );
default:
return -EINVAL;
}
}
/**
* Wait for VBLANK.
*
* \param inode device inode.
* \param filp file pointer.
* \param cmd command.
* \param data user argument, pointing to a drm_wait_vblank structure.
* \return zero on success or a negative number on failure.
*
* Verifies the IRQ is installed.
*
* If a signal is requested checks if this task has already scheduled the same signal
* for the same vblank sequence number - nothing to be done in
* that case. If the number of tasks waiting for the interrupt exceeds 100 the
* function fails. Otherwise adds a new entry to drm_device::vbl_sigs for this
* task.
*
* If a signal is not requested, then calls vblank_wait().
*/
int DRM(wait_vblank)( DRM_IOCTL_ARGS )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_wait_vblank_t __user *argp = (void __user *)data;
drm_wait_vblank_t vblwait;
struct timeval now;
int ret = 0;
unsigned int flags;
if (!drm_core_check_feature(dev, DRIVER_IRQ_VBL))
return -EINVAL;
if (!dev->irq)
return -EINVAL;
DRM_COPY_FROM_USER_IOCTL( vblwait, argp, sizeof(vblwait) );
switch ( vblwait.request.type & ~_DRM_VBLANK_FLAGS_MASK ) {
case _DRM_VBLANK_RELATIVE:
vblwait.request.sequence += atomic_read( &dev->vbl_received );
vblwait.request.type &= ~_DRM_VBLANK_RELATIVE;
case _DRM_VBLANK_ABSOLUTE:
break;
default:
return -EINVAL;
}
flags = vblwait.request.type & _DRM_VBLANK_FLAGS_MASK;
if ( flags & _DRM_VBLANK_SIGNAL ) {
unsigned long irqflags;
drm_vbl_sig_t *vbl_sig;
vblwait.reply.sequence = atomic_read( &dev->vbl_received );
spin_lock_irqsave( &dev->vbl_lock, irqflags );
/* Check if this task has already scheduled the same signal
* for the same vblank sequence number; nothing to be done in
* that case
*/
list_for_each_entry( vbl_sig, &dev->vbl_sigs.head, head ) {
if (vbl_sig->sequence == vblwait.request.sequence
&& vbl_sig->info.si_signo == vblwait.request.signal
&& vbl_sig->task == current)
{
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
goto done;
}
}
if ( dev->vbl_pending >= 100 ) {
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
return -EBUSY;
}
dev->vbl_pending++;
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
if ( !( vbl_sig = DRM_MALLOC( sizeof( drm_vbl_sig_t ) ) ) ) {
return -ENOMEM;
}
memset( (void *)vbl_sig, 0, sizeof(*vbl_sig) );
vbl_sig->sequence = vblwait.request.sequence;
vbl_sig->info.si_signo = vblwait.request.signal;
vbl_sig->task = current;
spin_lock_irqsave( &dev->vbl_lock, irqflags );
list_add_tail( (struct list_head *) vbl_sig, &dev->vbl_sigs.head );
spin_unlock_irqrestore( &dev->vbl_lock, irqflags );
} else {
if (dev->fn_tbl.vblank_wait)
ret = dev->fn_tbl.vblank_wait( dev, &vblwait.request.sequence );
do_gettimeofday( &now );
vblwait.reply.tval_sec = now.tv_sec;
vblwait.reply.tval_usec = now.tv_usec;
}
done:
DRM_COPY_TO_USER_IOCTL( argp, vblwait, sizeof(vblwait) );
return ret;
}
/**
* Send the VBLANK signals.
*
* \param dev DRM device.
*
* Sends a signal for each task in drm_device::vbl_sigs and empties the list.
*
* If a signal is not requested, then calls vblank_wait().
*/
void DRM(vbl_send_signals)( drm_device_t *dev )
{
struct list_head *list, *tmp;
drm_vbl_sig_t *vbl_sig;
unsigned int vbl_seq = atomic_read( &dev->vbl_received );
unsigned long flags;
spin_lock_irqsave( &dev->vbl_lock, flags );
list_for_each_safe( list, tmp, &dev->vbl_sigs.head ) {
vbl_sig = list_entry( list, drm_vbl_sig_t, head );
if ( ( vbl_seq - vbl_sig->sequence ) <= (1<<23) ) {
vbl_sig->info.si_code = vbl_seq;
send_sig_info( vbl_sig->info.si_signo, &vbl_sig->info, vbl_sig->task );
list_del( list );
DRM_FREE( vbl_sig, sizeof(*vbl_sig) );
dev->vbl_pending--;
}
}
spin_unlock_irqrestore( &dev->vbl_lock, flags );
}

View File

@@ -0,0 +1,168 @@
/**
* \file drm_lock.h
* IOCTLs for locking
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Tue Feb 2 08:37:54 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
/** No-op ioctl. */
int DRM(noop)(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
DRM_DEBUG("\n");
return 0;
}
/**
* Take the heavyweight lock.
*
* \param lock lock pointer.
* \param context locking context.
* \return one if the lock is held, or zero otherwise.
*
* Attempt to mark the lock as held by the given context, via the \p cmpxchg instruction.
*/
int DRM(lock_take)(__volatile__ unsigned int *lock, unsigned int context)
{
unsigned int old, new, prev;
do {
old = *lock;
if (old & _DRM_LOCK_HELD) new = old | _DRM_LOCK_CONT;
else new = context | _DRM_LOCK_HELD;
prev = cmpxchg(lock, old, new);
} while (prev != old);
if (_DRM_LOCKING_CONTEXT(old) == context) {
if (old & _DRM_LOCK_HELD) {
if (context != DRM_KERNEL_CONTEXT) {
DRM_ERROR("%d holds heavyweight lock\n",
context);
}
return 0;
}
}
if (new == (context | _DRM_LOCK_HELD)) {
/* Have lock */
return 1;
}
return 0;
}
/**
* This takes a lock forcibly and hands it to context. Should ONLY be used
* inside *_unlock to give lock to kernel before calling *_dma_schedule.
*
* \param dev DRM device.
* \param lock lock pointer.
* \param context locking context.
* \return always one.
*
* Resets the lock file pointer.
* Marks the lock as held by the given context, via the \p cmpxchg instruction.
*/
int DRM(lock_transfer)(drm_device_t *dev,
__volatile__ unsigned int *lock, unsigned int context)
{
unsigned int old, new, prev;
dev->lock.filp = NULL;
do {
old = *lock;
new = context | _DRM_LOCK_HELD;
prev = cmpxchg(lock, old, new);
} while (prev != old);
return 1;
}
/**
* Free lock.
*
* \param dev DRM device.
* \param lock lock.
* \param context context.
*
* Resets the lock file pointer.
* Marks the lock as not held, via the \p cmpxchg instruction. Wakes any task
* waiting on the lock queue.
*/
int DRM(lock_free)(drm_device_t *dev,
__volatile__ unsigned int *lock, unsigned int context)
{
unsigned int old, new, prev;
dev->lock.filp = NULL;
do {
old = *lock;
new = 0;
prev = cmpxchg(lock, old, new);
} while (prev != old);
if (_DRM_LOCK_IS_HELD(old) && _DRM_LOCKING_CONTEXT(old) != context) {
DRM_ERROR("%d freed heavyweight lock held by %d\n",
context,
_DRM_LOCKING_CONTEXT(old));
return 1;
}
wake_up_interruptible(&dev->lock.lock_queue);
return 0;
}
/**
* If we get here, it means that the process has called DRM_IOCTL_LOCK
* without calling DRM_IOCTL_UNLOCK.
*
* If the lock is not held, then let the signal proceed as usual. If the lock
* is held, then set the contended flag and keep the signal blocked.
*
* \param priv pointer to a drm_sigdata structure.
* \return one if the signal should be delivered normally, or zero if the
* signal should be blocked.
*/
int DRM(notifier)(void *priv)
{
drm_sigdata_t *s = (drm_sigdata_t *)priv;
unsigned int old, new, prev;
/* Allow signal delivery if lock isn't held */
if (!s->lock || !_DRM_LOCK_IS_HELD(s->lock->lock)
|| _DRM_LOCKING_CONTEXT(s->lock->lock) != s->context) return 1;
/* Otherwise, set flag to force call to
drmUnlock */
do {
old = s->lock->lock;
new = old | _DRM_LOCK_CONT;
prev = cmpxchg(&s->lock->lock, old, new);
} while (prev != old);
return 0;
}

View File

@@ -0,0 +1,369 @@
/**
* \file drm_memory.h
* Memory management wrappers for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Thu Feb 4 14:00:34 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <linux/config.h>
#include <linux/highmem.h>
#include "drmP.h"
/**
* Cut down version of drm_memory_debug.h, which used to be called
* drm_memory.h. If you want the debug functionality, change 0 to 1
* below.
*/
#define DEBUG_MEMORY 0
#if __OS_HAS_AGP
#include <linux/vmalloc.h>
#ifdef HAVE_PAGE_AGP
#include <asm/agp.h>
#else
# ifdef __powerpc__
# define PAGE_AGP __pgprot(_PAGE_KERNEL | _PAGE_NO_CACHE)
# else
# define PAGE_AGP PAGE_KERNEL
# endif
#endif
#include <asm/tlbflush.h>
/*
* Find the drm_map that covers the range [offset, offset+size).
*/
static inline drm_map_t *
drm_lookup_map (unsigned long offset, unsigned long size, drm_device_t *dev)
{
struct list_head *list;
drm_map_list_t *r_list;
drm_map_t *map;
list_for_each(list, &dev->maplist->head) {
r_list = (drm_map_list_t *) list;
map = r_list->map;
if (!map)
continue;
if (map->offset <= offset && (offset + size) <= (map->offset + map->size))
return map;
}
return NULL;
}
static inline void *
agp_remap (unsigned long offset, unsigned long size, drm_device_t *dev)
{
unsigned long *phys_addr_map, i, num_pages = PAGE_ALIGN(size) / PAGE_SIZE;
struct drm_agp_mem *agpmem;
struct page **page_map;
void *addr;
size = PAGE_ALIGN(size);
#ifdef __alpha__
offset -= dev->hose->mem_space->start;
#endif
for (agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next)
if (agpmem->bound <= offset
&& (agpmem->bound + (agpmem->pages << PAGE_SHIFT)) >= (offset + size))
break;
if (!agpmem)
return NULL;
/*
* OK, we're mapping AGP space on a chipset/platform on which memory accesses by
* the CPU do not get remapped by the GART. We fix this by using the kernel's
* page-table instead (that's probably faster anyhow...).
*/
/* note: use vmalloc() because num_pages could be large... */
page_map = vmalloc(num_pages * sizeof(struct page *));
if (!page_map)
return NULL;
phys_addr_map = agpmem->memory->memory + (offset - agpmem->bound) / PAGE_SIZE;
for (i = 0; i < num_pages; ++i)
page_map[i] = pfn_to_page(phys_addr_map[i] >> PAGE_SHIFT);
addr = vmap(page_map, num_pages, VM_IOREMAP, PAGE_AGP);
vfree(page_map);
return addr;
}
static inline unsigned long
drm_follow_page (void *vaddr)
{
pgd_t *pgd = pgd_offset_k((unsigned long) vaddr);
pmd_t *pmd = pmd_offset(pgd, (unsigned long) vaddr);
pte_t *ptep = pte_offset_kernel(pmd, (unsigned long) vaddr);
return pte_pfn(*ptep) << PAGE_SHIFT;
}
#else /* __OS_HAS_AGP */
static inline drm_map_t *drm_lookup_map(unsigned long offset, unsigned long size, drm_device_t *dev)
{
return NULL;
}
static inline void *agp_remap(unsigned long offset, unsigned long size, drm_device_t *dev)
{
return NULL;
}
static inline unsigned long drm_follow_page (void *vaddr)
{
return 0;
}
#endif
static inline void *drm_ioremap(unsigned long offset, unsigned long size, drm_device_t *dev)
{
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
drm_map_t *map = drm_lookup_map(offset, size, dev);
if (map && map->type == _DRM_AGP)
return agp_remap(offset, size, dev);
}
return ioremap(offset, size);
}
static inline void *drm_ioremap_nocache(unsigned long offset, unsigned long size,
drm_device_t *dev)
{
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture) {
drm_map_t *map = drm_lookup_map(offset, size, dev);
if (map && map->type == _DRM_AGP)
return agp_remap(offset, size, dev);
}
return ioremap_nocache(offset, size);
}
static inline void drm_ioremapfree(void *pt, unsigned long size, drm_device_t *dev)
{
/*
* This is a bit ugly. It would be much cleaner if the DRM API would use separate
* routines for handling mappings in the AGP space. Hopefully this can be done in
* a future revision of the interface...
*/
if (drm_core_has_AGP(dev) && dev->agp && dev->agp->cant_use_aperture
&& ((unsigned long) pt >= VMALLOC_START && (unsigned long) pt < VMALLOC_END))
{
unsigned long offset;
drm_map_t *map;
offset = drm_follow_page(pt) | ((unsigned long) pt & ~PAGE_MASK);
map = drm_lookup_map(offset, size, dev);
if (map && map->type == _DRM_AGP) {
vunmap(pt);
return;
}
}
iounmap(pt);
}
#if DEBUG_MEMORY
#include "drm_memory_debug.h"
#else
/** No-op. */
void DRM(mem_init)(void)
{
}
/**
* Called when "/proc/dri/%dev%/mem" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param len requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*
* No-op.
*/
int DRM(mem_info)(char *buf, char **start, off_t offset,
int len, int *eof, void *data)
{
return 0;
}
/** Wrapper around kmalloc() */
void *DRM(alloc)(size_t size, int area)
{
return kmalloc(size, GFP_KERNEL);
}
/** Wrapper around kmalloc() */
void *DRM(calloc)(size_t size, size_t nmemb, int area)
{
void *addr;
addr = kmalloc(size * nmemb, GFP_KERNEL);
if (addr != NULL)
memset((void *)addr, 0, size * nmemb);
return addr;
}
/** Wrapper around kmalloc() and kfree() */
void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
{
void *pt;
if (!(pt = kmalloc(size, GFP_KERNEL))) return NULL;
if (oldpt && oldsize) {
memcpy(pt, oldpt, oldsize);
kfree(oldpt);
}
return pt;
}
/** Wrapper around kfree() */
void DRM(free)(void *pt, size_t size, int area)
{
kfree(pt);
}
/**
* Allocate pages.
*
* \param order size order.
* \param area memory area. (Not used.)
* \return page address on success, or zero on failure.
*
* Allocate and reserve free pages.
*/
unsigned long DRM(alloc_pages)(int order, int area)
{
unsigned long address;
unsigned long bytes = PAGE_SIZE << order;
unsigned long addr;
unsigned int sz;
address = __get_free_pages(GFP_KERNEL, order);
if (!address)
return 0;
/* Zero */
memset((void *)address, 0, bytes);
/* Reserve */
for (addr = address, sz = bytes;
sz > 0;
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
SetPageReserved(virt_to_page(addr));
}
return address;
}
/**
* Free pages.
*
* \param address address of the pages to free.
* \param order size order.
* \param area memory area. (Not used.)
*
* Unreserve and free pages allocated by alloc_pages().
*/
void DRM(free_pages)(unsigned long address, int order, int area)
{
unsigned long bytes = PAGE_SIZE << order;
unsigned long addr;
unsigned int sz;
if (!address)
return;
/* Unreserve */
for (addr = address, sz = bytes;
sz > 0;
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
}
free_pages(address, order);
}
/** Wrapper around drm_ioremap() */
void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
{
return drm_ioremap(offset, size, dev);
}
/** Wrapper around drm_ioremap_nocache() */
void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
{
return drm_ioremap_nocache(offset, size, dev);
}
/** Wrapper around drm_iounmap() */
void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
{
drm_ioremapfree(pt, size, dev);
}
#if __OS_HAS_AGP
/** Wrapper around agp_allocate_memory() */
DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
{
return DRM(agp_allocate_memory)(pages, type);
}
/** Wrapper around agp_free_memory() */
int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
{
return DRM(agp_free_memory)(handle) ? 0 : -EINVAL;
}
/** Wrapper around agp_bind_memory() */
int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
{
return DRM(agp_bind_memory)(handle, start);
}
/** Wrapper around agp_unbind_memory() */
int DRM(unbind_agp)(DRM_AGP_MEM *handle)
{
return DRM(agp_unbind_memory)(handle);
}
#endif /* agp */
#endif /* debug_memory */

View File

@@ -0,0 +1,459 @@
/**
* \file drm_memory.h
* Memory management wrappers for DRM.
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include <linux/config.h>
#include "drmP.h"
typedef struct drm_mem_stats {
const char *name;
int succeed_count;
int free_count;
int fail_count;
unsigned long bytes_allocated;
unsigned long bytes_freed;
} drm_mem_stats_t;
static spinlock_t DRM(mem_lock) = SPIN_LOCK_UNLOCKED;
static unsigned long DRM(ram_available) = 0; /* In pages */
static unsigned long DRM(ram_used) = 0;
static drm_mem_stats_t DRM(mem_stats)[] = {
[DRM_MEM_DMA] = { "dmabufs" },
[DRM_MEM_SAREA] = { "sareas" },
[DRM_MEM_DRIVER] = { "driver" },
[DRM_MEM_MAGIC] = { "magic" },
[DRM_MEM_IOCTLS] = { "ioctltab" },
[DRM_MEM_MAPS] = { "maplist" },
[DRM_MEM_VMAS] = { "vmalist" },
[DRM_MEM_BUFS] = { "buflist" },
[DRM_MEM_SEGS] = { "seglist" },
[DRM_MEM_PAGES] = { "pagelist" },
[DRM_MEM_FILES] = { "files" },
[DRM_MEM_QUEUES] = { "queues" },
[DRM_MEM_CMDS] = { "commands" },
[DRM_MEM_MAPPINGS] = { "mappings" },
[DRM_MEM_BUFLISTS] = { "buflists" },
[DRM_MEM_AGPLISTS] = { "agplist" },
[DRM_MEM_SGLISTS] = { "sglist" },
[DRM_MEM_TOTALAGP] = { "totalagp" },
[DRM_MEM_BOUNDAGP] = { "boundagp" },
[DRM_MEM_CTXBITMAP] = { "ctxbitmap"},
[DRM_MEM_CTXLIST] = { "ctxlist" },
[DRM_MEM_STUB] = { "stub" },
{ NULL, 0, } /* Last entry must be null */
};
void DRM(mem_init)(void)
{
drm_mem_stats_t *mem;
struct sysinfo si;
for (mem = DRM(mem_stats); mem->name; ++mem) {
mem->succeed_count = 0;
mem->free_count = 0;
mem->fail_count = 0;
mem->bytes_allocated = 0;
mem->bytes_freed = 0;
}
si_meminfo(&si);
DRM(ram_available) = si.totalram;
DRM(ram_used) = 0;
}
/* drm_mem_info is called whenever a process reads /dev/drm/mem. */
static int DRM(_mem_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data)
{
drm_mem_stats_t *pt;
int len = 0;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
return 0;
}
*eof = 0;
*start = &buf[offset];
DRM_PROC_PRINT(" total counts "
" | outstanding \n");
DRM_PROC_PRINT("type alloc freed fail bytes freed"
" | allocs bytes\n\n");
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
"system", 0, 0, 0,
DRM(ram_available) << (PAGE_SHIFT - 10));
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu kB |\n",
"locked", 0, 0, 0, DRM(ram_used) >> 10);
DRM_PROC_PRINT("\n");
for (pt = DRM(mem_stats); pt->name; pt++) {
DRM_PROC_PRINT("%-9.9s %5d %5d %4d %10lu %10lu | %6d %10ld\n",
pt->name,
pt->succeed_count,
pt->free_count,
pt->fail_count,
pt->bytes_allocated,
pt->bytes_freed,
pt->succeed_count - pt->free_count,
(long)pt->bytes_allocated
- (long)pt->bytes_freed);
}
if (len > request + offset) return request;
*eof = 1;
return len - offset;
}
int DRM(mem_info)(char *buf, char **start, off_t offset,
int len, int *eof, void *data)
{
int ret;
spin_lock(&DRM(mem_lock));
ret = DRM(_mem_info)(buf, start, offset, len, eof, data);
spin_unlock(&DRM(mem_lock));
return ret;
}
void *DRM(alloc)(size_t size, int area)
{
void *pt;
if (!size) {
DRM_MEM_ERROR(area, "Allocating 0 bytes\n");
return NULL;
}
if (!(pt = kmalloc(size, GFP_KERNEL))) {
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[area].fail_count;
spin_unlock(&DRM(mem_lock));
return NULL;
}
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[area].succeed_count;
DRM(mem_stats)[area].bytes_allocated += size;
spin_unlock(&DRM(mem_lock));
return pt;
}
void *DRM(calloc)(size_t size, size_t nmemb, int area)
{
void *addr;
addr = DRM(alloc)(nmemb * size, area);
if (addr != NULL)
memset((void *)addr, 0, size * nmemb);
return addr;
}
void *DRM(realloc)(void *oldpt, size_t oldsize, size_t size, int area)
{
void *pt;
if (!(pt = DRM(alloc)(size, area))) return NULL;
if (oldpt && oldsize) {
memcpy(pt, oldpt, oldsize);
DRM(free)(oldpt, oldsize, area);
}
return pt;
}
void DRM(free)(void *pt, size_t size, int area)
{
int alloc_count;
int free_count;
if (!pt) DRM_MEM_ERROR(area, "Attempt to free NULL pointer\n");
else kfree(pt);
spin_lock(&DRM(mem_lock));
DRM(mem_stats)[area].bytes_freed += size;
free_count = ++DRM(mem_stats)[area].free_count;
alloc_count = DRM(mem_stats)[area].succeed_count;
spin_unlock(&DRM(mem_lock));
if (free_count > alloc_count) {
DRM_MEM_ERROR(area, "Excess frees: %d frees, %d allocs\n",
free_count, alloc_count);
}
}
unsigned long DRM(alloc_pages)(int order, int area)
{
unsigned long address;
unsigned long bytes = PAGE_SIZE << order;
unsigned long addr;
unsigned int sz;
spin_lock(&DRM(mem_lock));
if ((DRM(ram_used) >> PAGE_SHIFT)
> (DRM_RAM_PERCENT * DRM(ram_available)) / 100) {
spin_unlock(&DRM(mem_lock));
return 0;
}
spin_unlock(&DRM(mem_lock));
address = __get_free_pages(GFP_KERNEL, order);
if (!address) {
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[area].fail_count;
spin_unlock(&DRM(mem_lock));
return 0;
}
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[area].succeed_count;
DRM(mem_stats)[area].bytes_allocated += bytes;
DRM(ram_used) += bytes;
spin_unlock(&DRM(mem_lock));
/* Zero outside the lock */
memset((void *)address, 0, bytes);
/* Reserve */
for (addr = address, sz = bytes;
sz > 0;
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
SetPageReserved(virt_to_page(addr));
}
return address;
}
void DRM(free_pages)(unsigned long address, int order, int area)
{
unsigned long bytes = PAGE_SIZE << order;
int alloc_count;
int free_count;
unsigned long addr;
unsigned int sz;
if (!address) {
DRM_MEM_ERROR(area, "Attempt to free address 0\n");
} else {
/* Unreserve */
for (addr = address, sz = bytes;
sz > 0;
addr += PAGE_SIZE, sz -= PAGE_SIZE) {
ClearPageReserved(virt_to_page(addr));
}
free_pages(address, order);
}
spin_lock(&DRM(mem_lock));
free_count = ++DRM(mem_stats)[area].free_count;
alloc_count = DRM(mem_stats)[area].succeed_count;
DRM(mem_stats)[area].bytes_freed += bytes;
DRM(ram_used) -= bytes;
spin_unlock(&DRM(mem_lock));
if (free_count > alloc_count) {
DRM_MEM_ERROR(area,
"Excess frees: %d frees, %d allocs\n",
free_count, alloc_count);
}
}
void *DRM(ioremap)(unsigned long offset, unsigned long size, drm_device_t *dev)
{
void *pt;
if (!size) {
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
"Mapping 0 bytes at 0x%08lx\n", offset);
return NULL;
}
if (!(pt = drm_ioremap(offset, size, dev))) {
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
spin_unlock(&DRM(mem_lock));
return NULL;
}
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
spin_unlock(&DRM(mem_lock));
return pt;
}
void *DRM(ioremap_nocache)(unsigned long offset, unsigned long size, drm_device_t *dev)
{
void *pt;
if (!size) {
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
"Mapping 0 bytes at 0x%08lx\n", offset);
return NULL;
}
if (!(pt = drm_ioremap_nocache(offset, size, dev))) {
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[DRM_MEM_MAPPINGS].fail_count;
spin_unlock(&DRM(mem_lock));
return NULL;
}
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_allocated += size;
spin_unlock(&DRM(mem_lock));
return pt;
}
void DRM(ioremapfree)(void *pt, unsigned long size, drm_device_t *dev)
{
int alloc_count;
int free_count;
if (!pt)
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
"Attempt to free NULL pointer\n");
else
drm_ioremapfree(pt, size, dev);
spin_lock(&DRM(mem_lock));
DRM(mem_stats)[DRM_MEM_MAPPINGS].bytes_freed += size;
free_count = ++DRM(mem_stats)[DRM_MEM_MAPPINGS].free_count;
alloc_count = DRM(mem_stats)[DRM_MEM_MAPPINGS].succeed_count;
spin_unlock(&DRM(mem_lock));
if (free_count > alloc_count) {
DRM_MEM_ERROR(DRM_MEM_MAPPINGS,
"Excess frees: %d frees, %d allocs\n",
free_count, alloc_count);
}
}
#if __OS_HAS_AGP
DRM_AGP_MEM *DRM(alloc_agp)(int pages, u32 type)
{
DRM_AGP_MEM *handle;
if (!pages) {
DRM_MEM_ERROR(DRM_MEM_TOTALAGP, "Allocating 0 pages\n");
return NULL;
}
if ((handle = DRM(agp_allocate_memory)(pages, type))) {
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_allocated
+= pages << PAGE_SHIFT;
spin_unlock(&DRM(mem_lock));
return handle;
}
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[DRM_MEM_TOTALAGP].fail_count;
spin_unlock(&DRM(mem_lock));
return NULL;
}
int DRM(free_agp)(DRM_AGP_MEM *handle, int pages)
{
int alloc_count;
int free_count;
int retval = -EINVAL;
if (!handle) {
DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
"Attempt to free NULL AGP handle\n");
return retval;
}
if (DRM(agp_free_memory)(handle)) {
spin_lock(&DRM(mem_lock));
free_count = ++DRM(mem_stats)[DRM_MEM_TOTALAGP].free_count;
alloc_count = DRM(mem_stats)[DRM_MEM_TOTALAGP].succeed_count;
DRM(mem_stats)[DRM_MEM_TOTALAGP].bytes_freed
+= pages << PAGE_SHIFT;
spin_unlock(&DRM(mem_lock));
if (free_count > alloc_count) {
DRM_MEM_ERROR(DRM_MEM_TOTALAGP,
"Excess frees: %d frees, %d allocs\n",
free_count, alloc_count);
}
return 0;
}
return retval;
}
int DRM(bind_agp)(DRM_AGP_MEM *handle, unsigned int start)
{
int retcode = -EINVAL;
if (!handle) {
DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
"Attempt to bind NULL AGP handle\n");
return retcode;
}
if (!(retcode = DRM(agp_bind_memory)(handle, start))) {
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_allocated
+= handle->page_count << PAGE_SHIFT;
spin_unlock(&DRM(mem_lock));
return retcode;
}
spin_lock(&DRM(mem_lock));
++DRM(mem_stats)[DRM_MEM_BOUNDAGP].fail_count;
spin_unlock(&DRM(mem_lock));
return retcode;
}
int DRM(unbind_agp)(DRM_AGP_MEM *handle)
{
int alloc_count;
int free_count;
int retcode = -EINVAL;
if (!handle) {
DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
"Attempt to unbind NULL AGP handle\n");
return retcode;
}
if ((retcode = DRM(agp_unbind_memory)(handle))) return retcode;
spin_lock(&DRM(mem_lock));
free_count = ++DRM(mem_stats)[DRM_MEM_BOUNDAGP].free_count;
alloc_count = DRM(mem_stats)[DRM_MEM_BOUNDAGP].succeed_count;
DRM(mem_stats)[DRM_MEM_BOUNDAGP].bytes_freed
+= handle->page_count << PAGE_SHIFT;
spin_unlock(&DRM(mem_lock));
if (free_count > alloc_count) {
DRM_MEM_ERROR(DRM_MEM_BOUNDAGP,
"Excess frees: %d frees, %d allocs\n",
free_count, alloc_count);
}
return retcode;
}
#endif

View File

@@ -0,0 +1,157 @@
/**
* \file drm_os_linux.h
* OS abstraction macros.
*/
#include <linux/interrupt.h> /* For task queue support */
#include <linux/delay.h>
/** File pointer type */
#define DRMFILE struct file *
/** Ioctl arguments */
#define DRM_IOCTL_ARGS struct inode *inode, struct file *filp, unsigned int cmd, unsigned long data
#define DRM_ERR(d) -(d)
/** Current process ID */
#define DRM_CURRENTPID current->pid
#define DRM_UDELAY(d) udelay(d)
/** Read a byte from a MMIO region */
#define DRM_READ8(map, offset) readb(((void __iomem *)(map)->handle) + (offset))
/** Read a word from a MMIO region */
#define DRM_READ16(map, offset) readw(((void __iomem *)(map)->handle) + (offset))
/** Read a dword from a MMIO region */
#define DRM_READ32(map, offset) readl(((void __iomem *)(map)->handle) + (offset))
/** Write a byte into a MMIO region */
#define DRM_WRITE8(map, offset, val) writeb(val, ((void __iomem *)(map)->handle) + (offset))
/** Write a word into a MMIO region */
#define DRM_WRITE16(map, offset, val) writew(val, ((void __iomem *)(map)->handle) + (offset))
/** Write a dword into a MMIO region */
#define DRM_WRITE32(map, offset, val) writel(val, ((void __iomem *)(map)->handle) + (offset))
/** Read memory barrier */
#define DRM_READMEMORYBARRIER() rmb()
/** Write memory barrier */
#define DRM_WRITEMEMORYBARRIER() wmb()
/** Read/write memory barrier */
#define DRM_MEMORYBARRIER() mb()
/** DRM device local declaration */
#define DRM_DEVICE drm_file_t *priv = filp->private_data; \
drm_device_t *dev = priv->dev
/** IRQ handler arguments and return type and values */
#define DRM_IRQ_ARGS int irq, void *arg, struct pt_regs *regs
/** AGP types */
#if __OS_HAS_AGP
#define DRM_AGP_MEM struct agp_memory
#define DRM_AGP_KERN struct agp_kern_info
#else
/* define some dummy types for non AGP supporting kernels */
struct no_agp_kern {
unsigned long aper_base;
unsigned long aper_size;
};
#define DRM_AGP_MEM int
#define DRM_AGP_KERN struct no_agp_kern
#endif
#if !(__OS_HAS_MTRR)
static __inline__ int mtrr_add (unsigned long base, unsigned long size,
unsigned int type, char increment)
{
return -ENODEV;
}
static __inline__ int mtrr_del (int reg, unsigned long base,
unsigned long size)
{
return -ENODEV;
}
#define MTRR_TYPE_WRCOMB 1
#endif
/** Task queue handler arguments */
#define DRM_TASKQUEUE_ARGS void *arg
/** For data going into the kernel through the ioctl argument */
#define DRM_COPY_FROM_USER_IOCTL(arg1, arg2, arg3) \
if ( copy_from_user(&arg1, arg2, arg3) ) \
return -EFAULT
/** For data going from the kernel through the ioctl argument */
#define DRM_COPY_TO_USER_IOCTL(arg1, arg2, arg3) \
if ( copy_to_user(arg1, &arg2, arg3) ) \
return -EFAULT
/** Other copying of data to kernel space */
#define DRM_COPY_FROM_USER(arg1, arg2, arg3) \
copy_from_user(arg1, arg2, arg3)
/** Other copying of data from kernel space */
#define DRM_COPY_TO_USER(arg1, arg2, arg3) \
copy_to_user(arg1, arg2, arg3)
/* Macros for copyfrom user, but checking readability only once */
#define DRM_VERIFYAREA_READ( uaddr, size ) \
verify_area( VERIFY_READ, uaddr, size )
#define DRM_COPY_FROM_USER_UNCHECKED(arg1, arg2, arg3) \
__copy_from_user(arg1, arg2, arg3)
#define DRM_COPY_TO_USER_UNCHECKED(arg1, arg2, arg3) \
__copy_to_user(arg1, arg2, arg3)
#define DRM_GET_USER_UNCHECKED(val, uaddr) \
__get_user(val, uaddr)
#define DRM_PUT_USER_UNCHECKED(uaddr, val) \
__put_user(val, uaddr)
/** 'malloc' without the overhead of DRM(alloc)() */
#define DRM_MALLOC(x) kmalloc(x, GFP_KERNEL)
/** 'free' without the overhead of DRM(free)() */
#define DRM_FREE(x,size) kfree(x)
#define DRM_GET_PRIV_WITH_RETURN(_priv, _filp) _priv = _filp->private_data
/**
* Get the pointer to the SAREA.
*
* Searches the SAREA on the mapping lists and points drm_device::sarea to it.
*/
#define DRM_GETSAREA() \
do { \
drm_map_list_t *entry; \
list_for_each_entry( entry, &dev->maplist->head, head ) { \
if ( entry->map && \
entry->map->type == _DRM_SHM && \
(entry->map->flags & _DRM_CONTAINS_LOCK) ) { \
dev_priv->sarea = entry->map; \
break; \
} \
} \
} while (0)
#define DRM_HZ HZ
#define DRM_WAIT_ON( ret, queue, timeout, condition ) \
do { \
DECLARE_WAITQUEUE(entry, current); \
unsigned long end = jiffies + (timeout); \
add_wait_queue(&(queue), &entry); \
\
for (;;) { \
__set_current_state(TASK_INTERRUPTIBLE); \
if (condition) \
break; \
if (time_after_eq(jiffies, end)) { \
ret = -EBUSY; \
break; \
} \
schedule_timeout((HZ/100 > 1) ? HZ/100 : 1); \
if (signal_pending(current)) { \
ret = -EINTR; \
break; \
} \
} \
__set_current_state(TASK_RUNNING); \
remove_wait_queue(&(queue), &entry); \
} while (0)
#define DRM_WAKEUP( queue ) wake_up_interruptible( queue )
#define DRM_INIT_WAITQUEUE( queue ) init_waitqueue_head( queue )

View File

@@ -0,0 +1,211 @@
/*
This file is auto-generated from the drm_pciids.txt in the DRM CVS
Please contact dri-devel@lists.sf.net to add new cards to this list
*/
#define radeon_PCI_IDS \
{0x1002, 0x4136, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4137, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4237, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4242, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4336, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4337, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4437, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4965, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4966, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4967, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C57, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C58, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C59, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C5A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C65, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C66, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4C67, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5144, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5145, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5146, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5147, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5148, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5149, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x514F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5157, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5158, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5159, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x515A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5168, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5169, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x516A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x516B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x516C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5834, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5835, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5836, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5837, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5960, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5961, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5962, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5963, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5964, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5968, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5969, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x596A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x596B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5c61, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5c62, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5c63, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5c64, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define r128_PCI_IDS \
{0x1002, 0x4c45, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4d46, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4d4c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5041, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5042, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5043, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5044, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5045, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5046, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5047, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5048, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5049, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504A, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504B, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504D, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504E, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x504F, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5050, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5051, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5052, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5053, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5054, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5055, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5056, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5057, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5058, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5245, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5246, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5247, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x524b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x524c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x534d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5446, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x544C, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x5452, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define mga_PCI_IDS \
{0x102b, 0x0521, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x102b, 0x0525, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x102b, 0x2527, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define mach64_PCI_IDS \
{0x1002, 0x4749, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4750, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4751, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4742, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4744, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c49, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c50, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c51, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c42, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c44, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x474c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x474f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4752, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4753, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x474d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x474e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c52, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c53, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c4d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1002, 0x4c4e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define sisdrv_PCI_IDS \
{0x1039, 0x0300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x5300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x6300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1039, 0x7300, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define tdfx_PCI_IDS \
{0x121a, 0x0003, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x121a, 0x0004, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x121a, 0x0005, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x121a, 0x0007, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x121a, 0x0009, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x121a, 0x000b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define viadrv_PCI_IDS \
{0x1106, 0x3022, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x3122, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x7205, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x1106, 0x7204, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define i810_PCI_IDS \
{0x8086, 0x7121, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x7123, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x7125, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x1132, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define i830_PCI_IDS \
{0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define gamma_PCI_IDS \
{0x3d3d, 0x0008, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define savage_PCI_IDS \
{0x5333, 0x8a22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8a23, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c10, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c11, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c12, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c13, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c20, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c21, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c22, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c24, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2a, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2b, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2c, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2d, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2e, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8c2f, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8a25, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8a26, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8d01, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8d02, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x5333, 0x8d04, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}
#define ffb_PCI_IDS \
{0, 0, 0}
#define i915_PCI_IDS \
{0x8086, 0x3577, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2562, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x3582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2572, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0x8086, 0x2582, PCI_ANY_ID, PCI_ANY_ID, 0, 0, 0}, \
{0, 0, 0}

View File

@@ -0,0 +1,547 @@
/**
* \file drm_proc.h
* /proc support for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*
* \par Acknowledgements:
* Matthew J Sottek <matthew.j.sottek@intel.com> sent in a patch to fix
* the problem with the proc files not outputting all their information.
*/
/*
* Created: Mon Jan 11 09:48:47 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
static int DRM(name_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
static int DRM(vm_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
static int DRM(clients_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
static int DRM(queues_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
static int DRM(bufs_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
#if DRM_DEBUG_CODE
static int DRM(vma_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data);
#endif
/**
* Proc file list.
*/
struct drm_proc_list {
const char *name; /**< file name */
int (*f)(char *, char **, off_t, int, int *, void *); /**< proc callback*/
} DRM(proc_list)[] = {
{ "name", DRM(name_info) },
{ "mem", DRM(mem_info) },
{ "vm", DRM(vm_info) },
{ "clients", DRM(clients_info) },
{ "queues", DRM(queues_info) },
{ "bufs", DRM(bufs_info) },
#if DRM_DEBUG_CODE
{ "vma", DRM(vma_info) },
#endif
};
#define DRM_PROC_ENTRIES (sizeof(DRM(proc_list))/sizeof(DRM(proc_list)[0]))
/**
* Initialize the DRI proc filesystem for a device.
*
* \param dev DRM device.
* \param minor device minor number.
* \param root DRI proc dir entry.
* \param dev_root resulting DRI device proc dir entry.
* \return root entry pointer on success, or NULL on failure.
*
* Create the DRI proc root entry "/proc/dri", the device proc root entry
* "/proc/dri/%minor%/", and each entry in proc_list as
* "/proc/dri/%minor%/%name%".
*/
struct proc_dir_entry *DRM(proc_init)(drm_device_t *dev, int minor,
struct proc_dir_entry *root,
struct proc_dir_entry **dev_root)
{
struct proc_dir_entry *ent;
int i, j;
char name[64];
if (!minor) root = create_proc_entry("dri", S_IFDIR, NULL);
if (!root) {
DRM_ERROR("Cannot create /proc/dri\n");
return NULL;
}
sprintf(name, "%d", minor);
*dev_root = create_proc_entry(name, S_IFDIR, root);
if (!*dev_root) {
DRM_ERROR("Cannot create /proc/dri/%s\n", name);
return NULL;
}
for (i = 0; i < DRM_PROC_ENTRIES; i++) {
ent = create_proc_entry(DRM(proc_list)[i].name,
S_IFREG|S_IRUGO, *dev_root);
if (!ent) {
DRM_ERROR("Cannot create /proc/dri/%s/%s\n",
name, DRM(proc_list)[i].name);
for (j = 0; j < i; j++)
remove_proc_entry(DRM(proc_list)[i].name,
*dev_root);
remove_proc_entry(name, root);
if (!minor) remove_proc_entry("dri", NULL);
return NULL;
}
ent->read_proc = DRM(proc_list)[i].f;
ent->data = dev;
}
return root;
}
/**
* Cleanup the proc filesystem resources.
*
* \param minor device minor number.
* \param root DRI proc dir entry.
* \param dev_root DRI device proc dir entry.
* \return always zero.
*
* Remove all proc entries created by proc_init().
*/
int DRM(proc_cleanup)(int minor, struct proc_dir_entry *root,
struct proc_dir_entry *dev_root)
{
int i;
char name[64];
if (!root || !dev_root) return 0;
for (i = 0; i < DRM_PROC_ENTRIES; i++)
remove_proc_entry(DRM(proc_list)[i].name, dev_root);
sprintf(name, "%d", minor);
remove_proc_entry(name, root);
if (!minor) remove_proc_entry("dri", NULL);
return 0;
}
/**
* Called when "/proc/dri/.../name" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param request requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*
* Prints the device name together with the bus id if available.
*/
static int DRM(name_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
drm_device_t *dev = (drm_device_t *)data;
int len = 0;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
return 0;
}
*start = &buf[offset];
*eof = 0;
if (dev->unique) {
DRM_PROC_PRINT("%s 0x%lx %s\n",
dev->name, (long)old_encode_dev(dev->device), dev->unique);
} else {
DRM_PROC_PRINT("%s 0x%lx\n", dev->name, (long)old_encode_dev(dev->device));
}
if (len > request + offset) return request;
*eof = 1;
return len - offset;
}
/**
* Called when "/proc/dri/.../vm" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param request requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*
* Prints information about all mappings in drm_device::maplist.
*/
static int DRM(_vm_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
drm_device_t *dev = (drm_device_t *)data;
int len = 0;
drm_map_t *map;
drm_map_list_t *r_list;
struct list_head *list;
/* Hardcoded from _DRM_FRAME_BUFFER,
_DRM_REGISTERS, _DRM_SHM, _DRM_AGP, and
_DRM_SCATTER_GATHER. */
const char *types[] = { "FB", "REG", "SHM", "AGP", "SG" };
const char *type;
int i;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
return 0;
}
*start = &buf[offset];
*eof = 0;
DRM_PROC_PRINT("slot offset size type flags "
"address mtrr\n\n");
i = 0;
if (dev->maplist != NULL) list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head);
map = r_list->map;
if(!map) continue;
if (map->type < 0 || map->type > 4) type = "??";
else type = types[map->type];
DRM_PROC_PRINT("%4d 0x%08lx 0x%08lx %4.4s 0x%02x 0x%08lx ",
i,
map->offset,
map->size,
type,
map->flags,
(unsigned long)map->handle);
if (map->mtrr < 0) {
DRM_PROC_PRINT("none\n");
} else {
DRM_PROC_PRINT("%4d\n", map->mtrr);
}
i++;
}
if (len > request + offset) return request;
*eof = 1;
return len - offset;
}
/**
* Simply calls _vm_info() while holding the drm_device::struct_sem lock.
*/
static int DRM(vm_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
drm_device_t *dev = (drm_device_t *)data;
int ret;
down(&dev->struct_sem);
ret = DRM(_vm_info)(buf, start, offset, request, eof, data);
up(&dev->struct_sem);
return ret;
}
/**
* Called when "/proc/dri/.../queues" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param request requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*/
static int DRM(_queues_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data)
{
drm_device_t *dev = (drm_device_t *)data;
int len = 0;
int i;
drm_queue_t *q;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
return 0;
}
*start = &buf[offset];
*eof = 0;
DRM_PROC_PRINT(" ctx/flags use fin"
" blk/rw/rwf wait flushed queued"
" locks\n\n");
for (i = 0; i < dev->queue_count; i++) {
q = dev->queuelist[i];
atomic_inc(&q->use_count);
DRM_PROC_PRINT_RET(atomic_dec(&q->use_count),
"%5d/0x%03x %5d %5d"
" %5d/%c%c/%c%c%c %5Zd\n",
i,
q->flags,
atomic_read(&q->use_count),
atomic_read(&q->finalization),
atomic_read(&q->block_count),
atomic_read(&q->block_read) ? 'r' : '-',
atomic_read(&q->block_write) ? 'w' : '-',
waitqueue_active(&q->read_queue) ? 'r':'-',
waitqueue_active(&q->write_queue) ? 'w':'-',
waitqueue_active(&q->flush_queue) ? 'f':'-',
DRM_BUFCOUNT(&q->waitlist));
atomic_dec(&q->use_count);
}
if (len > request + offset) return request;
*eof = 1;
return len - offset;
}
/**
* Simply calls _queues_info() while holding the drm_device::struct_sem lock.
*/
static int DRM(queues_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
drm_device_t *dev = (drm_device_t *)data;
int ret;
down(&dev->struct_sem);
ret = DRM(_queues_info)(buf, start, offset, request, eof, data);
up(&dev->struct_sem);
return ret;
}
/**
* Called when "/proc/dri/.../bufs" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param request requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*/
static int DRM(_bufs_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
drm_device_t *dev = (drm_device_t *)data;
int len = 0;
drm_device_dma_t *dma = dev->dma;
int i;
if (!dma || offset > DRM_PROC_LIMIT) {
*eof = 1;
return 0;
}
*start = &buf[offset];
*eof = 0;
DRM_PROC_PRINT(" o size count free segs pages kB\n\n");
for (i = 0; i <= DRM_MAX_ORDER; i++) {
if (dma->bufs[i].buf_count)
DRM_PROC_PRINT("%2d %8d %5d %5d %5d %5d %5ld\n",
i,
dma->bufs[i].buf_size,
dma->bufs[i].buf_count,
atomic_read(&dma->bufs[i]
.freelist.count),
dma->bufs[i].seg_count,
dma->bufs[i].seg_count
*(1 << dma->bufs[i].page_order),
(dma->bufs[i].seg_count
* (1 << dma->bufs[i].page_order))
* PAGE_SIZE / 1024);
}
DRM_PROC_PRINT("\n");
for (i = 0; i < dma->buf_count; i++) {
if (i && !(i%32)) DRM_PROC_PRINT("\n");
DRM_PROC_PRINT(" %d", dma->buflist[i]->list);
}
DRM_PROC_PRINT("\n");
if (len > request + offset) return request;
*eof = 1;
return len - offset;
}
/**
* Simply calls _bufs_info() while holding the drm_device::struct_sem lock.
*/
static int DRM(bufs_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
drm_device_t *dev = (drm_device_t *)data;
int ret;
down(&dev->struct_sem);
ret = DRM(_bufs_info)(buf, start, offset, request, eof, data);
up(&dev->struct_sem);
return ret;
}
/**
* Called when "/proc/dri/.../clients" is read.
*
* \param buf output buffer.
* \param start start of output data.
* \param offset requested start offset.
* \param request requested number of bytes.
* \param eof whether there is no more data to return.
* \param data private data.
* \return number of written bytes.
*/
static int DRM(_clients_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data)
{
drm_device_t *dev = (drm_device_t *)data;
int len = 0;
drm_file_t *priv;
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
return 0;
}
*start = &buf[offset];
*eof = 0;
DRM_PROC_PRINT("a dev pid uid magic ioctls\n\n");
for (priv = dev->file_first; priv; priv = priv->next) {
DRM_PROC_PRINT("%c %3d %5d %5d %10u %10lu\n",
priv->authenticated ? 'y' : 'n',
priv->minor,
priv->pid,
priv->uid,
priv->magic,
priv->ioctl_count);
}
if (len > request + offset) return request;
*eof = 1;
return len - offset;
}
/**
* Simply calls _clients_info() while holding the drm_device::struct_sem lock.
*/
static int DRM(clients_info)(char *buf, char **start, off_t offset,
int request, int *eof, void *data)
{
drm_device_t *dev = (drm_device_t *)data;
int ret;
down(&dev->struct_sem);
ret = DRM(_clients_info)(buf, start, offset, request, eof, data);
up(&dev->struct_sem);
return ret;
}
#if DRM_DEBUG_CODE
static int DRM(_vma_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
drm_device_t *dev = (drm_device_t *)data;
int len = 0;
drm_vma_entry_t *pt;
struct vm_area_struct *vma;
#if defined(__i386__)
unsigned int pgprot;
#endif
if (offset > DRM_PROC_LIMIT) {
*eof = 1;
return 0;
}
*start = &buf[offset];
*eof = 0;
DRM_PROC_PRINT("vma use count: %d, high_memory = %p, 0x%08lx\n",
atomic_read(&dev->vma_count),
high_memory, virt_to_phys(high_memory));
for (pt = dev->vmalist; pt; pt = pt->next) {
if (!(vma = pt->vma)) continue;
DRM_PROC_PRINT("\n%5d 0x%08lx-0x%08lx %c%c%c%c%c%c 0x%08lx",
pt->pid,
vma->vm_start,
vma->vm_end,
vma->vm_flags & VM_READ ? 'r' : '-',
vma->vm_flags & VM_WRITE ? 'w' : '-',
vma->vm_flags & VM_EXEC ? 'x' : '-',
vma->vm_flags & VM_MAYSHARE ? 's' : 'p',
vma->vm_flags & VM_LOCKED ? 'l' : '-',
vma->vm_flags & VM_IO ? 'i' : '-',
VM_OFFSET(vma));
#if defined(__i386__)
pgprot = pgprot_val(vma->vm_page_prot);
DRM_PROC_PRINT(" %c%c%c%c%c%c%c%c%c",
pgprot & _PAGE_PRESENT ? 'p' : '-',
pgprot & _PAGE_RW ? 'w' : 'r',
pgprot & _PAGE_USER ? 'u' : 's',
pgprot & _PAGE_PWT ? 't' : 'b',
pgprot & _PAGE_PCD ? 'u' : 'c',
pgprot & _PAGE_ACCESSED ? 'a' : '-',
pgprot & _PAGE_DIRTY ? 'd' : '-',
pgprot & _PAGE_PSE ? 'm' : 'k',
pgprot & _PAGE_GLOBAL ? 'g' : 'l' );
#endif
DRM_PROC_PRINT("\n");
}
if (len > request + offset) return request;
*eof = 1;
return len - offset;
}
static int DRM(vma_info)(char *buf, char **start, off_t offset, int request,
int *eof, void *data)
{
drm_device_t *dev = (drm_device_t *)data;
int ret;
down(&dev->struct_sem);
ret = DRM(_vma_info)(buf, start, offset, request, eof, data);
up(&dev->struct_sem);
return ret;
}
#endif

View File

@@ -0,0 +1,78 @@
/**
* \file drm_sarea.h
* \brief SAREA definitions
*
* \author Michel Dänzer <michel@daenzer.net>
*/
/*
* Copyright 2002 Tungsten Graphics, Inc., Cedar Park, Texas.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#ifndef _DRM_SAREA_H_
#define _DRM_SAREA_H_
#include "drm.h"
/* SAREA area needs to be at least a page */
#if defined(__alpha__)
#define SAREA_MAX 0x2000
#elif defined(__ia64__)
#define SAREA_MAX 0x10000 /* 64kB */
#else
/* Intel 830M driver needs at least 8k SAREA */
#define SAREA_MAX 0x2000
#endif
/** Maximum number of drawables in the SAREA */
#define SAREA_MAX_DRAWABLES 256
#define SAREA_DRAWABLE_CLAIMED_ENTRY 0x80000000
/** SAREA drawable */
typedef struct drm_sarea_drawable {
unsigned int stamp;
unsigned int flags;
} drm_sarea_drawable_t;
/** SAREA frame */
typedef struct drm_sarea_frame {
unsigned int x;
unsigned int y;
unsigned int width;
unsigned int height;
unsigned int fullscreen;
} drm_sarea_frame_t;
/** SAREA */
typedef struct drm_sarea {
/** first thing is always the DRM locking structure */
drm_hw_lock_t lock;
/** \todo Use readers/writer lock for drm_sarea::drawable_lock */
drm_hw_lock_t drawable_lock;
drm_sarea_drawable_t drawableTable[SAREA_MAX_DRAWABLES]; /**< drawables */
drm_sarea_frame_t frame; /**< frame */
drm_context_t dummy_context;
} drm_sarea_t;
#endif /* _DRM_SAREA_H_ */

View File

@@ -0,0 +1,231 @@
/**
* \file drm_scatter.h
* IOCTLs to manage scatter/gather memory
*
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Mon Dec 18 23:20:54 2000 by gareth@valinux.com
*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include <linux/config.h>
#include <linux/vmalloc.h>
#include "drmP.h"
#define DEBUG_SCATTER 0
void DRM(sg_cleanup)( drm_sg_mem_t *entry )
{
struct page *page;
int i;
for ( i = 0 ; i < entry->pages ; i++ ) {
page = entry->pagelist[i];
if ( page )
ClearPageReserved( page );
}
vfree( entry->virtual );
DRM(free)( entry->busaddr,
entry->pages * sizeof(*entry->busaddr),
DRM_MEM_PAGES );
DRM(free)( entry->pagelist,
entry->pages * sizeof(*entry->pagelist),
DRM_MEM_PAGES );
DRM(free)( entry,
sizeof(*entry),
DRM_MEM_SGLISTS );
}
int DRM(sg_alloc)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_scatter_gather_t __user *argp = (void __user *)arg;
drm_scatter_gather_t request;
drm_sg_mem_t *entry;
unsigned long pages, i, j;
DRM_DEBUG( "%s\n", __FUNCTION__ );
if (!drm_core_check_feature(dev, DRIVER_SG))
return -EINVAL;
if ( dev->sg )
return -EINVAL;
if ( copy_from_user( &request, argp, sizeof(request) ) )
return -EFAULT;
entry = DRM(alloc)( sizeof(*entry), DRM_MEM_SGLISTS );
if ( !entry )
return -ENOMEM;
memset( entry, 0, sizeof(*entry) );
pages = (request.size + PAGE_SIZE - 1) / PAGE_SIZE;
DRM_DEBUG( "sg size=%ld pages=%ld\n", request.size, pages );
entry->pages = pages;
entry->pagelist = DRM(alloc)( pages * sizeof(*entry->pagelist),
DRM_MEM_PAGES );
if ( !entry->pagelist ) {
DRM(free)( entry, sizeof(*entry), DRM_MEM_SGLISTS );
return -ENOMEM;
}
memset(entry->pagelist, 0, pages * sizeof(*entry->pagelist));
entry->busaddr = DRM(alloc)( pages * sizeof(*entry->busaddr),
DRM_MEM_PAGES );
if ( !entry->busaddr ) {
DRM(free)( entry->pagelist,
entry->pages * sizeof(*entry->pagelist),
DRM_MEM_PAGES );
DRM(free)( entry,
sizeof(*entry),
DRM_MEM_SGLISTS );
return -ENOMEM;
}
memset( (void *)entry->busaddr, 0, pages * sizeof(*entry->busaddr) );
entry->virtual = vmalloc_32( pages << PAGE_SHIFT );
if ( !entry->virtual ) {
DRM(free)( entry->busaddr,
entry->pages * sizeof(*entry->busaddr),
DRM_MEM_PAGES );
DRM(free)( entry->pagelist,
entry->pages * sizeof(*entry->pagelist),
DRM_MEM_PAGES );
DRM(free)( entry,
sizeof(*entry),
DRM_MEM_SGLISTS );
return -ENOMEM;
}
/* This also forces the mapping of COW pages, so our page list
* will be valid. Please don't remove it...
*/
memset( entry->virtual, 0, pages << PAGE_SHIFT );
entry->handle = (unsigned long)entry->virtual;
DRM_DEBUG( "sg alloc handle = %08lx\n", entry->handle );
DRM_DEBUG( "sg alloc virtual = %p\n", entry->virtual );
for ( i = entry->handle, j = 0 ; j < pages ; i += PAGE_SIZE, j++ ) {
entry->pagelist[j] = vmalloc_to_page((void *)i);
if (!entry->pagelist[j])
goto failed;
SetPageReserved(entry->pagelist[j]);
}
request.handle = entry->handle;
if ( copy_to_user( argp, &request, sizeof(request) ) ) {
DRM(sg_cleanup)( entry );
return -EFAULT;
}
dev->sg = entry;
#if DEBUG_SCATTER
/* Verify that each page points to its virtual address, and vice
* versa.
*/
{
int error = 0;
for ( i = 0 ; i < pages ; i++ ) {
unsigned long *tmp;
tmp = page_address( entry->pagelist[i] );
for ( j = 0 ;
j < PAGE_SIZE / sizeof(unsigned long) ;
j++, tmp++ ) {
*tmp = 0xcafebabe;
}
tmp = (unsigned long *)((u8 *)entry->virtual +
(PAGE_SIZE * i));
for( j = 0 ;
j < PAGE_SIZE / sizeof(unsigned long) ;
j++, tmp++ ) {
if ( *tmp != 0xcafebabe && error == 0 ) {
error = 1;
DRM_ERROR( "Scatter allocation error, "
"pagelist does not match "
"virtual mapping\n" );
}
}
tmp = page_address( entry->pagelist[i] );
for(j = 0 ;
j < PAGE_SIZE / sizeof(unsigned long) ;
j++, tmp++) {
*tmp = 0;
}
}
if (error == 0)
DRM_ERROR( "Scatter allocation matches pagelist\n" );
}
#endif
return 0;
failed:
DRM(sg_cleanup)( entry );
return -ENOMEM;
}
int DRM(sg_free)( struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg )
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_scatter_gather_t request;
drm_sg_mem_t *entry;
if (!drm_core_check_feature(dev, DRIVER_SG))
return -EINVAL;
if ( copy_from_user( &request,
(drm_scatter_gather_t __user *)arg,
sizeof(request) ) )
return -EFAULT;
entry = dev->sg;
dev->sg = NULL;
if ( !entry || entry->handle != request.handle )
return -EINVAL;
DRM_DEBUG( "sg free virtual = %p\n", entry->virtual );
DRM(sg_cleanup)( entry );
return 0;
}

View File

@@ -0,0 +1,236 @@
/**
* \file drm_stub.h
* Stub support
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
*/
/*
* Created: Fri Jan 19 10:48:35 2001 by faith@acm.org
*
* Copyright 2001 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
#define DRM_STUB_MAXCARDS 16 /* Enough for one machine */
static struct class_simple *drm_class;
/** Stub list. One for each minor. */
static struct drm_stub_list {
const char *name;
struct file_operations *fops; /**< file operations */
struct proc_dir_entry *dev_root; /**< proc directory entry */
} *DRM(stub_list);
static struct proc_dir_entry *DRM(stub_root);
/** Stub information */
static struct drm_stub_info {
int (*info_register)(const char *name, struct file_operations *fops,
drm_device_t *dev);
int (*info_unregister)(int minor);
} DRM(stub_info);
/**
* File \c open operation.
*
* \param inode device inode.
* \param filp file pointer.
*
* Puts the drm_stub_list::fops corresponding to the device minor number into
* \p filp, call the \c open method, and restore the file operations.
*/
static int DRM(stub_open)(struct inode *inode, struct file *filp)
{
int minor = iminor(inode);
int err = -ENODEV;
struct file_operations *old_fops;
if (!DRM(stub_list) || !DRM(stub_list)[minor].fops) return -ENODEV;
old_fops = filp->f_op;
filp->f_op = fops_get(DRM(stub_list)[minor].fops);
if (filp->f_op->open && (err = filp->f_op->open(inode, filp))) {
fops_put(filp->f_op);
filp->f_op = fops_get(old_fops);
}
fops_put(old_fops);
return err;
}
/** File operations structure */
static struct file_operations DRM(stub_fops) = {
.owner = THIS_MODULE,
.open = DRM(stub_open)
};
/**
* Get a device minor number.
*
* \param name driver name.
* \param fops file operations.
* \param dev DRM device.
* \return minor number on success, or a negative number on failure.
*
* Allocate and initialize ::stub_list if one doesn't exist already. Search an
* empty entry and initialize it to the given parameters, and create the proc
* init entry via proc_init().
*/
static int DRM(stub_getminor)(const char *name, struct file_operations *fops,
drm_device_t *dev)
{
int i;
if (!DRM(stub_list)) {
DRM(stub_list) = DRM(alloc)(sizeof(*DRM(stub_list))
* DRM_STUB_MAXCARDS, DRM_MEM_STUB);
if(!DRM(stub_list)) return -1;
for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
DRM(stub_list)[i].name = NULL;
DRM(stub_list)[i].fops = NULL;
}
}
for (i = 0; i < DRM_STUB_MAXCARDS; i++) {
if (!DRM(stub_list)[i].fops) {
DRM(stub_list)[i].name = name;
DRM(stub_list)[i].fops = fops;
DRM(stub_root) = DRM(proc_init)(dev, i, DRM(stub_root),
&DRM(stub_list)[i]
.dev_root);
class_simple_device_add(drm_class, MKDEV(DRM_MAJOR, i), NULL, name);
return i;
}
}
return -1;
}
/**
* Put a device minor number.
*
* \param minor minor number.
* \return always zero.
*
* Cleans up the proc resources. If a minor is zero then release the foreign
* "drm" data, otherwise unregisters the "drm" data, frees the stub list and
* unregisters the character device.
*/
static int DRM(stub_putminor)(int minor)
{
if (minor < 0 || minor >= DRM_STUB_MAXCARDS) return -1;
DRM(stub_list)[minor].name = NULL;
DRM(stub_list)[minor].fops = NULL;
DRM(proc_cleanup)(minor, DRM(stub_root),
DRM(stub_list)[minor].dev_root);
if (minor) {
class_simple_device_remove(MKDEV(DRM_MAJOR, minor));
inter_module_put("drm");
} else {
inter_module_unregister("drm");
DRM(free)(DRM(stub_list),
sizeof(*DRM(stub_list)) * DRM_STUB_MAXCARDS,
DRM_MEM_STUB);
unregister_chrdev(DRM_MAJOR, "drm");
class_simple_device_remove(MKDEV(DRM_MAJOR, minor));
class_simple_destroy(drm_class);
}
return 0;
}
/**
* Register.
*
* \param name driver name.
* \param fops file operations
* \param dev DRM device.
* \return zero on success or a negative number on failure.
*
* Attempt to register the char device and get the foreign "drm" data. If
* successful then another module already registered so gets the stub info,
* otherwise use this module stub info and make it available for other modules.
*
* Finally calls stub_info::info_register.
*/
int DRM(stub_register)(const char *name, struct file_operations *fops,
drm_device_t *dev)
{
struct drm_stub_info *i = NULL;
int ret1;
int ret2;
DRM_DEBUG("\n");
ret1 = register_chrdev(DRM_MAJOR, "drm", &DRM(stub_fops));
if (!ret1) {
drm_class = class_simple_create(THIS_MODULE, "drm");
if (IS_ERR(drm_class)) {
printk (KERN_ERR "Error creating drm class.\n");
unregister_chrdev(DRM_MAJOR, "drm");
return PTR_ERR(drm_class);
}
}
else if (ret1 == -EBUSY)
i = (struct drm_stub_info *)inter_module_get("drm");
else
return -1;
if (i) {
/* Already registered */
DRM(stub_info).info_register = i->info_register;
DRM(stub_info).info_unregister = i->info_unregister;
DRM_DEBUG("already registered\n");
} else if (DRM(stub_info).info_register != DRM(stub_getminor)) {
DRM(stub_info).info_register = DRM(stub_getminor);
DRM(stub_info).info_unregister = DRM(stub_putminor);
DRM_DEBUG("calling inter_module_register\n");
inter_module_register("drm", THIS_MODULE, &DRM(stub_info));
}
if (DRM(stub_info).info_register) {
ret2 = DRM(stub_info).info_register(name, fops, dev);
if (ret2) {
if (!ret1) {
unregister_chrdev(DRM_MAJOR, "drm");
class_simple_destroy(drm_class);
}
if (!i)
inter_module_unregister("drm");
}
return ret2;
}
return -1;
}
/**
* Unregister.
*
* \param minor
*
* Calls drm_stub_info::unregister.
*/
int DRM(stub_unregister)(int minor)
{
DRM_DEBUG("%d\n", minor);
if (DRM(stub_info).info_unregister)
return DRM(stub_info).info_unregister(minor);
return -1;
}

View File

@@ -0,0 +1,667 @@
/**
* \file drm_vm.h
* Memory mapping for DRM
*
* \author Rickard E. (Rik) Faith <faith@valinux.com>
* \author Gareth Hughes <gareth@valinux.com>
*/
/*
* Created: Mon Jan 4 08:58:31 1999 by faith@valinux.com
*
* Copyright 1999 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*/
#include "drmP.h"
/**
* \c nopage method for AGP virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
* \return pointer to the page structure.
*
* Find the right map and if it's AGP memory find the real physical page to
* map, get the page, increment the use count and return it.
*/
#if __OS_HAS_AGP
static __inline__ struct page *DRM(do_vm_nopage)(struct vm_area_struct *vma,
unsigned long address)
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->dev;
drm_map_t *map = NULL;
drm_map_list_t *r_list;
struct list_head *list;
/*
* Find the right map
*/
if (!drm_core_has_AGP(dev))
goto vm_nopage_error;
if(!dev->agp || !dev->agp->cant_use_aperture) goto vm_nopage_error;
list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head);
map = r_list->map;
if (!map) continue;
if (map->offset == VM_OFFSET(vma)) break;
}
if (map && map->type == _DRM_AGP) {
unsigned long offset = address - vma->vm_start;
unsigned long baddr = VM_OFFSET(vma) + offset;
struct drm_agp_mem *agpmem;
struct page *page;
#ifdef __alpha__
/*
* Adjust to a bus-relative address
*/
baddr -= dev->hose->mem_space->start;
#endif
/*
* It's AGP memory - find the real physical page to map
*/
for(agpmem = dev->agp->memory; agpmem; agpmem = agpmem->next) {
if (agpmem->bound <= baddr &&
agpmem->bound + agpmem->pages * PAGE_SIZE > baddr)
break;
}
if (!agpmem) goto vm_nopage_error;
/*
* Get the page, inc the use count, and return it
*/
offset = (baddr - agpmem->bound) >> PAGE_SHIFT;
page = virt_to_page(__va(agpmem->memory->memory[offset]));
get_page(page);
DRM_DEBUG("baddr = 0x%lx page = 0x%p, offset = 0x%lx, count=%d\n",
baddr, __va(agpmem->memory->memory[offset]), offset,
page_count(page));
return page;
}
vm_nopage_error:
return NOPAGE_SIGBUS; /* Disallow mremap */
}
#else /* __OS_HAS_AGP */
static __inline__ struct page *DRM(do_vm_nopage)(struct vm_area_struct *vma,
unsigned long address)
{
return NOPAGE_SIGBUS;
}
#endif /* __OS_HAS_AGP */
/**
* \c nopage method for shared virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
* \return pointer to the page structure.
*
* Get the the mapping, find the real physical page to map, get the page, and
* return it.
*/
static __inline__ struct page *DRM(do_vm_shm_nopage)(struct vm_area_struct *vma,
unsigned long address)
{
drm_map_t *map = (drm_map_t *)vma->vm_private_data;
unsigned long offset;
unsigned long i;
struct page *page;
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
if (!map) return NOPAGE_OOM; /* Nothing allocated */
offset = address - vma->vm_start;
i = (unsigned long)map->handle + offset;
page = vmalloc_to_page((void *)i);
if (!page)
return NOPAGE_OOM;
get_page(page);
DRM_DEBUG("shm_nopage 0x%lx\n", address);
return page;
}
/**
* \c close method for shared virtual memory.
*
* \param vma virtual memory area.
*
* Deletes map information if we are the last
* person to close a mapping and it's not in the global maplist.
*/
void DRM(vm_shm_close)(struct vm_area_struct *vma)
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->dev;
drm_vma_entry_t *pt, *prev, *next;
drm_map_t *map;
drm_map_list_t *r_list;
struct list_head *list;
int found_maps = 0;
DRM_DEBUG("0x%08lx,0x%08lx\n",
vma->vm_start, vma->vm_end - vma->vm_start);
atomic_dec(&dev->vma_count);
map = vma->vm_private_data;
down(&dev->struct_sem);
for (pt = dev->vmalist, prev = NULL; pt; pt = next) {
next = pt->next;
if (pt->vma->vm_private_data == map) found_maps++;
if (pt->vma == vma) {
if (prev) {
prev->next = pt->next;
} else {
dev->vmalist = pt->next;
}
DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS);
} else {
prev = pt;
}
}
/* We were the only map that was found */
if(found_maps == 1 &&
map->flags & _DRM_REMOVABLE) {
/* Check to see if we are in the maplist, if we are not, then
* we delete this mappings information.
*/
found_maps = 0;
list = &dev->maplist->head;
list_for_each(list, &dev->maplist->head) {
r_list = list_entry(list, drm_map_list_t, head);
if (r_list->map == map) found_maps++;
}
if(!found_maps) {
switch (map->type) {
case _DRM_REGISTERS:
case _DRM_FRAME_BUFFER:
if (drm_core_has_MTRR(dev) && map->mtrr >= 0) {
int retcode;
retcode = mtrr_del(map->mtrr,
map->offset,
map->size);
DRM_DEBUG("mtrr_del = %d\n", retcode);
}
DRM(ioremapfree)(map->handle, map->size, dev);
break;
case _DRM_SHM:
vfree(map->handle);
break;
case _DRM_AGP:
case _DRM_SCATTER_GATHER:
break;
}
DRM(free)(map, sizeof(*map), DRM_MEM_MAPS);
}
}
up(&dev->struct_sem);
}
/**
* \c nopage method for DMA virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
* \return pointer to the page structure.
*
* Determine the page number from the page offset and get it from drm_device_dma::pagelist.
*/
static __inline__ struct page *DRM(do_vm_dma_nopage)(struct vm_area_struct *vma,
unsigned long address)
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->dev;
drm_device_dma_t *dma = dev->dma;
unsigned long offset;
unsigned long page_nr;
struct page *page;
if (!dma) return NOPAGE_SIGBUS; /* Error */
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
if (!dma->pagelist) return NOPAGE_OOM ; /* Nothing allocated */
offset = address - vma->vm_start; /* vm_[pg]off[set] should be 0 */
page_nr = offset >> PAGE_SHIFT;
page = virt_to_page((dma->pagelist[page_nr] +
(offset & (~PAGE_MASK))));
get_page(page);
DRM_DEBUG("dma_nopage 0x%lx (page %lu)\n", address, page_nr);
return page;
}
/**
* \c nopage method for scatter-gather virtual memory.
*
* \param vma virtual memory area.
* \param address access address.
* \return pointer to the page structure.
*
* Determine the map offset from the page offset and get it from drm_sg_mem::pagelist.
*/
static __inline__ struct page *DRM(do_vm_sg_nopage)(struct vm_area_struct *vma,
unsigned long address)
{
drm_map_t *map = (drm_map_t *)vma->vm_private_data;
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->dev;
drm_sg_mem_t *entry = dev->sg;
unsigned long offset;
unsigned long map_offset;
unsigned long page_offset;
struct page *page;
if (!entry) return NOPAGE_SIGBUS; /* Error */
if (address > vma->vm_end) return NOPAGE_SIGBUS; /* Disallow mremap */
if (!entry->pagelist) return NOPAGE_OOM ; /* Nothing allocated */
offset = address - vma->vm_start;
map_offset = map->offset - dev->sg->handle;
page_offset = (offset >> PAGE_SHIFT) + (map_offset >> PAGE_SHIFT);
page = entry->pagelist[page_offset];
get_page(page);
return page;
}
#if LINUX_VERSION_CODE > KERNEL_VERSION(2,6,0)
static struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
unsigned long address,
int *type) {
if (type) *type = VM_FAULT_MINOR;
return DRM(do_vm_nopage)(vma, address);
}
static struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
unsigned long address,
int *type) {
if (type) *type = VM_FAULT_MINOR;
return DRM(do_vm_shm_nopage)(vma, address);
}
static struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
unsigned long address,
int *type) {
if (type) *type = VM_FAULT_MINOR;
return DRM(do_vm_dma_nopage)(vma, address);
}
static struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
unsigned long address,
int *type) {
if (type) *type = VM_FAULT_MINOR;
return DRM(do_vm_sg_nopage)(vma, address);
}
#else /* LINUX_VERSION_CODE <= KERNEL_VERSION(2,6,0) */
static struct page *DRM(vm_nopage)(struct vm_area_struct *vma,
unsigned long address,
int unused) {
return DRM(do_vm_nopage)(vma, address);
}
static struct page *DRM(vm_shm_nopage)(struct vm_area_struct *vma,
unsigned long address,
int unused) {
return DRM(do_vm_shm_nopage)(vma, address);
}
static struct page *DRM(vm_dma_nopage)(struct vm_area_struct *vma,
unsigned long address,
int unused) {
return DRM(do_vm_dma_nopage)(vma, address);
}
static struct page *DRM(vm_sg_nopage)(struct vm_area_struct *vma,
unsigned long address,
int unused) {
return DRM(do_vm_sg_nopage)(vma, address);
}
#endif
/** AGP virtual memory operations */
static struct vm_operations_struct DRM(vm_ops) = {
.nopage = DRM(vm_nopage),
.open = DRM(vm_open),
.close = DRM(vm_close),
};
/** Shared virtual memory operations */
static struct vm_operations_struct DRM(vm_shm_ops) = {
.nopage = DRM(vm_shm_nopage),
.open = DRM(vm_open),
.close = DRM(vm_shm_close),
};
/** DMA virtual memory operations */
static struct vm_operations_struct DRM(vm_dma_ops) = {
.nopage = DRM(vm_dma_nopage),
.open = DRM(vm_open),
.close = DRM(vm_close),
};
/** Scatter-gather virtual memory operations */
static struct vm_operations_struct DRM(vm_sg_ops) = {
.nopage = DRM(vm_sg_nopage),
.open = DRM(vm_open),
.close = DRM(vm_close),
};
/**
* \c open method for shared virtual memory.
*
* \param vma virtual memory area.
*
* Create a new drm_vma_entry structure as the \p vma private data entry and
* add it to drm_device::vmalist.
*/
void DRM(vm_open)(struct vm_area_struct *vma)
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->dev;
drm_vma_entry_t *vma_entry;
DRM_DEBUG("0x%08lx,0x%08lx\n",
vma->vm_start, vma->vm_end - vma->vm_start);
atomic_inc(&dev->vma_count);
vma_entry = DRM(alloc)(sizeof(*vma_entry), DRM_MEM_VMAS);
if (vma_entry) {
down(&dev->struct_sem);
vma_entry->vma = vma;
vma_entry->next = dev->vmalist;
vma_entry->pid = current->pid;
dev->vmalist = vma_entry;
up(&dev->struct_sem);
}
}
/**
* \c close method for all virtual memory types.
*
* \param vma virtual memory area.
*
* Search the \p vma private data entry in drm_device::vmalist, unlink it, and
* free it.
*/
void DRM(vm_close)(struct vm_area_struct *vma)
{
drm_file_t *priv = vma->vm_file->private_data;
drm_device_t *dev = priv->dev;
drm_vma_entry_t *pt, *prev;
DRM_DEBUG("0x%08lx,0x%08lx\n",
vma->vm_start, vma->vm_end - vma->vm_start);
atomic_dec(&dev->vma_count);
down(&dev->struct_sem);
for (pt = dev->vmalist, prev = NULL; pt; prev = pt, pt = pt->next) {
if (pt->vma == vma) {
if (prev) {
prev->next = pt->next;
} else {
dev->vmalist = pt->next;
}
DRM(free)(pt, sizeof(*pt), DRM_MEM_VMAS);
break;
}
}
up(&dev->struct_sem);
}
/**
* mmap DMA memory.
*
* \param filp file pointer.
* \param vma virtual memory area.
* \return zero on success or a negative number on failure.
*
* Sets the virtual memory area operations structure to vm_dma_ops, the file
* pointer, and calls vm_open().
*/
int DRM(mmap_dma)(struct file *filp, struct vm_area_struct *vma)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev;
drm_device_dma_t *dma;
unsigned long length = vma->vm_end - vma->vm_start;
lock_kernel();
dev = priv->dev;
dma = dev->dma;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
/* Length must match exact page count */
if (!dma || (length >> PAGE_SHIFT) != dma->page_count) {
unlock_kernel();
return -EINVAL;
}
unlock_kernel();
vma->vm_ops = &DRM(vm_dma_ops);
#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
#else
vma->vm_flags |= VM_RESERVED; /* Don't swap */
#endif
vma->vm_file = filp; /* Needed for drm_vm_open() */
DRM(vm_open)(vma);
return 0;
}
unsigned long DRM(core_get_map_ofs)(drm_map_t *map)
{
return map->offset;
}
unsigned long DRM(core_get_reg_ofs)(struct drm_device *dev)
{
#ifdef __alpha__
return dev->hose->dense_mem_base - dev->hose->mem_space->start;
#else
return 0;
#endif
}
/**
* mmap DMA memory.
*
* \param filp file pointer.
* \param vma virtual memory area.
* \return zero on success or a negative number on failure.
*
* If the virtual memory area has no offset associated with it then it's a DMA
* area, so calls mmap_dma(). Otherwise searches the map in drm_device::maplist,
* checks that the restricted flag is not set, sets the virtual memory operations
* according to the mapping type and remaps the pages. Finally sets the file
* pointer and calls vm_open().
*/
int DRM(mmap)(struct file *filp, struct vm_area_struct *vma)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_map_t *map = NULL;
drm_map_list_t *r_list;
unsigned long offset = 0;
struct list_head *list;
DRM_DEBUG("start = 0x%lx, end = 0x%lx, offset = 0x%lx\n",
vma->vm_start, vma->vm_end, VM_OFFSET(vma));
if ( !priv->authenticated ) return -EACCES;
/* We check for "dma". On Apple's UniNorth, it's valid to have
* the AGP mapped at physical address 0
* --BenH.
*/
if (!VM_OFFSET(vma)
#if __OS_HAS_AGP
&& (!dev->agp || dev->agp->agp_info.device->vendor != PCI_VENDOR_ID_APPLE)
#endif
)
return DRM(mmap_dma)(filp, vma);
/* A sequential search of a linked list is
fine here because: 1) there will only be
about 5-10 entries in the list and, 2) a
DRI client only has to do this mapping
once, so it doesn't have to be optimized
for performance, even if the list was a
bit longer. */
list_for_each(list, &dev->maplist->head) {
unsigned long off;
r_list = list_entry(list, drm_map_list_t, head);
map = r_list->map;
if (!map) continue;
off = dev->fn_tbl.get_map_ofs(map);
if (off == VM_OFFSET(vma)) break;
}
if (!map || ((map->flags&_DRM_RESTRICTED) && !capable(CAP_SYS_ADMIN)))
return -EPERM;
/* Check for valid size. */
if (map->size != vma->vm_end - vma->vm_start) return -EINVAL;
if (!capable(CAP_SYS_ADMIN) && (map->flags & _DRM_READ_ONLY)) {
vma->vm_flags &= ~(VM_WRITE | VM_MAYWRITE);
#if defined(__i386__) || defined(__x86_64__)
pgprot_val(vma->vm_page_prot) &= ~_PAGE_RW;
#else
/* Ye gads this is ugly. With more thought
we could move this up higher and use
`protection_map' instead. */
vma->vm_page_prot = __pgprot(pte_val(pte_wrprotect(
__pte(pgprot_val(vma->vm_page_prot)))));
#endif
}
switch (map->type) {
case _DRM_AGP:
if (drm_core_has_AGP(dev) && dev->agp->cant_use_aperture) {
/*
* On some platforms we can't talk to bus dma address from the CPU, so for
* memory of type DRM_AGP, we'll deal with sorting out the real physical
* pages and mappings in nopage()
*/
#if defined(__powerpc__)
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE;
#endif
vma->vm_ops = &DRM(vm_ops);
break;
}
/* fall through to _DRM_FRAME_BUFFER... */
case _DRM_FRAME_BUFFER:
case _DRM_REGISTERS:
if (VM_OFFSET(vma) >= __pa(high_memory)) {
#if defined(__i386__) || defined(__x86_64__)
if (boot_cpu_data.x86 > 3 && map->type != _DRM_AGP) {
pgprot_val(vma->vm_page_prot) |= _PAGE_PCD;
pgprot_val(vma->vm_page_prot) &= ~_PAGE_PWT;
}
#elif defined(__powerpc__)
pgprot_val(vma->vm_page_prot) |= _PAGE_NO_CACHE | _PAGE_GUARDED;
#endif
vma->vm_flags |= VM_IO; /* not in core dump */
}
#if defined(__ia64__)
if (map->type != _DRM_AGP)
vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot);
#endif
offset = dev->fn_tbl.get_reg_ofs(dev);
#ifdef __sparc__
if (io_remap_page_range(DRM_RPR_ARG(vma) vma->vm_start,
VM_OFFSET(vma) + offset,
vma->vm_end - vma->vm_start,
vma->vm_page_prot, 0))
#else
if (remap_pfn_range(DRM_RPR_ARG(vma) vma->vm_start,
(VM_OFFSET(vma) + offset) >> PAGE_SHIFT,
vma->vm_end - vma->vm_start,
vma->vm_page_prot))
#endif
return -EAGAIN;
DRM_DEBUG(" Type = %d; start = 0x%lx, end = 0x%lx,"
" offset = 0x%lx\n",
map->type,
vma->vm_start, vma->vm_end, VM_OFFSET(vma) + offset);
vma->vm_ops = &DRM(vm_ops);
break;
case _DRM_SHM:
vma->vm_ops = &DRM(vm_shm_ops);
vma->vm_private_data = (void *)map;
/* Don't let this area swap. Change when
DRM_KERNEL advisory is supported. */
#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
vma->vm_flags |= VM_LOCKED;
#else
vma->vm_flags |= VM_RESERVED;
#endif
break;
case _DRM_SCATTER_GATHER:
vma->vm_ops = &DRM(vm_sg_ops);
vma->vm_private_data = (void *)map;
#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
vma->vm_flags |= VM_LOCKED;
#else
vma->vm_flags |= VM_RESERVED;
#endif
break;
default:
return -EINVAL; /* This should never happen. */
}
#if LINUX_VERSION_CODE <= 0x02040e /* KERNEL_VERSION(2,4,14) */
vma->vm_flags |= VM_LOCKED | VM_SHM; /* Don't swap */
#else
vma->vm_flags |= VM_RESERVED; /* Don't swap */
#endif
vma->vm_file = filp; /* Needed for drm_vm_open() */
DRM(vm_open)(vma);
return 0;
}

View File

@@ -0,0 +1,12 @@
/* ffb.h -- ffb DRM template customization -*- linux-c -*-
*/
#ifndef __FFB_H__
#define __FFB_H__
/* This remains constant for all DRM template files.
*/
#define DRM(x) ffb_##x
#endif

View File

@@ -0,0 +1,551 @@
/* $Id: ffb_context.c,v 1.5 2001/08/09 17:47:51 davem Exp $
* ffb_context.c: Creator/Creator3D DRI/DRM context switching.
*
* Copyright (C) 2000 David S. Miller (davem@redhat.com)
*
* Almost entirely stolen from tdfx_context.c, see there
* for authors.
*/
#include <linux/sched.h>
#include <asm/upa.h>
#include "ffb.h"
#include "drmP.h"
#include "ffb_drv.h"
static int DRM(alloc_queue)(drm_device_t *dev, int is_2d_only)
{
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
int i;
for (i = 0; i < FFB_MAX_CTXS; i++) {
if (fpriv->hw_state[i] == NULL)
break;
}
if (i == FFB_MAX_CTXS)
return -1;
fpriv->hw_state[i] = kmalloc(sizeof(struct ffb_hw_context), GFP_KERNEL);
if (fpriv->hw_state[i] == NULL)
return -1;
fpriv->hw_state[i]->is_2d_only = is_2d_only;
/* Plus one because 0 is the special DRM_KERNEL_CONTEXT. */
return i + 1;
}
static void ffb_save_context(ffb_dev_priv_t *fpriv, int idx)
{
ffb_fbcPtr ffb = fpriv->regs;
struct ffb_hw_context *ctx;
int i;
ctx = fpriv->hw_state[idx - 1];
if (idx == 0 || ctx == NULL)
return;
if (ctx->is_2d_only) {
/* 2D applications only care about certain pieces
* of state.
*/
ctx->drawop = upa_readl(&ffb->drawop);
ctx->ppc = upa_readl(&ffb->ppc);
ctx->wid = upa_readl(&ffb->wid);
ctx->fg = upa_readl(&ffb->fg);
ctx->bg = upa_readl(&ffb->bg);
ctx->xclip = upa_readl(&ffb->xclip);
ctx->fbc = upa_readl(&ffb->fbc);
ctx->rop = upa_readl(&ffb->rop);
ctx->cmp = upa_readl(&ffb->cmp);
ctx->matchab = upa_readl(&ffb->matchab);
ctx->magnab = upa_readl(&ffb->magnab);
ctx->pmask = upa_readl(&ffb->pmask);
ctx->xpmask = upa_readl(&ffb->xpmask);
ctx->lpat = upa_readl(&ffb->lpat);
ctx->fontxy = upa_readl(&ffb->fontxy);
ctx->fontw = upa_readl(&ffb->fontw);
ctx->fontinc = upa_readl(&ffb->fontinc);
/* stencil/stencilctl only exists on FFB2+ and later
* due to the introduction of 3DRAM-III.
*/
if (fpriv->ffb_type == ffb2_vertical_plus ||
fpriv->ffb_type == ffb2_horizontal_plus) {
ctx->stencil = upa_readl(&ffb->stencil);
ctx->stencilctl = upa_readl(&ffb->stencilctl);
}
for (i = 0; i < 32; i++)
ctx->area_pattern[i] = upa_readl(&ffb->pattern[i]);
ctx->ucsr = upa_readl(&ffb->ucsr);
return;
}
/* Fetch drawop. */
ctx->drawop = upa_readl(&ffb->drawop);
/* If we were saving the vertex registers, this is where
* we would do it. We would save 32 32-bit words starting
* at ffb->suvtx.
*/
/* Capture rendering attributes. */
ctx->ppc = upa_readl(&ffb->ppc); /* Pixel Processor Control */
ctx->wid = upa_readl(&ffb->wid); /* Current WID */
ctx->fg = upa_readl(&ffb->fg); /* Constant FG color */
ctx->bg = upa_readl(&ffb->bg); /* Constant BG color */
ctx->consty = upa_readl(&ffb->consty); /* Constant Y */
ctx->constz = upa_readl(&ffb->constz); /* Constant Z */
ctx->xclip = upa_readl(&ffb->xclip); /* X plane clip */
ctx->dcss = upa_readl(&ffb->dcss); /* Depth Cue Scale Slope */
ctx->vclipmin = upa_readl(&ffb->vclipmin); /* Primary XY clip, minimum */
ctx->vclipmax = upa_readl(&ffb->vclipmax); /* Primary XY clip, maximum */
ctx->vclipzmin = upa_readl(&ffb->vclipzmin); /* Primary Z clip, minimum */
ctx->vclipzmax = upa_readl(&ffb->vclipzmax); /* Primary Z clip, maximum */
ctx->dcsf = upa_readl(&ffb->dcsf); /* Depth Cue Scale Front Bound */
ctx->dcsb = upa_readl(&ffb->dcsb); /* Depth Cue Scale Back Bound */
ctx->dczf = upa_readl(&ffb->dczf); /* Depth Cue Scale Z Front */
ctx->dczb = upa_readl(&ffb->dczb); /* Depth Cue Scale Z Back */
ctx->blendc = upa_readl(&ffb->blendc); /* Alpha Blend Control */
ctx->blendc1 = upa_readl(&ffb->blendc1); /* Alpha Blend Color 1 */
ctx->blendc2 = upa_readl(&ffb->blendc2); /* Alpha Blend Color 2 */
ctx->fbc = upa_readl(&ffb->fbc); /* Frame Buffer Control */
ctx->rop = upa_readl(&ffb->rop); /* Raster Operation */
ctx->cmp = upa_readl(&ffb->cmp); /* Compare Controls */
ctx->matchab = upa_readl(&ffb->matchab); /* Buffer A/B Match Ops */
ctx->matchc = upa_readl(&ffb->matchc); /* Buffer C Match Ops */
ctx->magnab = upa_readl(&ffb->magnab); /* Buffer A/B Magnitude Ops */
ctx->magnc = upa_readl(&ffb->magnc); /* Buffer C Magnitude Ops */
ctx->pmask = upa_readl(&ffb->pmask); /* RGB Plane Mask */
ctx->xpmask = upa_readl(&ffb->xpmask); /* X Plane Mask */
ctx->ypmask = upa_readl(&ffb->ypmask); /* Y Plane Mask */
ctx->zpmask = upa_readl(&ffb->zpmask); /* Z Plane Mask */
/* Auxiliary Clips. */
ctx->auxclip0min = upa_readl(&ffb->auxclip[0].min);
ctx->auxclip0max = upa_readl(&ffb->auxclip[0].max);
ctx->auxclip1min = upa_readl(&ffb->auxclip[1].min);
ctx->auxclip1max = upa_readl(&ffb->auxclip[1].max);
ctx->auxclip2min = upa_readl(&ffb->auxclip[2].min);
ctx->auxclip2max = upa_readl(&ffb->auxclip[2].max);
ctx->auxclip3min = upa_readl(&ffb->auxclip[3].min);
ctx->auxclip3max = upa_readl(&ffb->auxclip[3].max);
ctx->lpat = upa_readl(&ffb->lpat); /* Line Pattern */
ctx->fontxy = upa_readl(&ffb->fontxy); /* XY Font Coordinate */
ctx->fontw = upa_readl(&ffb->fontw); /* Font Width */
ctx->fontinc = upa_readl(&ffb->fontinc); /* Font X/Y Increment */
/* These registers/features only exist on FFB2 and later chips. */
if (fpriv->ffb_type >= ffb2_prototype) {
ctx->dcss1 = upa_readl(&ffb->dcss1); /* Depth Cue Scale Slope 1 */
ctx->dcss2 = upa_readl(&ffb->dcss2); /* Depth Cue Scale Slope 2 */
ctx->dcss2 = upa_readl(&ffb->dcss3); /* Depth Cue Scale Slope 3 */
ctx->dcs2 = upa_readl(&ffb->dcs2); /* Depth Cue Scale 2 */
ctx->dcs3 = upa_readl(&ffb->dcs3); /* Depth Cue Scale 3 */
ctx->dcs4 = upa_readl(&ffb->dcs4); /* Depth Cue Scale 4 */
ctx->dcd2 = upa_readl(&ffb->dcd2); /* Depth Cue Depth 2 */
ctx->dcd3 = upa_readl(&ffb->dcd3); /* Depth Cue Depth 3 */
ctx->dcd4 = upa_readl(&ffb->dcd4); /* Depth Cue Depth 4 */
/* And stencil/stencilctl only exists on FFB2+ and later
* due to the introduction of 3DRAM-III.
*/
if (fpriv->ffb_type == ffb2_vertical_plus ||
fpriv->ffb_type == ffb2_horizontal_plus) {
ctx->stencil = upa_readl(&ffb->stencil);
ctx->stencilctl = upa_readl(&ffb->stencilctl);
}
}
/* Save the 32x32 area pattern. */
for (i = 0; i < 32; i++)
ctx->area_pattern[i] = upa_readl(&ffb->pattern[i]);
/* Finally, stash away the User Constol/Status Register. */
ctx->ucsr = upa_readl(&ffb->ucsr);
}
static void ffb_restore_context(ffb_dev_priv_t *fpriv, int old, int idx)
{
ffb_fbcPtr ffb = fpriv->regs;
struct ffb_hw_context *ctx;
int i;
ctx = fpriv->hw_state[idx - 1];
if (idx == 0 || ctx == NULL)
return;
if (ctx->is_2d_only) {
/* 2D applications only care about certain pieces
* of state.
*/
upa_writel(ctx->drawop, &ffb->drawop);
/* If we were restoring the vertex registers, this is where
* we would do it. We would restore 32 32-bit words starting
* at ffb->suvtx.
*/
upa_writel(ctx->ppc, &ffb->ppc);
upa_writel(ctx->wid, &ffb->wid);
upa_writel(ctx->fg, &ffb->fg);
upa_writel(ctx->bg, &ffb->bg);
upa_writel(ctx->xclip, &ffb->xclip);
upa_writel(ctx->fbc, &ffb->fbc);
upa_writel(ctx->rop, &ffb->rop);
upa_writel(ctx->cmp, &ffb->cmp);
upa_writel(ctx->matchab, &ffb->matchab);
upa_writel(ctx->magnab, &ffb->magnab);
upa_writel(ctx->pmask, &ffb->pmask);
upa_writel(ctx->xpmask, &ffb->xpmask);
upa_writel(ctx->lpat, &ffb->lpat);
upa_writel(ctx->fontxy, &ffb->fontxy);
upa_writel(ctx->fontw, &ffb->fontw);
upa_writel(ctx->fontinc, &ffb->fontinc);
/* stencil/stencilctl only exists on FFB2+ and later
* due to the introduction of 3DRAM-III.
*/
if (fpriv->ffb_type == ffb2_vertical_plus ||
fpriv->ffb_type == ffb2_horizontal_plus) {
upa_writel(ctx->stencil, &ffb->stencil);
upa_writel(ctx->stencilctl, &ffb->stencilctl);
upa_writel(0x80000000, &ffb->fbc);
upa_writel((ctx->stencilctl | 0x80000),
&ffb->rawstencilctl);
upa_writel(ctx->fbc, &ffb->fbc);
}
for (i = 0; i < 32; i++)
upa_writel(ctx->area_pattern[i], &ffb->pattern[i]);
upa_writel((ctx->ucsr & 0xf0000), &ffb->ucsr);
return;
}
/* Restore drawop. */
upa_writel(ctx->drawop, &ffb->drawop);
/* If we were restoring the vertex registers, this is where
* we would do it. We would restore 32 32-bit words starting
* at ffb->suvtx.
*/
/* Restore rendering attributes. */
upa_writel(ctx->ppc, &ffb->ppc); /* Pixel Processor Control */
upa_writel(ctx->wid, &ffb->wid); /* Current WID */
upa_writel(ctx->fg, &ffb->fg); /* Constant FG color */
upa_writel(ctx->bg, &ffb->bg); /* Constant BG color */
upa_writel(ctx->consty, &ffb->consty); /* Constant Y */
upa_writel(ctx->constz, &ffb->constz); /* Constant Z */
upa_writel(ctx->xclip, &ffb->xclip); /* X plane clip */
upa_writel(ctx->dcss, &ffb->dcss); /* Depth Cue Scale Slope */
upa_writel(ctx->vclipmin, &ffb->vclipmin); /* Primary XY clip, minimum */
upa_writel(ctx->vclipmax, &ffb->vclipmax); /* Primary XY clip, maximum */
upa_writel(ctx->vclipzmin, &ffb->vclipzmin); /* Primary Z clip, minimum */
upa_writel(ctx->vclipzmax, &ffb->vclipzmax); /* Primary Z clip, maximum */
upa_writel(ctx->dcsf, &ffb->dcsf); /* Depth Cue Scale Front Bound */
upa_writel(ctx->dcsb, &ffb->dcsb); /* Depth Cue Scale Back Bound */
upa_writel(ctx->dczf, &ffb->dczf); /* Depth Cue Scale Z Front */
upa_writel(ctx->dczb, &ffb->dczb); /* Depth Cue Scale Z Back */
upa_writel(ctx->blendc, &ffb->blendc); /* Alpha Blend Control */
upa_writel(ctx->blendc1, &ffb->blendc1); /* Alpha Blend Color 1 */
upa_writel(ctx->blendc2, &ffb->blendc2); /* Alpha Blend Color 2 */
upa_writel(ctx->fbc, &ffb->fbc); /* Frame Buffer Control */
upa_writel(ctx->rop, &ffb->rop); /* Raster Operation */
upa_writel(ctx->cmp, &ffb->cmp); /* Compare Controls */
upa_writel(ctx->matchab, &ffb->matchab); /* Buffer A/B Match Ops */
upa_writel(ctx->matchc, &ffb->matchc); /* Buffer C Match Ops */
upa_writel(ctx->magnab, &ffb->magnab); /* Buffer A/B Magnitude Ops */
upa_writel(ctx->magnc, &ffb->magnc); /* Buffer C Magnitude Ops */
upa_writel(ctx->pmask, &ffb->pmask); /* RGB Plane Mask */
upa_writel(ctx->xpmask, &ffb->xpmask); /* X Plane Mask */
upa_writel(ctx->ypmask, &ffb->ypmask); /* Y Plane Mask */
upa_writel(ctx->zpmask, &ffb->zpmask); /* Z Plane Mask */
/* Auxiliary Clips. */
upa_writel(ctx->auxclip0min, &ffb->auxclip[0].min);
upa_writel(ctx->auxclip0max, &ffb->auxclip[0].max);
upa_writel(ctx->auxclip1min, &ffb->auxclip[1].min);
upa_writel(ctx->auxclip1max, &ffb->auxclip[1].max);
upa_writel(ctx->auxclip2min, &ffb->auxclip[2].min);
upa_writel(ctx->auxclip2max, &ffb->auxclip[2].max);
upa_writel(ctx->auxclip3min, &ffb->auxclip[3].min);
upa_writel(ctx->auxclip3max, &ffb->auxclip[3].max);
upa_writel(ctx->lpat, &ffb->lpat); /* Line Pattern */
upa_writel(ctx->fontxy, &ffb->fontxy); /* XY Font Coordinate */
upa_writel(ctx->fontw, &ffb->fontw); /* Font Width */
upa_writel(ctx->fontinc, &ffb->fontinc); /* Font X/Y Increment */
/* These registers/features only exist on FFB2 and later chips. */
if (fpriv->ffb_type >= ffb2_prototype) {
upa_writel(ctx->dcss1, &ffb->dcss1); /* Depth Cue Scale Slope 1 */
upa_writel(ctx->dcss2, &ffb->dcss2); /* Depth Cue Scale Slope 2 */
upa_writel(ctx->dcss3, &ffb->dcss2); /* Depth Cue Scale Slope 3 */
upa_writel(ctx->dcs2, &ffb->dcs2); /* Depth Cue Scale 2 */
upa_writel(ctx->dcs3, &ffb->dcs3); /* Depth Cue Scale 3 */
upa_writel(ctx->dcs4, &ffb->dcs4); /* Depth Cue Scale 4 */
upa_writel(ctx->dcd2, &ffb->dcd2); /* Depth Cue Depth 2 */
upa_writel(ctx->dcd3, &ffb->dcd3); /* Depth Cue Depth 3 */
upa_writel(ctx->dcd4, &ffb->dcd4); /* Depth Cue Depth 4 */
/* And stencil/stencilctl only exists on FFB2+ and later
* due to the introduction of 3DRAM-III.
*/
if (fpriv->ffb_type == ffb2_vertical_plus ||
fpriv->ffb_type == ffb2_horizontal_plus) {
/* Unfortunately, there is a hardware bug on
* the FFB2+ chips which prevents a normal write
* to the stencil control register from working
* as it should.
*
* The state controlled by the FFB stencilctl register
* really gets transferred to the per-buffer instances
* of the stencilctl register in the 3DRAM chips.
*
* The bug is that FFB does not update buffer C correctly,
* so we have to do it by hand for them.
*/
/* This will update buffers A and B. */
upa_writel(ctx->stencil, &ffb->stencil);
upa_writel(ctx->stencilctl, &ffb->stencilctl);
/* Force FFB to use buffer C 3dram regs. */
upa_writel(0x80000000, &ffb->fbc);
upa_writel((ctx->stencilctl | 0x80000),
&ffb->rawstencilctl);
/* Now restore the correct FBC controls. */
upa_writel(ctx->fbc, &ffb->fbc);
}
}
/* Restore the 32x32 area pattern. */
for (i = 0; i < 32; i++)
upa_writel(ctx->area_pattern[i], &ffb->pattern[i]);
/* Finally, stash away the User Constol/Status Register.
* The only state we really preserve here is the picking
* control.
*/
upa_writel((ctx->ucsr & 0xf0000), &ffb->ucsr);
}
#define FFB_UCSR_FB_BUSY 0x01000000
#define FFB_UCSR_RP_BUSY 0x02000000
#define FFB_UCSR_ALL_BUSY (FFB_UCSR_RP_BUSY|FFB_UCSR_FB_BUSY)
static void FFBWait(ffb_fbcPtr ffb)
{
int limit = 100000;
do {
u32 regval = upa_readl(&ffb->ucsr);
if ((regval & FFB_UCSR_ALL_BUSY) == 0)
break;
} while (--limit);
}
int ffb_driver_context_switch(drm_device_t *dev, int old, int new)
{
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
#ifdef DRM_DMA_HISTOGRAM
dev->ctx_start = get_cycles();
#endif
DRM_DEBUG("Context switch from %d to %d\n", old, new);
if (new == dev->last_context ||
dev->last_context == 0) {
dev->last_context = new;
return 0;
}
FFBWait(fpriv->regs);
ffb_save_context(fpriv, old);
ffb_restore_context(fpriv, old, new);
FFBWait(fpriv->regs);
dev->last_context = new;
return 0;
}
int ffb_driver_resctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_ctx_res_t res;
drm_ctx_t ctx;
int i;
DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
if (copy_from_user(&res, (drm_ctx_res_t __user *)arg, sizeof(res)))
return -EFAULT;
if (res.count >= DRM_RESERVED_CONTEXTS) {
memset(&ctx, 0, sizeof(ctx));
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
ctx.handle = i;
if (copy_to_user(&res.contexts[i],
&i,
sizeof(i)))
return -EFAULT;
}
}
res.count = DRM_RESERVED_CONTEXTS;
if (copy_to_user((drm_ctx_res_t __user *)arg, &res, sizeof(res)))
return -EFAULT;
return 0;
}
int ffb_driver_addctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
int idx;
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
return -EFAULT;
idx = DRM(alloc_queue)(dev, (ctx.flags & _DRM_CONTEXT_2DONLY));
if (idx < 0)
return -ENFILE;
DRM_DEBUG("%d\n", ctx.handle);
ctx.handle = idx;
if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx)))
return -EFAULT;
return 0;
}
int ffb_driver_modctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
struct ffb_hw_context *hwctx;
drm_ctx_t ctx;
int idx;
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
return -EFAULT;
idx = ctx.handle;
if (idx <= 0 || idx >= FFB_MAX_CTXS)
return -EINVAL;
hwctx = fpriv->hw_state[idx - 1];
if (hwctx == NULL)
return -EINVAL;
if ((ctx.flags & _DRM_CONTEXT_2DONLY) == 0)
hwctx->is_2d_only = 0;
else
hwctx->is_2d_only = 1;
return 0;
}
int ffb_driver_getctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
struct ffb_hw_context *hwctx;
drm_ctx_t ctx;
int idx;
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
return -EFAULT;
idx = ctx.handle;
if (idx <= 0 || idx >= FFB_MAX_CTXS)
return -EINVAL;
hwctx = fpriv->hw_state[idx - 1];
if (hwctx == NULL)
return -EINVAL;
if (hwctx->is_2d_only != 0)
ctx.flags = _DRM_CONTEXT_2DONLY;
else
ctx.flags = 0;
if (copy_to_user((drm_ctx_t __user *)arg, &ctx, sizeof(ctx)))
return -EFAULT;
return 0;
}
int ffb_driver_switchctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
return ffb_driver_context_switch(dev, dev->last_context, ctx.handle);
}
int ffb_driver_newctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_ctx_t ctx;
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
return 0;
}
int ffb_driver_rmctx(struct inode *inode, struct file *filp, unsigned int cmd,
unsigned long arg)
{
drm_ctx_t ctx;
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
int idx;
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
idx = ctx.handle - 1;
if (idx < 0 || idx >= FFB_MAX_CTXS)
return -EINVAL;
if (fpriv->hw_state[idx] != NULL) {
kfree(fpriv->hw_state[idx]);
fpriv->hw_state[idx] = NULL;
}
return 0;
}
void ffb_set_context_ioctls(void)
{
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_ADD_CTX)].func = ffb_driver_addctx;
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RM_CTX)].func = ffb_driver_rmctx;
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_MOD_CTX)].func = ffb_driver_modctx;
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_GET_CTX)].func = ffb_driver_getctx;
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_SWITCH_CTX)].func = ffb_driver_switchctx;
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_NEW_CTX)].func = ffb_driver_newctx;
DRM(ioctls)[DRM_IOCTL_NR(DRM_IOCTL_RES_CTX)].func = ffb_driver_resctx;
}

View File

@@ -0,0 +1,322 @@
/* $Id: ffb_drv.c,v 1.16 2001/10/18 16:00:24 davem Exp $
* ffb_drv.c: Creator/Creator3D direct rendering driver.
*
* Copyright (C) 2000 David S. Miller (davem@redhat.com)
*/
#include <linux/config.h>
#include "ffb.h"
#include "drmP.h"
#include "ffb_drv.h"
#include <linux/sched.h>
#include <linux/smp_lock.h>
#include <asm/shmparam.h>
#include <asm/oplib.h>
#include <asm/upa.h>
#define DRIVER_AUTHOR "David S. Miller"
#define DRIVER_NAME "ffb"
#define DRIVER_DESC "Creator/Creator3D"
#define DRIVER_DATE "20000517"
#define DRIVER_MAJOR 0
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 1
typedef struct _ffb_position_t {
int node;
int root;
} ffb_position_t;
static ffb_position_t *ffb_position;
static void get_ffb_type(ffb_dev_priv_t *ffb_priv, int instance)
{
volatile unsigned char *strap_bits;
unsigned char val;
strap_bits = (volatile unsigned char *)
(ffb_priv->card_phys_base + 0x00200000UL);
/* Don't ask, you have to read the value twice for whatever
* reason to get correct contents.
*/
val = upa_readb(strap_bits);
val = upa_readb(strap_bits);
switch (val & 0x78) {
case (0x0 << 5) | (0x0 << 3):
ffb_priv->ffb_type = ffb1_prototype;
printk("ffb%d: Detected FFB1 pre-FCS prototype\n", instance);
break;
case (0x0 << 5) | (0x1 << 3):
ffb_priv->ffb_type = ffb1_standard;
printk("ffb%d: Detected FFB1\n", instance);
break;
case (0x0 << 5) | (0x3 << 3):
ffb_priv->ffb_type = ffb1_speedsort;
printk("ffb%d: Detected FFB1-SpeedSort\n", instance);
break;
case (0x1 << 5) | (0x0 << 3):
ffb_priv->ffb_type = ffb2_prototype;
printk("ffb%d: Detected FFB2/vertical pre-FCS prototype\n", instance);
break;
case (0x1 << 5) | (0x1 << 3):
ffb_priv->ffb_type = ffb2_vertical;
printk("ffb%d: Detected FFB2/vertical\n", instance);
break;
case (0x1 << 5) | (0x2 << 3):
ffb_priv->ffb_type = ffb2_vertical_plus;
printk("ffb%d: Detected FFB2+/vertical\n", instance);
break;
case (0x2 << 5) | (0x0 << 3):
ffb_priv->ffb_type = ffb2_horizontal;
printk("ffb%d: Detected FFB2/horizontal\n", instance);
break;
case (0x2 << 5) | (0x2 << 3):
ffb_priv->ffb_type = ffb2_horizontal;
printk("ffb%d: Detected FFB2+/horizontal\n", instance);
break;
default:
ffb_priv->ffb_type = ffb2_vertical;
printk("ffb%d: Unknown boardID[%08x], assuming FFB2\n", instance, val);
break;
};
}
static void ffb_apply_upa_parent_ranges(int parent,
struct linux_prom64_registers *regs)
{
struct linux_prom64_ranges ranges[PROMREG_MAX];
char name[128];
int len, i;
prom_getproperty(parent, "name", name, sizeof(name));
if (strcmp(name, "upa") != 0)
return;
len = prom_getproperty(parent, "ranges", (void *) ranges, sizeof(ranges));
if (len <= 0)
return;
len /= sizeof(struct linux_prom64_ranges);
for (i = 0; i < len; i++) {
struct linux_prom64_ranges *rng = &ranges[i];
u64 phys_addr = regs->phys_addr;
if (phys_addr >= rng->ot_child_base &&
phys_addr < (rng->ot_child_base + rng->or_size)) {
regs->phys_addr -= rng->ot_child_base;
regs->phys_addr += rng->ot_parent_base;
return;
}
}
return;
}
static int ffb_init_one(drm_device_t *dev, int prom_node, int parent_node,
int instance)
{
struct linux_prom64_registers regs[2*PROMREG_MAX];
ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private;
int i;
ffb_priv->prom_node = prom_node;
if (prom_getproperty(ffb_priv->prom_node, "reg",
(void *)regs, sizeof(regs)) <= 0) {
return -EINVAL;
}
ffb_apply_upa_parent_ranges(parent_node, &regs[0]);
ffb_priv->card_phys_base = regs[0].phys_addr;
ffb_priv->regs = (ffb_fbcPtr)
(regs[0].phys_addr + 0x00600000UL);
get_ffb_type(ffb_priv, instance);
for (i = 0; i < FFB_MAX_CTXS; i++)
ffb_priv->hw_state[i] = NULL;
return 0;
}
static drm_map_t *ffb_find_map(struct file *filp, unsigned long off)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev;
drm_map_list_t *r_list;
struct list_head *list;
drm_map_t *map;
if (!priv || (dev = priv->dev) == NULL)
return NULL;
list_for_each(list, &dev->maplist->head) {
unsigned long uoff;
r_list = (drm_map_list_t *)list;
map = r_list->map;
if (!map)
continue;
uoff = (map->offset & 0xffffffff);
if (uoff == off)
return map;
}
return NULL;
}
unsigned long ffb_get_unmapped_area(struct file *filp,
unsigned long hint,
unsigned long len,
unsigned long pgoff,
unsigned long flags)
{
drm_map_t *map = ffb_find_map(filp, pgoff << PAGE_SHIFT);
unsigned long addr = -ENOMEM;
if (!map)
return get_unmapped_area(NULL, hint, len, pgoff, flags);
if (map->type == _DRM_FRAME_BUFFER ||
map->type == _DRM_REGISTERS) {
#ifdef HAVE_ARCH_FB_UNMAPPED_AREA
addr = get_fb_unmapped_area(filp, hint, len, pgoff, flags);
#else
addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
#endif
} else if (map->type == _DRM_SHM && SHMLBA > PAGE_SIZE) {
unsigned long slack = SHMLBA - PAGE_SIZE;
addr = get_unmapped_area(NULL, hint, len + slack, pgoff, flags);
if (!(addr & ~PAGE_MASK)) {
unsigned long kvirt = (unsigned long) map->handle;
if ((kvirt & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
unsigned long koff, aoff;
koff = kvirt & (SHMLBA - 1);
aoff = addr & (SHMLBA - 1);
if (koff < aoff)
koff += SHMLBA;
addr += (koff - aoff);
}
}
} else {
addr = get_unmapped_area(NULL, hint, len, pgoff, flags);
}
return addr;
}
#include "drm_core.h"
/* This functions must be here since it references DRM(numdevs)
* which drm_drv.h declares.
*/
static int ffb_presetup(drm_device_t *dev)
{
ffb_dev_priv_t *ffb_priv;
drm_device_t *temp_dev;
int ret = 0;
int i;
/* Check for the case where no device was found. */
if (ffb_position == NULL)
return -ENODEV;
/* Find our instance number by finding our device in dev structure */
for (i = 0; i < DRM(numdevs); i++) {
temp_dev = &(DRM(device)[i]);
if(temp_dev == dev)
break;
}
if (i == DRM(numdevs))
return -ENODEV;
ffb_priv = kmalloc(sizeof(ffb_dev_priv_t), GFP_KERNEL);
if (!ffb_priv)
return -ENOMEM;
memset(ffb_priv, 0, sizeof(*ffb_priv));
dev->dev_private = ffb_priv;
ret = ffb_init_one(dev,
ffb_position[i].node,
ffb_position[i].root,
i);
return ret;
}
static void ffb_driver_release(drm_device_t *dev, struct file *filp)
{
ffb_dev_priv_t *fpriv = (ffb_dev_priv_t *) dev->dev_private;
int context = _DRM_LOCKING_CONTEXT(dev->lock.hw_lock->lock);
int idx;
idx = context - 1;
if (fpriv &&
context != DRM_KERNEL_CONTEXT &&
fpriv->hw_state[idx] != NULL) {
kfree(fpriv->hw_state[idx]);
fpriv->hw_state[idx] = NULL;
}
}
static void ffb_driver_pretakedown(drm_device_t *dev)
{
if (dev->dev_private) kfree(dev->dev_private);
}
static int ffb_driver_postcleanup(drm_device_t *dev)
{
if (ffb_position != NULL) kfree(ffb_position);
return 0;
}
static void ffb_driver_kernel_context_switch_unlock(struct drm_device *dev, drm_lock_t *lock)
{
dev->lock.filp = 0;
{
__volatile__ unsigned int *plock = &dev->lock.hw_lock->lock;
unsigned int old, new, prev, ctx;
ctx = lock->context;
do {
old = *plock;
new = ctx;
prev = cmpxchg(plock, old, new);
} while (prev != old);
}
wake_up_interruptible(&dev->lock.lock_queue);
}
static unsigned long ffb_driver_get_map_ofs(drm_map_t *map)
{
return (map->offset & 0xffffffff);
}
static unsigned long ffb_driver_get_reg_ofs(drm_device_t *dev)
{
ffb_dev_priv_t *ffb_priv = (ffb_dev_priv_t *)dev->dev_private;
if (ffb_priv)
return ffb_priv->card_phys_base;
return 0;
}
void ffb_driver_register_fns(drm_device_t *dev)
{
ffb_set_context_ioctls();
DRM(fops).get_unmapped_area = ffb_get_unmapped_area;
dev->fn_tbl.release = ffb_driver_release;
dev->fn_tbl.presetup = ffb_presetup;
dev->fn_tbl.pretakedown = ffb_driver_pretakedown;
dev->fn_tbl.postcleanup = ffb_driver_postcleanup;
dev->fn_tbl.kernel_context_switch = ffb_context_switch;
dev->fn_tbl.kernel_context_switch_unlock = ffb_driver_kernel_context_switch_unlock;
dev->fn_tbl.get_map_ofs = ffb_driver_get_map_ofs;
dev->fn_tbl.get_reg_ofs = ffb_driver_get_reg_ofs;
}

View File

@@ -0,0 +1,286 @@
/* $Id: ffb_drv.h,v 1.1 2000/06/01 04:24:39 davem Exp $
* ffb_drv.h: Creator/Creator3D direct rendering driver.
*
* Copyright (C) 2000 David S. Miller (davem@redhat.com)
*/
/* Auxilliary clips. */
typedef struct {
volatile unsigned int min;
volatile unsigned int max;
} ffb_auxclip, *ffb_auxclipPtr;
/* FFB register set. */
typedef struct _ffb_fbc {
/* Next vertex registers, on the right we list which drawops
* use said register and the logical name the register has in
* that context.
*/ /* DESCRIPTION DRAWOP(NAME) */
/*0x00*/unsigned int pad1[3]; /* Reserved */
/*0x0c*/volatile unsigned int alpha; /* ALPHA Transparency */
/*0x10*/volatile unsigned int red; /* RED */
/*0x14*/volatile unsigned int green; /* GREEN */
/*0x18*/volatile unsigned int blue; /* BLUE */
/*0x1c*/volatile unsigned int z; /* DEPTH */
/*0x20*/volatile unsigned int y; /* Y triangle(DOYF) */
/* aadot(DYF) */
/* ddline(DYF) */
/* aaline(DYF) */
/*0x24*/volatile unsigned int x; /* X triangle(DOXF) */
/* aadot(DXF) */
/* ddline(DXF) */
/* aaline(DXF) */
/*0x28*/unsigned int pad2[2]; /* Reserved */
/*0x30*/volatile unsigned int ryf; /* Y (alias to DOYF) ddline(RYF) */
/* aaline(RYF) */
/* triangle(RYF) */
/*0x34*/volatile unsigned int rxf; /* X ddline(RXF) */
/* aaline(RXF) */
/* triangle(RXF) */
/*0x38*/unsigned int pad3[2]; /* Reserved */
/*0x40*/volatile unsigned int dmyf; /* Y (alias to DOYF) triangle(DMYF) */
/*0x44*/volatile unsigned int dmxf; /* X triangle(DMXF) */
/*0x48*/unsigned int pad4[2]; /* Reserved */
/*0x50*/volatile unsigned int ebyi; /* Y (alias to RYI) polygon(EBYI) */
/*0x54*/volatile unsigned int ebxi; /* X polygon(EBXI) */
/*0x58*/unsigned int pad5[2]; /* Reserved */
/*0x60*/volatile unsigned int by; /* Y brline(RYI) */
/* fastfill(OP) */
/* polygon(YI) */
/* rectangle(YI) */
/* bcopy(SRCY) */
/* vscroll(SRCY) */
/*0x64*/volatile unsigned int bx; /* X brline(RXI) */
/* polygon(XI) */
/* rectangle(XI) */
/* bcopy(SRCX) */
/* vscroll(SRCX) */
/* fastfill(GO) */
/*0x68*/volatile unsigned int dy; /* destination Y fastfill(DSTY) */
/* bcopy(DSRY) */
/* vscroll(DSRY) */
/*0x6c*/volatile unsigned int dx; /* destination X fastfill(DSTX) */
/* bcopy(DSTX) */
/* vscroll(DSTX) */
/*0x70*/volatile unsigned int bh; /* Y (alias to RYI) brline(DYI) */
/* dot(DYI) */
/* polygon(ETYI) */
/* Height fastfill(H) */
/* bcopy(H) */
/* vscroll(H) */
/* Y count fastfill(NY) */
/*0x74*/volatile unsigned int bw; /* X dot(DXI) */
/* brline(DXI) */
/* polygon(ETXI) */
/* fastfill(W) */
/* bcopy(W) */
/* vscroll(W) */
/* fastfill(NX) */
/*0x78*/unsigned int pad6[2]; /* Reserved */
/*0x80*/unsigned int pad7[32]; /* Reserved */
/* Setup Unit's vertex state register */
/*100*/ volatile unsigned int suvtx;
/*104*/ unsigned int pad8[63]; /* Reserved */
/* Frame Buffer Control Registers */
/*200*/ volatile unsigned int ppc; /* Pixel Processor Control */
/*204*/ volatile unsigned int wid; /* Current WID */
/*208*/ volatile unsigned int fg; /* FG data */
/*20c*/ volatile unsigned int bg; /* BG data */
/*210*/ volatile unsigned int consty; /* Constant Y */
/*214*/ volatile unsigned int constz; /* Constant Z */
/*218*/ volatile unsigned int xclip; /* X Clip */
/*21c*/ volatile unsigned int dcss; /* Depth Cue Scale Slope */
/*220*/ volatile unsigned int vclipmin; /* Viewclip XY Min Bounds */
/*224*/ volatile unsigned int vclipmax; /* Viewclip XY Max Bounds */
/*228*/ volatile unsigned int vclipzmin; /* Viewclip Z Min Bounds */
/*22c*/ volatile unsigned int vclipzmax; /* Viewclip Z Max Bounds */
/*230*/ volatile unsigned int dcsf; /* Depth Cue Scale Front Bound */
/*234*/ volatile unsigned int dcsb; /* Depth Cue Scale Back Bound */
/*238*/ volatile unsigned int dczf; /* Depth Cue Z Front */
/*23c*/ volatile unsigned int dczb; /* Depth Cue Z Back */
/*240*/ unsigned int pad9; /* Reserved */
/*244*/ volatile unsigned int blendc; /* Alpha Blend Control */
/*248*/ volatile unsigned int blendc1; /* Alpha Blend Color 1 */
/*24c*/ volatile unsigned int blendc2; /* Alpha Blend Color 2 */
/*250*/ volatile unsigned int fbramitc; /* FB RAM Interleave Test Control */
/*254*/ volatile unsigned int fbc; /* Frame Buffer Control */
/*258*/ volatile unsigned int rop; /* Raster OPeration */
/*25c*/ volatile unsigned int cmp; /* Frame Buffer Compare */
/*260*/ volatile unsigned int matchab; /* Buffer AB Match Mask */
/*264*/ volatile unsigned int matchc; /* Buffer C(YZ) Match Mask */
/*268*/ volatile unsigned int magnab; /* Buffer AB Magnitude Mask */
/*26c*/ volatile unsigned int magnc; /* Buffer C(YZ) Magnitude Mask */
/*270*/ volatile unsigned int fbcfg0; /* Frame Buffer Config 0 */
/*274*/ volatile unsigned int fbcfg1; /* Frame Buffer Config 1 */
/*278*/ volatile unsigned int fbcfg2; /* Frame Buffer Config 2 */
/*27c*/ volatile unsigned int fbcfg3; /* Frame Buffer Config 3 */
/*280*/ volatile unsigned int ppcfg; /* Pixel Processor Config */
/*284*/ volatile unsigned int pick; /* Picking Control */
/*288*/ volatile unsigned int fillmode; /* FillMode */
/*28c*/ volatile unsigned int fbramwac; /* FB RAM Write Address Control */
/*290*/ volatile unsigned int pmask; /* RGB PlaneMask */
/*294*/ volatile unsigned int xpmask; /* X PlaneMask */
/*298*/ volatile unsigned int ypmask; /* Y PlaneMask */
/*29c*/ volatile unsigned int zpmask; /* Z PlaneMask */
/*2a0*/ ffb_auxclip auxclip[4]; /* Auxilliary Viewport Clip */
/* New 3dRAM III support regs */
/*2c0*/ volatile unsigned int rawblend2;
/*2c4*/ volatile unsigned int rawpreblend;
/*2c8*/ volatile unsigned int rawstencil;
/*2cc*/ volatile unsigned int rawstencilctl;
/*2d0*/ volatile unsigned int threedram1;
/*2d4*/ volatile unsigned int threedram2;
/*2d8*/ volatile unsigned int passin;
/*2dc*/ volatile unsigned int rawclrdepth;
/*2e0*/ volatile unsigned int rawpmask;
/*2e4*/ volatile unsigned int rawcsrc;
/*2e8*/ volatile unsigned int rawmatch;
/*2ec*/ volatile unsigned int rawmagn;
/*2f0*/ volatile unsigned int rawropblend;
/*2f4*/ volatile unsigned int rawcmp;
/*2f8*/ volatile unsigned int rawwac;
/*2fc*/ volatile unsigned int fbramid;
/*300*/ volatile unsigned int drawop; /* Draw OPeration */
/*304*/ unsigned int pad10[2]; /* Reserved */
/*30c*/ volatile unsigned int lpat; /* Line Pattern control */
/*310*/ unsigned int pad11; /* Reserved */
/*314*/ volatile unsigned int fontxy; /* XY Font coordinate */
/*318*/ volatile unsigned int fontw; /* Font Width */
/*31c*/ volatile unsigned int fontinc; /* Font Increment */
/*320*/ volatile unsigned int font; /* Font bits */
/*324*/ unsigned int pad12[3]; /* Reserved */
/*330*/ volatile unsigned int blend2;
/*334*/ volatile unsigned int preblend;
/*338*/ volatile unsigned int stencil;
/*33c*/ volatile unsigned int stencilctl;
/*340*/ unsigned int pad13[4]; /* Reserved */
/*350*/ volatile unsigned int dcss1; /* Depth Cue Scale Slope 1 */
/*354*/ volatile unsigned int dcss2; /* Depth Cue Scale Slope 2 */
/*358*/ volatile unsigned int dcss3; /* Depth Cue Scale Slope 3 */
/*35c*/ volatile unsigned int widpmask;
/*360*/ volatile unsigned int dcs2;
/*364*/ volatile unsigned int dcs3;
/*368*/ volatile unsigned int dcs4;
/*36c*/ unsigned int pad14; /* Reserved */
/*370*/ volatile unsigned int dcd2;
/*374*/ volatile unsigned int dcd3;
/*378*/ volatile unsigned int dcd4;
/*37c*/ unsigned int pad15; /* Reserved */
/*380*/ volatile unsigned int pattern[32]; /* area Pattern */
/*400*/ unsigned int pad16[8]; /* Reserved */
/*420*/ volatile unsigned int reset; /* chip RESET */
/*424*/ unsigned int pad17[247]; /* Reserved */
/*800*/ volatile unsigned int devid; /* Device ID */
/*804*/ unsigned int pad18[63]; /* Reserved */
/*900*/ volatile unsigned int ucsr; /* User Control & Status Register */
/*904*/ unsigned int pad19[31]; /* Reserved */
/*980*/ volatile unsigned int mer; /* Mode Enable Register */
/*984*/ unsigned int pad20[1439]; /* Reserved */
} ffb_fbc, *ffb_fbcPtr;
struct ffb_hw_context {
int is_2d_only;
unsigned int ppc;
unsigned int wid;
unsigned int fg;
unsigned int bg;
unsigned int consty;
unsigned int constz;
unsigned int xclip;
unsigned int dcss;
unsigned int vclipmin;
unsigned int vclipmax;
unsigned int vclipzmin;
unsigned int vclipzmax;
unsigned int dcsf;
unsigned int dcsb;
unsigned int dczf;
unsigned int dczb;
unsigned int blendc;
unsigned int blendc1;
unsigned int blendc2;
unsigned int fbc;
unsigned int rop;
unsigned int cmp;
unsigned int matchab;
unsigned int matchc;
unsigned int magnab;
unsigned int magnc;
unsigned int pmask;
unsigned int xpmask;
unsigned int ypmask;
unsigned int zpmask;
unsigned int auxclip0min;
unsigned int auxclip0max;
unsigned int auxclip1min;
unsigned int auxclip1max;
unsigned int auxclip2min;
unsigned int auxclip2max;
unsigned int auxclip3min;
unsigned int auxclip3max;
unsigned int drawop;
unsigned int lpat;
unsigned int fontxy;
unsigned int fontw;
unsigned int fontinc;
unsigned int area_pattern[32];
unsigned int ucsr;
unsigned int stencil;
unsigned int stencilctl;
unsigned int dcss1;
unsigned int dcss2;
unsigned int dcss3;
unsigned int dcs2;
unsigned int dcs3;
unsigned int dcs4;
unsigned int dcd2;
unsigned int dcd3;
unsigned int dcd4;
unsigned int mer;
};
#define FFB_MAX_CTXS 32
enum ffb_chip_type {
ffb1_prototype = 0, /* Early pre-FCS FFB */
ffb1_standard, /* First FCS FFB, 100Mhz UPA, 66MHz gclk */
ffb1_speedsort, /* Second FCS FFB, 100Mhz UPA, 75MHz gclk */
ffb2_prototype, /* Early pre-FCS vertical FFB2 */
ffb2_vertical, /* First FCS FFB2/vertical, 100Mhz UPA, 100MHZ gclk,
75(SingleBuffer)/83(DoubleBuffer) MHz fclk */
ffb2_vertical_plus, /* Second FCS FFB2/vertical, same timings */
ffb2_horizontal, /* First FCS FFB2/horizontal, same timings as FFB2/vert */
ffb2_horizontal_plus, /* Second FCS FFB2/horizontal, same timings */
afb_m3, /* FCS Elite3D, 3 float chips */
afb_m6 /* FCS Elite3D, 6 float chips */
};
typedef struct ffb_dev_priv {
/* Misc software state. */
int prom_node;
enum ffb_chip_type ffb_type;
u64 card_phys_base;
struct miscdevice miscdev;
/* Controller registers. */
ffb_fbcPtr regs;
/* Context table. */
struct ffb_hw_context *hw_state[FFB_MAX_CTXS];
} ffb_dev_priv_t;
extern struct file_operations DRM(fops);
extern unsigned long ffb_get_unmapped_area(struct file *filp,
unsigned long hint,
unsigned long len,
unsigned long pgoff,
unsigned long flags);
extern void ffb_set_context_ioctls(void);
extern drm_ioctl_desc_t DRM(ioctls)[];

View File

@@ -0,0 +1,77 @@
/* gamma.c -- 3dlabs GMX 2000 driver -*- linux-c -*-
* Created: Mon Jan 4 08:58:31 1999 by gareth@valinux.com
*
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
* DEALINGS IN THE SOFTWARE.
*
* Authors:
* Gareth Hughes <gareth@valinux.com>
*/
#ifndef __GAMMA_H__
#define __GAMMA_H__
/* This remains constant for all DRM template files.
*/
#define DRM(x) gamma_##x
/* General customization:
*/
#define DRIVER_AUTHOR "VA Linux Systems Inc."
#define DRIVER_NAME "gamma"
#define DRIVER_DESC "3DLabs gamma"
#define DRIVER_DATE "20010624"
#define DRIVER_MAJOR 2
#define DRIVER_MINOR 0
#define DRIVER_PATCHLEVEL 0
#define DRIVER_IOCTLS \
[DRM_IOCTL_NR(DRM_IOCTL_DMA)] = { gamma_dma, 1, 0 }, \
[DRM_IOCTL_NR(DRM_IOCTL_GAMMA_INIT)] = { gamma_dma_init, 1, 1 }, \
[DRM_IOCTL_NR(DRM_IOCTL_GAMMA_COPY)] = { gamma_dma_copy, 1, 1 }
#define IOCTL_TABLE_NAME DRM(ioctls)
#define IOCTL_FUNC_NAME DRM(ioctl)
#define __HAVE_COUNTERS 5
#define __HAVE_COUNTER6 _DRM_STAT_IRQ
#define __HAVE_COUNTER7 _DRM_STAT_DMA
#define __HAVE_COUNTER8 _DRM_STAT_PRIMARY
#define __HAVE_COUNTER9 _DRM_STAT_SPECIAL
#define __HAVE_COUNTER10 _DRM_STAT_MISSED
/* Driver customization:
*/
#define DRIVER_PRETAKEDOWN() do { \
gamma_do_cleanup_dma( dev ); \
} while (0)
/* DMA customization:
*/
#define __HAVE_MULTIPLE_DMA_QUEUES 1
#define __HAVE_DMA_WAITQUEUE 1
/* removed from DRM HAVE_DMA_FREELIST & HAVE_DMA_SCHEDULE */
#endif /* __GAMMA_H__ */

View File

@@ -0,0 +1,492 @@
/* drm_context.h -- IOCTLs for generic contexts -*- linux-c -*-
* Created: Fri Nov 24 18:31:37 2000 by gareth@valinux.com
*
* Copyright 1999, 2000 Precision Insight, Inc., Cedar Park, Texas.
* Copyright 2000 VA Linux Systems, Inc., Sunnyvale, California.
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining a
* copy of this software and associated documentation files (the "Software"),
* to deal in the Software without restriction, including without limitation
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
* and/or sell copies of the Software, and to permit persons to whom the
* Software is furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice (including the next
* paragraph) shall be included in all copies or substantial portions of the
* Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
* VA LINUX SYSTEMS AND/OR ITS SUPPLIERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
* OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
* ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
* OTHER DEALINGS IN THE SOFTWARE.
*
* Authors:
* Rickard E. (Rik) Faith <faith@valinux.com>
* Gareth Hughes <gareth@valinux.com>
* ChangeLog:
* 2001-11-16 Torsten Duwe <duwe@caldera.de>
* added context constructor/destructor hooks,
* needed by SiS driver's memory management.
*/
/* ================================================================
* Old-style context support -- only used by gamma.
*/
/* The drm_read and drm_write_string code (especially that which manages
the circular buffer), is based on Alessandro Rubini's LINUX DEVICE
DRIVERS (Cambridge: O'Reilly, 1998), pages 111-113. */
ssize_t gamma_fops_read(struct file *filp, char __user *buf, size_t count, loff_t *off)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
int left;
int avail;
int send;
int cur;
DRM_DEBUG("%p, %p\n", dev->buf_rp, dev->buf_wp);
while (dev->buf_rp == dev->buf_wp) {
DRM_DEBUG(" sleeping\n");
if (filp->f_flags & O_NONBLOCK) {
return -EAGAIN;
}
interruptible_sleep_on(&dev->buf_readers);
if (signal_pending(current)) {
DRM_DEBUG(" interrupted\n");
return -ERESTARTSYS;
}
DRM_DEBUG(" awake\n");
}
left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
avail = DRM_BSZ - left;
send = DRM_MIN(avail, count);
while (send) {
if (dev->buf_wp > dev->buf_rp) {
cur = DRM_MIN(send, dev->buf_wp - dev->buf_rp);
} else {
cur = DRM_MIN(send, dev->buf_end - dev->buf_rp);
}
if (copy_to_user(buf, dev->buf_rp, cur))
return -EFAULT;
dev->buf_rp += cur;
if (dev->buf_rp == dev->buf_end) dev->buf_rp = dev->buf;
send -= cur;
}
wake_up_interruptible(&dev->buf_writers);
return DRM_MIN(avail, count);
}
/* In an incredibly convoluted setup, the kernel module actually calls
* back into the X server to perform context switches on behalf of the
* 3d clients.
*/
int DRM(write_string)(drm_device_t *dev, const char *s)
{
int left = (dev->buf_rp + DRM_BSZ - dev->buf_wp) % DRM_BSZ;
int send = strlen(s);
int count;
DRM_DEBUG("%d left, %d to send (%p, %p)\n",
left, send, dev->buf_rp, dev->buf_wp);
if (left == 1 || dev->buf_wp != dev->buf_rp) {
DRM_ERROR("Buffer not empty (%d left, wp = %p, rp = %p)\n",
left,
dev->buf_wp,
dev->buf_rp);
}
while (send) {
if (dev->buf_wp >= dev->buf_rp) {
count = DRM_MIN(send, dev->buf_end - dev->buf_wp);
if (count == left) --count; /* Leave a hole */
} else {
count = DRM_MIN(send, dev->buf_rp - dev->buf_wp - 1);
}
strncpy(dev->buf_wp, s, count);
dev->buf_wp += count;
if (dev->buf_wp == dev->buf_end) dev->buf_wp = dev->buf;
send -= count;
}
if (dev->buf_async) kill_fasync(&dev->buf_async, SIGIO, POLL_IN);
DRM_DEBUG("waking\n");
wake_up_interruptible(&dev->buf_readers);
return 0;
}
unsigned int gamma_fops_poll(struct file *filp, struct poll_table_struct *wait)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
poll_wait(filp, &dev->buf_readers, wait);
if (dev->buf_wp != dev->buf_rp) return POLLIN | POLLRDNORM;
return 0;
}
int DRM(context_switch)(drm_device_t *dev, int old, int new)
{
char buf[64];
drm_queue_t *q;
if (test_and_set_bit(0, &dev->context_flag)) {
DRM_ERROR("Reentering -- FIXME\n");
return -EBUSY;
}
DRM_DEBUG("Context switch from %d to %d\n", old, new);
if (new >= dev->queue_count) {
clear_bit(0, &dev->context_flag);
return -EINVAL;
}
if (new == dev->last_context) {
clear_bit(0, &dev->context_flag);
return 0;
}
q = dev->queuelist[new];
atomic_inc(&q->use_count);
if (atomic_read(&q->use_count) == 1) {
atomic_dec(&q->use_count);
clear_bit(0, &dev->context_flag);
return -EINVAL;
}
/* This causes the X server to wake up & do a bunch of hardware
* interaction to actually effect the context switch.
*/
sprintf(buf, "C %d %d\n", old, new);
DRM(write_string)(dev, buf);
atomic_dec(&q->use_count);
return 0;
}
int DRM(context_switch_complete)(drm_device_t *dev, int new)
{
drm_device_dma_t *dma = dev->dma;
dev->last_context = new; /* PRE/POST: This is the _only_ writer. */
dev->last_switch = jiffies;
if (!_DRM_LOCK_IS_HELD(dev->lock.hw_lock->lock)) {
DRM_ERROR("Lock isn't held after context switch\n");
}
if (!dma || !(dma->next_buffer && dma->next_buffer->while_locked)) {
if (DRM(lock_free)(dev, &dev->lock.hw_lock->lock,
DRM_KERNEL_CONTEXT)) {
DRM_ERROR("Cannot free lock\n");
}
}
clear_bit(0, &dev->context_flag);
wake_up_interruptible(&dev->context_wait);
return 0;
}
static int DRM(init_queue)(drm_device_t *dev, drm_queue_t *q, drm_ctx_t *ctx)
{
DRM_DEBUG("\n");
if (atomic_read(&q->use_count) != 1
|| atomic_read(&q->finalization)
|| atomic_read(&q->block_count)) {
DRM_ERROR("New queue is already in use: u%d f%d b%d\n",
atomic_read(&q->use_count),
atomic_read(&q->finalization),
atomic_read(&q->block_count));
}
atomic_set(&q->finalization, 0);
atomic_set(&q->block_count, 0);
atomic_set(&q->block_read, 0);
atomic_set(&q->block_write, 0);
atomic_set(&q->total_queued, 0);
atomic_set(&q->total_flushed, 0);
atomic_set(&q->total_locks, 0);
init_waitqueue_head(&q->write_queue);
init_waitqueue_head(&q->read_queue);
init_waitqueue_head(&q->flush_queue);
q->flags = ctx->flags;
DRM(waitlist_create)(&q->waitlist, dev->dma->buf_count);
return 0;
}
/* drm_alloc_queue:
PRE: 1) dev->queuelist[0..dev->queue_count] is allocated and will not
disappear (so all deallocation must be done after IOCTLs are off)
2) dev->queue_count < dev->queue_slots
3) dev->queuelist[i].use_count == 0 and
dev->queuelist[i].finalization == 0 if i not in use
POST: 1) dev->queuelist[i].use_count == 1
2) dev->queue_count < dev->queue_slots */
static int DRM(alloc_queue)(drm_device_t *dev)
{
int i;
drm_queue_t *queue;
int oldslots;
int newslots;
/* Check for a free queue */
for (i = 0; i < dev->queue_count; i++) {
atomic_inc(&dev->queuelist[i]->use_count);
if (atomic_read(&dev->queuelist[i]->use_count) == 1
&& !atomic_read(&dev->queuelist[i]->finalization)) {
DRM_DEBUG("%d (free)\n", i);
return i;
}
atomic_dec(&dev->queuelist[i]->use_count);
}
/* Allocate a new queue */
down(&dev->struct_sem);
queue = DRM(alloc)(sizeof(*queue), DRM_MEM_QUEUES);
memset(queue, 0, sizeof(*queue));
atomic_set(&queue->use_count, 1);
++dev->queue_count;
if (dev->queue_count >= dev->queue_slots) {
oldslots = dev->queue_slots * sizeof(*dev->queuelist);
if (!dev->queue_slots) dev->queue_slots = 1;
dev->queue_slots *= 2;
newslots = dev->queue_slots * sizeof(*dev->queuelist);
dev->queuelist = DRM(realloc)(dev->queuelist,
oldslots,
newslots,
DRM_MEM_QUEUES);
if (!dev->queuelist) {
up(&dev->struct_sem);
DRM_DEBUG("out of memory\n");
return -ENOMEM;
}
}
dev->queuelist[dev->queue_count-1] = queue;
up(&dev->struct_sem);
DRM_DEBUG("%d (new)\n", dev->queue_count - 1);
return dev->queue_count - 1;
}
int DRM(resctx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_ctx_res_t __user *argp = (void __user *)arg;
drm_ctx_res_t res;
drm_ctx_t ctx;
int i;
DRM_DEBUG("%d\n", DRM_RESERVED_CONTEXTS);
if (copy_from_user(&res, argp, sizeof(res)))
return -EFAULT;
if (res.count >= DRM_RESERVED_CONTEXTS) {
memset(&ctx, 0, sizeof(ctx));
for (i = 0; i < DRM_RESERVED_CONTEXTS; i++) {
ctx.handle = i;
if (copy_to_user(&res.contexts[i],
&i,
sizeof(i)))
return -EFAULT;
}
}
res.count = DRM_RESERVED_CONTEXTS;
if (copy_to_user(argp, &res, sizeof(res)))
return -EFAULT;
return 0;
}
int DRM(addctx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
drm_ctx_t __user *argp = (void __user *)arg;
if (copy_from_user(&ctx, argp, sizeof(ctx)))
return -EFAULT;
if ((ctx.handle = DRM(alloc_queue)(dev)) == DRM_KERNEL_CONTEXT) {
/* Init kernel's context and get a new one. */
DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
ctx.handle = DRM(alloc_queue)(dev);
}
DRM(init_queue)(dev, dev->queuelist[ctx.handle], &ctx);
DRM_DEBUG("%d\n", ctx.handle);
if (copy_to_user(argp, &ctx, sizeof(ctx)))
return -EFAULT;
return 0;
}
int DRM(modctx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
drm_queue_t *q;
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
if (ctx.handle < 0 || ctx.handle >= dev->queue_count) return -EINVAL;
q = dev->queuelist[ctx.handle];
atomic_inc(&q->use_count);
if (atomic_read(&q->use_count) == 1) {
/* No longer in use */
atomic_dec(&q->use_count);
return -EINVAL;
}
if (DRM_BUFCOUNT(&q->waitlist)) {
atomic_dec(&q->use_count);
return -EBUSY;
}
q->flags = ctx.flags;
atomic_dec(&q->use_count);
return 0;
}
int DRM(getctx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t __user *argp = (void __user *)arg;
drm_ctx_t ctx;
drm_queue_t *q;
if (copy_from_user(&ctx, argp, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
if (ctx.handle >= dev->queue_count) return -EINVAL;
q = dev->queuelist[ctx.handle];
atomic_inc(&q->use_count);
if (atomic_read(&q->use_count) == 1) {
/* No longer in use */
atomic_dec(&q->use_count);
return -EINVAL;
}
ctx.flags = q->flags;
atomic_dec(&q->use_count);
if (copy_to_user(argp, &ctx, sizeof(ctx)))
return -EFAULT;
return 0;
}
int DRM(switchctx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
return DRM(context_switch)(dev, dev->last_context, ctx.handle);
}
int DRM(newctx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
DRM(context_switch_complete)(dev, ctx.handle);
return 0;
}
int DRM(rmctx)(struct inode *inode, struct file *filp,
unsigned int cmd, unsigned long arg)
{
drm_file_t *priv = filp->private_data;
drm_device_t *dev = priv->dev;
drm_ctx_t ctx;
drm_queue_t *q;
drm_buf_t *buf;
if (copy_from_user(&ctx, (drm_ctx_t __user *)arg, sizeof(ctx)))
return -EFAULT;
DRM_DEBUG("%d\n", ctx.handle);
if (ctx.handle >= dev->queue_count) return -EINVAL;
q = dev->queuelist[ctx.handle];
atomic_inc(&q->use_count);
if (atomic_read(&q->use_count) == 1) {
/* No longer in use */
atomic_dec(&q->use_count);
return -EINVAL;
}
atomic_inc(&q->finalization); /* Mark queue in finalization state */
atomic_sub(2, &q->use_count); /* Mark queue as unused (pending
finalization) */
while (test_and_set_bit(0, &dev->interrupt_flag)) {
schedule();
if (signal_pending(current)) {
clear_bit(0, &dev->interrupt_flag);
return -EINTR;
}
}
/* Remove queued buffers */
while ((buf = DRM(waitlist_get)(&q->waitlist))) {
DRM(free_buffer)(dev, buf);
}
clear_bit(0, &dev->interrupt_flag);
/* Wakeup blocked processes */
wake_up_interruptible(&q->read_queue);
wake_up_interruptible(&q->write_queue);
wake_up_interruptible(&q->flush_queue);
/* Finalization over. Queue is made
available when both use_count and
finalization become 0, which won't
happen until all the waiting processes
stop waiting. */
atomic_dec(&q->finalization);
return 0;
}

Some files were not shown because too many files have changed in this diff Show More