linux 2.6.16.38 w/ vs2.0.3-rc1
[linux-2.6.git] / arch / x86_64 / ia32 / sys_ia32.c
index 0a8fb7d..f3d4615 100644 (file)
@@ -30,6 +30,7 @@
 #include <linux/resource.h>
 #include <linux/times.h>
 #include <linux/utsname.h>
+#include <linux/timex.h>
 #include <linux/smp.h>
 #include <linux/smp_lock.h>
 #include <linux/sem.h>
@@ -430,12 +431,24 @@ put_tv32(struct compat_timeval __user *o, struct timeval *i)
        return err; 
 }
 
-extern unsigned int alarm_setitimer(unsigned int seconds);
+extern int do_setitimer(int which, struct itimerval *, struct itimerval *);
 
 asmlinkage long
 sys32_alarm(unsigned int seconds)
 {
-       return alarm_setitimer(seconds);
+       struct itimerval it_new, it_old;
+       unsigned int oldalarm;
+
+       it_new.it_interval.tv_sec = it_new.it_interval.tv_usec = 0;
+       it_new.it_value.tv_sec = seconds;
+       it_new.it_value.tv_usec = 0;
+       do_setitimer(ITIMER_REAL, &it_new, &it_old);
+       oldalarm = it_old.it_value.tv_sec;
+       /* ehhh.. We can't return 0 if we have an alarm pending.. */
+       /* And we'd better return too much than too little anyway */
+       if (it_old.it_value.tv_usec)
+               oldalarm++;
+       return oldalarm;
 }
 
 /* Translations due to time_t size differences.  Which affects all
@@ -510,9 +523,17 @@ sys32_waitpid(compat_pid_t pid, unsigned int *stat_addr, int options)
 }
 
 int sys32_ni_syscall(int call)
-{
-       return -ENOSYS;
-}
+{ 
+       struct task_struct *me = current;
+       static char lastcomm[sizeof(me->comm)];
+
+       if (strncmp(lastcomm, me->comm, sizeof(lastcomm))) {
+               printk(KERN_INFO "IA32 syscall %d from %s not implemented\n",
+                      call, me->comm);
+               strncpy(lastcomm, me->comm, sizeof(lastcomm));
+       } 
+       return -ENOSYS;        
+} 
 
 /* 32-bit timeval and related flotsam.  */
 
@@ -759,6 +780,82 @@ sys32_sendfile(int out_fd, int in_fd, compat_off_t __user *offset, s32 count)
        return ret;
 }
 
+/* Handle adjtimex compatibility. */
+
+struct timex32 {
+       u32 modes;
+       s32 offset, freq, maxerror, esterror;
+       s32 status, constant, precision, tolerance;
+       struct compat_timeval time;
+       s32 tick;
+       s32 ppsfreq, jitter, shift, stabil;
+       s32 jitcnt, calcnt, errcnt, stbcnt;
+       s32  :32; s32  :32; s32  :32; s32  :32;
+       s32  :32; s32  :32; s32  :32; s32  :32;
+       s32  :32; s32  :32; s32  :32; s32  :32;
+};
+
+extern int do_adjtimex(struct timex *);
+
+asmlinkage long
+sys32_adjtimex(struct timex32 __user *utp)
+{
+       struct timex txc;
+       int ret;
+
+       memset(&txc, 0, sizeof(struct timex));
+
+       if (!access_ok(VERIFY_READ, utp, sizeof(struct timex32)) ||
+          __get_user(txc.modes, &utp->modes) ||
+          __get_user(txc.offset, &utp->offset) ||
+          __get_user(txc.freq, &utp->freq) ||
+          __get_user(txc.maxerror, &utp->maxerror) ||
+          __get_user(txc.esterror, &utp->esterror) ||
+          __get_user(txc.status, &utp->status) ||
+          __get_user(txc.constant, &utp->constant) ||
+          __get_user(txc.precision, &utp->precision) ||
+          __get_user(txc.tolerance, &utp->tolerance) ||
+          __get_user(txc.time.tv_sec, &utp->time.tv_sec) ||
+          __get_user(txc.time.tv_usec, &utp->time.tv_usec) ||
+          __get_user(txc.tick, &utp->tick) ||
+          __get_user(txc.ppsfreq, &utp->ppsfreq) ||
+          __get_user(txc.jitter, &utp->jitter) ||
+          __get_user(txc.shift, &utp->shift) ||
+          __get_user(txc.stabil, &utp->stabil) ||
+          __get_user(txc.jitcnt, &utp->jitcnt) ||
+          __get_user(txc.calcnt, &utp->calcnt) ||
+          __get_user(txc.errcnt, &utp->errcnt) ||
+          __get_user(txc.stbcnt, &utp->stbcnt))
+               return -EFAULT;
+
+       ret = do_adjtimex(&txc);
+
+       if (!access_ok(VERIFY_WRITE, utp, sizeof(struct timex32)) ||
+          __put_user(txc.modes, &utp->modes) ||
+          __put_user(txc.offset, &utp->offset) ||
+          __put_user(txc.freq, &utp->freq) ||
+          __put_user(txc.maxerror, &utp->maxerror) ||
+          __put_user(txc.esterror, &utp->esterror) ||
+          __put_user(txc.status, &utp->status) ||
+          __put_user(txc.constant, &utp->constant) ||
+          __put_user(txc.precision, &utp->precision) ||
+          __put_user(txc.tolerance, &utp->tolerance) ||
+          __put_user(txc.time.tv_sec, &utp->time.tv_sec) ||
+          __put_user(txc.time.tv_usec, &utp->time.tv_usec) ||
+          __put_user(txc.tick, &utp->tick) ||
+          __put_user(txc.ppsfreq, &utp->ppsfreq) ||
+          __put_user(txc.jitter, &utp->jitter) ||
+          __put_user(txc.shift, &utp->shift) ||
+          __put_user(txc.stabil, &utp->stabil) ||
+          __put_user(txc.jitcnt, &utp->jitcnt) ||
+          __put_user(txc.calcnt, &utp->calcnt) ||
+          __put_user(txc.errcnt, &utp->errcnt) ||
+          __put_user(txc.stbcnt, &utp->stbcnt))
+               ret = -EFAULT;
+
+       return ret;
+}
+
 asmlinkage long sys32_mmap2(unsigned long addr, unsigned long len,
        unsigned long prot, unsigned long flags,
        unsigned long fd, unsigned long pgoff)
@@ -933,3 +1030,4 @@ static int __init ia32_init (void)
 __initcall(ia32_init);
 
 extern unsigned long ia32_sys_call_table[];
+EXPORT_SYMBOL(ia32_sys_call_table);