diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-06-19 22:45:37 +0000 |
commit | 6d403070f28cd44860fdb3a53be5da0275c65cf4 (patch) | |
tree | 0d0e7fe7b5fb7568d19e11d7d862b77a866ce081 /include/asm-ppc | |
parent | ecf1bf5f6c2e668d03b0a9fb026db7aa41e292e1 (diff) |
Merge with 2.4.0-test1-ac21 + pile of MIPS cleanups to make merging
possible. Chainsawed RM200 kernel to compile again. Jazz machine
status unknown.
Diffstat (limited to 'include/asm-ppc')
-rw-r--r-- | include/asm-ppc/bitops.h | 127 | ||||
-rw-r--r-- | include/asm-ppc/byteorder.h | 10 | ||||
-rw-r--r-- | include/asm-ppc/cache.h | 4 | ||||
-rw-r--r-- | include/asm-ppc/est8260.h | 10 | ||||
-rw-r--r-- | include/asm-ppc/io.h | 14 | ||||
-rw-r--r-- | include/asm-ppc/mmu.h | 25 | ||||
-rw-r--r-- | include/asm-ppc/mmu_context.h | 10 | ||||
-rw-r--r-- | include/asm-ppc/pgtable.h | 2 | ||||
-rw-r--r-- | include/asm-ppc/posix_types.h | 11 | ||||
-rw-r--r-- | include/asm-ppc/processor.h | 4 | ||||
-rw-r--r-- | include/asm-ppc/prom.h | 4 | ||||
-rw-r--r-- | include/asm-ppc/ptrace.h | 2 | ||||
-rw-r--r-- | include/asm-ppc/rpxclassic.h | 21 | ||||
-rw-r--r-- | include/asm-ppc/smp.h | 4 | ||||
-rw-r--r-- | include/asm-ppc/system.h | 1 | ||||
-rw-r--r-- | include/asm-ppc/uaccess.h | 12 |
16 files changed, 181 insertions, 80 deletions
diff --git a/include/asm-ppc/bitops.h b/include/asm-ppc/bitops.h index f62ad151f..7f6f12155 100644 --- a/include/asm-ppc/bitops.h +++ b/include/asm-ppc/bitops.h @@ -29,67 +29,121 @@ extern int test_and_change_bit(int nr, volatile void *addr); #define SMP_MB #endif /* CONFIG_SMP */ +#define __INLINE_BITOPS 1 + +#if __INLINE_BITOPS /* - * These are if'd out here because using : "cc" as a constraint - * results in errors from gcc. -- Cort - * Besides, they need to be changed so we have both set_bit - * and test_and_set_bit, etc. + * These used to be if'd out here because using : "cc" as a constraint + * resulted in errors from egcs. Things may be OK with gcc-2.95. */ -#if 0 -extern __inline__ int set_bit(int nr, void * addr) +extern __inline__ void set_bit(int nr, volatile void * addr) { - unsigned long old, t; + unsigned long old; unsigned long mask = 1 << (nr & 0x1f); unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - __asm__ __volatile__( - "1:lwarx %0,0,%3 \n\t" - "or %1,%0,%2 \n\t" - "stwcx. %1,0,%3 \n\t" - "bne 1b \n\t" - : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/ - : "r" (mask), "r" (p) - /*: "cc" */); - - return (old & mask) != 0; + __asm__ __volatile__(SMP_WMB "\ +1: lwarx %0,0,%3 + or %0,%0,%2 + stwcx. %0,0,%3 + bne 1b" + SMP_MB + : "=&r" (old), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc" ); } -extern __inline__ unsigned long clear_bit(unsigned long nr, void *addr) +extern __inline__ void clear_bit(int nr, volatile void *addr) { - unsigned long old, t; + unsigned long old; unsigned long mask = 1 << (nr & 0x1f); unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - __asm__ __volatile__("\n\ + __asm__ __volatile__(SMP_WMB "\ 1: lwarx %0,0,%3 - andc %1,%0,%2 - stwcx. %1,0,%3 + andc %0,%0,%2 + stwcx. %0,0,%3 bne 1b" - : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/ - : "r" (mask), "r" (p) - /*: "cc"*/); - - return (old & mask) != 0; + SMP_MB + : "=&r" (old), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc"); } -extern __inline__ unsigned long change_bit(unsigned long nr, void *addr) +extern __inline__ void change_bit(int nr, volatile void *addr) { - unsigned long old, t; + unsigned long old; unsigned long mask = 1 << (nr & 0x1f); unsigned long *p = ((unsigned long *)addr) + (nr >> 5); - __asm__ __volatile__("\n\ + __asm__ __volatile__(SMP_WMB "\ 1: lwarx %0,0,%3 - xor %1,%0,%2 - stwcx. %1,0,%3 + xor %0,%0,%2 + stwcx. %0,0,%3 + bne 1b" + SMP_MB + : "=&r" (old), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc"); +} + +extern __inline__ int test_and_set_bit(int nr, volatile void *addr) +{ + unsigned int old, t; + unsigned int mask = 1 << (nr & 0x1f); + volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); + + __asm__ __volatile__(SMP_WMB "\ +1: lwarx %0,0,%4 + or %1,%0,%3 + stwcx. %1,0,%4 + bne 1b" + SMP_MB + : "=&r" (old), "=&r" (t), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc"); + + return (old & mask) != 0; +} + +extern __inline__ int test_and_clear_bit(int nr, volatile void *addr) +{ + unsigned int old, t; + unsigned int mask = 1 << (nr & 0x1f); + volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); + + __asm__ __volatile__(SMP_WMB "\ +1: lwarx %0,0,%4 + andc %1,%0,%3 + stwcx. %1,0,%4 + bne 1b" + SMP_MB + : "=&r" (old), "=&r" (t), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc"); + + return (old & mask) != 0; +} + +extern __inline__ int test_and_change_bit(int nr, volatile void *addr) +{ + unsigned int old, t; + unsigned int mask = 1 << (nr & 0x1f); + volatile unsigned int *p = ((volatile unsigned int *)addr) + (nr >> 5); + + __asm__ __volatile__(SMP_WMB "\ +1: lwarx %0,0,%4 + xor %1,%0,%3 + stwcx. %1,0,%4 bne 1b" - : "=&r" (old), "=&r" (t) /*, "=m" (*p)*/ - : "r" (mask), "r" (p) - /*: "cc"*/); + SMP_MB + : "=&r" (old), "=&r" (t), "=m" (*p) + : "r" (mask), "r" (p), "m" (*p) + : "cc"); return (old & mask) != 0; } -#endif +#endif /* __INLINE_BITOPS */ extern __inline__ int test_bit(int nr, __const__ volatile void *addr) { @@ -277,4 +331,3 @@ found_middle: #define minix_find_first_zero_bit(addr,size) ext2_find_first_zero_bit(addr,size) #endif /* _PPC_BITOPS_H */ - diff --git a/include/asm-ppc/byteorder.h b/include/asm-ppc/byteorder.h index 453c846d2..c45dba13b 100644 --- a/include/asm-ppc/byteorder.h +++ b/include/asm-ppc/byteorder.h @@ -9,7 +9,7 @@ #ifdef __GNUC__ -extern __inline__ unsigned ld_le16(volatile unsigned short *addr) +extern __inline__ unsigned ld_le16(const volatile unsigned short *addr) { unsigned val; @@ -17,12 +17,12 @@ extern __inline__ unsigned ld_le16(volatile unsigned short *addr) return val; } -extern __inline__ void st_le16(volatile unsigned short *addr, unsigned val) +extern __inline__ void st_le16(volatile unsigned short *addr, const unsigned val) { __asm__ __volatile__ ("sthbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } -extern __inline__ unsigned ld_le32(volatile unsigned *addr) +extern __inline__ unsigned ld_le32(const volatile unsigned *addr) { unsigned val; @@ -30,7 +30,7 @@ extern __inline__ unsigned ld_le32(volatile unsigned *addr) return val; } -extern __inline__ void st_le32(volatile unsigned *addr, unsigned val) +extern __inline__ void st_le32(volatile unsigned *addr, const unsigned val) { __asm__ __volatile__ ("stwbrx %1,0,%2" : "=m" (*addr) : "r" (val), "r" (addr)); } @@ -38,7 +38,7 @@ extern __inline__ void st_le32(volatile unsigned *addr, unsigned val) /* alas, egcs sounds like it has a bug in this code that doesn't use the inline asm correctly, and can cause file corruption. Until I hear that it's fixed, I can live without the extra speed. I hope. */ -#if !(__GNUC__ >= 2 && __GNUC_MINOR__ >= 90) +#if !((__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 90)) #if 0 # define __arch_swab16(x) ld_le16(&x) # define __arch_swab32(x) ld_le32(&x) diff --git a/include/asm-ppc/cache.h b/include/asm-ppc/cache.h index 069ad9707..c45fd8409 100644 --- a/include/asm-ppc/cache.h +++ b/include/asm-ppc/cache.h @@ -9,7 +9,11 @@ /* bytes per L1 cache line */ #if !defined(CONFIG_8xx) || defined(CONFIG_8260) +#if defined(CONFIG_PPC64BRIDGE) +#define L1_CACHE_BYTES 128 +#else #define L1_CACHE_BYTES 32 +#endif /* PPC64 */ #else #define L1_CACHE_BYTES 16 #endif /* !8xx || 8260 */ diff --git a/include/asm-ppc/est8260.h b/include/asm-ppc/est8260.h index 201286ab4..99337e790 100644 --- a/include/asm-ppc/est8260.h +++ b/include/asm-ppc/est8260.h @@ -1,4 +1,10 @@ +/* Board information for the EST8260, which should be generic for + * all 8260 boards. The IMMR is now given to us so the hard define + * will soon be removed. All of the clock values are computed from + * the configuration SCMR and the Power-On-Reset word. + */ + #define IMAP_ADDR ((uint)0xf0000000) @@ -12,8 +18,10 @@ typedef struct bd_info { unsigned int bi_busfreq; /* Bus Freq, in MHz */ unsigned int bi_cpmfreq; /* CPM Freq, in MHz */ unsigned int bi_brgfreq; /* BRG Freq, in MHz */ + unsigned int bi_vco; /* VCO Out from PLL */ + unsigned int bi_baudrate; /* Default console baud rate */ + unsigned int bi_immr; /* IMMR when called from boot rom */ unsigned char bi_enetaddr[6]; - unsigned int bi_baudrate; } bd_t; extern bd_t m8xx_board_info; diff --git a/include/asm-ppc/io.h b/include/asm-ppc/io.h index a4be6b7e2..6e5a57ad6 100644 --- a/include/asm-ppc/io.h +++ b/include/asm-ppc/io.h @@ -161,6 +161,20 @@ extern inline void * bus_to_virt(unsigned long address) } /* + * The PCI bus bridge can translate addresses issued by the processor(s) + * into a different address on the PCI bus. On 32-bit cpus, we assume + * this mapping is 1-1, but on 64-bit systems it often isn't. + */ +#ifndef CONFIG_PPC64BRIDGE +#define phys_to_bus(x) (x) +#define bus_to_phys(x) (x) + +#else +extern unsigned long phys_to_bus(unsigned long pa); +extern unsigned long bus_to_phys(unsigned int ba, int busnr); +#endif /* CONFIG_PPC64BRIDGE */ + +/* * Change virtual addresses to physical addresses and vv, for * addresses in the area where the kernel has the RAM mapped. */ diff --git a/include/asm-ppc/mmu.h b/include/asm-ppc/mmu.h index 55f185d91..4a3a42f26 100644 --- a/include/asm-ppc/mmu.h +++ b/include/asm-ppc/mmu.h @@ -10,20 +10,20 @@ #ifndef __ASSEMBLY__ /* Hardware Page Table Entry */ typedef struct _PTE { -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC64BRIDGE unsigned long long vsid:52; unsigned long api:5; unsigned long :5; unsigned long h:1; unsigned long v:1; unsigned long long rpn:52; -#else /* CONFIG_PPC64 */ +#else /* CONFIG_PPC64BRIDGE */ unsigned long v:1; /* Entry is valid */ unsigned long vsid:24; /* Virtual segment identifier */ unsigned long h:1; /* Hash algorithm indicator */ unsigned long api:6; /* Abbreviated page index */ unsigned long rpn:20; /* Real (physical) page number */ -#endif /* CONFIG_PPC64 */ +#endif /* CONFIG_PPC64BRIDGE */ unsigned long :3; /* Unused */ unsigned long r:1; /* Referenced */ unsigned long c:1; /* Changed */ @@ -64,11 +64,11 @@ typedef struct _P601_BATU { /* Upper part of BAT for 601 processor */ } P601_BATU; typedef struct _BATU { /* Upper part of BAT (all except 601) */ -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC64BRIDGE unsigned long long bepi:47; -#else /* CONFIG_PPC64 */ +#else /* CONFIG_PPC64BRIDGE */ unsigned long bepi:15; /* Effective page index (virtual address) */ -#endif /* CONFIG_PPC64 */ +#endif /* CONFIG_PPC64BRIDGE */ unsigned long :4; /* Unused */ unsigned long bl:11; /* Block size mask */ unsigned long vs:1; /* Supervisor valid */ @@ -83,11 +83,11 @@ typedef struct _P601_BATL { /* Lower part of BAT for 601 processor */ } P601_BATL; typedef struct _BATL { /* Lower part of BAT (all except 601) */ -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC64BRIDGE unsigned long long brpn:47; -#else /* CONFIG_PPC64 */ +#else /* CONFIG_PPC64BRIDGE */ unsigned long brpn:15; /* Real page index (physical address) */ -#endif /* CONFIG_PPC64 */ +#endif /* CONFIG_PPC64BRIDGE */ unsigned long :10; /* Unused */ unsigned long w:1; /* Write-thru cache */ unsigned long i:1; /* Cache inhibit */ @@ -135,12 +135,7 @@ typedef struct _MMU_context { pte **pmap; /* Two-level page-map structure */ } MMU_context; -/* invalidate a TLB entry */ -extern inline void _tlbie(unsigned long va) -{ - asm volatile ("tlbie %0" : : "r"(va)); -} - +extern void _tlbie(unsigned long va); /* invalidate a TLB entry */ extern void _tlbia(void); /* invalidate all TLB entries */ #endif /* __ASSEMBLY__ */ diff --git a/include/asm-ppc/mmu_context.h b/include/asm-ppc/mmu_context.h index 88d6970a5..bdb1447ed 100644 --- a/include/asm-ppc/mmu_context.h +++ b/include/asm-ppc/mmu_context.h @@ -48,8 +48,12 @@ extern void mmu_context_overflow(void); * Set the current MMU context. * On 32-bit PowerPCs (other than the 8xx embedded chips), this is done by * loading up the segment registers for the user part of the address space. + * + * On the 8xx parts, the context currently includes the page directory, + * and once I implement a real TLB context manager this will disappear. + * The PGD is ignored on other processors. - Dan */ -extern void set_context(int context); +extern void set_context(int context, void *pgd); #ifdef CONFIG_8xx extern inline void mmu_context_overflow(void) @@ -85,7 +89,7 @@ static inline void switch_mm(struct mm_struct *prev, struct mm_struct *next, { tsk->thread.pgdir = next->pgd; get_mmu_context(next); - set_context(next->context); + set_context(next->context, next->pgd); } /* @@ -96,7 +100,7 @@ static inline void activate_mm(struct mm_struct *active_mm, struct mm_struct *mm { current->thread.pgdir = mm->pgd; get_mmu_context(mm); - set_context(mm->context); + set_context(mm->context, mm->pgd); } /* diff --git a/include/asm-ppc/pgtable.h b/include/asm-ppc/pgtable.h index 5c4e39902..505f0c5b6 100644 --- a/include/asm-ppc/pgtable.h +++ b/include/asm-ppc/pgtable.h @@ -72,7 +72,7 @@ extern void __flush_page_to_ram(unsigned long page_va); #define flush_page_to_ram(page) __flush_page_to_ram(page_address(page)) extern unsigned long va_to_phys(unsigned long address); -extern pte_t *va_to_pte(struct task_struct *tsk, unsigned long address); +extern pte_t *va_to_pte(unsigned long address); extern unsigned long ioremap_bot, ioremap_base; #endif /* __ASSEMBLY__ */ diff --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h index 47539d3a7..2d8f38fd5 100644 --- a/include/asm-ppc/posix_types.h +++ b/include/asm-ppc/posix_types.h @@ -1,8 +1,6 @@ #ifndef _PPC_POSIX_TYPES_H #define _PPC_POSIX_TYPES_H -#include <linux/config.h> /* for CONFIG_PPC64 */ - /* * This file is generally used by user-level software, so you need to * be a little careful about namespace pollution etc. Also, we cannot @@ -17,17 +15,8 @@ typedef long __kernel_off_t; typedef int __kernel_pid_t; typedef unsigned int __kernel_uid_t; typedef unsigned int __kernel_gid_t; - -/* Grrr... gcc thinks size_t is unsigned int, so we either - have to have this nonsense or use -fno-builtin. - paulus */ -#ifdef CONFIG_PPC64 -typedef unsigned long __kernel_size_t; -typedef long __kernel_ssize_t; -#else typedef unsigned int __kernel_size_t; typedef int __kernel_ssize_t; -#endif /* CONFIG_PPC64 */ - typedef long __kernel_ptrdiff_t; typedef long __kernel_time_t; typedef long __kernel_suseconds_t; diff --git a/include/asm-ppc/processor.h b/include/asm-ppc/processor.h index 3088dd279..86a086e79 100644 --- a/include/asm-ppc/processor.h +++ b/include/asm-ppc/processor.h @@ -15,10 +15,10 @@ /* Machine State Register (MSR) Fields */ -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC64BRIDGE #define MSR_SF (1<<63) #define MSR_ISF (1<<61) -#endif /* CONFIG_PPC64 */ +#endif /* CONFIG_PPC64BRIDGE */ #define MSR_VEC (1<<25) /* Enable AltiVec */ #define MSR_POW (1<<18) /* Enable Power Management */ #define MSR_WE (1<<18) /* Wait State Enable */ diff --git a/include/asm-ppc/prom.h b/include/asm-ppc/prom.h index 66eaedda5..70ff81302 100644 --- a/include/asm-ppc/prom.h +++ b/include/asm-ppc/prom.h @@ -4,6 +4,8 @@ * * Copyright (C) 1996 Paul Mackerras. */ +#ifndef _PPC_PROM_H +#define _PPC_PROM_H typedef void *phandle; typedef void *ihandle; @@ -86,3 +88,5 @@ extern int call_rtas(const char *service, int nargs, int nret, extern void prom_drawstring(const char *c); extern void prom_drawhex(unsigned long v); extern void prom_drawchar(char c); + +#endif /* _PPC_PROM_H */ diff --git a/include/asm-ppc/ptrace.h b/include/asm-ppc/ptrace.h index 448f0b274..f95656dd2 100644 --- a/include/asm-ppc/ptrace.h +++ b/include/asm-ppc/ptrace.h @@ -20,7 +20,7 @@ #include <linux/config.h> #ifndef __ASSEMBLY__ -#ifdef CONFIG_PPC64 +#ifdef CONFIG_PPC64BRIDGE #define PPC_REG unsigned long /*long*/ #else #define PPC_REG unsigned long diff --git a/include/asm-ppc/rpxclassic.h b/include/asm-ppc/rpxclassic.h index 74be56085..b84a20d12 100644 --- a/include/asm-ppc/rpxclassic.h +++ b/include/asm-ppc/rpxclassic.h @@ -8,6 +8,8 @@ #ifndef __MACH_RPX_DEFS #define __MACH_RPX_DEFS +#include <linux/config.h> + /* A Board Information structure that is given to a program when * prom starts it up. */ @@ -26,8 +28,6 @@ extern bd_t m8xx_board_info; * We just map a few things we need. The CSR is actually 4 byte-wide * registers that can be accessed as 8-, 16-, or 32-bit values. */ -#define PCMCIA_MEM_ADDR ((uint)0x04000000) -#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) #define PCI_ISA_IO_ADDR ((unsigned)0x80000000) #define PCI_ISA_IO_SIZE ((uint)(512 * 1024 * 1024)) #define PCI_ISA_MEM_ADDR ((unsigned)0xc0000000) @@ -38,6 +38,12 @@ extern bd_t m8xx_board_info; #define IMAP_SIZE ((uint)(64 * 1024)) #define PCI_CSR_ADDR ((uint)0x80000000) #define PCI_CSR_SIZE ((uint)(64 * 1024)) +#define PCMCIA_MEM_ADDR ((uint)0xe0000000) +#define PCMCIA_MEM_SIZE ((uint)(64 * 1024)) +#define PCMCIA_IO_ADDR ((uint)0xe4000000) +#define PCMCIA_IO_SIZE ((uint)(4 * 1024)) +#define PCMCIA_ATTRB_ADDR ((uint)0xe8000000) +#define PCMCIA_ATTRB_SIZE ((uint)(4 * 1024)) /* Things of interest in the CSR. */ @@ -49,8 +55,19 @@ extern bd_t m8xx_board_info; #define BCSR0_FLASH_SEL ((uint)0x02000000) #define BCSR0_ENMONXCVR ((uint)0x01000000) +#define BCSR0_PCMCIAVOLT ((uint)0x000f0000) /* CLLF */ +#define BCSR0_PCMCIA3VOLT ((uint)0x000a0000) /* CLLF */ +#define BCSR0_PCMCIA5VOLT ((uint)0x00060000) /* CLLF */ + #define BCSR2_EN232XCVR ((uint)0x00008000) #define BCSR2_QSPACESEL ((uint)0x00004000) +#define BCSR2_FETHLEDMODE ((uint)0x00000800) /* CLLF */ + +#if defined(CONFIG_RPXLCD) || defined(CONFIG_HTDMSOUND) +/* HIOX Expansion card. +*/ +#include <asm/rpx_hiox.h> +#endif /* Interrupt level assignments. */ diff --git a/include/asm-ppc/smp.h b/include/asm-ppc/smp.h index af62f7b5a..aec727670 100644 --- a/include/asm-ppc/smp.h +++ b/include/asm-ppc/smp.h @@ -37,9 +37,11 @@ void smp_send_tlb_invalidate(int); #define cpu_number_map(x) (x) extern volatile unsigned long cpu_callin_map[NR_CPUS]; -#define hard_smp_processor_id() (0) #define smp_processor_id() (current->processor) +extern int smp_hw_index[NR_CPUS]; +#define hard_smp_processor_id() (smp_hw_index[smp_processor_id()]) + struct klock_info_struct { unsigned long kernel_flag; unsigned char akp; diff --git a/include/asm-ppc/system.h b/include/asm-ppc/system.h index fa9bc9944..162a09a1d 100644 --- a/include/asm-ppc/system.h +++ b/include/asm-ppc/system.h @@ -8,7 +8,6 @@ #include <linux/config.h> #include <linux/kdev_t.h> -#include <linux/bitops.h> #include <asm/processor.h> #include <asm/atomic.h> diff --git a/include/asm-ppc/uaccess.h b/include/asm-ppc/uaccess.h index c2a9c91e5..3eafdbd91 100644 --- a/include/asm-ppc/uaccess.h +++ b/include/asm-ppc/uaccess.h @@ -211,16 +211,28 @@ extern int __copy_tofrom_user(void *to, const void *from, unsigned long size); extern inline unsigned long copy_from_user(void *to, const void *from, unsigned long n) { + unsigned long over; + if (access_ok(VERIFY_READ, from, n)) return __copy_tofrom_user(to, from, n); + if ((unsigned long)from < TASK_SIZE) { + over = (unsigned long)from + n - TASK_SIZE; + return __copy_tofrom_user(to, from, n - over) + over; + } return n; } extern inline unsigned long copy_to_user(void *to, const void *from, unsigned long n) { + unsigned long over; + if (access_ok(VERIFY_WRITE, to, n)) return __copy_tofrom_user(to, from, n); + if ((unsigned long)to < TASK_SIZE) { + over = (unsigned long)to + n - TASK_SIZE; + return __copy_tofrom_user(to, from, n - over) + over; + } return n; } |