diff --git a/arch/parisc/hpux/fs.c b/arch/parisc/hpux/fs.c index 2d58b92b57e368094635d1d4431bdcb782ed6d40..4204cd1f3cf9c2f3fce7769b51e606278055635e 100644 --- a/arch/parisc/hpux/fs.c +++ b/arch/parisc/hpux/fs.c @@ -73,7 +73,7 @@ struct getdents_callback { #define ROUND_UP(x) (((x)+sizeof(long)-1) & ~(sizeof(long)-1)) static int filldir(void * __buf, const char * name, int namlen, loff_t offset, - ino_t ino, unsigned d_type) + u64 ino, unsigned d_type) { struct hpux_dirent * dirent; struct getdents_callback * buf = (struct getdents_callback *) __buf; diff --git a/arch/parisc/kernel/drivers.c b/arch/parisc/kernel/drivers.c index 3d569a485a1a6540735f282eb87879705fd4574c..2b257e4f17df28da51a9495d4beeaf9efcf72885 100644 --- a/arch/parisc/kernel/drivers.c +++ b/arch/parisc/kernel/drivers.c @@ -424,7 +424,10 @@ struct parisc_device * create_tree_node(char id, struct device *parent) /* make the generic dma mask a pointer to the parisc one */ dev->dev.dma_mask = &dev->dma_mask; dev->dev.coherent_dma_mask = dev->dma_mask; - device_register(&dev->dev); + if (!device_register(&dev->dev)) { + kfree(dev); + return NULL; + } return dev; } @@ -850,8 +853,10 @@ static void print_parisc_device(struct parisc_device *dev) */ void init_parisc_bus(void) { - bus_register(&parisc_bus_type); - device_register(&root); + if (!bus_register(&parisc_bus_type)) + panic("Could not register PA-RISC bus type\n"); + if (!device_register(&root)) + panic("Could not register PA-RISC root device\n"); get_device(&root); } diff --git a/arch/parisc/kernel/pci.c b/arch/parisc/kernel/pci.c index d3b8fc52dfc1e130a2c9a6e621116c62ed8a74f7..199887a61c765dea150132dc9d870b9c14a0e9f6 100644 --- a/arch/parisc/kernel/pci.c +++ b/arch/parisc/kernel/pci.c @@ -290,7 +290,7 @@ EXPORT_SYMBOL(pcibios_bus_to_resource); void pcibios_align_resource(void *data, struct resource *res, resource_size_t size, resource_size_t alignment) { - unsigned long mask, align; + resource_size_t mask, align; DBG_RES("pcibios_align_resource(%s, (%p) [%lx,%lx]/%x, 0x%lx, 0x%lx)\n", pci_name(((struct pci_dev *) data)), diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c index 1db5588ceacf7474ebba8d947b6b7c31da09a906..512642d8f707ce7208a99b5c0e2136c02c065c5e 100644 --- a/arch/parisc/kernel/sys_parisc.c +++ b/arch/parisc/kernel/sys_parisc.c @@ -266,30 +266,17 @@ long parisc_personality(unsigned long personality) return err; } -static inline int override_machine(char __user *mach) { -#ifdef CONFIG_COMPAT - if (personality(current->personality) == PER_LINUX32) { - if (__put_user(0, mach + 6) || - __put_user(0, mach + 7)) - return -EFAULT; - } - - return 0; -#else /*!CONFIG_COMPAT*/ - return 0; -#endif /*CONFIG_COMPAT*/ -} - -long parisc_newuname(struct new_utsname __user *utsname) +long parisc_newuname(struct new_utsname __user *name) { - int err = 0; + int err = sys_newuname(name); - down_read(&uts_sem); - if (copy_to_user(utsname, &system_utsname, sizeof(*utsname))) - err = -EFAULT; - up_read(&uts_sem); - - err = override_machine(utsname->machine); +#ifdef CONFIG_COMPAT + if (!err && personality(current->personality) == PER_LINUX32) { + if (__put_user(0, name->machine + 6) || + __put_user(0, name->machine + 7)) + err = -EFAULT; + } +#endif - return (long)err; + return err; } diff --git a/arch/parisc/kernel/sys_parisc32.c b/arch/parisc/kernel/sys_parisc32.c index e3b30bc36453a0d05b830c3d9967de27112ab0c3..29be4377aca6c0fb1e2cebd00d4fba4556efdc01 100644 --- a/arch/parisc/kernel/sys_parisc32.c +++ b/arch/parisc/kernel/sys_parisc32.c @@ -111,13 +111,14 @@ struct __sysctl_args32 { asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) { +#ifndef CONFIG_SYSCTL_SYSCALL + return -ENOSYS; +#else struct __sysctl_args32 tmp; int error; unsigned int oldlen32; - size_t oldlen, *oldlenp = NULL; + size_t oldlen, __user *oldlenp = NULL; unsigned long addr = (((long __force)&args->__unused[0]) + 7) & ~7; - extern int do_sysctl(int *name, int nlen, void *oldval, size_t *oldlenp, - void *newval, size_t newlen); DBG(("sysctl32(%p)\n", args)); @@ -144,8 +145,9 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) } lock_kernel(); - error = do_sysctl((int *)(u64)tmp.name, tmp.nlen, (void *)(u64)tmp.oldval, - oldlenp, (void *)(u64)tmp.newval, tmp.newlen); + error = do_sysctl((int __user *)(u64)tmp.name, tmp.nlen, + (void __user *)(u64)tmp.oldval, oldlenp, + (void __user *)(u64)tmp.newval, tmp.newlen); unlock_kernel(); if (oldlenp) { if (!error) { @@ -157,10 +159,11 @@ asmlinkage long sys32_sysctl(struct __sysctl_args32 __user *args) error = -EFAULT; } } - if (copy_to_user(&args->__unused[0], tmp.__unused, sizeof(tmp.__unused))) + if (copy_to_user(args->__unused, tmp.__unused, sizeof(tmp.__unused))) error = -EFAULT; } return error; +#endif } #endif /* CONFIG_SYSCTL */ @@ -310,9 +313,8 @@ struct readdir32_callback { #define ROUND_UP(x,a) ((__typeof__(x))(((unsigned long)(x) + ((a) - 1)) & ~((a) - 1))) #define NAME_OFFSET(de) ((int) ((de)->d_name - (char __user *) (de))) -static int -filldir32 (void *__buf, const char *name, int namlen, loff_t offset, ino_t ino, - unsigned int d_type) +static int filldir32 (void *__buf, const char *name, int namlen, + loff_t offset, u64 ino, unsigned int d_type) { struct linux32_dirent __user * dirent; struct getdents32_callback * buf = (struct getdents32_callback *) __buf; @@ -374,9 +376,8 @@ sys32_getdents (unsigned int fd, void __user * dirent, unsigned int count) return error; } -static int -fillonedir32 (void * __buf, const char * name, int namlen, loff_t offset, ino_t ino, - unsigned int d_type) +static int fillonedir32(void * __buf, const char * name, int namlen, + loff_t offset, u64 ino, unsigned int d_type) { struct readdir32_callback * buf = (struct readdir32_callback *) __buf; struct old_linux32_dirent __user * dirent; diff --git a/arch/parisc/kernel/time.c b/arch/parisc/kernel/time.c index b3496b592a2d7db687793899388a4db9ce73f064..1d58ce0e37ad7b6b24daabe182913fe3b101ee29 100644 --- a/arch/parisc/kernel/time.c +++ b/arch/parisc/kernel/time.c @@ -38,11 +38,28 @@ static unsigned long clocktick __read_mostly; /* timer cycles per tick */ extern void smp_do_timer(struct pt_regs *regs); #endif +/* + * We keep time on PA-RISC Linux by using the Interval Timer which is + * a pair of registers; one is read-only and one is write-only; both + * accessed through CR16. The read-only register is 32 or 64 bits wide, + * and increments by 1 every CPU clock tick. The architecture only + * guarantees us a rate between 0.5 and 2, but all implementations use a + * rate of 1. The write-only register is 32-bits wide. When the lowest + * 32 bits of the read-only register compare equal to the write-only + * register, it raises a maskable external interrupt. Each processor has + * an Interval Timer of its own and they are not synchronised. + * + * We want to generate an interrupt every 1/HZ seconds. So we program + * CR16 to interrupt every @clocktick cycles. The it_value in cpu_data + * is programmed with the intended time of the next tick. We can be + * held off for an arbitrarily long period of time by interrupts being + * disabled, so we may miss one or more ticks. + */ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) { unsigned long now; unsigned long next_tick; - unsigned long cycles_elapsed; + unsigned long cycles_elapsed, ticks_elapsed; unsigned long cycles_remainder; unsigned int cpu = smp_processor_id(); @@ -67,11 +84,14 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * of the more expensive div/mul method */ cycles_remainder = cycles_elapsed; + ticks_elapsed = 1; while (cycles_remainder > cpt) { cycles_remainder -= cpt; + ticks_elapsed++; } } else { cycles_remainder = cycles_elapsed % cpt; + ticks_elapsed = 1 + cycles_elapsed / cpt; } /* Can we differentiate between "early CR16" (aka Scenario 1) and @@ -81,18 +101,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) * cycles after the IT fires. But it's arbitrary how much time passes * before we call it "late". I've picked one second. */ -/* aproximate HZ with shifts. Intended math is "(elapsed/clocktick) > HZ" */ -#if HZ == 1000 - if (cycles_elapsed > (cpt << 10) ) -#elif HZ == 250 - if (cycles_elapsed > (cpt << 8) ) -#elif HZ == 100 - if (cycles_elapsed > (cpt << 7) ) -#else -#warn WTF is HZ set to anyway? - if (cycles_elapsed > (HZ * cpt) ) -#endif - { + if (ticks_elapsed > HZ) { /* Scenario 3: very long delay? bad in any case */ printk (KERN_CRIT "timer_interrupt(CPU %d): delayed!" " cycles %lX rem %lX " @@ -136,7 +145,7 @@ irqreturn_t timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) #endif if (cpu == 0) { write_seqlock(&xtime_lock); - do_timer(regs); + do_timer(ticks_elapsed); write_sequnlock(&xtime_lock); } diff --git a/drivers/parisc/sba_iommu.c b/drivers/parisc/sba_iommu.c index 294c1117098d69d6a0a9c13e26cd9f4727fbf528..f1e7ccd5475bb413888272112e1937d67e4d5f36 100644 --- a/drivers/parisc/sba_iommu.c +++ b/drivers/parisc/sba_iommu.c @@ -1320,12 +1320,12 @@ sba_ioc_init_pluto(struct parisc_device *sba, struct ioc *ioc, int ioc_num) ** the GART code to handshake on. */ klist_iter_init(&sba->dev.klist_children, &i); - while (dev = next_device(&i)) { + while ((dev = next_device(&i))) { struct parisc_device *lba = to_parisc_device(dev); if (IS_QUICKSILVER(lba)) agp_found = 1; } - klist_iter_exit(&sba->dev.klist_children, &i); + klist_iter_exit(&i); if (agp_found && sba_reserve_agpgart) { printk(KERN_INFO "%s: reserving %dMb of IOVA space for agpgart\n",