From 5658374766d9e0249bd04e9d62bdb8456b916b64 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:33:38 -0400 Subject: [PARISC] Convert parisc_device tree to use struct device klists Fix parse_tree_node. much more needs to be done to fix this file. Signed-off-by: Matthew Wilcox Make drivers.c compile based on a patch from Pat Mochel. From: Patrick Mochel Signed-off-by: Kyle McMartin Fix drivers.c to create new device tree nodes when no match is found. Signed-off-by: Richard Hirst Do a proper depth-first search returning parents before children, using the new klist infrastructure. Signed-off-by: Richard Hirst Fixed parisc_device traversal so that pdc_stable works again Fixed check_dev so it doesn't dereference a parisc_device until it has verified the bus type Signed-off-by: Randolph Chung Convert pa_dev->hpa from an unsigned long to a struct resource. Use insert_resource() instead of request_mem_region(). Request resources at bus walk time instead of driver probe time. Don't release the resources as we don't have any hotplug parisc_device support yet. Add parisc_pathname() to conveniently get the textual representation of the hwpath used in sysfs. Inline the remnants of claim_device() into its caller. Signed-off-by: Matthew Wilcox I noticed that some of the STI regions weren't showing up in iomem. Reading the STI spec indicated that all STI devices occupy at least 32MB. So check for STI HPAs and give them 32MB instead of 4kB. Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- include/asm-parisc/parisc-device.h | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h index ef69ab4b17a..cbde8b41c84 100644 --- a/include/asm-parisc/parisc-device.h +++ b/include/asm-parisc/parisc-device.h @@ -39,6 +39,11 @@ struct parisc_driver { #define to_parisc_driver(d) container_of(d, struct parisc_driver, drv) #define parisc_parent(d) to_parisc_device(d->dev.parent) +static inline char *parisc_pathname(struct parisc_device *d) +{ + return d->dev.bus_id; +} + static inline void parisc_set_drvdata(struct parisc_device *d, void *p) { -- cgit v1.2.3 From 53f01bba49938f115237fe43a261c31ac13ae5c6 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:36:40 -0400 Subject: [PARISC] Convert parisc_device to use struct resource for hpa Convert pa_dev->hpa from an unsigned long to a struct resource. Signed-off-by: Matthew Wilcox Fix up users of ->hpa to use ->hpa.start instead. Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- include/asm-parisc/parisc-device.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/parisc-device.h b/include/asm-parisc/parisc-device.h index cbde8b41c84..1d247e32a60 100644 --- a/include/asm-parisc/parisc-device.h +++ b/include/asm-parisc/parisc-device.h @@ -1,7 +1,7 @@ #include struct parisc_device { - unsigned long hpa; /* Hard Physical Address */ + struct resource hpa; /* Hard Physical Address */ struct parisc_device_id id; struct parisc_driver *driver; /* Driver for this device */ char name[80]; /* The hardware description */ -- cgit v1.2.3 From 896a375623c3643a3f189353e7d4828c48a7fdf8 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:40:07 -0400 Subject: [PARISC] Make sure use of RFI conforms to PA 2.0 and 1.1 arch docs 2.6.12-rc4-pa3 : first pass at making sure use of RFI conforms to PA 2.0 arch pages F-4 and F-5, PA 1.1 Arch page 3-19 and 3-20. The discussion revolves around all the rules for clearing PSW Q-bit. The hard part is meeting all the rules for "relied upon translation". .align directive is used to guarantee the critical sequence ends more than 8 instructions (32 bytes) from the end of page. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- include/asm-parisc/assembly.h | 25 +++++++++++++++++++++ include/asm-parisc/psw.h | 51 ++++++++++++++++++++++--------------------- include/asm-parisc/tlbflush.h | 9 +++----- 3 files changed, 54 insertions(+), 31 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index 30b023411fe..b24a99e3ef9 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h @@ -450,5 +450,30 @@ REST_CR (%cr22, PT_PSW (\regs)) .endm + + /* First step to create a "relied upon translation" + * See PA 2.0 Arch. page F-4 and F-5. + * + * The ssm was originally necessary due to a "PCxT bug". + * But someone decided it needed to be added to the architecture + * and this "feature" went into rev3 of PA-RISC 1.1 Arch Manual. + * It's been carried forward into PA 2.0 Arch as well. :^( + * + * "ssm 0,%r0" is a NOP with side effects (prefetch barrier). + * rsm/ssm prevents the ifetch unit from speculatively fetching + * instructions past this line in the code stream. + * PA 2.0 processor will single step all insn in the same QUAD (4 insn). + */ + .macro pcxt_ssm_bug + rsm PSW_SM_I,%r0 + nop /* 1 */ + nop /* 2 */ + nop /* 3 */ + nop /* 4 */ + nop /* 5 */ + nop /* 6 */ + nop /* 7 */ + .endm + #endif /* __ASSEMBLY__ */ #endif diff --git a/include/asm-parisc/psw.h b/include/asm-parisc/psw.h index 51323029f37..4334d6ca2ad 100644 --- a/include/asm-parisc/psw.h +++ b/include/asm-parisc/psw.h @@ -1,4 +1,7 @@ #ifndef _PARISC_PSW_H + +#include + #define PSW_I 0x00000001 #define PSW_D 0x00000002 #define PSW_P 0x00000004 @@ -9,6 +12,16 @@ #define PSW_G 0x00000040 /* PA1.x only */ #define PSW_O 0x00000080 /* PA2.0 only */ +/* ssm/rsm instructions number PSW_W and PSW_E differently */ +#define PSW_SM_I PSW_I /* Enable External Interrupts */ +#define PSW_SM_D PSW_D +#define PSW_SM_P PSW_P +#define PSW_SM_Q PSW_Q /* Enable Interrupt State Collection */ +#define PSW_SM_R PSW_R /* Enable Recover Counter Trap */ +#define PSW_SM_W 0x200 /* PA2.0 only : Enable Wide Mode */ + +#define PSW_SM_QUIET PSW_SM_R+PSW_SM_Q+PSW_SM_P+PSW_SM_D+PSW_SM_I + #define PSW_CB 0x0000ff00 #define PSW_M 0x00010000 @@ -30,33 +43,21 @@ #define PSW_Z 0x40000000 /* PA1.x only */ #define PSW_Y 0x80000000 /* PA1.x only */ -#ifdef __LP64__ -#define PSW_HI_CB 0x000000ff /* PA2.0 only */ +#ifdef CONFIG_64BIT +# define PSW_HI_CB 0x000000ff /* PA2.0 only */ #endif -/* PSW bits to be used with ssm/rsm */ -#define PSW_SM_I 0x1 -#define PSW_SM_D 0x2 -#define PSW_SM_P 0x4 -#define PSW_SM_Q 0x8 -#define PSW_SM_R 0x10 -#define PSW_SM_F 0x20 -#define PSW_SM_G 0x40 -#define PSW_SM_O 0x80 -#define PSW_SM_E 0x100 -#define PSW_SM_W 0x200 - -#ifdef __LP64__ -# define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) -# define KERNEL_PSW (PSW_W | PSW_C | PSW_Q | PSW_P | PSW_D) -# define REAL_MODE_PSW (PSW_W | PSW_Q) -# define USER_PSW_MASK (PSW_W | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) -# define USER_PSW_HI_MASK (PSW_HI_CB) -#else -# define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) -# define KERNEL_PSW (PSW_C | PSW_Q | PSW_P | PSW_D) -# define REAL_MODE_PSW (PSW_Q) -# define USER_PSW_MASK (PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) +#ifdef CONFIG_64BIT +# define USER_PSW_HI_MASK PSW_HI_CB +# define WIDE_PSW PSW_W +#else +# define WIDE_PSW 0 #endif +/* Used when setting up for rfi */ +#define KERNEL_PSW (WIDE_PSW | PSW_C | PSW_Q | PSW_P | PSW_D) +#define REAL_MODE_PSW (WIDE_PSW | PSW_Q) +#define USER_PSW_MASK (WIDE_PSW | PSW_T | PSW_N | PSW_X | PSW_B | PSW_V | PSW_CB) +#define USER_PSW (PSW_C | PSW_Q | PSW_P | PSW_D | PSW_I) + #endif diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h index eb27b78930e..efbb2d8625b 100644 --- a/include/asm-parisc/tlbflush.h +++ b/include/asm-parisc/tlbflush.h @@ -64,29 +64,26 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, { unsigned long npages; - npages = ((end - (start & PAGE_MASK)) + (PAGE_SIZE - 1)) >> PAGE_SHIFT; - if (npages >= 512) /* XXX arbitrary, should be tuned */ + if (npages >= 512) /* 2MB of space: arbitrary, should be tuned */ flush_tlb_all(); else { mtsp(vma->vm_mm->context,1); + purge_tlb_start(); if (split_tlb) { - purge_tlb_start(); while (npages--) { pdtlb(start); pitlb(start); start += PAGE_SIZE; } - purge_tlb_end(); } else { - purge_tlb_start(); while (npages--) { pdtlb(start); start += PAGE_SIZE; } - purge_tlb_end(); } + purge_tlb_end(); } } -- cgit v1.2.3 From 04d472dc83388c59deb6241e9aed841926aa1c8c Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:40:24 -0400 Subject: [PARISC] Move pa_tlb_lock to tlb_flush.h move pa_tlb_lock and it's primary consumers to tlb_flush.h Future step will be to move spinlock_t definition out of system.h. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- include/asm-parisc/system.h | 19 ------------------- include/asm-parisc/tlbflush.h | 20 ++++++++++++++++++++ 2 files changed, 20 insertions(+), 19 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h index 26ff844a21c..a25e9dcd2e7 100644 --- a/include/asm-parisc/system.h +++ b/include/asm-parisc/system.h @@ -164,25 +164,6 @@ static inline void set_eiem(unsigned long val) #endif #define KERNEL_START (0x10100000 - 0x1000) - -/* This is for the serialisation of PxTLB broadcasts. At least on the - * N class systems, only one PxTLB inter processor broadcast can be - * active at any one time on the Merced bus. This tlb purge - * synchronisation is fairly lightweight and harmless so we activate - * it on all SMP systems not just the N class. */ -#ifdef CONFIG_SMP -extern spinlock_t pa_tlb_lock; - -#define purge_tlb_start(x) spin_lock(&pa_tlb_lock) -#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock) - -#else - -#define purge_tlb_start(x) do { } while(0) -#define purge_tlb_end(x) do { } while (0) - -#endif - #define arch_align_stack(x) (x) #endif diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h index efbb2d8625b..84af4ab1fe5 100644 --- a/include/asm-parisc/tlbflush.h +++ b/include/asm-parisc/tlbflush.h @@ -7,6 +7,26 @@ #include #include + +/* This is for the serialisation of PxTLB broadcasts. At least on the + * N class systems, only one PxTLB inter processor broadcast can be + * active at any one time on the Merced bus. This tlb purge + * synchronisation is fairly lightweight and harmless so we activate + * it on all SMP systems not just the N class. */ +#ifdef CONFIG_SMP +extern spinlock_t pa_tlb_lock; + +#define purge_tlb_start(x) spin_lock(&pa_tlb_lock) +#define purge_tlb_end(x) spin_unlock(&pa_tlb_lock) + +#else + +#define purge_tlb_start(x) do { } while(0) +#define purge_tlb_end(x) do { } while (0) + +#endif + + extern void flush_tlb_all(void); /* -- cgit v1.2.3 From 14e256c107304367eff401d20f2ab9fa72e33136 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:41:25 -0400 Subject: [PARISC] Update spinlocks from parisc tree Neaten up the CONFIG_PA20 ifdefs More merge fixes, this time for SMP Signed-off-by: Matthew Wilcox Prettify the CONFIG_DEBUG_SPINLOCK __SPIN_LOCK_UNLOCKED initializers. Clean up some warnings with CONFIG_DEBUG_SPINLOCK enabled. Fix build with spinlock debugging turned on. Patch is cleaner like this, too. Remove mandatory 16-byte alignment requirement on PA2.0 processors by using the ldcw,CO completer. Provides a nice insn savings. Signed-off-by: Kyle McMartin --- include/asm-parisc/spinlock.h | 5 ----- include/asm-parisc/spinlock_types.h | 8 ++++++-- include/asm-parisc/system.h | 31 ++++++++++++++++++++++++------- 3 files changed, 30 insertions(+), 14 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/spinlock.h b/include/asm-parisc/spinlock.h index 43eaa6e742e..7c3f406a746 100644 --- a/include/asm-parisc/spinlock.h +++ b/include/asm-parisc/spinlock.h @@ -5,11 +5,6 @@ #include #include -/* Note that PA-RISC has to use `1' to mean unlocked and `0' to mean locked - * since it only has load-and-zero. Moreover, at least on some PA processors, - * the semaphore address has to be 16-byte aligned. - */ - static inline int __raw_spin_is_locked(raw_spinlock_t *x) { volatile unsigned int *a = __ldcw_align(x); diff --git a/include/asm-parisc/spinlock_types.h b/include/asm-parisc/spinlock_types.h index 785bba822fb..d6b479bdb88 100644 --- a/include/asm-parisc/spinlock_types.h +++ b/include/asm-parisc/spinlock_types.h @@ -6,11 +6,15 @@ #endif typedef struct { +#ifdef CONFIG_PA20 + volatile unsigned int slock; +# define __RAW_SPIN_LOCK_UNLOCKED { 1 } +#else volatile unsigned int lock[4]; +# define __RAW_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } } +#endif } raw_spinlock_t; -#define __RAW_SPIN_LOCK_UNLOCKED { { 1, 1, 1, 1 } } - typedef struct { raw_spinlock_t lock; volatile int counter; diff --git a/include/asm-parisc/system.h b/include/asm-parisc/system.h index a25e9dcd2e7..f3928d3a80c 100644 --- a/include/asm-parisc/system.h +++ b/include/asm-parisc/system.h @@ -138,13 +138,7 @@ static inline void set_eiem(unsigned long val) #define set_wmb(var, value) do { var = value; wmb(); } while (0) -/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ -#define __ldcw(a) ({ \ - unsigned __ret; \ - __asm__ __volatile__("ldcw 0(%1),%0" : "=r" (__ret) : "r" (a)); \ - __ret; \ -}) - +#ifndef CONFIG_PA20 /* Because kmalloc only guarantees 8-byte alignment for kmalloc'd data, and GCC only guarantees 8-byte alignment for stack locals, we can't be assured of 16-byte alignment for atomic lock data even if we @@ -152,12 +146,35 @@ static inline void set_eiem(unsigned long val) we use a struct containing an array of four ints for the atomic lock type and dynamically select the 16-byte aligned int from the array for the semaphore. */ + #define __PA_LDCW_ALIGNMENT 16 #define __ldcw_align(a) ({ \ unsigned long __ret = (unsigned long) &(a)->lock[0]; \ __ret = (__ret + __PA_LDCW_ALIGNMENT - 1) & ~(__PA_LDCW_ALIGNMENT - 1); \ (volatile unsigned int *) __ret; \ }) +#define LDCW "ldcw" + +#else /*CONFIG_PA20*/ +/* From: "Jim Hull" + I've attached a summary of the change, but basically, for PA 2.0, as + long as the ",CO" (coherent operation) completer is specified, then the + 16-byte alignment requirement for ldcw and ldcd is relaxed, and instead + they only require "natural" alignment (4-byte for ldcw, 8-byte for + ldcd). */ + +#define __PA_LDCW_ALIGNMENT 4 +#define __ldcw_align(a) ((volatile unsigned int *)a) +#define LDCW "ldcw,co" + +#endif /*!CONFIG_PA20*/ + +/* LDCW, the only atomic read-write operation PA-RISC has. *sigh*. */ +#define __ldcw(a) ({ \ + unsigned __ret; \ + __asm__ __volatile__(LDCW " 0(%1),%0" : "=r" (__ret) : "r" (a)); \ + __ret; \ +}) #ifdef CONFIG_SMP # define __lock_aligned __attribute__((__section__(".data.lock_aligned"))) -- cgit v1.2.3 From 5cd55b0edee7f979530c86b23728d461ddeb9f3f Mon Sep 17 00:00:00 2001 From: Randolph Chung Date: Fri, 21 Oct 2005 22:42:18 -0400 Subject: [PARISC] Take into account nullified insn and lock functions for profiling export profile_pc() symbol - oprofile needs it when built as a module. Signed-off-by: Grant Grundler Take into account nullified insn and lock functions for profiling This is needed at the end of functions; it is typical that the return branch nullifies the next insn, which is in the next function. This causes profiling data to show up against the "wrong" function. We also count lock times against the locker. This is consistent with other architectures. Signed-off-by: Randolph Chung Signed-off-by: Kyle McMartin --- include/asm-parisc/ptrace.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/ptrace.h b/include/asm-parisc/ptrace.h index 3f428aa371a..93f990e418f 100644 --- a/include/asm-parisc/ptrace.h +++ b/include/asm-parisc/ptrace.h @@ -49,7 +49,7 @@ struct pt_regs { #define user_mode(regs) (((regs)->iaoq[0] & 3) ? 1 : 0) #define user_space(regs) (((regs)->iasq[1] != 0) ? 1 : 0) #define instruction_pointer(regs) ((regs)->iaoq[0] & ~3) -#define profile_pc(regs) instruction_pointer(regs) +unsigned long profile_pc(struct pt_regs *); extern void show_regs(struct pt_regs *); #endif -- cgit v1.2.3 From f053725b8985d10c2cc4b837a80a381104c936a4 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 21 Oct 2005 22:43:15 -0400 Subject: [PARISC] Add ability for prctl to change unaligned trap behaviour Add support for changing unaligned trap behaviour on a per-thread basis. Signed-off-by: Kyle McMartin --- include/asm-parisc/processor.h | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/processor.h b/include/asm-parisc/processor.h index a9dfadd0565..aae40e8c3aa 100644 --- a/include/asm-parisc/processor.h +++ b/include/asm-parisc/processor.h @@ -122,8 +122,27 @@ struct thread_struct { }; /* Thread struct flags. */ +#define PARISC_UAC_NOPRINT (1UL << 0) /* see prctl and unaligned.c */ +#define PARISC_UAC_SIGBUS (1UL << 1) #define PARISC_KERNEL_DEATH (1UL << 31) /* see die_if_kernel()... */ +#define PARISC_UAC_SHIFT 0 +#define PARISC_UAC_MASK (PARISC_UAC_NOPRINT|PARISC_UAC_SIGBUS) + +#define SET_UNALIGN_CTL(task,value) \ + ({ \ + (task)->thread.flags = (((task)->thread.flags & ~PARISC_UAC_MASK) \ + | (((value) << PARISC_UAC_SHIFT) & \ + PARISC_UAC_MASK)); \ + 0; \ + }) + +#define GET_UNALIGN_CTL(task,addr) \ + ({ \ + put_user(((task)->thread.flags & PARISC_UAC_MASK) \ + >> PARISC_UAC_SHIFT, (int __user *) (addr)); \ + }) + #define INIT_THREAD { \ regs: { gr: { 0, }, \ fr: { 0, }, \ -- cgit v1.2.3 From a366064c3ff46c985a3c7243468be197d29874dc Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:45:22 -0400 Subject: [PARISC] Update bitops from parisc tree Optimize ext2_find_next_zero_bit. Gives about 25% perf improvement with a rsync test with ext3. Signed-off-by: Randolph Chung fix ext3 performance - ext2_find_next_zero() was culprit. Kudos to jejb for pointing out the the possibility that ext2_test_bit and ext2_find_next_zero() may in fact not be enumerating bits in the bitmap because of endianess. Took sparc64 implementation and adapted it to our tree. I suspect the real problem is ffz() wants an unsigned long and was getting garbage in the top half of the unsigned int. Not confirmed but that's what I suspect. Signed-off-by: Grant Grundler Fix find_next_bit for 32-bit Make masking consistent for bitops From: Joel Soete Signed-off-by: Randolph Chung Add back incorrectly removed ext2_find_first_zero_bit definition Signed-off-by: James Bottomley Fixup bitops.h to use volatile for *_bit() ops Based on this email thread: http://marc.theaimsgroup.com/?t=108826637900003 In a nutshell: *_bit() want use of volatile. __*_bit() are "relaxed" and don't use spinlock or volatile. other minor changes: o replaces hweight64() macro with alias to generic_hweight64() (Joel Soete) o cleanup ext2* macros so (a) it's obvious what the XOR magic is about and (b) one version that works for both 32/64-bit. o replace 2 uses of CONFIG_64BIT with __LP64__. bitops.h used both. I think header files that might go to user space should use something userspace will know about (__LP64__). Signed-off-by: Grant Grundler Move SHIFT_PER_LONG to standard location for BITS_PER_LONG (asm/types.h) and ditch the second definition of BITS_PER_LONG in bitops.h Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- include/asm-parisc/bitops.h | 290 ++++++++++++++++++++------------------------ include/asm-parisc/types.h | 2 + 2 files changed, 134 insertions(+), 158 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/bitops.h b/include/asm-parisc/bitops.h index af7db694b22..55b98c67fd8 100644 --- a/include/asm-parisc/bitops.h +++ b/include/asm-parisc/bitops.h @@ -2,7 +2,7 @@ #define _PARISC_BITOPS_H #include -#include +#include /* for BITS_PER_LONG/SHIFT_PER_LONG */ #include #include @@ -12,193 +12,157 @@ * to include/asm-i386/bitops.h or kerneldoc */ -#ifdef __LP64__ -# define SHIFT_PER_LONG 6 -#ifndef BITS_PER_LONG -# define BITS_PER_LONG 64 -#endif -#else -# define SHIFT_PER_LONG 5 -#ifndef BITS_PER_LONG -# define BITS_PER_LONG 32 -#endif -#endif - -#define CHOP_SHIFTCOUNT(x) ((x) & (BITS_PER_LONG - 1)) +#define CHOP_SHIFTCOUNT(x) (((unsigned long) (x)) & (BITS_PER_LONG - 1)) #define smp_mb__before_clear_bit() smp_mb() #define smp_mb__after_clear_bit() smp_mb() -static __inline__ void set_bit(int nr, volatile unsigned long * address) +/* See http://marc.theaimsgroup.com/?t=108826637900003 for discussion + * on use of volatile and __*_bit() (set/clear/change): + * *_bit() want use of volatile. + * __*_bit() are "relaxed" and don't use spinlock or volatile. + */ + +static __inline__ void set_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); *addr |= mask; _atomic_spin_unlock_irqrestore(addr, flags); } -static __inline__ void __set_bit(int nr, volatile unsigned long * address) +static __inline__ void __set_bit(unsigned long nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG); - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - *addr |= mask; + *m |= 1UL << CHOP_SHIFTCOUNT(nr); } -static __inline__ void clear_bit(int nr, volatile unsigned long * address) +static __inline__ void clear_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long mask = ~(1UL << CHOP_SHIFTCOUNT(nr)); unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); - *addr &= ~mask; + *addr &= mask; _atomic_spin_unlock_irqrestore(addr, flags); } -static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long * address) +static __inline__ void __clear_bit(unsigned long nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG); - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - *addr &= ~mask; + *m &= ~(1UL << CHOP_SHIFTCOUNT(nr)); } -static __inline__ void change_bit(int nr, volatile unsigned long * address) +static __inline__ void change_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); *addr ^= mask; _atomic_spin_unlock_irqrestore(addr, flags); } -static __inline__ void __change_bit(int nr, volatile unsigned long * address) +static __inline__ void __change_bit(unsigned long nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; + unsigned long *m = (unsigned long *) addr + (nr >> SHIFT_PER_LONG); - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - *addr ^= mask; + *m ^= 1UL << CHOP_SHIFTCOUNT(nr); } -static __inline__ int test_and_set_bit(int nr, volatile unsigned long * address) +static __inline__ int test_and_set_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long oldbit; unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); - oldbit = (*addr & mask) ? 1 : 0; - *addr |= mask; + oldbit = *addr; + *addr = oldbit | mask; _atomic_spin_unlock_irqrestore(addr, flags); - return oldbit; + return (oldbit & mask) ? 1 : 0; } static __inline__ int __test_and_set_bit(int nr, volatile unsigned long * address) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long oldbit; + unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG); - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - oldbit = (*addr & mask) ? 1 : 0; - *addr |= mask; + oldbit = *addr; + *addr = oldbit | mask; - return oldbit; + return (oldbit & mask) ? 1 : 0; } -static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * address) +static __inline__ int test_and_clear_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long oldbit; unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); - oldbit = (*addr & mask) ? 1 : 0; - *addr &= ~mask; + oldbit = *addr; + *addr = oldbit & ~mask; _atomic_spin_unlock_irqrestore(addr, flags); - return oldbit; + return (oldbit & mask) ? 1 : 0; } static __inline__ int __test_and_clear_bit(int nr, volatile unsigned long * address) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG); + unsigned long oldbit; - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - oldbit = (*addr & mask) ? 1 : 0; - *addr &= ~mask; + oldbit = *addr; + *addr = oldbit & ~mask; - return oldbit; + return (oldbit & mask) ? 1 : 0; } -static __inline__ int test_and_change_bit(int nr, volatile unsigned long * address) +static __inline__ int test_and_change_bit(int nr, volatile unsigned long * addr) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long oldbit; unsigned long flags; addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); _atomic_spin_lock_irqsave(addr, flags); - oldbit = (*addr & mask) ? 1 : 0; - *addr ^= mask; + oldbit = *addr; + *addr = oldbit ^ mask; _atomic_spin_unlock_irqrestore(addr, flags); - return oldbit; + return (oldbit & mask) ? 1 : 0; } static __inline__ int __test_and_change_bit(int nr, volatile unsigned long * address) { - unsigned long mask; - unsigned long *addr = (unsigned long *) address; - int oldbit; + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + unsigned long *addr = (unsigned long *)address + (nr >> SHIFT_PER_LONG); + unsigned long oldbit; - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); - oldbit = (*addr & mask) ? 1 : 0; - *addr ^= mask; + oldbit = *addr; + *addr = oldbit ^ mask; - return oldbit; + return (oldbit & mask) ? 1 : 0; } static __inline__ int test_bit(int nr, const volatile unsigned long *address) { - unsigned long mask; - const unsigned long *addr = (const unsigned long *)address; - - addr += (nr >> SHIFT_PER_LONG); - mask = 1L << CHOP_SHIFTCOUNT(nr); + unsigned long mask = 1UL << CHOP_SHIFTCOUNT(nr); + const unsigned long *addr = (const unsigned long *)address + (nr >> SHIFT_PER_LONG); return !!(*addr & mask); } @@ -229,7 +193,7 @@ static __inline__ unsigned long __ffs(unsigned long x) unsigned long ret; __asm__( -#if BITS_PER_LONG > 32 +#ifdef __LP64__ " ldi 63,%1\n" " extrd,u,*<> %0,63,32,%%r0\n" " extrd,u,*TR %0,31,32,%0\n" /* move top 32-bits down */ @@ -304,14 +268,7 @@ static __inline__ int fls(int x) * hweightN: returns the hamming weight (i.e. the number * of bits set) of a N-bit word */ -#define hweight64(x) \ -({ \ - unsigned long __x = (x); \ - unsigned int __w; \ - __w = generic_hweight32((unsigned int) __x); \ - __w += generic_hweight32((unsigned int) (__x>>32)); \ - __w; \ -}) +#define hweight64(x) generic_hweight64(x) #define hweight32(x) generic_hweight32(x) #define hweight16(x) generic_hweight16(x) #define hweight8(x) generic_hweight8(x) @@ -324,7 +281,13 @@ static __inline__ int fls(int x) */ static inline int sched_find_first_bit(const unsigned long *b) { -#ifndef __LP64__ +#ifdef __LP64__ + if (unlikely(b[0])) + return __ffs(b[0]); + if (unlikely(b[1])) + return __ffs(b[1]) + 64; + return __ffs(b[2]) + 128; +#else if (unlikely(b[0])) return __ffs(b[0]); if (unlikely(b[1])) @@ -334,14 +297,6 @@ static inline int sched_find_first_bit(const unsigned long *b) if (b[3]) return __ffs(b[3]) + 96; return __ffs(b[4]) + 128; -#else - if (unlikely(b[0])) - return __ffs(b[0]); - if (unlikely(((unsigned int)b[1]))) - return __ffs(b[1]) + 64; - if (b[1] >> 32) - return __ffs(b[1] >> 32) + 96; - return __ffs(b[2]) + 128; #endif } @@ -391,7 +346,7 @@ found_middle: static __inline__ unsigned long find_next_bit(const unsigned long *addr, unsigned long size, unsigned long offset) { - const unsigned long *p = addr + (offset >> 6); + const unsigned long *p = addr + (offset >> SHIFT_PER_LONG); unsigned long result = offset & ~(BITS_PER_LONG-1); unsigned long tmp; @@ -445,71 +400,90 @@ found_middle: * test_and_{set,clear}_bit guarantee atomicity without * disabling interrupts. */ -#ifdef __LP64__ -#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr) -#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x38, (unsigned long *)addr) -#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr) -#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x38, (unsigned long *)addr) -#else -#define ext2_set_bit(nr, addr) __test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr) -#define ext2_set_bit_atomic(l,nr,addr) test_and_set_bit((nr) ^ 0x18, (unsigned long *)addr) -#define ext2_clear_bit(nr, addr) __test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr) -#define ext2_clear_bit_atomic(l,nr,addr) test_and_clear_bit((nr) ^ 0x18, (unsigned long *)addr) -#endif -#endif /* __KERNEL__ */ +/* '3' is bits per byte */ +#define LE_BYTE_ADDR ((sizeof(unsigned long) - 1) << 3) -static __inline__ int ext2_test_bit(int nr, __const__ void * addr) -{ - __const__ unsigned char *ADDR = (__const__ unsigned char *) addr; +#define ext2_test_bit(nr, addr) \ + test_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) +#define ext2_set_bit(nr, addr) \ + __test_and_set_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) +#define ext2_clear_bit(nr, addr) \ + __test_and_clear_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) - return (ADDR[nr >> 3] >> (nr & 7)) & 1; -} +#define ext2_set_bit_atomic(l,nr,addr) \ + test_and_set_bit((nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) +#define ext2_clear_bit_atomic(l,nr,addr) \ + test_and_clear_bit( (nr) ^ LE_BYTE_ADDR, (unsigned long *)addr) + +#endif /* __KERNEL__ */ -/* - * This implementation of ext2_find_{first,next}_zero_bit was stolen from - * Linus' asm-alpha/bitops.h and modified for a big-endian machine. - */ #define ext2_find_first_zero_bit(addr, size) \ - ext2_find_next_zero_bit((addr), (size), 0) + ext2_find_next_zero_bit((addr), (size), 0) -extern __inline__ unsigned long ext2_find_next_zero_bit(void *addr, - unsigned long size, unsigned long offset) +/* include/linux/byteorder does not support "unsigned long" type */ +static inline unsigned long ext2_swabp(unsigned long * x) { - unsigned int *p = ((unsigned int *) addr) + (offset >> 5); - unsigned int result = offset & ~31UL; - unsigned int tmp; +#ifdef __LP64__ + return (unsigned long) __swab64p((u64 *) x); +#else + return (unsigned long) __swab32p((u32 *) x); +#endif +} + +/* include/linux/byteorder doesn't support "unsigned long" type */ +static inline unsigned long ext2_swab(unsigned long y) +{ +#ifdef __LP64__ + return (unsigned long) __swab64((u64) y); +#else + return (unsigned long) __swab32((u32) y); +#endif +} + +static __inline__ unsigned long ext2_find_next_zero_bit(void *addr, unsigned long size, unsigned long offset) +{ + unsigned long *p = (unsigned long *) addr + (offset >> SHIFT_PER_LONG); + unsigned long result = offset & ~(BITS_PER_LONG - 1); + unsigned long tmp; if (offset >= size) return size; size -= result; - offset &= 31UL; + offset &= (BITS_PER_LONG - 1UL); if (offset) { - tmp = cpu_to_le32p(p++); - tmp |= ~0UL >> (32-offset); - if (size < 32) + tmp = ext2_swabp(p++); + tmp |= (~0UL >> (BITS_PER_LONG - offset)); + if (size < BITS_PER_LONG) goto found_first; - if (tmp != ~0U) + if (~tmp) goto found_middle; - size -= 32; - result += 32; + size -= BITS_PER_LONG; + result += BITS_PER_LONG; } - while (size >= 32) { - if ((tmp = cpu_to_le32p(p++)) != ~0U) - goto found_middle; - result += 32; - size -= 32; + + while (size & ~(BITS_PER_LONG - 1)) { + if (~(tmp = *(p++))) + goto found_middle_swap; + result += BITS_PER_LONG; + size -= BITS_PER_LONG; } if (!size) return result; - tmp = cpu_to_le32p(p); + tmp = ext2_swabp(p); found_first: - tmp |= ~0U << size; + tmp |= ~0UL << size; + if (tmp == ~0UL) /* Are any bits zero? */ + return result + size; /* Nope. Skip ffz */ found_middle: return result + ffz(tmp); + +found_middle_swap: + return result + ffz(ext2_swab(tmp)); } + /* Bitmap functions for the minix filesystem. */ #define minix_test_and_set_bit(nr,addr) ext2_set_bit(nr,addr) #define minix_set_bit(nr,addr) ((void)ext2_set_bit(nr,addr)) diff --git a/include/asm-parisc/types.h b/include/asm-parisc/types.h index d21b9d0d63e..34fdce361a5 100644 --- a/include/asm-parisc/types.h +++ b/include/asm-parisc/types.h @@ -33,8 +33,10 @@ typedef unsigned long long __u64; #ifdef __LP64__ #define BITS_PER_LONG 64 +#define SHIFT_PER_LONG 6 #else #define BITS_PER_LONG 32 +#define SHIFT_PER_LONG 5 #endif #ifndef __ASSEMBLY__ -- cgit v1.2.3 From ba1f188cae2f58e6bf3ecf4ea99a8dc4b0e2ea0e Mon Sep 17 00:00:00 2001 From: Jens Axboe Date: Fri, 21 Oct 2005 22:45:57 -0400 Subject: [PARISC] Add new ioprio_{set,get} syscalls add syscall entries for ioprio_set/get as per Jens Axboe. Signed-off-by: Jens Axboe Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- include/asm-parisc/unistd.h | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index 6a9f0cadff5..e7a620c5c5e 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h @@ -687,8 +687,8 @@ #define __NR_shmget (__NR_Linux + 194) #define __NR_shmctl (__NR_Linux + 195) -#define __NR_getpmsg (__NR_Linux + 196) /* some people actually want streams */ -#define __NR_putpmsg (__NR_Linux + 197) /* some people actually want streams */ +#define __NR_getpmsg (__NR_Linux + 196) /* Somebody *wants* streams? */ +#define __NR_putpmsg (__NR_Linux + 197) #define __NR_lstat64 (__NR_Linux + 198) #define __NR_truncate64 (__NR_Linux + 199) @@ -755,8 +755,14 @@ #define __NR_mbind (__NR_Linux + 260) #define __NR_get_mempolicy (__NR_Linux + 261) #define __NR_set_mempolicy (__NR_Linux + 262) +#define __NR_vserver (__NR_Linux + 263) +#define __NR_add_key (__NR_Linux + 264) +#define __NR_request_key (__NR_Linux + 265) +#define __NR_keyctl (__NR_Linux + 266) +#define __NR_ioprio_set (__NR_Linux + 267) +#define __NR_ioprio_get (__NR_Linux + 268) -#define __NR_Linux_syscalls 263 +#define __NR_Linux_syscalls 269 #define HPUX_GATEWAY_ADDR 0xC0000004 #define LINUX_GATEWAY_ADDR 0x100 @@ -807,10 +813,10 @@ #define K_INLINE_SYSCALL(name, nr, args...) ({ \ long __sys_res; \ { \ - register unsigned long __res asm("r28"); \ + register unsigned long __res __asm__("r28"); \ K_LOAD_ARGS_##nr(args) \ /* FIXME: HACK stw/ldw r19 around syscall */ \ - asm volatile( \ + __asm__ volatile( \ K_STW_ASM_PIC \ " ble 0x100(%%sr2, %%r0)\n" \ " ldi %1, %%r20\n" \ -- cgit v1.2.3 From 3499495205a676d85fcc2f3c28e35ec9b43c47e3 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:46:18 -0400 Subject: [PARISC] Use work queue in LED/LCD driver instead of tasklet. 2.6.12-rc1-pa6 use work queue in LED/LCD driver instead of tasklet. Main advantage is it allows use of msleep() in the led_LCD_driver to "atomically" perform two MMIO writes (CMD, then DATA). Lead to nice cleanup of the main led_work_func() and led_LCD_driver(). Kudos to David for being persistent. From: David Pye Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- include/asm-parisc/led.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/led.h b/include/asm-parisc/led.h index 1ac8ab6c580..efadfd543ec 100644 --- a/include/asm-parisc/led.h +++ b/include/asm-parisc/led.h @@ -23,9 +23,6 @@ #define LED_CMD_REG_NONE 0 /* NULL == no addr for the cmd register */ -/* led tasklet struct */ -extern struct tasklet_struct led_tasklet; - /* register_led_driver() */ int __init register_led_driver(int model, unsigned long cmd_reg, unsigned long data_reg); -- cgit v1.2.3 From 74d13f84a9905e02a025d952ced6abb2e064f1c1 Mon Sep 17 00:00:00 2001 From: Matthew Wilcox Date: Fri, 21 Oct 2005 22:49:05 -0400 Subject: [PARISC] Fix compile warning in pci.h Signed-off-by: Matthew Wilcox Signed-off-by: Kyle McMartin --- include/asm-parisc/pci.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/pci.h b/include/asm-parisc/pci.h index d0b761f690b..fa39d07d49e 100644 --- a/include/asm-parisc/pci.h +++ b/include/asm-parisc/pci.h @@ -69,7 +69,7 @@ struct pci_hba_data { #define PCI_PORT_HBA(a) ((a) >> HBA_PORT_SPACE_BITS) #define PCI_PORT_ADDR(a) ((a) & (HBA_PORT_SPACE_SIZE - 1)) -#if CONFIG_64BIT +#ifdef CONFIG_64BIT #define PCI_F_EXTEND 0xffffffff00000000UL #define PCI_IS_LMMIO(hba,a) pci_is_lmmio(hba,a) -- cgit v1.2.3 From 618febd6784054eea928d712b7e564558a7cefd5 Mon Sep 17 00:00:00 2001 From: James Bottomley Date: Fri, 21 Oct 2005 22:53:26 -0400 Subject: [PARISC] Fix the alloc_slabmgmt panic Fix the alloc_slabmgmt panic Hopefully this should also fix a lot of other intermittent kernel bugs. The problem has been around since 2.6.9-rc2-pa6 when we allowed floating point registers to be used in kernel code. The essence of the problem is that gcc prefers to use floating point for integer divides and multiples. Further, it can rely on the values in the no clobber fp regs being correct across a function call. Unfortunately, our task switch function only saves the integer no clobber registers, not the fp ones, so if gcc makes a function call to any function in the kernel which could sleep, the values it is relying on in any no clobber floating point register may be lost. In the case of alloc_slabmgmt, the value of the page offset is being stored in %fr12 across a call to kmem_getpages(), which sleeps if no pages are available. Thus, the offset can be trashed and the slab code can end up with a completely bogus address leading to corruption. Kudos to Randolph who came up with the program to trip this problem at will and thus allowed it to be tracked and fixed. Signed-off-by: James Bottomley Signed-off-by: Kyle McMartin --- include/asm-parisc/assembly.h | 40 ++++++++++++++++++++++++++++++++++------ 1 file changed, 34 insertions(+), 6 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index b24a99e3ef9..fb8bc7c16e0 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h @@ -21,6 +21,7 @@ #ifndef _PARISC_ASSEMBLY_H #define _PARISC_ASSEMBLY_H +#define CALLEE_FLOAT_FRAME_SIZE 80 #ifdef __LP64__ #define LDREG ldd #define STREG std @@ -30,7 +31,7 @@ #define SHRREG shrd #define RP_OFFSET 16 #define FRAME_SIZE 128 -#define CALLEE_SAVE_FRAME_SIZE 144 +#define CALLEE_REG_FRAME_SIZE 144 #else #define LDREG ldw #define STREG stw @@ -40,8 +41,9 @@ #define SHRREG shr #define RP_OFFSET 20 #define FRAME_SIZE 64 -#define CALLEE_SAVE_FRAME_SIZE 128 +#define CALLEE_REG_FRAME_SIZE 128 #endif +#define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE) #ifdef CONFIG_PA20 #define BL b,l @@ -300,9 +302,35 @@ fldd,mb -8(\regs), %fr0 .endm + .macro callee_save_float + fstd,ma %fr12, 8(%r30) + fstd,ma %fr13, 8(%r30) + fstd,ma %fr14, 8(%r30) + fstd,ma %fr15, 8(%r30) + fstd,ma %fr16, 8(%r30) + fstd,ma %fr17, 8(%r30) + fstd,ma %fr18, 8(%r30) + fstd,ma %fr19, 8(%r30) + fstd,ma %fr20, 8(%r30) + fstd,ma %fr21, 8(%r30) + .endm + + .macro callee_rest_float + fldd,mb -8(%r30), %fr21 + fldd,mb -8(%r30), %fr20 + fldd,mb -8(%r30), %fr19 + fldd,mb -8(%r30), %fr18 + fldd,mb -8(%r30), %fr17 + fldd,mb -8(%r30), %fr16 + fldd,mb -8(%r30), %fr15 + fldd,mb -8(%r30), %fr14 + fldd,mb -8(%r30), %fr13 + fldd,mb -8(%r30), %fr12 + .endm + #ifdef __LP64__ .macro callee_save - std,ma %r3, CALLEE_SAVE_FRAME_SIZE(%r30) + std,ma %r3, CALLEE_REG_FRAME_SIZE(%r30) mfctl %cr27, %r3 std %r4, -136(%r30) std %r5, -128(%r30) @@ -340,13 +368,13 @@ ldd -128(%r30), %r5 ldd -136(%r30), %r4 mtctl %r3, %cr27 - ldd,mb -CALLEE_SAVE_FRAME_SIZE(%r30), %r3 + ldd,mb -CALLEE_REG_FRAME_SIZE(%r30), %r3 .endm #else /* ! __LP64__ */ .macro callee_save - stw,ma %r3, CALLEE_SAVE_FRAME_SIZE(%r30) + stw,ma %r3, CALLEE_REG_FRAME_SIZE(%r30) mfctl %cr27, %r3 stw %r4, -124(%r30) stw %r5, -120(%r30) @@ -384,7 +412,7 @@ ldw -120(%r30), %r5 ldw -124(%r30), %r4 mtctl %r3, %cr27 - ldw,mb -CALLEE_SAVE_FRAME_SIZE(%r30), %r3 + ldw,mb -CALLEE_REG_FRAME_SIZE(%r30), %r3 .endm #endif /* ! __LP64__ */ -- cgit v1.2.3 From 05aa10de701409b893484d2901c8974b3382f8fe Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:53:43 -0400 Subject: [PARISC] Add ECANCELED to errno.h add ECANCELED - SuSv3 wants one L. IB/SDP actually returns this error. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- include/asm-parisc/errno.h | 1 + 1 file changed, 1 insertion(+) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/errno.h b/include/asm-parisc/errno.h index 08464c40547..e2f3ddc796b 100644 --- a/include/asm-parisc/errno.h +++ b/include/asm-parisc/errno.h @@ -114,6 +114,7 @@ #define ENOTSUP 252 /* Function not implemented (POSIX.4 / HPUX) */ #define ECANCELLED 253 /* aio request was canceled before complete (POSIX.4 / HPUX) */ +#define ECANCELED ECANCELLED /* SuSv3 and Solaris wants one 'L' */ /* for robust mutexes */ #define EOWNERDEAD 254 /* Owner died */ -- cgit v1.2.3 From b4b45313e58bf25886072a4ab111fac553747802 Mon Sep 17 00:00:00 2001 From: Kyle McMartin Date: Fri, 21 Oct 2005 22:54:00 -0400 Subject: [PARISC] Add other CRT_ID for newer cards to grfioctl.h Add IDs for some other STI graphics cards found on HP PA-RISC machines. Signed-off-by: Kyle McMartin --- include/asm-parisc/grfioctl.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/grfioctl.h b/include/asm-parisc/grfioctl.h index d3cfc0168fb..6a910311b56 100644 --- a/include/asm-parisc/grfioctl.h +++ b/include/asm-parisc/grfioctl.h @@ -69,6 +69,8 @@ #define CRT_ID_TVRX S9000_ID_98765 /* TVRX (gto/falcon) */ #define CRT_ID_ARTIST S9000_ID_ARTIST /* Artist */ #define CRT_ID_SUMMIT 0x2FC1066B /* Summit FX2, FX4, FX6 ... */ +#define CRT_ID_LEGO 0x35ACDA30 /* Lego FX5, FX10 ... */ +#define CRT_ID_PINNACLE 0x35ACDA16 /* Pinnacle FXe */ /* structure for ioctl(GCDESCRIBE) */ -- cgit v1.2.3 From 63af965d2bc8d8c5d4c5949b8d3dbdc3c7b7d97a Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:54:20 -0400 Subject: [PARISC] Define pgprot_noncached macro in pgtable.h drivers/infiniband depends on definition of pgprot_noncached() macro. Someone else will have to fix it's wrong. Signed-off-by: Grant Grundler --- include/asm-parisc/pgtable.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/pgtable.h b/include/asm-parisc/pgtable.h index 820c6e712cd..c28fb6f48c6 100644 --- a/include/asm-parisc/pgtable.h +++ b/include/asm-parisc/pgtable.h @@ -501,6 +501,8 @@ static inline void ptep_set_wrprotect(struct mm_struct *mm, unsigned long addr, #define io_remap_pfn_range(vma, vaddr, pfn, size, prot) \ remap_pfn_range(vma, vaddr, pfn, size, prot) +#define pgprot_noncached(prot) __pgprot(pgprot_val(prot) | _PAGE_NO_CACHE) + #define MK_IOSPACE_PFN(space, pfn) (pfn) #define GET_IOSPACE(pfn) 0 #define GET_PFN(pfn) (pfn) -- cgit v1.2.3 From 61520e1f8f5ec3a78510a3254947324711944b98 Mon Sep 17 00:00:00 2001 From: Grant Grundler Date: Fri, 21 Oct 2005 22:56:35 -0400 Subject: [PARISC] Specify level to fix binutils level promotion bug fixup.S needs to specify .level and use correct LDREG macro. New binutils has a bug where it doesn't "promote" from PA1.0 to PA1.1 correctly when using ",s" completer. remove use of __LP64__ in assembly.h and add some white space. Signed-off-by: Grant Grundler Signed-off-by: Kyle McMartin --- include/asm-parisc/assembly.h | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/assembly.h b/include/asm-parisc/assembly.h index fb8bc7c16e0..3ce3440d1b0 100644 --- a/include/asm-parisc/assembly.h +++ b/include/asm-parisc/assembly.h @@ -22,7 +22,8 @@ #define _PARISC_ASSEMBLY_H #define CALLEE_FLOAT_FRAME_SIZE 80 -#ifdef __LP64__ + +#ifdef CONFIG_64BIT #define LDREG ldd #define STREG std #define LDREGX ldd,s @@ -32,7 +33,7 @@ #define RP_OFFSET 16 #define FRAME_SIZE 128 #define CALLEE_REG_FRAME_SIZE 144 -#else +#else /* CONFIG_64BIT */ #define LDREG ldw #define STREG stw #define LDREGX ldwx,s @@ -43,6 +44,7 @@ #define FRAME_SIZE 64 #define CALLEE_REG_FRAME_SIZE 128 #endif + #define CALLEE_SAVE_FRAME_SIZE (CALLEE_REG_FRAME_SIZE + CALLEE_FLOAT_FRAME_SIZE) #ifdef CONFIG_PA20 -- cgit v1.2.3 From 5c1fb41f40b7b6d819a617f52dbd66b6938ef362 Mon Sep 17 00:00:00 2001 From: Al Viro Date: Fri, 21 Oct 2005 03:21:28 -0400 Subject: [PATCH] gfp_t: dma-mapping (parisc) Signed-off-by: Al Viro Signed-off-by: Linus Torvalds --- include/asm-parisc/dma-mapping.h | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/dma-mapping.h b/include/asm-parisc/dma-mapping.h index 4db84f969e9..74d4ac6f215 100644 --- a/include/asm-parisc/dma-mapping.h +++ b/include/asm-parisc/dma-mapping.h @@ -9,8 +9,8 @@ /* See Documentation/DMA-mapping.txt */ struct hppa_dma_ops { int (*dma_supported)(struct device *dev, u64 mask); - void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, int flag); - void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, int flag); + void *(*alloc_consistent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag); + void *(*alloc_noncoherent)(struct device *dev, size_t size, dma_addr_t *iova, gfp_t flag); void (*free_consistent)(struct device *dev, size_t size, void *vaddr, dma_addr_t iova); dma_addr_t (*map_single)(struct device *dev, void *addr, size_t size, enum dma_data_direction direction); void (*unmap_single)(struct device *dev, dma_addr_t iova, size_t size, enum dma_data_direction direction); @@ -49,14 +49,14 @@ extern struct hppa_dma_ops *hppa_dma_ops; static inline void * dma_alloc_coherent(struct device *dev, size_t size, dma_addr_t *dma_handle, - int flag) + gfp_t flag) { return hppa_dma_ops->alloc_consistent(dev, size, dma_handle, flag); } static inline void * dma_alloc_noncoherent(struct device *dev, size_t size, dma_addr_t *dma_handle, - int flag) + gfp_t flag) { return hppa_dma_ops->alloc_noncoherent(dev, size, dma_handle, flag); } -- cgit v1.2.3 From 663b97f7efd001b0c56bd5fce059c5272725b86f Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Sat, 29 Oct 2005 18:16:28 -0700 Subject: [PATCH] mm: flush_tlb_range outside ptlock There was one small but very significant change in the previous patch: mprotect's flush_tlb_range fell outside the page_table_lock: as it is in 2.4, but that doesn't prove it safe in 2.6. On some architectures flush_tlb_range comes to the same as flush_tlb_mm, which has always been called from outside page_table_lock in dup_mmap, and is so proved safe. Others required a deeper audit: I could find no reliance on page_table_lock in any; but in ia64 and parisc found some code which looks a bit as if it might want preemption disabled. That won't do any actual harm, so pending a decision from the maintainers, disable preemption there. Remove comments on page_table_lock from flush_tlb_mm, flush_tlb_range and flush_tlb_page entries in cachetlb.txt: they were rather misleading (what generic code does is different from what usually happens), the rules are now changing, and it's not yet clear where we'll end up (will the generic tlb_flush_mmu happen always under lock? never under lock? or sometimes under and sometimes not?). Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-parisc/tlbflush.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/tlbflush.h b/include/asm-parisc/tlbflush.h index 84af4ab1fe5..e97aa8d1eff 100644 --- a/include/asm-parisc/tlbflush.h +++ b/include/asm-parisc/tlbflush.h @@ -88,7 +88,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, if (npages >= 512) /* 2MB of space: arbitrary, should be tuned */ flush_tlb_all(); else { - + preempt_disable(); mtsp(vma->vm_mm->context,1); purge_tlb_start(); if (split_tlb) { @@ -102,6 +102,7 @@ static inline void flush_tlb_range(struct vm_area_struct *vma, pdtlb(start); start += PAGE_SIZE; } + preempt_enable(); } purge_tlb_end(); } -- cgit v1.2.3 From 92dc6fcc845d99e87d8168e0786796525832d130 Mon Sep 17 00:00:00 2001 From: Hugh Dickins Date: Sat, 29 Oct 2005 18:16:36 -0700 Subject: [PATCH] mm: parisc pte atomicity There's a worrying function translation_exists in parisc cacheflush.h, unaffected by split ptlock since flush_dcache_page is using it on some other mm, without any relevant lock. Oh well, make it a slightly more robust by factoring the pfn check within it. And it looked liable to confuse a camouflaged swap or file entry with a good pte: fix that too. Signed-off-by: Hugh Dickins Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-parisc/cacheflush.h | 35 +++++++++++++++++++---------------- 1 file changed, 19 insertions(+), 16 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/cacheflush.h b/include/asm-parisc/cacheflush.h index aa592d8c0e3..1bc3c83ee74 100644 --- a/include/asm-parisc/cacheflush.h +++ b/include/asm-parisc/cacheflush.h @@ -100,30 +100,34 @@ static inline void flush_cache_range(struct vm_area_struct *vma, /* Simple function to work out if we have an existing address translation * for a user space vma. */ -static inline pte_t *__translation_exists(struct mm_struct *mm, - unsigned long addr) +static inline int translation_exists(struct vm_area_struct *vma, + unsigned long addr, unsigned long pfn) { - pgd_t *pgd = pgd_offset(mm, addr); + pgd_t *pgd = pgd_offset(vma->vm_mm, addr); pmd_t *pmd; - pte_t *pte; + pte_t pte; if(pgd_none(*pgd)) - return NULL; + return 0; pmd = pmd_offset(pgd, addr); if(pmd_none(*pmd) || pmd_bad(*pmd)) - return NULL; + return 0; - pte = pte_offset_map(pmd, addr); + /* We cannot take the pte lock here: flush_cache_page is usually + * called with pte lock already held. Whereas flush_dcache_page + * takes flush_dcache_mmap_lock, which is lower in the hierarchy: + * the vma itself is secure, but the pte might come or go racily. + */ + pte = *pte_offset_map(pmd, addr); + /* But pte_unmap() does nothing on this architecture */ - /* The PA flush mappings show up as pte_none, but they're - * valid none the less */ - if(pte_none(*pte) && ((pte_val(*pte) & _PAGE_FLUSH) == 0)) - return NULL; - return pte; -} -#define translation_exists(vma, addr) __translation_exists((vma)->vm_mm, addr) + /* Filter out coincidental file entries and swap entries */ + if (!(pte_val(pte) & (_PAGE_FLUSH|_PAGE_PRESENT))) + return 0; + return pte_pfn(pte) == pfn; +} /* Private function to flush a page from the cache of a non-current * process. cr25 contains the Page Directory of the current user @@ -175,9 +179,8 @@ flush_cache_page(struct vm_area_struct *vma, unsigned long vmaddr, unsigned long { BUG_ON(!vma->vm_mm->context); - if(likely(translation_exists(vma, vmaddr))) + if (likely(translation_exists(vma, vmaddr, pfn))) __flush_cache_page(vma, vmaddr); } #endif - -- cgit v1.2.3 From 2774812f417db562f0d659d2c1b5755ba35d2770 Mon Sep 17 00:00:00 2001 From: Dave Hansen Date: Sat, 29 Oct 2005 18:16:49 -0700 Subject: [PATCH] memory hotplug prep: kill local_mapnr The following series implements memory hot-add for ppc64 and i386. There are x86_64 and ia64 implementations that will be submitted shortly as well, through the normal maintainers. This patch: local_mapnr is unused, except for in an alpha header. Keep the alpha one, kill the rest. Signed-off-by: Dave Hansen Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-parisc/mmzone.h | 6 ------ 1 file changed, 6 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/mmzone.h b/include/asm-parisc/mmzone.h index 595d3dce120..ae039f4fd71 100644 --- a/include/asm-parisc/mmzone.h +++ b/include/asm-parisc/mmzone.h @@ -27,12 +27,6 @@ extern struct node_map_data node_data[]; }) #define node_localnr(pfn, nid) ((pfn) - node_start_pfn(nid)) -#define local_mapnr(kvaddr) \ -({ \ - unsigned long __pfn = __pa(kvaddr) >> PAGE_SHIFT; \ - (__pfn - node_start_pfn(pfn_to_nid(__pfn))); \ -}) - #define pfn_to_page(pfn) \ ({ \ unsigned long __pfn = (pfn); \ -- cgit v1.2.3 From d61780c0d384939ef31c46b47442854d5def4623 Mon Sep 17 00:00:00 2001 From: Jeff Garzik Date: Sun, 30 Oct 2005 15:01:51 -0800 Subject: [PATCH] remove some more check_region stuff Removed some more references to check_region(). I checked these changes into the 'checkreg' branch of rsync://rsync.kernel.org/pub/scm/linux/kernel/git/jgarzik/misc-2.6.git The only valid references remaining are in: drivers/scsi/advansys.c drivers/scsi/BusLogic.c drivers/cdrom/sbpcd.c sound/oss/pss.c Remove last vestiges of ide_check_region() drivers/char/specialix: trim trailing whitespace drivers/char/specialix: eliminate use of check_region() Remove outdated and unused references to check_region() [sound oss] remove check_region() usage from cs4232, wavfront [netdrvr eepro] trim trailing whitespace [netdrvr eepro] remove check_region() usage Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-parisc/ide.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/ide.h b/include/asm-parisc/ide.h index 3243cf2cd22..b27bf7aeb25 100644 --- a/include/asm-parisc/ide.h +++ b/include/asm-parisc/ide.h @@ -22,7 +22,6 @@ #define ide_request_irq(irq,hand,flg,dev,id) request_irq((irq),(hand),(flg),(dev),(id)) #define ide_free_irq(irq,dev_id) free_irq((irq), (dev_id)) -#define ide_check_region(from,extent) check_region((from), (extent)) #define ide_request_region(from,extent,name) request_region((from), (extent), (name)) #define ide_release_region(from,extent) release_region((from), (extent)) /* Generic I/O and MEMIO string operations. */ -- cgit v1.2.3 From 7024a9b884ed7657fb873e655cd124d85ae792a4 Mon Sep 17 00:00:00 2001 From: Christoph Hellwig Date: Sun, 30 Oct 2005 15:02:21 -0800 Subject: [PATCH] adjust parisc sys_ptrace prototype Make the pid argument a long as on every other arcihtecture. Despite pid_t beeing a 32bit type even on 64bit parisc this is not an ABI change due to the parisc calling conventions. And even if it did it wouldn't matter too much because 64bit userspace on parisc is in an embrionic stage. Acked-by: Matthew Wilcox Signed-off-by: Christoph Hellwig Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-parisc/unistd.h | 1 - 1 file changed, 1 deletion(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/unistd.h b/include/asm-parisc/unistd.h index e7a620c5c5e..80b7b98c70a 100644 --- a/include/asm-parisc/unistd.h +++ b/include/asm-parisc/unistd.h @@ -1011,7 +1011,6 @@ int sys_clone(unsigned long clone_flags, unsigned long usp, struct pt_regs *regs); int sys_vfork(struct pt_regs *regs); int sys_pipe(int *fildes); -long sys_ptrace(long request, pid_t pid, long addr, long data); struct sigaction; asmlinkage long sys_rt_sigaction(int sig, const struct sigaction __user *act, -- cgit v1.2.3 From 727a53bd535fe3bde644ac346db27456ad964083 Mon Sep 17 00:00:00 2001 From: Arthur Othieno Date: Sun, 30 Oct 2005 15:03:14 -0800 Subject: [PATCH] semaphore: Remove __MUTEX_INITIALIZER() __MUTEX_INITIALIZER() has no users, and equates to the more commonly used DECLARE_MUTEX(), thus making it pretty much redundant. Remove it for good. Signed-off-by: Arthur Othieno Signed-off-by: Andrew Morton Signed-off-by: Linus Torvalds --- include/asm-parisc/semaphore.h | 3 --- 1 file changed, 3 deletions(-) (limited to 'include/asm-parisc') diff --git a/include/asm-parisc/semaphore.h b/include/asm-parisc/semaphore.h index f78bb2e3453..c9ee41cd070 100644 --- a/include/asm-parisc/semaphore.h +++ b/include/asm-parisc/semaphore.h @@ -49,9 +49,6 @@ struct semaphore { .wait = __WAIT_QUEUE_HEAD_INITIALIZER((name).wait) \ } -#define __MUTEX_INITIALIZER(name) \ - __SEMAPHORE_INITIALIZER(name,1) - #define __DECLARE_SEMAPHORE_GENERIC(name,count) \ struct semaphore name = __SEMAPHORE_INITIALIZER(name,count) -- cgit v1.2.3