Commit 3f43be64 authored by David S. Miller's avatar David S. Miller

Merge

parents 9c75ad3b 21872250
......@@ -251,6 +251,10 @@ CONFIG_ALPHA_PRIMO
CONFIG_ALPHA_GAMMA
Say Y if you have an AS 2000 5/xxx or an AS 2100 5/xxx.
CONFIG_ALPHA_EV67
Is this a machine based on the EV67 core? If in doubt, select N here
and the machine will be treated as an EV6.
CONFIG_ALPHA_SRM
There are two different types of booting firmware on Alphas: SRM,
which is command line driven, and ARC, which uses menus and arrow
......@@ -610,3 +614,14 @@ CONFIG_DEBUG_SPINLOCK
best used in conjunction with the NMI watchdog so that spinlock
deadlocks are also debuggable.
CONFIG_DEBUG_RWLOCK
If you say Y here then read-write lock processing will count how many
times it has tried to get the lock and issue an error message after
too many attempts. If you suspect a rwlock problem or a kernel
hacker asks for this option then say Y. Otherwise say N.
CONFIG_DEBUG_SEMAPHORE
If you say Y here then semaphore processing will issue lots of
verbose debugging messages. If you suspect a semaphore problem or a
kernel hacker asks for this option then say Y. Otherwise say N.
......@@ -99,30 +99,32 @@ export libs-y
MAKEBOOT = $(MAKE) -C arch/alpha/boot
rawboot:
rawboot: vmlinux
@$(MAKEBOOT) rawboot
boot: vmlinux
@$(MAKEBOOT)
#
# My boot writes directly to a specific disk partition, I doubt most
# people will want to do that without changes..
#
msb my-special-boot:
msb my-special-boot: vmlinux
@$(MAKEBOOT) msb
bootimage:
bootimage: vmlinux
@$(MAKEBOOT) bootimage
srmboot:
srmboot: vmlinux
@$(MAKEBOOT) srmboot
archclean:
@$(MAKE) -C arch/alpha/kernel clean
@$(MAKEBOOT) clean
archmrproper:
rm -f include/asm-alpha/asm_offsets.h
bootpfile:
bootpfile: vmlinux
@$(MAKEBOOT) bootpfile
......
......@@ -8,7 +8,9 @@
# Copyright (C) 1994 by Linus Torvalds
#
LINKFLAGS = -static -T bootloader.lds #-N -relax
LINKFLAGS = -static -T bootloader.lds -uvsprintf #-N -relax
CFLAGS := $(CFLAGS) -I$(TOPDIR)/include
.S.s:
$(CPP) $(AFLAGS) -traditional -o $*.o $<
......
......@@ -8,8 +8,9 @@ EXTRA_AFLAGS := $(CFLAGS)
export-objs := alpha_ksyms.o
obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o irq_alpha.o \
signal.o setup.o ptrace.o time.o semaphore.o alpha_ksyms.o
obj-y := entry.o traps.o process.o init_task.o osf_sys.o irq.o \
irq_alpha.o signal.o setup.o ptrace.o time.o semaphore.o \
alpha_ksyms.o systbls.o
#
# FIXME!
......
......@@ -161,7 +161,6 @@ EXPORT_SYMBOL(sys_read);
EXPORT_SYMBOL(sys_lseek);
EXPORT_SYMBOL(__kernel_execve);
EXPORT_SYMBOL(sys_setsid);
EXPORT_SYMBOL(sys_sync);
EXPORT_SYMBOL(sys_wait4);
/* Networking helper routines. */
......
......@@ -9,8 +9,7 @@
#include <asm/cache.h>
#include <asm/asm_offsets.h>
#include <asm/thread_info.h>
#define NR_SYSCALLS 381
#include <asm/unistd.h>
/*
* stack offsets
......@@ -677,6 +676,7 @@ ret_success:
.end entSys
.align 3
.globl sys_sigreturn
.ent sys_sigreturn
sys_sigreturn:
mov $30,$17
......@@ -688,6 +688,7 @@ sys_sigreturn:
.end sys_sigreturn
.align 3
.globl sys_rt_sigreturn
.ent sys_rt_sigreturn
sys_rt_sigreturn:
mov $30,$17
......@@ -699,6 +700,7 @@ sys_rt_sigreturn:
.end sys_rt_sigreturn
.align 3
.globl sys_sigsuspend
.ent sys_sigsuspend
sys_sigsuspend:
mov $30,$17
......@@ -713,6 +715,7 @@ sys_sigsuspend:
.end sys_sigsuspend
.align 3
.globl sys_rt_sigsuspend
.ent sys_rt_sigsuspend
sys_rt_sigsuspend:
mov $30,$18
......@@ -725,421 +728,3 @@ sys_rt_sigsuspend:
lda $30,SWITCH_STACK_SIZE+16($30)
ret $31,($26),1
.end sys_rt_sigsuspend
.data
.align 3
.globl sys_call_table
sys_call_table:
.quad alpha_ni_syscall /* 0 */
.quad sys_exit
.quad sys_fork
.quad sys_read
.quad sys_write
.quad alpha_ni_syscall /* 5 */
.quad sys_close
.quad osf_wait4
.quad alpha_ni_syscall
.quad sys_link
.quad sys_unlink /* 10 */
.quad alpha_ni_syscall
.quad sys_chdir
.quad sys_fchdir
.quad sys_mknod
.quad sys_chmod /* 15 */
.quad sys_chown
.quad osf_brk
.quad alpha_ni_syscall
.quad sys_lseek
.quad sys_getxpid /* 20 */
.quad osf_mount
.quad sys_umount
.quad sys_setuid
.quad sys_getxuid
.quad alpha_ni_syscall /* 25 */
.quad sys_ptrace
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 30 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad sys_access
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 35 */
.quad sys_sync
.quad sys_kill
.quad alpha_ni_syscall
.quad sys_setpgid
.quad alpha_ni_syscall /* 40 */
.quad sys_dup
.quad sys_pipe
.quad osf_set_program_attributes
.quad alpha_ni_syscall
.quad sys_open /* 45 */
.quad alpha_ni_syscall
.quad sys_getxgid
.quad osf_sigprocmask
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 50 */
.quad sys_acct
.quad sys_sigpending
.quad alpha_ni_syscall
.quad sys_ioctl
.quad alpha_ni_syscall /* 55 */
.quad alpha_ni_syscall
.quad sys_symlink
.quad sys_readlink
.quad sys_execve
.quad sys_umask /* 60 */
.quad sys_chroot
.quad alpha_ni_syscall
.quad sys_getpgrp
.quad sys_getpagesize
.quad alpha_ni_syscall /* 65 */
.quad sys_vfork
.quad sys_newstat
.quad sys_newlstat
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 70 */
.quad osf_mmap
.quad alpha_ni_syscall
.quad sys_munmap
.quad sys_mprotect
.quad sys_madvise /* 75 */
.quad sys_vhangup
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad sys_getgroups
/* map BSD's setpgrp to sys_setpgid for binary compatibility: */
.quad sys_setgroups /* 80 */
.quad alpha_ni_syscall
.quad sys_setpgid
.quad osf_setitimer
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 85 */
.quad osf_getitimer
.quad sys_gethostname
.quad sys_sethostname
.quad sys_getdtablesize
.quad sys_dup2 /* 90 */
.quad sys_newfstat
.quad sys_fcntl
.quad osf_select
.quad sys_poll
.quad sys_fsync /* 95 */
.quad sys_setpriority
.quad sys_socket
.quad sys_connect
.quad sys_accept
.quad osf_getpriority /* 100 */
.quad sys_send
.quad sys_recv
.quad sys_sigreturn
.quad sys_bind
.quad sys_setsockopt /* 105 */
.quad sys_listen
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 110 */
.quad sys_sigsuspend
.quad osf_sigstack
.quad sys_recvmsg
.quad sys_sendmsg
.quad alpha_ni_syscall /* 115 */
.quad osf_gettimeofday
.quad osf_getrusage
.quad sys_getsockopt
.quad alpha_ni_syscall
#ifdef CONFIG_OSF4_COMPAT
.quad osf_readv /* 120 */
.quad osf_writev
#else
.quad sys_readv /* 120 */
.quad sys_writev
#endif
.quad osf_settimeofday
.quad sys_fchown
.quad sys_fchmod
.quad sys_recvfrom /* 125 */
.quad sys_setreuid
.quad sys_setregid
.quad sys_rename
.quad sys_truncate
.quad sys_ftruncate /* 130 */
.quad sys_flock
.quad sys_setgid
.quad sys_sendto
.quad sys_shutdown
.quad sys_socketpair /* 135 */
.quad sys_mkdir
.quad sys_rmdir
.quad osf_utimes
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 140 */
.quad sys_getpeername
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad sys_getrlimit
.quad sys_setrlimit /* 145 */
.quad alpha_ni_syscall
.quad sys_setsid
.quad sys_quotactl
.quad alpha_ni_syscall
.quad sys_getsockname /* 150 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 155 */
.quad osf_sigaction
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad osf_getdirentries
.quad osf_statfs /* 160 */
.quad osf_fstatfs
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad osf_getdomainname /* 165 */
.quad sys_setdomainname
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 170 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 175 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 180 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 185 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 190 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 195 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad osf_swapon
.quad sys_msgctl /* 200 */
.quad sys_msgget
.quad sys_msgrcv
.quad sys_msgsnd
.quad sys_semctl
.quad sys_semget /* 205 */
.quad sys_semop
.quad osf_utsname
.quad sys_lchown
.quad osf_shmat
.quad sys_shmctl /* 210 */
.quad sys_shmdt
.quad sys_shmget
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 215 */
.quad alpha_ni_syscall
.quad sys_msync
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 220 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 225 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 230 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad sys_getpgid
.quad sys_getsid
.quad sys_sigaltstack /* 235 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 240 */
.quad osf_sysinfo
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad osf_proplist_syscall
.quad alpha_ni_syscall /* 245 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 250 */
.quad osf_usleep_thread
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad sys_sysfs
.quad alpha_ni_syscall /* 255 */
.quad osf_getsysinfo
.quad osf_setsysinfo
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 260 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 265 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 270 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 275 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 280 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 285 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 290 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 295 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
/* linux-specific system calls start at 300 */
.quad sys_bdflush /* 300 */
.quad sys_sethae
.quad sys_mount
.quad sys_old_adjtimex
.quad sys_swapoff
.quad sys_getdents /* 305 */
.quad alpha_create_module
.quad sys_init_module
.quad sys_delete_module
.quad sys_get_kernel_syms
.quad sys_syslog /* 310 */
.quad sys_reboot
.quad sys_clone
.quad sys_uselib
.quad sys_mlock
.quad sys_munlock /* 315 */
.quad sys_mlockall
.quad sys_munlockall
.quad sys_sysinfo
.quad sys_sysctl
.quad sys_ni_syscall /* 320 */
.quad sys_oldumount
.quad sys_swapon
.quad sys_times
.quad sys_personality
.quad sys_setfsuid /* 325 */
.quad sys_setfsgid
.quad sys_ustat
.quad sys_statfs
.quad sys_fstatfs
.quad sys_sched_setparam /* 330 */
.quad sys_sched_getparam
.quad sys_sched_setscheduler
.quad sys_sched_getscheduler
.quad sys_sched_yield
.quad sys_sched_get_priority_max /* 335 */
.quad sys_sched_get_priority_min
.quad sys_sched_rr_get_interval
.quad sys_ni_syscall /* sys_afs_syscall */
.quad sys_newuname
.quad sys_nanosleep /* 340 */
.quad sys_mremap
.quad sys_nfsservctl
.quad sys_setresuid
.quad sys_getresuid
.quad sys_pciconfig_read /* 345 */
.quad sys_pciconfig_write
.quad sys_query_module
.quad sys_prctl
.quad sys_pread64
.quad sys_pwrite64 /* 350 */
.quad sys_rt_sigreturn
.quad sys_rt_sigaction
.quad sys_rt_sigprocmask
.quad sys_rt_sigpending
.quad sys_rt_sigtimedwait /* 355 */
.quad sys_rt_sigqueueinfo
.quad sys_rt_sigsuspend
.quad sys_select
.quad sys_gettimeofday
.quad sys_settimeofday /* 360 */
.quad sys_getitimer
.quad sys_setitimer
.quad sys_utimes
.quad sys_getrusage
.quad sys_wait4 /* 365 */
.quad sys_adjtimex
.quad sys_getcwd
.quad sys_capget
.quad sys_capset
.quad sys_sendfile /* 370 */
.quad sys_setresgid
.quad sys_getresgid
.quad sys_ni_syscall /* sys_dipc */
.quad sys_pivot_root
.quad sys_mincore /* 375 */
.quad sys_pciconfig_iobase
.quad sys_getdents64
.quad sys_gettid
.quad sys_readahead
.quad sys_ni_syscall /* 380, sys_security */
.quad sys_tkill
.quad sys_setxattr
.quad sys_lsetxattr
.quad sys_fsetxattr
.quad sys_getxattr
.quad sys_lgetxattr
.quad sys_fgetxattr
.quad sys_listxattr
.quad sys_llistxattr
.quad sys_flistxattr /* 390 */
.quad sys_removexattr
.quad sys_lremovexattr
.quad sys_fremovexattr
.quad sys_futex
.quad sys_sched_setaffinity
.quad sys_sched_getaffinity
.quad sys_ni_syscall /* 397, tux */
.quad sys_io_setup
.quad sys_io_destroy
.quad sys_io_getevents /* 400 */
.quad sys_io_submit
.quad sys_io_cancel
.quad sys_ni_syscall /* 403, sys_alloc_hugepages */
.quad sys_ni_syscall /* 404, sys_free_hugepages */
.quad sys_exit_group
......@@ -44,8 +44,9 @@
#include <asm/processor.h>
extern int do_pipe(int *);
extern asmlinkage unsigned long sys_brk(unsigned long);
extern int sys_getpriority(int, int);
extern asmlinkage unsigned long sys_create_module(char *, unsigned long);
/*
* Brk needs to return an error. Still support Linux's brk(0) query idiom,
......@@ -53,7 +54,8 @@ extern asmlinkage unsigned long sys_brk(unsigned long);
* identical to OSF as we don't return 0 on success, but doing otherwise
* would require changes to libc. Hopefully this is good enough.
*/
asmlinkage unsigned long osf_brk(unsigned long brk)
asmlinkage unsigned long
osf_brk(unsigned long brk)
{
unsigned long retval = sys_brk(brk);
if (brk && brk != retval)
......@@ -64,8 +66,8 @@ asmlinkage unsigned long osf_brk(unsigned long brk)
/*
* This is pure guess-work..
*/
asmlinkage int osf_set_program_attributes(
unsigned long text_start, unsigned long text_len,
asmlinkage int
osf_set_program_attributes(unsigned long text_start, unsigned long text_len,
unsigned long bss_start, unsigned long bss_len)
{
struct mm_struct *mm;
......@@ -106,7 +108,8 @@ struct osf_dirent_callback {
int error;
};
static int osf_filldir(void *__buf, const char *name, int namlen, loff_t offset,
static int
osf_filldir(void *__buf, const char *name, int namlen, loff_t offset,
ino_t ino, unsigned int d_type)
{
struct osf_dirent *dirent;
......@@ -134,7 +137,8 @@ static int osf_filldir(void *__buf, const char *name, int namlen, loff_t offset,
return 0;
}
asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
asmlinkage int
osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
unsigned int count, long *basep)
{
int error;
......@@ -159,9 +163,9 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
if (count != buf.count)
error = count - buf.count;
out_putf:
out_putf:
fput(file);
out:
out:
return error;
}
......@@ -172,8 +176,9 @@ asmlinkage int osf_getdirentries(unsigned int fd, struct osf_dirent *dirent,
* Alpha syscall convention has no problem returning negative
* values:
*/
asmlinkage int osf_getpriority(int which, int who, int a2, int a3, int a4,
int a5, struct pt_regs regs)
asmlinkage int
osf_getpriority(int which, int who,
int a2, int a3, int a4, int a5, struct pt_regs regs)
{
extern int sys_getpriority(int, int);
int prio;
......@@ -194,24 +199,24 @@ asmlinkage int osf_getpriority(int which, int who, int a2, int a3, int a4,
/*
* No need to acquire the kernel lock, we're local..
*/
asmlinkage unsigned long sys_getxuid(int a0, int a1, int a2, int a3, int a4,
int a5, struct pt_regs regs)
asmlinkage unsigned long
sys_getxuid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
struct task_struct * tsk = current;
(&regs)->r20 = tsk->euid;
return tsk->uid;
}
asmlinkage unsigned long sys_getxgid(int a0, int a1, int a2, int a3, int a4,
int a5, struct pt_regs regs)
asmlinkage unsigned long
sys_getxgid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
struct task_struct * tsk = current;
(&regs)->r20 = tsk->egid;
return tsk->gid;
}
asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4,
int a5, struct pt_regs regs)
asmlinkage unsigned long
sys_getxpid(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
struct task_struct *tsk = current;
......@@ -226,9 +231,9 @@ asmlinkage unsigned long sys_getxpid(int a0, int a1, int a2, int a3, int a4,
return tsk->tgid;
}
asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
unsigned long prot, unsigned long flags, unsigned long fd,
unsigned long off)
asmlinkage unsigned long
osf_mmap(unsigned long addr, unsigned long len, unsigned long prot,
unsigned long flags, unsigned long fd, unsigned long off)
{
struct file *file = NULL;
unsigned long ret = -EBADF;
......@@ -249,7 +254,7 @@ asmlinkage unsigned long osf_mmap(unsigned long addr, unsigned long len,
up_write(&current->mm->mmap_sem);
if (file)
fput(file);
out:
out:
return ret;
}
......@@ -271,7 +276,9 @@ struct osf_statfs {
__kernel_fsid_t f_fsid;
} *osf_stat;
static int linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf_stat, unsigned long bufsiz)
static int
linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf_stat,
unsigned long bufsiz)
{
struct osf_statfs tmp_stat;
......@@ -291,7 +298,9 @@ static int linux_to_osf_statfs(struct statfs *linux_stat, struct osf_statfs *osf
return copy_to_user(osf_stat, &tmp_stat, bufsiz) ? -EFAULT : 0;
}
static int do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer, unsigned long bufsiz)
static int
do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer,
unsigned long bufsiz)
{
struct statfs linux_stat;
int error = vfs_statfs(dentry->d_inode->i_sb, &linux_stat);
......@@ -300,7 +309,8 @@ static int do_osf_statfs(struct dentry * dentry, struct osf_statfs *buffer, unsi
return error;
}
asmlinkage int osf_statfs(char *path, struct osf_statfs *buffer, unsigned long bufsiz)
asmlinkage int
osf_statfs(char *path, struct osf_statfs *buffer, unsigned long bufsiz)
{
struct nameidata nd;
int retval;
......@@ -313,7 +323,8 @@ asmlinkage int osf_statfs(char *path, struct osf_statfs *buffer, unsigned long b
return retval;
}
asmlinkage int osf_fstatfs(unsigned long fd, struct osf_statfs *buffer, unsigned long bufsiz)
asmlinkage int
osf_fstatfs(unsigned long fd, struct osf_statfs *buffer, unsigned long bufsiz)
{
struct file *file;
int retval;
......@@ -342,10 +353,9 @@ struct cdfs_args {
char *devname;
int flags;
uid_t exroot;
/*
* This has lots more here, which Linux handles with the option block
* but I'm too lazy to do the translation into ASCII.
*/
/* This has lots more here, which Linux handles with the option block
but I'm too lazy to do the translation into ASCII. */
};
struct procfs_args {
......@@ -362,7 +372,8 @@ struct procfs_args {
* Just how long ago was it written? OTOH our UFS driver may be still
* unhappy with OSF UFS. [CHECKME]
*/
static int osf_ufs_mount(char *dirname, struct ufs_args *args, int flags)
static int
osf_ufs_mount(char *dirname, struct ufs_args *args, int flags)
{
int retval;
struct cdfs_args tmp;
......@@ -377,11 +388,12 @@ static int osf_ufs_mount(char *dirname, struct ufs_args *args, int flags)
goto out;
retval = do_mount(devname, dirname, "ext2", flags, NULL);
putname(devname);
out:
out:
return retval;
}
static int osf_cdfs_mount(char *dirname, struct cdfs_args *args, int flags)
static int
osf_cdfs_mount(char *dirname, struct cdfs_args *args, int flags)
{
int retval;
struct cdfs_args tmp;
......@@ -396,11 +408,12 @@ static int osf_cdfs_mount(char *dirname, struct cdfs_args *args, int flags)
goto out;
retval = do_mount(devname, dirname, "iso9660", flags, NULL);
putname(devname);
out:
out:
return retval;
}
static int osf_procfs_mount(char *dirname, struct procfs_args *args, int flags)
static int
osf_procfs_mount(char *dirname, struct procfs_args *args, int flags)
{
struct procfs_args tmp;
......@@ -410,7 +423,8 @@ static int osf_procfs_mount(char *dirname, struct procfs_args *args, int flags)
return do_mount("", dirname, "proc", flags, NULL);
}
asmlinkage int osf_mount(unsigned long typenr, char *path, int flag, void *data)
asmlinkage int
osf_mount(unsigned long typenr, char *path, int flag, void *data)
{
int retval = -EINVAL;
char *name;
......@@ -435,12 +449,13 @@ asmlinkage int osf_mount(unsigned long typenr, char *path, int flag, void *data)
printk("osf_mount(%ld, %x)\n", typenr, flag);
}
putname(name);
out:
out:
unlock_kernel();
return retval;
}
asmlinkage int osf_utsname(char *name)
asmlinkage int
osf_utsname(char *name)
{
int error;
......@@ -458,12 +473,13 @@ asmlinkage int osf_utsname(char *name)
goto out;
error = 0;
out:
out:
up_read(&uts_sem);
return error;
}
asmlinkage int osf_swapon(const char *path, int flags, int lowat, int hiwat)
asmlinkage int
osf_swapon(const char *path, int flags, int lowat, int hiwat)
{
int ret;
......@@ -474,35 +490,36 @@ asmlinkage int osf_swapon(const char *path, int flags, int lowat, int hiwat)
return ret;
}
asmlinkage unsigned long sys_getpagesize(void)
asmlinkage unsigned long
sys_getpagesize(void)
{
return PAGE_SIZE;
}
asmlinkage unsigned long sys_getdtablesize(void)
asmlinkage unsigned long
sys_getdtablesize(void)
{
return NR_OPEN;
}
asmlinkage int sys_pipe(int a0, int a1, int a2, int a3, int a4, int a5,
struct pt_regs regs)
asmlinkage int
sys_pipe(int a0, int a1, int a2, int a3, int a4, int a5, struct pt_regs regs)
{
int fd[2];
int error;
int fd[2], error;
error = do_pipe(fd);
if (error)
goto out;
(&regs)->r20 = fd[1];
if (!error) {
regs.r20 = fd[1];
error = fd[0];
out:
}
return error;
}
/*
* For compatibility with OSF/1 only. Use utsname(2) instead.
*/
asmlinkage int osf_getdomainname(char *name, int namelen)
asmlinkage int
osf_getdomainname(char *name, int namelen)
{
unsigned len;
int i, error;
......@@ -522,12 +539,12 @@ asmlinkage int osf_getdomainname(char *name, int namelen)
break;
}
up_read(&uts_sem);
out:
out:
return error;
}
asmlinkage long osf_shmat(int shmid, void *shmaddr, int shmflg)
asmlinkage long
osf_shmat(int shmid, void *shmaddr, int shmflg)
{
unsigned long raddr;
long err;
......@@ -541,7 +558,7 @@ asmlinkage long osf_shmat(int shmid, void *shmaddr, int shmflg)
* non-negative longs!
*/
err = raddr;
out:
out:
unlock_kernel();
return err;
}
......@@ -612,7 +629,8 @@ enum pl_code {
PL_DEL = 5, PL_FDEL = 6
};
asmlinkage long osf_proplist_syscall(enum pl_code code, union pl_args *args)
asmlinkage long
osf_proplist_syscall(enum pl_code code, union pl_args *args)
{
long error;
int *min_buf_size_ptr;
......@@ -655,7 +673,8 @@ asmlinkage long osf_proplist_syscall(enum pl_code code, union pl_args *args)
return error;
}
asmlinkage int osf_sigstack(struct sigstack *uss, struct sigstack *uoss)
asmlinkage int
osf_sigstack(struct sigstack *uss, struct sigstack *uoss)
{
unsigned long usp = rdusp();
unsigned long oss_sp = current->sas_ss_sp + current->sas_ss_size;
......@@ -691,7 +710,7 @@ asmlinkage int osf_sigstack(struct sigstack *uss, struct sigstack *uoss)
}
error = 0;
out:
out:
return error;
}
......@@ -702,32 +721,28 @@ asmlinkage int osf_sigstack(struct sigstack *uss, struct sigstack *uoss)
* create_module() because it's one of the few system calls
* that return kernel addresses (which are negative).
*/
asmlinkage unsigned long alpha_create_module(char *module_name, unsigned long size,
int a3, int a4, int a5, int a6,
struct pt_regs regs)
asmlinkage unsigned long
alpha_create_module(char *module_name, unsigned long size,
int a3, int a4, int a5, int a6, struct pt_regs regs)
{
asmlinkage unsigned long sys_create_module(char *, unsigned long);
long retval;
lock_kernel();
retval = sys_create_module(module_name, size);
/*
* we get either a module address or an error number,
* and we know the error number is a small negative
* number, while the address is always negative but
* much larger.
*/
if (retval + 1000 > 0)
goto out;
/* tell entry.S:syscall_error that this is NOT an error: */
/* We get either a module address or an error number, and we know
the error number is a small negative number, while the address
is always negative but much larger. */
if (retval + 1000 < 0)
regs.r0 = 0;
out:
unlock_kernel();
return retval;
}
asmlinkage long osf_sysinfo(int command, char *buf, long count)
asmlinkage long
osf_sysinfo(int command, char *buf, long count)
{
static char * sysinfo_table[] = {
system_utsname.sysname,
......@@ -761,12 +776,12 @@ asmlinkage long osf_sysinfo(int command, char *buf, long count)
else
err = 0;
up_read(&uts_sem);
out:
out:
return err;
}
asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer,
unsigned long nbytes,
asmlinkage unsigned long
osf_getsysinfo(unsigned long op, void *buffer, unsigned long nbytes,
int *start, void *arg)
{
unsigned long w;
......@@ -823,8 +838,8 @@ asmlinkage unsigned long osf_getsysinfo(unsigned long op, void *buffer,
return -EOPNOTSUPP;
}
asmlinkage unsigned long osf_setsysinfo(unsigned long op, void *buffer,
unsigned long nbytes,
asmlinkage unsigned long
osf_setsysinfo(unsigned long op, void *buffer, unsigned long nbytes,
int *start, void *arg)
{
switch (op) {
......@@ -925,21 +940,24 @@ struct itimerval32
struct timeval32 it_value;
};
static inline long get_tv32(struct timeval *o, struct timeval32 *i)
static inline long
get_tv32(struct timeval *o, struct timeval32 *i)
{
return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
(__get_user(o->tv_sec, &i->tv_sec) |
__get_user(o->tv_usec, &i->tv_usec)));
}
static inline long put_tv32(struct timeval32 *o, struct timeval *i)
static inline long
put_tv32(struct timeval32 *o, struct timeval *i)
{
return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
(__put_user(i->tv_sec, &o->tv_sec) |
__put_user(i->tv_usec, &o->tv_usec)));
}
static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
static inline long
get_it32(struct itimerval *o, struct itimerval32 *i)
{
return (!access_ok(VERIFY_READ, i, sizeof(*i)) ||
(__get_user(o->it_interval.tv_sec, &i->it_interval.tv_sec) |
......@@ -948,7 +966,8 @@ static inline long get_it32(struct itimerval *o, struct itimerval32 *i)
__get_user(o->it_value.tv_usec, &i->it_value.tv_usec)));
}
static inline long put_it32(struct itimerval32 *o, struct itimerval *i)
static inline long
put_it32(struct itimerval32 *o, struct itimerval *i)
{
return (!access_ok(VERIFY_WRITE, o, sizeof(*o)) ||
(__put_user(i->it_interval.tv_sec, &o->it_interval.tv_sec) |
......@@ -964,7 +983,8 @@ jiffies_to_timeval32(unsigned long jiffies, struct timeval32 *value)
value->tv_sec = jiffies / HZ;
}
asmlinkage int osf_gettimeofday(struct timeval32 *tv, struct timezone *tz)
asmlinkage int
osf_gettimeofday(struct timeval32 *tv, struct timezone *tz)
{
if (tv) {
struct timeval ktv;
......@@ -979,7 +999,8 @@ asmlinkage int osf_gettimeofday(struct timeval32 *tv, struct timezone *tz)
return 0;
}
asmlinkage int osf_settimeofday(struct timeval32 *tv, struct timezone *tz)
asmlinkage int
osf_settimeofday(struct timeval32 *tv, struct timezone *tz)
{
struct timeval ktv;
struct timezone ktz;
......@@ -996,7 +1017,8 @@ asmlinkage int osf_settimeofday(struct timeval32 *tv, struct timezone *tz)
return do_sys_settimeofday(tv ? &ktv : NULL, tz ? &ktz : NULL);
}
asmlinkage int osf_getitimer(int which, struct itimerval32 *it)
asmlinkage int
osf_getitimer(int which, struct itimerval32 *it)
{
struct itimerval kit;
int error;
......@@ -1008,8 +1030,8 @@ asmlinkage int osf_getitimer(int which, struct itimerval32 *it)
return error;
}
asmlinkage int osf_setitimer(int which, struct itimerval32 *in,
struct itimerval32 *out)
asmlinkage int
osf_setitimer(int which, struct itimerval32 *in, struct itimerval32 *out)
{
struct itimerval kin, kout;
int error;
......@@ -1031,7 +1053,8 @@ asmlinkage int osf_setitimer(int which, struct itimerval32 *in,
}
asmlinkage int osf_utimes(const char *filename, struct timeval32 *tvs)
asmlinkage int
osf_utimes(const char *filename, struct timeval32 *tvs)
{
char *kfilename;
struct timeval ktvs[2];
......@@ -1136,9 +1159,9 @@ osf_select(int n, fd_set *inp, fd_set *outp, fd_set *exp,
set_fd_set(n, outp->fds_bits, fds.res_out);
set_fd_set(n, exp->fds_bits, fds.res_ex);
out:
out:
kfree(bits);
out_nofds:
out_nofds:
return ret;
}
......@@ -1161,7 +1184,8 @@ struct rusage32 {
long ru_nivcsw; /* involuntary " */
};
asmlinkage int osf_getrusage(int who, struct rusage32 *ru)
asmlinkage int
osf_getrusage(int who, struct rusage32 *ru)
{
struct rusage32 r;
......@@ -1198,8 +1222,8 @@ asmlinkage int osf_getrusage(int who, struct rusage32 *ru)
return copy_to_user(ru, &r, sizeof(r)) ? -EFAULT : 0;
}
asmlinkage int osf_wait4(pid_t pid, int *ustatus, int options,
struct rusage32 *ur)
asmlinkage int
osf_wait4(pid_t pid, int *ustatus, int options, struct rusage32 *ur)
{
if (!ur) {
return sys_wait4(pid, ustatus, options, NULL);
......@@ -1245,7 +1269,8 @@ asmlinkage int osf_wait4(pid_t pid, int *ustatus, int options,
* seems to be a timeval pointer, and I suspect the second
* one is the time remaining.. Ho humm.. No documentation.
*/
asmlinkage int osf_usleep_thread(struct timeval32 *sleep, struct timeval32 *remain)
asmlinkage int
osf_usleep_thread(struct timeval32 *sleep, struct timeval32 *remain)
{
struct timeval tmp;
unsigned long ticks;
......@@ -1268,7 +1293,7 @@ asmlinkage int osf_usleep_thread(struct timeval32 *sleep, struct timeval32 *rema
}
return 0;
fault:
fault:
return -EFAULT;
}
......@@ -1302,7 +1327,8 @@ struct timex32 {
int :32; int :32; int :32; int :32;
};
asmlinkage int sys_old_adjtimex(struct timex32 *txc_p)
asmlinkage int
sys_old_adjtimex(struct timex32 *txc_p)
{
struct timex txc;
int ret;
......
......@@ -191,26 +191,13 @@ machine_power_off(void)
common_shutdown(LINUX_REBOOT_CMD_POWER_OFF, NULL);
}
/* Used by sysrq-p, among others. I don't believe r9-r15 are ever
saved in the context it's used. */
void
show_regs(struct pt_regs * regs)
show_regs(struct pt_regs *regs)
{
printk("\n");
printk("Pid: %d, comm: %20s\n", current->pid, current->comm);
printk("ps: %04lx pc: [<%016lx>] CPU %d %s\n",
regs->ps, regs->pc, smp_processor_id(), print_tainted());
printk("rp: [<%016lx>] sp: %p\n", regs->r26, regs+1);
printk(" r0: %016lx r1: %016lx r2: %016lx r3: %016lx\n",
regs->r0, regs->r1, regs->r2, regs->r3);
printk(" r4: %016lx r5: %016lx r6: %016lx r7: %016lx\n",
regs->r4, regs->r5, regs->r6, regs->r7);
printk(" r8: %016lx r16: %016lx r17: %016lx r18: %016lx\n",
regs->r8, regs->r16, regs->r17, regs->r18);
printk("r19: %016lx r20: %016lx r21: %016lx r22: %016lx\n",
regs->r19, regs->r20, regs->r21, regs->r22);
printk("r23: %016lx r24: %016lx r25: %016lx r26: %016lx\n",
regs->r23, regs->r24, regs->r25, regs->r26);
printk("r27: %016lx r28: %016lx r29: %016lx hae: %016lx\n",
regs->r27, regs->r28, regs->gp, regs->hae);
dik_show_regs(regs, 0);
}
/*
......
......@@ -37,6 +37,11 @@
#include <linux/blk.h>
#endif
#ifdef CONFIG_MAGIC_SYSRQ
#include <linux/sysrq.h>
#include <linux/reboot.h>
#endif
#include <linux/notifier.h>
extern struct notifier_block *panic_notifier_list;
static int alpha_panic_event(struct notifier_block *, unsigned long, void *);
......@@ -539,6 +544,15 @@ setup_arch(char **cmdline_p)
register_srm_console();
}
#ifdef CONFIG_MAGIC_SYSRQ
/* If we're using SRM, make sysrq-b halt back to the prom,
not auto-reboot. */
if (alpha_using_srm) {
struct sysrq_key_op *op = __sysrq_get_key_op('b');
op->handler = (void *) machine_halt;
}
#endif
/*
* Indentify and reconfigure for the current system.
*/
......
/*
* arch/alpha/kernel/systbls.S
*
* The system call table.
*/
#include <asm/unistd.h>
.data
.align 3
.globl sys_call_table
sys_call_table:
.quad alpha_ni_syscall /* 0 */
.quad sys_exit
.quad sys_fork
.quad sys_read
.quad sys_write
.quad alpha_ni_syscall /* 5 */
.quad sys_close
.quad osf_wait4
.quad alpha_ni_syscall
.quad sys_link
.quad sys_unlink /* 10 */
.quad alpha_ni_syscall
.quad sys_chdir
.quad sys_fchdir
.quad sys_mknod
.quad sys_chmod /* 15 */
.quad sys_chown
.quad osf_brk
.quad alpha_ni_syscall
.quad sys_lseek
.quad sys_getxpid /* 20 */
.quad osf_mount
.quad sys_umount
.quad sys_setuid
.quad sys_getxuid
.quad alpha_ni_syscall /* 25 */
.quad sys_ptrace
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 30 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad sys_access
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 35 */
.quad sys_sync
.quad sys_kill
.quad alpha_ni_syscall
.quad sys_setpgid
.quad alpha_ni_syscall /* 40 */
.quad sys_dup
.quad sys_pipe
.quad osf_set_program_attributes
.quad alpha_ni_syscall
.quad sys_open /* 45 */
.quad alpha_ni_syscall
.quad sys_getxgid
.quad osf_sigprocmask
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 50 */
.quad sys_acct
.quad sys_sigpending
.quad alpha_ni_syscall
.quad sys_ioctl
.quad alpha_ni_syscall /* 55 */
.quad alpha_ni_syscall
.quad sys_symlink
.quad sys_readlink
.quad sys_execve
.quad sys_umask /* 60 */
.quad sys_chroot
.quad alpha_ni_syscall
.quad sys_getpgrp
.quad sys_getpagesize
.quad alpha_ni_syscall /* 65 */
.quad sys_vfork
.quad sys_newstat
.quad sys_newlstat
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 70 */
.quad osf_mmap
.quad alpha_ni_syscall
.quad sys_munmap
.quad sys_mprotect
.quad sys_madvise /* 75 */
.quad sys_vhangup
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad sys_getgroups
/* map BSD's setpgrp to sys_setpgid for binary compatibility: */
.quad sys_setgroups /* 80 */
.quad alpha_ni_syscall
.quad sys_setpgid
.quad osf_setitimer
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 85 */
.quad osf_getitimer
.quad sys_gethostname
.quad sys_sethostname
.quad sys_getdtablesize
.quad sys_dup2 /* 90 */
.quad sys_newfstat
.quad sys_fcntl
.quad osf_select
.quad sys_poll
.quad sys_fsync /* 95 */
.quad sys_setpriority
.quad sys_socket
.quad sys_connect
.quad sys_accept
.quad osf_getpriority /* 100 */
.quad sys_send
.quad sys_recv
.quad sys_sigreturn
.quad sys_bind
.quad sys_setsockopt /* 105 */
.quad sys_listen
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 110 */
.quad sys_sigsuspend
.quad osf_sigstack
.quad sys_recvmsg
.quad sys_sendmsg
.quad alpha_ni_syscall /* 115 */
.quad osf_gettimeofday
.quad osf_getrusage
.quad sys_getsockopt
.quad alpha_ni_syscall
#ifdef CONFIG_OSF4_COMPAT
.quad osf_readv /* 120 */
.quad osf_writev
#else
.quad sys_readv /* 120 */
.quad sys_writev
#endif
.quad osf_settimeofday
.quad sys_fchown
.quad sys_fchmod
.quad sys_recvfrom /* 125 */
.quad sys_setreuid
.quad sys_setregid
.quad sys_rename
.quad sys_truncate
.quad sys_ftruncate /* 130 */
.quad sys_flock
.quad sys_setgid
.quad sys_sendto
.quad sys_shutdown
.quad sys_socketpair /* 135 */
.quad sys_mkdir
.quad sys_rmdir
.quad osf_utimes
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 140 */
.quad sys_getpeername
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad sys_getrlimit
.quad sys_setrlimit /* 145 */
.quad alpha_ni_syscall
.quad sys_setsid
.quad sys_quotactl
.quad alpha_ni_syscall
.quad sys_getsockname /* 150 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 155 */
.quad osf_sigaction
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad osf_getdirentries
.quad osf_statfs /* 160 */
.quad osf_fstatfs
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad osf_getdomainname /* 165 */
.quad sys_setdomainname
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 170 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 175 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 180 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 185 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 190 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 195 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad osf_swapon
.quad sys_msgctl /* 200 */
.quad sys_msgget
.quad sys_msgrcv
.quad sys_msgsnd
.quad sys_semctl
.quad sys_semget /* 205 */
.quad sys_semop
.quad osf_utsname
.quad sys_lchown
.quad osf_shmat
.quad sys_shmctl /* 210 */
.quad sys_shmdt
.quad sys_shmget
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 215 */
.quad alpha_ni_syscall
.quad sys_msync
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 220 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 225 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 230 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad sys_getpgid
.quad sys_getsid
.quad sys_sigaltstack /* 235 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 240 */
.quad osf_sysinfo
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad osf_proplist_syscall
.quad alpha_ni_syscall /* 245 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 250 */
.quad osf_usleep_thread
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad sys_sysfs
.quad alpha_ni_syscall /* 255 */
.quad osf_getsysinfo
.quad osf_setsysinfo
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 260 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 265 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 270 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 275 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 280 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 285 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 290 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall /* 295 */
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
.quad alpha_ni_syscall
/* linux-specific system calls start at 300 */
.quad sys_bdflush /* 300 */
.quad sys_sethae
.quad sys_mount
.quad sys_old_adjtimex
.quad sys_swapoff
.quad sys_getdents /* 305 */
.quad alpha_create_module
.quad sys_init_module
.quad sys_delete_module
.quad sys_get_kernel_syms
.quad sys_syslog /* 310 */
.quad sys_reboot
.quad sys_clone
.quad sys_uselib
.quad sys_mlock
.quad sys_munlock /* 315 */
.quad sys_mlockall
.quad sys_munlockall
.quad sys_sysinfo
.quad sys_sysctl
.quad sys_ni_syscall /* 320 */
.quad sys_oldumount
.quad sys_swapon
.quad sys_times
.quad sys_personality
.quad sys_setfsuid /* 325 */
.quad sys_setfsgid
.quad sys_ustat
.quad sys_statfs
.quad sys_fstatfs
.quad sys_sched_setparam /* 330 */
.quad sys_sched_getparam
.quad sys_sched_setscheduler
.quad sys_sched_getscheduler
.quad sys_sched_yield
.quad sys_sched_get_priority_max /* 335 */
.quad sys_sched_get_priority_min
.quad sys_sched_rr_get_interval
.quad sys_ni_syscall /* sys_afs_syscall */
.quad sys_newuname
.quad sys_nanosleep /* 340 */
.quad sys_mremap
.quad sys_nfsservctl
.quad sys_setresuid
.quad sys_getresuid
.quad sys_pciconfig_read /* 345 */
.quad sys_pciconfig_write
.quad sys_query_module
.quad sys_prctl
.quad sys_pread64
.quad sys_pwrite64 /* 350 */
.quad sys_rt_sigreturn
.quad sys_rt_sigaction
.quad sys_rt_sigprocmask
.quad sys_rt_sigpending
.quad sys_rt_sigtimedwait /* 355 */
.quad sys_rt_sigqueueinfo
.quad sys_rt_sigsuspend
.quad sys_select
.quad sys_gettimeofday
.quad sys_settimeofday /* 360 */
.quad sys_getitimer
.quad sys_setitimer
.quad sys_utimes
.quad sys_getrusage
.quad sys_wait4 /* 365 */
.quad sys_adjtimex
.quad sys_getcwd
.quad sys_capget
.quad sys_capset
.quad sys_sendfile /* 370 */
.quad sys_setresgid
.quad sys_getresgid
.quad sys_ni_syscall /* sys_dipc */
.quad sys_pivot_root
.quad sys_mincore /* 375 */
.quad sys_pciconfig_iobase
.quad sys_getdents64
.quad sys_gettid
.quad sys_readahead
.quad sys_ni_syscall /* 380, sys_security */
.quad sys_tkill
.quad sys_setxattr
.quad sys_lsetxattr
.quad sys_fsetxattr
.quad sys_getxattr /* 385 */
.quad sys_lgetxattr
.quad sys_fgetxattr
.quad sys_listxattr
.quad sys_llistxattr
.quad sys_flistxattr /* 390 */
.quad sys_removexattr
.quad sys_lremovexattr
.quad sys_fremovexattr
.quad sys_futex
.quad sys_sched_setaffinity /* 395 */
.quad sys_sched_getaffinity
.quad sys_ni_syscall /* 397, tux */
.quad sys_io_setup
.quad sys_io_destroy
.quad sys_io_getevents /* 400 */
.quad sys_io_submit
.quad sys_io_cancel
.quad sys_ni_syscall /* 403, sys_alloc_hugepages */
.quad sys_ni_syscall /* 404, sys_free_hugepages */
.quad sys_exit_group
.size sys_call_table, . - sys_call_table
.type sys_call_table, @object
/* Remember to update everything, kids. */
.ifne (. - sys_call_table) - (NR_SYSCALLS * 8)
.err
.endif
......@@ -51,14 +51,16 @@ obj-$(CONFIG_SMP) += dec_and_lock.o
include $(TOPDIR)/Rules.make
__divqu.o: $(ev6)divide.S
$(CC) $(AFLAGS) -DDIV -c -o __divqu.o $(ev6)divide.S
$(obj)/__divqu.o: $(obj)/$(ev6)divide.S
$(CC) $(AFLAGS) -DDIV -c -o $(obj)/__divqu.o $(obj)/$(ev6)divide.S
__remqu.o: $(ev6)divide.S
$(CC) $(AFLAGS) -DREM -c -o __remqu.o $(ev6)divide.S
$(obj)/__remqu.o: $(obj)/$(ev6)divide.S
$(CC) $(AFLAGS) -DREM -c -o $(obj)/__remqu.o $(obj)/$(ev6)divide.S
__divlu.o: $(ev6)divide.S
$(CC) $(AFLAGS) -DDIV -DINTSIZE -c -o __divlu.o $(ev6)divide.S
$(obj)/__divlu.o: $(obj)/$(ev6)divide.S
$(CC) $(AFLAGS) -DDIV -DINTSIZE \
-c -o $(obj)/__divlu.o $(obj)/$(ev6)divide.S
__remlu.o: $(ev6)divide.S
$(CC) $(AFLAGS) -DREM -DINTSIZE -c -o __remlu.o $(ev6)divide.S
$(obj)/__remlu.o: $(obj)/$(ev6)divide.S
$(CC) $(AFLAGS) -DREM -DINTSIZE \
-c -o $(obj)/__remlu.o $(obj)/$(ev6)divide.S
......@@ -278,7 +278,7 @@ $u_eoc:
extqh t2, a1, t0 # e0 : extract low bits for last word
or t1, t0, t1 # e1 :
1: cmpbge zero, t1, t7
1: cmpbge zero, t1, t8
mov t1, t0
$u_eocfin: # end-of-count, final word
......
......@@ -125,11 +125,10 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
goto bad_area;
if (expand_stack(vma, address))
goto bad_area;
/*
* Ok, we have a good vm_area for this memory access, so
* we can handle it..
*/
good_area:
/* Ok, we have a good vm_area for this memory access, so
we can handle it. */
good_area:
if (cause < 0) {
if (!(vma->vm_flags & VM_EXEC))
goto bad_area;
......@@ -143,11 +142,9 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
}
survive:
/*
* If for any reason at all we couldn't handle the fault,
* make sure we exit gracefully rather than endlessly redo
* the fault.
*/
/* If for any reason at all we couldn't handle the fault,
make sure we exit gracefully rather than endlessly redo
the fault. */
fault = handle_mm_fault(mm, vma, address, cause > 0);
up_read(&mm->mmap_sem);
......@@ -155,14 +152,11 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
goto out_of_memory;
if (fault == 0)
goto do_sigbus;
return;
/*
* Something tried to access memory that isn't in our memory map..
* Fix it, but check if it's kernel or user first..
*/
bad_area:
/* Something tried to access memory that isn't in our memory map.
Fix it, but check if it's kernel or user first. */
bad_area:
up_read(&mm->mmap_sem);
if (user_mode(regs)) {
......@@ -170,7 +164,7 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
return;
}
no_context:
no_context:
/* Are we prepared to handle this fault as an exception? */
if ((fixup = search_exception_table(regs->pc, regs->gp)) != 0) {
unsigned long newpc;
......@@ -183,20 +177,16 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
return;
}
/*
* Oops. The kernel tried to access some bad page. We'll have to
* terminate things with extreme prejudice.
*/
/* Oops. The kernel tried to access some bad page. We'll have to
terminate things with extreme prejudice. */
printk(KERN_ALERT "Unable to handle kernel paging request at "
"virtual address %016lx\n", address);
die_if_kernel("Oops", regs, cause, (unsigned long*)regs - 16);
do_exit(SIGKILL);
/*
* We ran out of memory, or some other thing happened to us that made
* us unable to handle the page fault gracefully.
*/
out_of_memory:
/* We ran out of memory, or some other thing happened to us that
made us unable to handle the page fault gracefully. */
out_of_memory:
if (current->pid == 1) {
yield();
down_read(&mm->mmap_sem);
......@@ -208,18 +198,16 @@ do_page_fault(unsigned long address, unsigned long mmcsr,
goto no_context;
do_exit(SIGKILL);
do_sigbus:
/*
* Send a sigbus, regardless of whether we were in kernel
* or user mode.
*/
do_sigbus:
/* Send a sigbus, regardless of whether we were in kernel
or user mode. */
force_sig(SIGBUS, current);
if (!user_mode(regs))
goto no_context;
return;
#ifdef CONFIG_ALPHA_LARGE_VMALLOC
vmalloc_fault:
vmalloc_fault:
if (user_mode(regs)) {
force_sig(SIGSEGV, current);
return;
......
......@@ -58,10 +58,11 @@ SECTIONS
__initcall_end = .;
}
. = ALIGN(64);
.data.percpu ALIGN(64): {
__per_cpu_start = .;
.data.percpu : { *(.data.percpu) }
*(.data.percpu)
__per_cpu_end = .;
}
/* The initial task and kernel stack */
.data.init_thread ALIGN(2*8192) : {
......
......@@ -65,6 +65,14 @@ CONFIG_X86_NUMAQ
You will need a new lynxer.elf file to flash your firmware with - send
email to Martin.Bligh@us.ibm.com
CONFIG_X86_CYCLONE
This patch used the Cyclone performance counter on IBM x440, x360,
and other Summit based systems for calculating gettimeofday. This
fixes problems resulting from TSC skew found in multi-CEC system.
If you are suffering from time skew using a multi-CEC system, say YES.
Otherwise it is safe to say NO.
CONFIG_X86_UP_IOAPIC
An IO-APIC (I/O Advanced Programmable Interrupt Controller) is an
SMP-capable replacement for PC-style interrupt controllers. Most
......
......@@ -53,7 +53,7 @@ HEAD := arch/i386/kernel/head.o arch/i386/kernel/init_task.o
libs-y += arch/i386/lib/
core-y += arch/i386/kernel/ arch/i386/mm/ \
arch/i386/$(MACHINE)/
arch/i386/$(MACHINE)/ arch/i386/kernel/timers/
drivers-$(CONFIG_MATH_EMULATION) += arch/i386/math-emu/
drivers-$(CONFIG_PCI) += arch/i386/pci/
......
......@@ -53,6 +53,7 @@
#include <asm/mpspec.h>
#include <asm/uaccess.h>
#include <asm/processor.h>
#include <asm/timer.h>
#include <linux/mc146818rtc.h>
#include <linux/timex.h>
......@@ -73,161 +74,15 @@ u64 jiffies_64;
unsigned long cpu_khz; /* Detected as we calibrate the TSC */
/* Number of usecs that the last interrupt was delayed */
static int delay_at_last_interrupt;
static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
/* Cached *multiplier* to convert TSC counts to microseconds.
* (see the equation below).
* Equal to 2^32 * (1 / (clocks per usec) ).
* Initialized in time_init.
*/
unsigned long fast_gettimeoffset_quotient;
extern rwlock_t xtime_lock;
extern unsigned long wall_jiffies;
spinlock_t rtc_lock = SPIN_LOCK_UNLOCKED;
static inline unsigned long do_fast_gettimeoffset(void)
{
register unsigned long eax, edx;
/* Read the Time Stamp Counter */
rdtsc(eax,edx);
/* .. relative to previous jiffy (32 bits is enough) */
eax -= last_tsc_low; /* tsc_low delta */
/*
* Time offset = (tsc_low delta) * fast_gettimeoffset_quotient
* = (tsc_low delta) * (usecs_per_clock)
* = (tsc_low delta) * (usecs_per_jiffy / clocks_per_jiffy)
*
* Using a mull instead of a divl saves up to 31 clock cycles
* in the critical path.
*/
__asm__("mull %2"
:"=a" (eax), "=d" (edx)
:"rm" (fast_gettimeoffset_quotient),
"0" (eax));
/* our adjusted time offset in microseconds */
return delay_at_last_interrupt + edx;
}
#define TICK_SIZE (tick_nsec / 1000)
spinlock_t i8253_lock = SPIN_LOCK_UNLOCKED;
EXPORT_SYMBOL(i8253_lock);
#ifndef CONFIG_X86_TSC
/* This function must be called with interrupts disabled
* It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs
*
* However, the pc-audio speaker driver changes the divisor so that
* it gets interrupted rather more often - it loads 64 into the
* counter rather than 11932! This has an adverse impact on
* do_gettimeoffset() -- it stops working! What is also not
* good is that the interval that our timer function gets called
* is no longer 10.0002 ms, but 9.9767 ms. To get around this
* would require using a different timing source. Maybe someone
* could use the RTC - I know that this can interrupt at frequencies
* ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix
* it so that at startup, the timer code in sched.c would select
* using either the RTC or the 8253 timer. The decision would be
* based on whether there was any other device around that needed
* to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz,
* and then do some jiggery to have a version of do_timer that
* advanced the clock by 1/1024 s. Every time that reached over 1/100
* of a second, then do all the old code. If the time was kept correct
* then do_gettimeoffset could just return 0 - there is no low order
* divider that can be accessed.
*
* Ideally, you would be able to use the RTC for the speaker driver,
* but it appears that the speaker driver really needs interrupt more
* often than every 120 us or so.
*
* Anyway, this needs more thought.... pjsg (1993-08-28)
*
* If you are really that interested, you should be reading
* comp.protocols.time.ntp!
*/
static unsigned long do_slow_gettimeoffset(void)
{
int count;
static int count_p = LATCH; /* for the first call after boot */
static unsigned long jiffies_p = 0;
/*
* cache volatile jiffies temporarily; we have IRQs turned off.
*/
unsigned long jiffies_t;
/* gets recalled with irq locally disabled */
spin_lock(&i8253_lock);
/* timer count may underflow right here */
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
/*
* We do this guaranteed double memory access instead of a _p
* postfix in the previous port access. Wheee, hackady hack
*/
jiffies_t = jiffies;
count |= inb_p(0x40) << 8;
/* VIA686a test code... reset the latch if count > max + 1 */
if (count > LATCH) {
outb_p(0x34, 0x43);
outb_p(LATCH & 0xff, 0x40);
outb(LATCH >> 8, 0x40);
count = LATCH - 1;
}
spin_unlock(&i8253_lock);
/*
* avoiding timer inconsistencies (they are rare, but they happen)...
* there are two kinds of problems that must be avoided here:
* 1. the timer counter underflows
* 2. hardware problem with the timer, not giving us continuous time,
* the counter does small "jumps" upwards on some Pentium systems,
* (see c't 95/10 page 335 for Neptun bug.)
*/
if( jiffies_t == jiffies_p ) {
if( count > count_p ) {
/* the nutcase */
count = do_timer_overflow(count);
}
} else
jiffies_p = jiffies_t;
count_p = count;
count = ((LATCH-1) - count) * TICK_SIZE;
count = (count + LATCH/2) / LATCH;
return count;
}
static unsigned long (*do_gettimeoffset)(void) = do_slow_gettimeoffset;
#else
#define do_gettimeoffset() do_fast_gettimeoffset()
#endif
struct timer_opts* timer;
/*
* This version of gettimeofday has microsecond resolution
......@@ -239,7 +94,7 @@ void do_gettimeofday(struct timeval *tv)
unsigned long usec, sec;
read_lock_irqsave(&xtime_lock, flags);
usec = do_gettimeoffset();
usec = timer->get_offset();
{
unsigned long lost = jiffies - wall_jiffies;
if (lost)
......@@ -267,7 +122,7 @@ void do_settimeofday(struct timeval *tv)
* wall time. Discover what correction gettimeofday() would have
* made, and then undo it!
*/
tv->tv_usec -= do_gettimeoffset();
tv->tv_usec -= timer->get_offset();
tv->tv_usec -= (jiffies - wall_jiffies) * (1000000 / HZ);
while (tv->tv_usec < 0) {
......@@ -433,34 +288,7 @@ void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs)
*/
write_lock(&xtime_lock);
if (use_tsc)
{
/*
* It is important that these two operations happen almost at
* the same time. We do the RDTSC stuff first, since it's
* faster. To avoid any inconsistencies, we need interrupts
* disabled locally.
*/
/*
* Interrupts are just disabled locally since the timer irq
* has the SA_INTERRUPT flag set. -arca
*/
/* read Pentium cycle counter */
rdtscl(last_tsc_low);
spin_lock(&i8253_lock);
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8;
spin_unlock(&i8253_lock);
count = ((LATCH-1) - count) * TICK_SIZE;
delay_at_last_interrupt = (count + LATCH/2) / LATCH;
}
timer->mark_offset();
do_timer_interrupt(irq, NULL, regs);
......@@ -510,85 +338,7 @@ unsigned long get_cmos_time(void)
return mktime(year, mon, day, hour, min, sec);
}
/* ------ Calibrate the TSC -------
* Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
* Too much 64-bit arithmetic here to do this cleanly in C, and for
* accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
* output busy loop as low as possible. We avoid reading the CTC registers
* directly because of the awkward 8-bit access mechanism of the 82C54
* device.
*/
#define CALIBRATE_LATCH (5 * LATCH)
#define CALIBRATE_TIME (5 * 1000020/HZ)
#ifdef CONFIG_X86_TSC
static unsigned long __init calibrate_tsc(void)
{
/* Set the Gate high, disable speaker */
outb((inb(0x61) & ~0x02) | 0x01, 0x61);
/*
* Now let's take care of CTC channel 2
*
* Set the Gate high, program CTC channel 2 for mode 0,
* (interrupt on terminal count mode), binary count,
* load 5 * LATCH count, (LSB and MSB) to begin countdown.
*/
outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */
outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
outb(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */
{
unsigned long startlow, starthigh;
unsigned long endlow, endhigh;
unsigned long count;
rdtsc(startlow,starthigh);
count = 0;
do {
count++;
} while ((inb(0x61) & 0x20) == 0);
rdtsc(endlow,endhigh);
last_tsc_low = endlow;
/* Error: ECTCNEVERSET */
if (count <= 1)
goto bad_ctc;
/* 64-bit subtract - gcc just messes up with long longs */
__asm__("subl %2,%0\n\t"
"sbbl %3,%1"
:"=a" (endlow), "=d" (endhigh)
:"g" (startlow), "g" (starthigh),
"0" (endlow), "1" (endhigh));
/* Error: ECPUTOOFAST */
if (endhigh)
goto bad_ctc;
/* Error: ECPUTOOSLOW */
if (endlow <= CALIBRATE_TIME)
goto bad_ctc;
__asm__("divl %2"
:"=a" (endlow), "=d" (endhigh)
:"r" (endlow), "0" (0), "1" (CALIBRATE_TIME));
return endlow;
}
/*
* The CTC wasn't reliable: we got a hit on the very first read,
* or the CPU was so fast/slow that the quotient wouldn't fit in
* 32 bits..
*/
bad_ctc:
return 0;
}
#endif /* CONFIG_X86_TSC */
/* XXX this driverfs stuff should probably go elsewhere later -john */
static struct sys_device device_i8253 = {
.name = "rtc",
.id = 0,
......@@ -605,119 +355,13 @@ static int time_init_device(void)
device_initcall(time_init_device);
#ifdef CONFIG_CPU_FREQ
static int
time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
void *data)
{
struct cpufreq_freqs *freq = data;
unsigned int i;
if (!cpu_has_tsc)
return 0;
switch (val) {
case CPUFREQ_PRECHANGE:
if ((freq->old < freq->new) &&
((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == 0))) {
cpu_khz = cpufreq_scale(cpu_khz, freq->old, freq->new);
fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_quotient, freq->new, freq->old);
}
for (i=0; i<NR_CPUS; i++)
if ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == i))
cpu_data[i].loops_per_jiffy = cpufreq_scale(cpu_data[i].loops_per_jiffy, freq->old, freq->new);
break;
case CPUFREQ_POSTCHANGE:
if ((freq->new < freq->old) &&
((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == 0))) {
cpu_khz = cpufreq_scale(cpu_khz, freq->old, freq->new);
fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_quotient, freq->new, freq->old);
}
for (i=0; i<NR_CPUS; i++)
if ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == i))
cpu_data[i].loops_per_jiffy = cpufreq_scale(cpu_data[i].loops_per_jiffy, freq->old, freq->new);
break;
}
return 0;
}
static struct notifier_block time_cpufreq_notifier_block = {
notifier_call: time_cpufreq_notifier
};
#endif
void __init time_init(void)
{
#ifdef CONFIG_X86_TSC
extern int x86_udelay_tsc;
#endif
xtime.tv_sec = get_cmos_time();
xtime.tv_nsec = 0;
/*
* If we have APM enabled or the CPU clock speed is variable
* (CPU stops clock on HLT or slows clock to save power)
* then the TSC timestamps may diverge by up to 1 jiffy from
* 'real time' but nothing will break.
* The most frequent case is that the CPU is "woken" from a halt
* state by the timer interrupt itself, so we get 0 error. In the
* rare cases where a driver would "wake" the CPU and request a
* timestamp, the maximum error is < 1 jiffy. But timestamps are
* still perfectly ordered.
* Note that the TSC counter will be reset if APM suspends
* to disk; this won't break the kernel, though, 'cuz we're
* smart. See arch/i386/kernel/apm.c.
*/
#ifdef CONFIG_X86_TSC
/*
* Firstly we have to do a CPU check for chips with
* a potentially buggy TSC. At this point we haven't run
* the ident/bugs checks so we must run this hook as it
* may turn off the TSC flag.
*
* NOTE: this doesnt yet handle SMP 486 machines where only
* some CPU's have a TSC. Thats never worked and nobody has
* moaned if you have the only one in the world - you fix it!
*/
dodgy_tsc();
if (cpu_has_tsc) {
unsigned long tsc_quotient = calibrate_tsc();
if (tsc_quotient) {
fast_gettimeoffset_quotient = tsc_quotient;
use_tsc = 1;
/*
* We could be more selective here I suspect
* and just enable this for the next intel chips ?
*/
x86_udelay_tsc = 1;
#ifndef do_gettimeoffset
do_gettimeoffset = do_fast_gettimeoffset;
#endif
/* report CPU clock rate in Hz.
* The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
* clock/second. Our precision is about 100 ppm.
*/
{ unsigned long eax=0, edx=1000;
__asm__("divl %2"
:"=a" (cpu_khz), "=d" (edx)
:"r" (tsc_quotient),
"0" (eax), "1" (edx));
printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
}
#ifdef CONFIG_CPU_FREQ
cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
#endif
}
}
#endif /* CONFIG_X86_TSC */
timer = select_timer();
time_init_hook();
}
#
# Makefile for x86 timers
#
obj-y := timer.o
obj-y += timer_tsc.o
obj-y += timer_pit.o
obj-$(CONFIG_X86_CYCLONE) += timer_cyclone.o
include $(TOPDIR)/Rules.make
#include <linux/kernel.h>
#include <asm/timer.h>
/* list of externed timers */
#ifndef CONFIG_X86_TSC
extern struct timer_opts timer_pit;
#endif
extern struct timer_opts timer_tsc;
/* list of timers, ordered by preference */
struct timer_opts* timers[] = {
&timer_tsc
#ifndef CONFIG_X86_TSC
,&timer_pit
#endif
};
#define NR_TIMERS (sizeof(timers)/sizeof(timers[0]))
/* iterates through the list of timers, returning the first
* one that initializes successfully.
*/
struct timer_opts* select_timer(void)
{
int i;
/* find most preferred working timer */
for(i=0; i < NR_TIMERS; i++)
if(timers[i]->init())
return timers[i];
panic("select_timer: Cannot find a suitable timer\n");
return 0;
}
/* Cyclone-timer:
* This code implements timer_ops for the cyclone counter found
* on IBM x440, x360, and other Summit based systems.
*
* Copyright (C) 2002 IBM, John Stultz (johnstul@us.ibm.com)
*/
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/timex.h>
#include <asm/timer.h>
#include <asm/io.h>
#include <asm/pgtable.h>
#include <asm/fixmap.h>
extern spinlock_t i8253_lock;
/* Number of usecs that the last interrupt was delayed */
static int delay_at_last_interrupt;
#define CYCLONE_CBAR_ADDR 0xFEB00CD0
#define CYCLONE_PMCC_OFFSET 0x51A0
#define CYCLONE_MPMC_OFFSET 0x51D0
#define CYCLONE_MPCS_OFFSET 0x51A8
#define CYCLONE_TIMER_FREQ 100000000
int use_cyclone = 0;
static u32* volatile cyclone_timer; /* Cyclone MPMC0 register */
static u32 last_cyclone_timer;
static void mark_offset_cyclone(void)
{
int count;
spin_lock(&i8253_lock);
/* quickly read the cyclone timer */
if(cyclone_timer)
last_cyclone_timer = cyclone_timer[0];
/* calculate delay_at_last_interrupt */
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8;
spin_unlock(&i8253_lock);
count = ((LATCH-1) - count) * TICK_SIZE;
delay_at_last_interrupt = (count + LATCH/2) / LATCH;
}
static unsigned long get_offset_cyclone(void)
{
u32 offset;
if(!cyclone_timer)
return delay_at_last_interrupt;
/* Read the cyclone timer */
offset = cyclone_timer[0];
/* .. relative to previous jiffy */
offset = offset - last_cyclone_timer;
/* convert cyclone ticks to microseconds */
/* XXX slow, can we speed this up? */
offset = offset/(CYCLONE_TIMER_FREQ/1000000);
/* our adjusted time offset in microseconds */
return delay_at_last_interrupt + offset;
}
static int init_cyclone(void)
{
u32* reg;
u32 base; /* saved cyclone base address */
u32 pageaddr; /* page that contains cyclone_timer register */
u32 offset; /* offset from pageaddr to cyclone_timer register */
int i;
/*make sure we're on a summit box*/
/*XXX need to use proper summit hooks! such as xapic -john*/
if(!use_cyclone) return 0;
printk(KERN_INFO "Summit chipset: Starting Cyclone Counter.\n");
/* find base address */
pageaddr = (CYCLONE_CBAR_ADDR)&PAGE_MASK;
offset = (CYCLONE_CBAR_ADDR)&(~PAGE_MASK);
set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr);
reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset);
if(!reg){
printk(KERN_ERR "Summit chipset: Could not find valid CBAR register.\n");
return 0;
}
base = *reg;
if(!base){
printk(KERN_ERR "Summit chipset: Could not find valid CBAR value.\n");
return 0;
}
/* setup PMCC */
pageaddr = (base + CYCLONE_PMCC_OFFSET)&PAGE_MASK;
offset = (base + CYCLONE_PMCC_OFFSET)&(~PAGE_MASK);
set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr);
reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset);
if(!reg){
printk(KERN_ERR "Summit chipset: Could not find valid PMCC register.\n");
return 0;
}
reg[0] = 0x00000001;
/* setup MPCS */
pageaddr = (base + CYCLONE_MPCS_OFFSET)&PAGE_MASK;
offset = (base + CYCLONE_MPCS_OFFSET)&(~PAGE_MASK);
set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr);
reg = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset);
if(!reg){
printk(KERN_ERR "Summit chipset: Could not find valid MPCS register.\n");
return 0;
}
reg[0] = 0x00000001;
/* map in cyclone_timer */
pageaddr = (base + CYCLONE_MPMC_OFFSET)&PAGE_MASK;
offset = (base + CYCLONE_MPMC_OFFSET)&(~PAGE_MASK);
set_fixmap_nocache(FIX_CYCLONE_TIMER, pageaddr);
cyclone_timer = (u32*)(fix_to_virt(FIX_CYCLONE_TIMER) + offset);
if(!cyclone_timer){
printk(KERN_ERR "Summit chipset: Could not find valid MPMC register.\n");
return 0;
}
/*quick test to make sure its ticking*/
for(i=0; i<3; i++){
u32 old = cyclone_timer[0];
int stall = 100;
while(stall--) barrier();
if(cyclone_timer[0] == old){
printk(KERN_ERR "Summit chipset: Counter not counting! DISABLED\n");
cyclone_timer = 0;
return 0;
}
}
/* Everything looks good! */
return 1;
}
#if 0 /* XXX future work */
static void delay_cyclone(unsigned long loops)
{
unsigned long bclock, now;
if(!cyclone_timer)
return;
bclock = cyclone_timer[0];
do {
rep_nop();
now = cyclone_timer[0];
} while ((now-bclock) < loops);
}
#endif
/************************************************************/
/* cyclone timer_opts struct */
struct timer_opts timer_cyclone = {
init: init_cyclone,
mark_offset: mark_offset_cyclone,
get_offset: get_offset_cyclone
};
/*
* This code largely moved from arch/i386/kernel/time.c.
* See comments there for proper credits.
*/
#include <linux/spinlock.h>
#include <linux/module.h>
#include <linux/device.h>
#include <asm/timer.h>
#include <asm/io.h>
extern spinlock_t i8259A_lock;
extern spinlock_t i8253_lock;
#include "do_timer.h"
static int init_pit(void)
{
return 1;
}
static void mark_offset_pit(void)
{
/* nothing needed */
}
/* This function must be called with interrupts disabled
* It was inspired by Steve McCanne's microtime-i386 for BSD. -- jrs
*
* However, the pc-audio speaker driver changes the divisor so that
* it gets interrupted rather more often - it loads 64 into the
* counter rather than 11932! This has an adverse impact on
* do_gettimeoffset() -- it stops working! What is also not
* good is that the interval that our timer function gets called
* is no longer 10.0002 ms, but 9.9767 ms. To get around this
* would require using a different timing source. Maybe someone
* could use the RTC - I know that this can interrupt at frequencies
* ranging from 8192Hz to 2Hz. If I had the energy, I'd somehow fix
* it so that at startup, the timer code in sched.c would select
* using either the RTC or the 8253 timer. The decision would be
* based on whether there was any other device around that needed
* to trample on the 8253. I'd set up the RTC to interrupt at 1024 Hz,
* and then do some jiggery to have a version of do_timer that
* advanced the clock by 1/1024 s. Every time that reached over 1/100
* of a second, then do all the old code. If the time was kept correct
* then do_gettimeoffset could just return 0 - there is no low order
* divider that can be accessed.
*
* Ideally, you would be able to use the RTC for the speaker driver,
* but it appears that the speaker driver really needs interrupt more
* often than every 120 us or so.
*
* Anyway, this needs more thought.... pjsg (1993-08-28)
*
* If you are really that interested, you should be reading
* comp.protocols.time.ntp!
*/
static unsigned long get_offset_pit(void)
{
int count;
static int count_p = LATCH; /* for the first call after boot */
static unsigned long jiffies_p = 0;
/*
* cache volatile jiffies temporarily; we have IRQs turned off.
*/
unsigned long jiffies_t;
/* gets recalled with irq locally disabled */
spin_lock(&i8253_lock);
/* timer count may underflow right here */
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
/*
* We do this guaranteed double memory access instead of a _p
* postfix in the previous port access. Wheee, hackady hack
*/
jiffies_t = jiffies;
count |= inb_p(0x40) << 8;
/* VIA686a test code... reset the latch if count > max + 1 */
if (count > LATCH) {
outb_p(0x34, 0x43);
outb_p(LATCH & 0xff, 0x40);
outb(LATCH >> 8, 0x40);
count = LATCH - 1;
}
spin_unlock(&i8253_lock);
/*
* avoiding timer inconsistencies (they are rare, but they happen)...
* there are two kinds of problems that must be avoided here:
* 1. the timer counter underflows
* 2. hardware problem with the timer, not giving us continuous time,
* the counter does small "jumps" upwards on some Pentium systems,
* (see c't 95/10 page 335 for Neptun bug.)
*/
if( jiffies_t == jiffies_p ) {
if( count > count_p ) {
/* the nutcase */
count = do_timer_overflow(count);
}
} else
jiffies_p = jiffies_t;
count_p = count;
count = ((LATCH-1) - count) * TICK_SIZE;
count = (count + LATCH/2) / LATCH;
return count;
}
/* tsc timer_opts struct */
struct timer_opts timer_pit = {
init: init_pit,
mark_offset: mark_offset_pit,
get_offset: get_offset_pit
};
/*
* This code largely moved from arch/i386/kernel/time.c.
* See comments there for proper credits.
*/
#include <linux/spinlock.h>
#include <linux/init.h>
#include <linux/timex.h>
#include <asm/timer.h>
#include <asm/io.h>
extern int x86_udelay_tsc;
extern spinlock_t i8253_lock;
static int use_tsc;
/* Number of usecs that the last interrupt was delayed */
static int delay_at_last_interrupt;
static unsigned long last_tsc_low; /* lsb 32 bits of Time Stamp Counter */
/* Cached *multiplier* to convert TSC counts to microseconds.
* (see the equation below).
* Equal to 2^32 * (1 / (clocks per usec) ).
* Initialized in time_init.
*/
unsigned long fast_gettimeoffset_quotient;
static unsigned long get_offset_tsc(void)
{
register unsigned long eax, edx;
/* Read the Time Stamp Counter */
rdtsc(eax,edx);
/* .. relative to previous jiffy (32 bits is enough) */
eax -= last_tsc_low; /* tsc_low delta */
/*
* Time offset = (tsc_low delta) * fast_gettimeoffset_quotient
* = (tsc_low delta) * (usecs_per_clock)
* = (tsc_low delta) * (usecs_per_jiffy / clocks_per_jiffy)
*
* Using a mull instead of a divl saves up to 31 clock cycles
* in the critical path.
*/
__asm__("mull %2"
:"=a" (eax), "=d" (edx)
:"rm" (fast_gettimeoffset_quotient),
"0" (eax));
/* our adjusted time offset in microseconds */
return delay_at_last_interrupt + edx;
}
static void mark_offset_tsc(void)
{
int count;
/*
* It is important that these two operations happen almost at
* the same time. We do the RDTSC stuff first, since it's
* faster. To avoid any inconsistencies, we need interrupts
* disabled locally.
*/
/*
* Interrupts are just disabled locally since the timer irq
* has the SA_INTERRUPT flag set. -arca
*/
/* read Pentium cycle counter */
rdtscl(last_tsc_low);
spin_lock(&i8253_lock);
outb_p(0x00, 0x43); /* latch the count ASAP */
count = inb_p(0x40); /* read the latched count */
count |= inb(0x40) << 8;
spin_unlock(&i8253_lock);
count = ((LATCH-1) - count) * TICK_SIZE;
delay_at_last_interrupt = (count + LATCH/2) / LATCH;
}
/* ------ Calibrate the TSC -------
* Return 2^32 * (1 / (TSC clocks per usec)) for do_fast_gettimeoffset().
* Too much 64-bit arithmetic here to do this cleanly in C, and for
* accuracy's sake we want to keep the overhead on the CTC speaker (channel 2)
* output busy loop as low as possible. We avoid reading the CTC registers
* directly because of the awkward 8-bit access mechanism of the 82C54
* device.
*/
#define CALIBRATE_LATCH (5 * LATCH)
#define CALIBRATE_TIME (5 * 1000020/HZ)
static unsigned long __init calibrate_tsc(void)
{
/* Set the Gate high, disable speaker */
outb((inb(0x61) & ~0x02) | 0x01, 0x61);
/*
* Now let's take care of CTC channel 2
*
* Set the Gate high, program CTC channel 2 for mode 0,
* (interrupt on terminal count mode), binary count,
* load 5 * LATCH count, (LSB and MSB) to begin countdown.
*/
outb(0xb0, 0x43); /* binary, mode 0, LSB/MSB, Ch 2 */
outb(CALIBRATE_LATCH & 0xff, 0x42); /* LSB of count */
outb(CALIBRATE_LATCH >> 8, 0x42); /* MSB of count */
{
unsigned long startlow, starthigh;
unsigned long endlow, endhigh;
unsigned long count;
rdtsc(startlow,starthigh);
count = 0;
do {
count++;
} while ((inb(0x61) & 0x20) == 0);
rdtsc(endlow,endhigh);
last_tsc_low = endlow;
/* Error: ECTCNEVERSET */
if (count <= 1)
goto bad_ctc;
/* 64-bit subtract - gcc just messes up with long longs */
__asm__("subl %2,%0\n\t"
"sbbl %3,%1"
:"=a" (endlow), "=d" (endhigh)
:"g" (startlow), "g" (starthigh),
"0" (endlow), "1" (endhigh));
/* Error: ECPUTOOFAST */
if (endhigh)
goto bad_ctc;
/* Error: ECPUTOOSLOW */
if (endlow <= CALIBRATE_TIME)
goto bad_ctc;
__asm__("divl %2"
:"=a" (endlow), "=d" (endhigh)
:"r" (endlow), "0" (0), "1" (CALIBRATE_TIME));
return endlow;
}
/*
* The CTC wasn't reliable: we got a hit on the very first read,
* or the CPU was so fast/slow that the quotient wouldn't fit in
* 32 bits..
*/
bad_ctc:
return 0;
}
#ifdef CONFIG_CPU_FREQ
static int
time_cpufreq_notifier(struct notifier_block *nb, unsigned long val,
void *data)
{
struct cpufreq_freqs *freq = data;
unsigned int i;
if (!cpu_has_tsc)
return 0;
switch (val) {
case CPUFREQ_PRECHANGE:
if ((freq->old < freq->new) &&
((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == 0))) {
cpu_khz = cpufreq_scale(cpu_khz, freq->old, freq->new);
fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_quotient, freq->new, freq->old);
}
for (i=0; i<NR_CPUS; i++)
if ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == i))
cpu_data[i].loops_per_jiffy = cpufreq_scale(cpu_data[i].loops_per_jiffy, freq->old, freq->new);
break;
case CPUFREQ_POSTCHANGE:
if ((freq->new < freq->old) &&
((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == 0))) {
cpu_khz = cpufreq_scale(cpu_khz, freq->old, freq->new);
fast_gettimeoffset_quotient = cpufreq_scale(fast_gettimeoffset_quotient, freq->new, freq->old);
}
for (i=0; i<NR_CPUS; i++)
if ((freq->cpu == CPUFREQ_ALL_CPUS) || (freq->cpu == i))
cpu_data[i].loops_per_jiffy = cpufreq_scale(cpu_data[i].loops_per_jiffy, freq->old, freq->new);
break;
}
return 0;
}
static struct notifier_block time_cpufreq_notifier_block = {
notifier_call: time_cpufreq_notifier
};
#endif
static int init_tsc(void)
{
/*
* If we have APM enabled or the CPU clock speed is variable
* (CPU stops clock on HLT or slows clock to save power)
* then the TSC timestamps may diverge by up to 1 jiffy from
* 'real time' but nothing will break.
* The most frequent case is that the CPU is "woken" from a halt
* state by the timer interrupt itself, so we get 0 error. In the
* rare cases where a driver would "wake" the CPU and request a
* timestamp, the maximum error is < 1 jiffy. But timestamps are
* still perfectly ordered.
* Note that the TSC counter will be reset if APM suspends
* to disk; this won't break the kernel, though, 'cuz we're
* smart. See arch/i386/kernel/apm.c.
*/
/*
* Firstly we have to do a CPU check for chips with
* a potentially buggy TSC. At this point we haven't run
* the ident/bugs checks so we must run this hook as it
* may turn off the TSC flag.
*
* NOTE: this doesnt yet handle SMP 486 machines where only
* some CPU's have a TSC. Thats never worked and nobody has
* moaned if you have the only one in the world - you fix it!
*/
dodgy_tsc();
if (cpu_has_tsc) {
unsigned long tsc_quotient = calibrate_tsc();
if (tsc_quotient) {
fast_gettimeoffset_quotient = tsc_quotient;
use_tsc = 1;
/*
* We could be more selective here I suspect
* and just enable this for the next intel chips ?
*/
x86_udelay_tsc = 1;
/* report CPU clock rate in Hz.
* The formula is (10^6 * 2^32) / (2^32 * 1 / (clocks/us)) =
* clock/second. Our precision is about 100 ppm.
*/
{ unsigned long eax=0, edx=1000;
__asm__("divl %2"
:"=a" (cpu_khz), "=d" (edx)
:"r" (tsc_quotient),
"0" (eax), "1" (edx));
printk("Detected %lu.%03lu MHz processor.\n", cpu_khz / 1000, cpu_khz % 1000);
}
#ifdef CONFIG_CPU_FREQ
cpufreq_register_notifier(&time_cpufreq_notifier_block, CPUFREQ_TRANSITION_NOTIFIER);
#endif
return 1;
}
}
return 0;
}
/************************************************************/
/* tsc timer_opts struct */
struct timer_opts timer_tsc = {
init: init_tsc,
mark_offset: mark_offset_tsc,
get_offset: get_offset_tsc
};
......@@ -30,6 +30,10 @@ static struct file_operations raw_ctl_fops;
/*
* Open/close code for raw IO.
*
* We just rewrite the i_mapping for the /dev/raw/rawN file descriptor to
* point at the blockdev's address_space and set the file handle to use
* O_DIRECT.
*
* Set the device's soft blocksize to the minimum possible. This gives the
* finest possible alignment and has no adverse impact on performance.
*/
......@@ -56,7 +60,12 @@ static int raw_open(struct inode *inode, struct file *filp)
err = blkdev_get(bdev, filp->f_mode, 0, BDEV_RAW);
if (!err) {
err = set_blocksize(bdev, bdev_hardsect_size(bdev));
if (err == 0) {
raw_devices[minor].inuse++;
filp->f_dentry->d_inode->i_mapping =
bdev->bd_inode->i_mapping;
filp->f_flags |= O_DIRECT;
}
}
}
up(&raw_mutex);
......@@ -200,72 +209,22 @@ raw_ctl_ioctl(struct inode *inode, struct file *filp,
return err;
}
static ssize_t
rw_raw_dev(int rw, struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *offp)
static ssize_t raw_file_write(struct file *file, const char *buf,
size_t count, loff_t *ppos)
{
const int minor = minor(filp->f_dentry->d_inode->i_rdev);
struct block_device *bdev = raw_devices[minor].binding;
struct inode *inode = bdev->bd_inode;
size_t count = iov_length(iov, nr_segs);
ssize_t ret = 0;
if (count == 0)
goto out;
if ((ssize_t)count < 0)
return -EINVAL;
if (*offp >= inode->i_size)
return -ENXIO;
struct iovec local_iov = { .iov_base = (void *)buf, .iov_len = count };
if (count + *offp > inode->i_size) {
count = inode->i_size - *offp;
nr_segs = iov_shorten((struct iovec *)iov, nr_segs, count);
}
ret = generic_file_direct_IO(rw, filp, iov, *offp, nr_segs);
if (ret > 0)
*offp += ret;
out:
return ret;
}
static ssize_t
raw_read(struct file *filp, char *buf, size_t size, loff_t *offp)
{
struct iovec local_iov = { .iov_base = buf, .iov_len = size};
return rw_raw_dev(READ, filp, &local_iov, 1, offp);
}
static ssize_t
raw_write(struct file *filp, const char *buf, size_t size, loff_t *offp)
{
struct iovec local_iov = { .iov_base = (char *)buf, .iov_len = size};
return rw_raw_dev(WRITE, filp, &local_iov, 1, offp);
}
static ssize_t
raw_readv(struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *offp)
{
return rw_raw_dev(READ, filp, iov, nr_segs, offp);
}
static ssize_t
raw_writev(struct file *filp, const struct iovec *iov, unsigned long nr_segs, loff_t *offp)
{
return rw_raw_dev(WRITE, filp, iov, nr_segs, offp);
return generic_file_write_nolock(file, &local_iov, 1, ppos);
}
static struct file_operations raw_fops = {
.read = raw_read,
.write = raw_write,
.read = generic_file_read,
.write = raw_file_write,
.open = raw_open,
.release= raw_release,
.ioctl = raw_ioctl,
.readv = raw_readv,
.writev = raw_writev,
.readv = generic_file_readv,
.writev = generic_file_writev,
.owner = THIS_MODULE,
};
......
......@@ -1434,9 +1434,10 @@ int journal_stop(handle_t *handle)
* by 30x or more...
*/
if (handle->h_sync) {
set_current_state(TASK_RUNNING);
do {
old_handle_count = transaction->t_handle_count;
yield();
schedule();
} while (old_handle_count != transaction->t_handle_count);
}
......
......@@ -316,7 +316,7 @@ static ssize_t do_readv_writev(int type, struct file *file,
size_t tot_len;
struct iovec iovstack[UIO_FASTIOV];
struct iovec *iov=iovstack;
ssize_t ret = -EINVAL;
ssize_t ret;
int seg;
io_fn_t fn;
iov_fn_t fnv;
......@@ -325,8 +325,9 @@ static ssize_t do_readv_writev(int type, struct file *file,
/*
* SuS says "The readv() function *may* fail if the iovcnt argument
* was less than or equal to 0, or greater than {IOV_MAX}. Linux has
* traditionally returned -EINVAL for zero segments, so...
* traditionally returned zero for zero segments, so...
*/
ret = 0;
if (nr_segs == 0)
goto out;
......@@ -334,6 +335,7 @@ static ssize_t do_readv_writev(int type, struct file *file,
* First get the "struct iovec" from user memory and
* verify all the pointers
*/
ret = -EINVAL;
if ((nr_segs > UIO_MAXIOV) || (nr_segs <= 0))
goto out;
if (!file->f_op)
......
......@@ -45,7 +45,7 @@
#define PAL_wrperfmon 57
#define PAL_rdusp 58
#define PAL_whami 60
#define PAL_rtsys 61
#define PAL_retsys 61
#define PAL_rti 63
#endif /* __ALPHA_PAL_H */
......@@ -343,7 +343,7 @@
#define __NR_alloc_hugepages 403
#define __NR_free_hugepages 404
#define __NR_exit_group 405
#define NR_SYSCALLS 406
#if defined(__GNUC__)
......@@ -598,7 +598,7 @@ static inline pid_t waitpid(int pid, int * wait_stat, int flags)
return sys_wait4(pid, wait_stat, flags, NULL);
}
#endif
#endif /* __KERNEL_SYSCALLS__ */
/*
* "Conditional" syscalls
......
......@@ -91,7 +91,7 @@ typedef struct siginfo {
#define __SI_FAULT (3 << 16)
#define __SI_CHLD (4 << 16)
#define __SI_RT (5 << 16)
#define __SI_CODE(T,N) ((T) << 16 | ((N) & 0xffff))
#define __SI_CODE(T,N) ((T) | ((N) & 0xffff))
#else
#define __SI_KILL 0
#define __SI_TIMER 0
......
......@@ -65,6 +65,9 @@ enum fixed_addresses {
#ifdef CONFIG_X86_F00F_BUG
FIX_F00F_IDT, /* Virtual mapping for IDT */
#endif
#ifdef CONFIG_X86_CYCLONE
FIX_CYCLONE_TIMER, /*cyclone timer register*/
#endif
#ifdef CONFIG_HIGHMEM
FIX_KMAP_BEGIN, /* reserved pte's for temporary kernel mappings */
FIX_KMAP_END = FIX_KMAP_BEGIN+(KM_TYPE_NR*NR_CPUS)-1,
......
......@@ -259,12 +259,21 @@ static inline pte_t pte_modify(pte_t pte, pgprot_t newprot)
((address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1))
#define pte_offset_kernel(dir, address) \
((pte_t *) pmd_page_kernel(*(dir)) + __pte_offset(address))
#if defined(CONFIG_HIGHPTE)
#define pte_offset_map(dir, address) \
((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE0) + __pte_offset(address))
#define pte_offset_map_nested(dir, address) \
((pte_t *)kmap_atomic(pmd_page(*(dir)),KM_PTE1) + __pte_offset(address))
#define pte_unmap(pte) kunmap_atomic(pte, KM_PTE0)
#define pte_unmap_nested(pte) kunmap_atomic(pte, KM_PTE1)
#else
#define pte_offset_map(dir, address) \
((pte_t *)page_address(pmd_page(*(dir))) + __pte_offset(address))
#define pte_offset_map_nested(dir, address) pte_offset_map(dir, address)
#define pte_unmap(pte) do { } while (0)
#define pte_unmap_nested(pte) do { } while (0)
#endif
#if defined(CONFIG_HIGHPTE) && defined(CONFIG_HIGHMEM4G)
typedef u32 pte_addr_t;
......
#ifndef _ASMi386_TIMER_H
#define _ASMi386_TIMER_H
struct timer_opts{
/* probes and initializes timer. returns 1 on sucess, 0 on failure */
int (*init)(void);
/* called by the timer interrupt */
void (*mark_offset)(void);
/* called by gettimeofday. returns # ms since the last timer interrupt */
unsigned long (*get_offset)(void);
};
#define TICK_SIZE (tick_nsec / 1000)
struct timer_opts* select_timer(void);
#endif
......@@ -21,8 +21,6 @@
struct radix_tree_node;
#define RADIX_TREE_SLOT_RESERVED ((void *)~0UL)
struct radix_tree_root {
unsigned int height;
int gfp_mask;
......@@ -41,7 +39,6 @@ do { \
(root)->rnode = NULL; \
} while (0)
extern int radix_tree_reserve(struct radix_tree_root *, unsigned long, void ***);
extern int radix_tree_insert(struct radix_tree_root *, unsigned long, void *);
extern void *radix_tree_lookup(struct radix_tree_root *, unsigned long);
extern int radix_tree_delete(struct radix_tree_root *, unsigned long);
......
......@@ -266,29 +266,31 @@ int del_timer(timer_t *timer)
int del_timer_sync(timer_t *timer)
{
tvec_base_t *base = tvec_bases;
int i, ret;
int i, ret = 0;
ret = del_timer(timer);
del_again:
ret += del_timer(timer);
for (i = 0; i < NR_CPUS; i++) {
for (i = 0; i < NR_CPUS; i++, base++) {
if (!cpu_online(i))
continue;
if (base->running_timer == timer) {
while (base->running_timer == timer) {
cpu_relax();
preempt_disable();
preempt_enable();
preempt_check_resched();
}
break;
}
base++;
}
if (timer_pending(timer))
goto del_again;
return ret;
}
#endif
static void cascade(tvec_base_t *base, tvec_t *tv)
static int cascade(tvec_base_t *base, tvec_t *tv)
{
/* cascade all the timers from tv up one level */
struct list_head *head, *curr, *next;
......@@ -310,7 +312,8 @@ static void cascade(tvec_base_t *base, tvec_t *tv)
curr = next;
}
INIT_LIST_HEAD(head);
tv->index = (tv->index + 1) & TVN_MASK;
return tv->index = (tv->index + 1) & TVN_MASK;
}
/***
......@@ -322,26 +325,18 @@ static void cascade(tvec_base_t *base, tvec_t *tv)
*/
static inline void __run_timers(tvec_base_t *base)
{
unsigned long flags;
spin_lock_irqsave(&base->lock, flags);
spin_lock_irq(&base->lock);
while ((long)(jiffies - base->timer_jiffies) >= 0) {
struct list_head *head, *curr;
/*
* Cascade timers:
*/
if (!base->tv1.index) {
cascade(base, &base->tv2);
if (base->tv2.index == 1) {
cascade(base, &base->tv3);
if (base->tv3.index == 1) {
cascade(base, &base->tv4);
if (base->tv4.index == 1)
if (!base->tv1.index &&
(cascade(base, &base->tv2) == 1) &&
(cascade(base, &base->tv3) == 1) &&
cascade(base, &base->tv4) == 1)
cascade(base, &base->tv5);
}
}
}
repeat:
head = base->tv1.vec + base->tv1.index;
curr = head->next;
......@@ -360,6 +355,9 @@ static inline void __run_timers(tvec_base_t *base)
base->running_timer = timer;
#endif
spin_unlock_irq(&base->lock);
if (!fn)
printk("Bad: timer %p has NULL fn. (data: %08lx)\n", timer, data);
else
fn(data);
spin_lock_irq(&base->lock);
goto repeat;
......@@ -370,7 +368,7 @@ static inline void __run_timers(tvec_base_t *base)
#if CONFIG_SMP
base->running_timer = NULL;
#endif
spin_unlock_irqrestore(&base->lock, flags);
spin_unlock_irq(&base->lock);
}
/******************************************************************/
......
......@@ -77,7 +77,6 @@ static inline unsigned long radix_tree_maxindex(unsigned int height)
return index;
}
/*
* Extend a radix tree so it can store key @index.
*/
......@@ -109,16 +108,15 @@ static int radix_tree_extend(struct radix_tree_root *root, unsigned long index)
return 0;
}
/**
* radix_tree_reserve - reserve space in a radix tree
* radix_tree_insert - insert into a radix tree
* @root: radix tree root
* @index: index key
* @pslot: pointer to reserved slot
* @item: item to insert
*
* Reserve a slot in a radix tree for the key @index.
* Insert an item into the radix tree at position @index.
*/
int radix_tree_reserve(struct radix_tree_root *root, unsigned long index, void ***pslot)
int radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item)
{
struct radix_tree_node *node = NULL, *tmp, **slot;
unsigned int height, shift;
......@@ -158,36 +156,11 @@ int radix_tree_reserve(struct radix_tree_root *root, unsigned long index, void *
if (node)
node->count++;
*pslot = (void **)slot;
**pslot = RADIX_TREE_SLOT_RESERVED;
return 0;
}
EXPORT_SYMBOL(radix_tree_reserve);
/**
* radix_tree_insert - insert into a radix tree
* @root: radix tree root
* @index: index key
* @item: item to insert
*
* Insert an item into the radix tree at position @index.
*/
int radix_tree_insert(struct radix_tree_root *root, unsigned long index, void *item)
{
void **slot;
int error;
error = radix_tree_reserve(root, index, &slot);
if (!error)
*slot = item;
return error;
return 0;
}
EXPORT_SYMBOL(radix_tree_insert);
/**
* radix_tree_lookup - perform lookup operation on a radix tree
* @root: radix tree root
......@@ -267,8 +240,8 @@ __lookup(struct radix_tree_root *root, void **results, unsigned long index,
out:
*next_index = index;
return nr_found;
}
/**
* radix_tree_gang_lookup - perform multiple lookup on a radix tree
* @root: radix tree root
......@@ -371,7 +344,6 @@ int radix_tree_delete(struct radix_tree_root *root, unsigned long index)
return 0;
}
EXPORT_SYMBOL(radix_tree_delete);
static void radix_tree_node_ctor(void *node, kmem_cache_t *cachep, unsigned long flags)
......
......@@ -194,7 +194,8 @@ static inline unsigned long move_vma(struct vm_area_struct * vma,
prev->vm_end = next->vm_end;
__vma_unlink(mm, next, prev);
spin_unlock(&mm->page_table_lock);
if (vma == next)
vma = prev;
mm->map_count--;
kmem_cache_free(vm_area_cachep, next);
}
......
......@@ -199,16 +199,14 @@ void delete_from_swap_cache(struct page *page)
int move_to_swap_cache(struct page *page, swp_entry_t entry)
{
struct address_space *mapping = page->mapping;
void **pslot;
int err;
write_lock(&swapper_space.page_lock);
write_lock(&mapping->page_lock);
err = radix_tree_reserve(&swapper_space.page_tree, entry.val, &pslot);
err = radix_tree_insert(&swapper_space.page_tree, entry.val, page);
if (!err) {
__remove_from_page_cache(page);
*pslot = page;
___add_to_page_cache(page, &swapper_space, entry.val);
}
......@@ -231,7 +229,6 @@ int move_from_swap_cache(struct page *page, unsigned long index,
struct address_space *mapping)
{
swp_entry_t entry;
void **pslot;
int err;
BUG_ON(!PageLocked(page));
......@@ -243,10 +240,9 @@ int move_from_swap_cache(struct page *page, unsigned long index,
write_lock(&swapper_space.page_lock);
write_lock(&mapping->page_lock);
err = radix_tree_reserve(&mapping->page_tree, index, &pslot);
err = radix_tree_insert(&mapping->page_tree, index, page);
if (!err) {
__delete_from_swap_cache(page);
*pslot = page;
___add_to_page_cache(page, mapping, index);
}
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment