diff options
Diffstat (limited to 'include/asm-mips')
38 files changed, 751 insertions, 171 deletions
diff --git a/include/asm-mips/asm.h b/include/asm-mips/asm.h index 20dd39cb6..cd4dcf284 100644 --- a/include/asm-mips/asm.h +++ b/include/asm-mips/asm.h @@ -118,7 +118,7 @@ symbol = value #define TEXT(msg) \ .data; \ 8: .asciiz msg; \ - .text; + .previous; /* * Build text tables @@ -126,9 +126,10 @@ symbol = value #define TTABLE(string) \ .text; \ .word 1f; \ + .previous; \ .data; \ 1: .asciz string; \ - .text + .previous /* * MIPS IV pref instruction. diff --git a/include/asm-mips/atomic.h b/include/asm-mips/atomic.h index 1faf804c6..7b1187768 100644 --- a/include/asm-mips/atomic.h +++ b/include/asm-mips/atomic.h @@ -23,7 +23,16 @@ */ #define __atomic_fool_gcc(x) (*(struct { int a[100]; } *)x) -typedef int atomic_t; +#ifdef __SMP__ +typedef struct { volatile int counter; } atomic_t; +#else +typedef struct { int counter; } atomic_t; +#endif + +#define ATOMIC_INIT(i) { (i) } + +#define atomic_read(v) ((v)->counter) +#define atomic_set(v,i) ((v)->counter = (i)) #if (_MIPS_ISA == _MIPS_ISA_MIPS1) @@ -33,7 +42,7 @@ typedef int atomic_t; * The MIPS I implementation is only atomic with respect to * interrupts. R3000 based multiprocessor machines are rare anyway ... */ -extern __inline__ void atomic_add(atomic_t i, atomic_t * v) +extern __inline__ void atomic_add(int i, volatile atomic_t * v) { int flags; @@ -43,7 +52,7 @@ extern __inline__ void atomic_add(atomic_t i, atomic_t * v) restore_flags(flags); } -extern __inline__ void atomic_sub(atomic_t i, atomic_t * v) +extern __inline__ void atomic_sub(int i, volatile atomic_t * v) { int flags; @@ -53,7 +62,7 @@ extern __inline__ void atomic_sub(atomic_t i, atomic_t * v) restore_flags(flags); } -extern __inline__ int atomic_add_return(atomic_t i, atomic_t * v) +extern __inline__ int atomic_add_return(int i, atomic_t * v) { int temp, flags; @@ -67,7 +76,7 @@ extern __inline__ int atomic_add_return(atomic_t i, atomic_t * v) return temp; } -extern __inline__ int atomic_sub_return(atomic_t i, atomic_t * v) +extern __inline__ int atomic_sub_return(int i, atomic_t * v) { int temp, flags; @@ -88,7 +97,7 @@ extern __inline__ int atomic_sub_return(atomic_t i, atomic_t * v) * ... while for MIPS II and better we can use ll/sc instruction. This * implementation is SMP safe ... */ -extern __inline__ void atomic_add(atomic_t i, atomic_t * v) +extern __inline__ void atomic_add(int i, volatile atomic_t * v) { unsigned long temp; @@ -103,7 +112,7 @@ extern __inline__ void atomic_add(atomic_t i, atomic_t * v) "m" (__atomic_fool_gcc(v))); } -extern __inline__ void atomic_sub(atomic_t i, atomic_t * v) +extern __inline__ void atomic_sub(int i, volatile atomic_t * v) { unsigned long temp; @@ -121,7 +130,7 @@ extern __inline__ void atomic_sub(atomic_t i, atomic_t * v) /* * Same as above, but return the result value */ -extern __inline__ int atomic_add_return(atomic_t i, atomic_t * v) +extern __inline__ int atomic_add_return(int i, atomic_t * v) { unsigned long temp, result; @@ -142,7 +151,7 @@ extern __inline__ int atomic_add_return(atomic_t i, atomic_t * v) return result; } -extern __inline__ int atomic_sub_return(atomic_t i, atomic_t * v) +extern __inline__ int atomic_sub_return(int i, atomic_t * v) { unsigned long temp, result; diff --git a/include/asm-mips/bitops.h b/include/asm-mips/bitops.h index 53de94227..d28a881a4 100644 --- a/include/asm-mips/bitops.h +++ b/include/asm-mips/bitops.h @@ -449,6 +449,15 @@ found_middle: #define ext2_find_first_zero_bit(addr, size) find_first_zero_bit((addr), (size)) #define ext2_find_next_zero_bit(addr, size, offset) \ find_next_zero_bit((addr), (size), (offset)) -#endif + +/* + * Bitmap functions for the minix filesystem. + * FIXME: These assume that Minix uses the native byte/bitorder. + */ +#define minix_set_bit(nr,addr) set_bit(nr,addr) +#define minix_clear_bit(nr,addr) clear_bit(nr,addr) +#define minix_test_bit(nr,addr) test_bit(nr,addr) +#define minix_find_first_zero_bit(addr,size) find_first_zero_bit(addr,size) +#endif /* __KERNEL__ */ #endif /* __ASM_MIPS_BITOPS_H */ diff --git a/include/asm-mips/bootinfo.h b/include/asm-mips/bootinfo.h index 7388b34d0..2816e599f 100644 --- a/include/asm-mips/bootinfo.h +++ b/include/asm-mips/bootinfo.h @@ -284,6 +284,7 @@ void bi_TagWalk(void); /* screen info will dissapear... soon */ #define DEFAULT_SCREEN_INFO {0, 0, {0, 0, }, 0, 0, 158, 0, 0, 0, 62, 0, 16} +#define DEFAULT_DRIVE_INFO { {0,}} #else diff --git a/include/asm-mips/bugs.h b/include/asm-mips/bugs.h index f2c12e853..5f00d4508 100644 --- a/include/asm-mips/bugs.h +++ b/include/asm-mips/bugs.h @@ -19,7 +19,9 @@ static void check_wait(void) printk("Checking for 'wait' instruction... "); switch(mips_cputype) { case CPU_R4200: + case CPU_R4300: case CPU_R4600: + case CPU_R5000: wait_available = 1; printk(" available.\n"); break; diff --git a/include/asm-mips/cache.h b/include/asm-mips/cache.h new file mode 100644 index 000000000..83211ad98 --- /dev/null +++ b/include/asm-mips/cache.h @@ -0,0 +1,12 @@ +/* + * include/asm-mips/cache.h + */ +#ifndef __ASM_MIPS_CACHE_H +#define __ASM_MIPS_CACHE_H + +/* bytes per L1 cache line */ +#define L1_CACHE_BYTES 32 /* a guess */ + +#define L1_CACHE_ALIGN(x) (((x)+(L1_CACHE_BYTES-1))&~(L1_CACHE_BYTES-1)) + +#endif /* __ASM_MIPS_CACHE_H */ diff --git a/include/asm-mips/checksum.h b/include/asm-mips/checksum.h index f6423ecce..c5f9d20c7 100644 --- a/include/asm-mips/checksum.h +++ b/include/asm-mips/checksum.h @@ -36,10 +36,18 @@ unsigned int csum_partial_copy(const char *src, char *dst, int len, unsigned int /* * the same as csum_partial, but copies from user space (but on MIPS * we have just one address space, so this is identical to the above) + * + * this is obsolete and will go away. */ #define csum_partial_copy_fromuser csum_partial_copy /* + * this is a new version of the above that records errors it finds in *errp, + * but continues and zeros the rest of the buffer. + */ +unsigned int csum_partial_copy_from_user(const char *src, char *dst, int len, unsigned int sum, int *errp); + +/* * Fold a partial checksum without adding pseudo headers */ static inline unsigned short int csum_fold(unsigned int sum) diff --git a/include/asm-mips/cpu.h b/include/asm-mips/cpu.h index b93af21c8..4d42be6f1 100644 --- a/include/asm-mips/cpu.h +++ b/include/asm-mips/cpu.h @@ -23,9 +23,13 @@ #define PRID_IMP_R4600 0x2000 #define PRID_IMP_R4700 0x2100 #define PRID_IMP_R4640 0x2200 -#define PRID_IMP_R4650 0x2200 +#define PRID_IMP_R4650 0x2200 /* Same as R4640 */ #define PRID_IMP_R5000 0x2300 #define PRID_IMP_SONIC 0x2400 +#define PRID_IMP_MAGIC 0x2500 +#define PRID_IMP_RM7000 0x2700 +#define PRID_IMP_NEVADA 0x2800 /* RM5260 ??? */ + #define PRID_IMP_UNKNOWN 0xff00 #define PRID_REV_R4400 0x0040 diff --git a/include/asm-mips/current.h b/include/asm-mips/current.h new file mode 100644 index 000000000..7955aad50 --- /dev/null +++ b/include/asm-mips/current.h @@ -0,0 +1,13 @@ +#ifndef __ASM_MIPS_CURRENT_H +#define __ASM_MIPS_CURRENT_H + +/* + * Some architectures may want to do something "clever" here since + * this is the most frequently accessed piece of data in the entire + * kernel. For an example, see the Sparc implementation where an + * entire register is hard locked to contain the value of current. + */ +extern struct task_struct *current_set[NR_CPUS]; +#define current (current_set[smp_processor_id()]) /* Current on this processor */ + +#endif /* __ASM_MIPS_CURRENT_H */ diff --git a/include/asm-mips/errno.h b/include/asm-mips/errno.h index 70b1effd9..38fd881be 100644 --- a/include/asm-mips/errno.h +++ b/include/asm-mips/errno.h @@ -139,6 +139,12 @@ #define ECANCELED 158 /* AIO operation canceled */ /* + * These error are Linux extensions. + */ +#define ENOMEDIUM 159 /* No medium found */ +#define EMEDIUMTYPE 160 /* Wrong medium type */ + +/* * IRIX 5 error number start from 1000. * Stupid enough; ECANCELED gets redefined with a different value ... #define ECANCELED 1000 diff --git a/include/asm-mips/hardirq.h b/include/asm-mips/hardirq.h new file mode 100644 index 000000000..f372b24d5 --- /dev/null +++ b/include/asm-mips/hardirq.h @@ -0,0 +1,24 @@ +#ifndef __ASM_MIPS_HARDIRQ_H +#define __ASM_MIPS_HARDIRQ_H + +#include <linux/tasks.h> + +extern unsigned int local_irq_count[NR_CPUS]; +#define in_interrupt() (local_irq_count[smp_processor_id()] != 0) + +#ifndef __SMP__ + +#define hardirq_trylock(cpu) (local_irq_count[cpu] == 0) +#define hardirq_endlock(cpu) do { } while (0) + +#define hardirq_enter(cpu) (local_irq_count[cpu]++) +#define hardirq_exit(cpu) (local_irq_count[cpu]--) + +#define synchronize_irq() do { } while (0) + +#else + +#error No habla MIPS SMP + +#endif /* __SMP__ */ +#endif /* __ASM_MIPS_HARDIRQ_H */ diff --git a/include/asm-mips/ide.h b/include/asm-mips/ide.h index e6f925e64..bda27206d 100644 --- a/include/asm-mips/ide.h +++ b/include/asm-mips/ide.h @@ -97,7 +97,7 @@ static __inline__ void ide_release_region (ide_ioreg_t from, unsigned int extent /* * The following are not needed for the non-m68k ports */ -static __inline__ int ide_ack_intr (ide_ioreg_t base_port, ide_ioreg_t irq_port) +static __inline__ int ide_ack_intr (ide_ioreg_t status_port, ide_ioreg_t irq_port) { return(1); } diff --git a/include/asm-mips/init.h b/include/asm-mips/init.h new file mode 100644 index 000000000..cd963cb98 --- /dev/null +++ b/include/asm-mips/init.h @@ -0,0 +1,14 @@ +#ifndef __ASM_MIPS_INIT_H +#define __ASM_MIPS_INIT_H + +/* Throwing the initialization code and data out is not supported yet... */ + +#define __init +#define __initdata +#define __initfunc(__arginit) __arginit +/* For assembly routines */ +#define __INIT +#define __FINIT +#define __INITDATA + +#endif /* __ASM_MIPS_INIT_H */ diff --git a/include/asm-mips/io.h b/include/asm-mips/io.h index 591f6f46d..28ec2f73f 100644 --- a/include/asm-mips/io.h +++ b/include/asm-mips/io.h @@ -88,10 +88,23 @@ extern unsigned long isa_slot_offset; * times, so "ioremap()" and "iounmap()" do not need to do anything. * (This isn't true for all machines but we still handle these cases * with wired TLB entries anyway ...) + * + * We cheat a bit and always return uncachable areas until we've fixed + * the drivers to handle caching properly. + */ +extern inline void * ioremap(unsigned long offset, unsigned long size) +{ + return (void *) KSEG1ADDR(offset); +} + +/* + * This one maps high address device memory and turns off caching for that area. + * it's useful if some control registers are in such an area and write combining + * or read caching is not desirable: */ -extern inline void * ioremap(unsigned long phys_addr, unsigned long size) +extern inline void * ioremap_nocache (unsigned long offset, unsigned long size) { - return (void *) KSEG1ADDR(phys_addr); + return (void *) KSEG1ADDR(offset); } extern inline void iounmap(void *addr) diff --git a/include/asm-mips/keyboard.h b/include/asm-mips/keyboard.h index a99289d00..04dada787 100644 --- a/include/asm-mips/keyboard.h +++ b/include/asm-mips/keyboard.h @@ -45,7 +45,7 @@ #define KBD_REPORT_ERR #endif -static int initialize_kbd(void); +__initfunc(int initialize_kbd(void)); int (*kbd_inb_p)(unsigned short port); int (*kbd_inb)(unsigned short port); @@ -192,7 +192,7 @@ static void kbd_write(int address, int data) kbd_outb(data, address); /* write out the data*/ } -static int initialize_kbd(void) +__initfunc(int initialize_kbd(void)) { unsigned long flags; diff --git a/include/asm-mips/mmu_context.h b/include/asm-mips/mmu_context.h index d905d8f11..87b12792e 100644 --- a/include/asm-mips/mmu_context.h +++ b/include/asm-mips/mmu_context.h @@ -44,4 +44,22 @@ extern inline void get_mmu_context(struct task_struct *p) } } +/* + * Initialize the context related info for a new mm_struct + * instance. + */ +extern inline void init_new_context(struct mm_struct *mm) +{ + mm->context = 0; +} + +/* + * Destroy context related info for an mm_struct that is about + * to be put to rest. + */ +extern inline void destroy_context(struct mm_struct *mm) +{ + mm->context = 0; +} + #endif /* __ASM_MIPS_MMU_CONTEXT_H */ diff --git a/include/asm-mips/namei.h b/include/asm-mips/namei.h new file mode 100644 index 000000000..8f3267eda --- /dev/null +++ b/include/asm-mips/namei.h @@ -0,0 +1,66 @@ +/* + * linux/include/asm-mips/namei.h + * + * Included from linux/fs/namei.c + */ +#ifndef __ASM_MIPS_NAMEI_H +#define __ASM_MIPS_NAMEI_H + +#include <linux/config.h> + +#ifdef CONFIG_BINFMT_IRIX + +/* Only one at this time. */ +#define IRIX32_EMUL "/usr/gnemul/irix" + +#define translate_namei(pathname, base, follow_links, res_inode) ({ \ + if ((current->personality == PER_IRIX32) && !base && *pathname == '/') { \ + struct inode *emul_ino; \ + int namelen; \ + const char *name; \ + \ + while (*pathname == '/') \ + pathname++; \ + current->fs->root->i_count++; \ + if (dir_namei (IRIX32_EMUL, \ + &namelen, &name, current->fs->root, &emul_ino) >= 0 && emul_ino) { \ + *res_inode = NULL; \ + if (_namei (pathname, emul_ino, follow_links, res_inode) >= 0 && *res_inode) \ + return 0; \ + } \ + base = current->fs->root; \ + base->i_count++; \ + } \ +}) + +#define translate_open_namei(pathname, flag, mode, res_inode, base) ({ \ + if ((current->personality == PER_IRIX32) && !base && *pathname == '/') { \ + struct inode *emul_ino; \ + int namelen; \ + const char *name; \ + \ + while (*pathname == '/') \ + pathname++; \ + current->fs->root->i_count++; \ + if (dir_namei (IRIX32_EMUL, \ + &namelen, &name, current->fs->root, &emul_ino) >= 0 && emul_ino) { \ + *res_inode = NULL; \ + if (open_namei (pathname, flag, mode, res_inode, emul_ino) >= 0 && *res_inode) \ + return 0; \ + } \ + base = current->fs->root; \ + base->i_count++; \ + } \ +}) + +#else /* !defined(CONFIG_BINFMT_IRIX) */ + +#define translate_namei(pathname, base, follow_links, res_inode) \ + do { } while (0) + +#define translate_open_namei(pathname, flag, mode, res_inode, base) \ + do { } while (0) + +#endif /* !defined(CONFIG_BINFMT_IRIX) */ + +#endif /* __ASM_MIPS_NAMEI_H */ diff --git a/include/asm-mips/pci.h b/include/asm-mips/pci.h new file mode 100644 index 000000000..a506e4bb2 --- /dev/null +++ b/include/asm-mips/pci.h @@ -0,0 +1,39 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Declarations for the MIPS specific implementation of the PCI BIOS32 services. + */ +#ifndef __ASM_MIPS_PCI_H +#define __ASM_MIPS_PCI_H + +extern unsigned long (*_pcibios_init)(unsigned long memory_start, unsigned long memory_end); +extern unsigned long (*_pcibios_fixup) (unsigned long memory_start, + unsigned long memory_end); +extern int (*_pcibios_read_config_byte) (unsigned char bus, + unsigned char dev_fn, + unsigned char where, + unsigned char *val); +extern int (*_pcibios_read_config_word) (unsigned char bus, + unsigned char dev_fn, + unsigned char where, + unsigned short *val); +extern int (*_pcibios_read_config_dword) (unsigned char bus, + unsigned char dev_fn, + unsigned char where, + unsigned int *val); +extern int (*_pcibios_write_config_byte) (unsigned char bus, + unsigned char dev_fn, + unsigned char where, + unsigned char val); +extern int (*_pcibios_write_config_word) (unsigned char bus, + unsigned char dev_fn, + unsigned char where, + unsigned short val); +extern int (*_pcibios_write_config_dword) (unsigned char bus, + unsigned char dev_fn, + unsigned char where, + unsigned int val); + +#endif /* __ASM_MIPS_PCI_H */ diff --git a/include/asm-mips/pgtable.h b/include/asm-mips/pgtable.h index 2192a39d5..c6bb9b2de 100644 --- a/include/asm-mips/pgtable.h +++ b/include/asm-mips/pgtable.h @@ -347,6 +347,9 @@ extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) return __pte((pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot)); } +/* to find an entry in a kernel page-table-directory */ +#define pgd_offset_k(address) pgd_offset(&init_mm, address) + /* to find an entry in a page-table-directory */ extern inline pgd_t *pgd_offset(struct mm_struct *mm, unsigned long address) { @@ -376,6 +379,8 @@ extern inline void pte_free_kernel(pte_t *pte) free_page((unsigned long) pte); } +extern const char bad_pmd_string[]; + extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address) { address = (address >> PAGE_SHIFT) & (PTRS_PER_PTE - 1); @@ -392,7 +397,7 @@ extern inline pte_t *pte_alloc_kernel(pmd_t *pmd, unsigned long address) free_page((unsigned long) page); } if (pmd_bad(*pmd)) { - printk("Bad pmd in pte_alloc_kernel: %08lx\n", pmd_val(*pmd)); + printk(bad_pmd_string, pmd_val(*pmd)); pmd_set(pmd, (pte_t *) BAD_PAGETABLE); return NULL; } @@ -434,7 +439,7 @@ extern inline pte_t *pte_alloc(pmd_t *pmd, unsigned long address) free_page((unsigned long) page); } if (pmd_bad(*pmd)) { - printk("Bad pmd in pte_alloc: %08lx\n", pmd_val(*pmd)); + printk(bad_pmd_string, pmd_val(*pmd)); pmd_set(pmd, (pte_t *) BAD_PAGETABLE); return NULL; } @@ -758,21 +763,6 @@ extern inline void set_context(unsigned long val) : : "r" (val)); } -/* Kernel stack allocation/freeing. */ -extern inline unsigned long alloc_kernel_stack(void) -{ - unsigned long stack; - stack = __get_free_pages(GFP_KERNEL, 1, 0); - memset((void *)stack, 0, (size_t) KERNEL_STACK_SIZE); - - return stack; -} - -extern inline void free_kernel_stack(unsigned long stack) -{ - free_pages(stack, 1); -} - #endif /* !defined (__LANGUAGE_ASSEMBLY__) */ #endif /* __ASM_MIPS_PGTABLE_H */ diff --git a/include/asm-mips/poll.h b/include/asm-mips/poll.h new file mode 100644 index 000000000..a1d2a47d3 --- /dev/null +++ b/include/asm-mips/poll.h @@ -0,0 +1,26 @@ +#ifndef __ASM_MIPS_POLL_H +#define __ASM_MIPS_POLL_H + +#define POLLIN 0x0001 +#define POLLPRI 0x0002 +#define POLLOUT 0x0004 + +#define POLLERR 0x0008 +#define POLLHUP 0x0010 +#define POLLNVAL 0x0020 + +#define POLLRDNORM 0x0040 +#define POLLRDBAND 0x0080 +#define POLLWRNORM POLLOUT /* XXX */ +#define POLLWRBAND 0x0100 + +/* XXX This one seems to be more-or-less nonstandard. */ +#define POLLMSG 0x0400 + +struct pollfd { + int fd; + short events; + short revents; +}; + +#endif /* __ASM_MIPS_POLL_H */ diff --git a/include/asm-mips/posix_types.h b/include/asm-mips/posix_types.h index 21217ebae..deffcf200 100644 --- a/include/asm-mips/posix_types.h +++ b/include/asm-mips/posix_types.h @@ -36,7 +36,7 @@ typedef long __kernel_time_t; typedef long __kernel_clock_t; typedef long __kernel_daddr_t; typedef char * __kernel_caddr_t; -typedef unsigned long __kernel_sigset_t; +/* typedef unsigned long __kernel_sigset_t; anybody using this type? */ #ifdef __GNUC__ typedef long long __kernel_loff_t; diff --git a/include/asm-mips/processor.h b/include/asm-mips/processor.h index 1d308a439..b202ac4ca 100644 --- a/include/asm-mips/processor.h +++ b/include/asm-mips/processor.h @@ -19,9 +19,6 @@ */ extern char wait_available; /* only available on R4[26]00 */ -extern unsigned long intr_count; -extern unsigned long event; - /* * Bus types (default is ISA, but people can check others with these..) * MCA_bus hardcoded to 0 for now. @@ -47,6 +44,11 @@ extern int EISA_bus; */ #define TASK_SIZE (0x80000000UL) +/* This decides where the kernel will search for a free chunk of vm + * space during mmap's. + */ +#define TASK_UNMAPPED_BASE (TASK_SIZE / 3) + /* * Size of io_bitmap in longwords: 32 is ports 0-0x3ff. */ @@ -139,6 +141,10 @@ struct thread_struct { #define KERNEL_STACK_SIZE 8192 #if !defined (__LANGUAGE_ASSEMBLY__) + +/* Free all resources held by a thread. */ +extern void release_thread(struct task_struct *); + /* * Return saved PC of a blocked thread. */ @@ -152,13 +158,20 @@ extern inline unsigned long thread_saved_pc(struct thread_struct *t) */ extern void start_thread(struct pt_regs * regs, unsigned long pc, unsigned long sp); -#endif /* !defined (__LANGUAGE_ASSEMBLY__) */ - /* * Does the process account for user or for system time? */ #define USES_USER_TIME(regs) (!((regs)->cp0_status & 0x18)) +/* Allocation and freeing of basic task resources. */ +#define alloc_task_struct() kmalloc(sizeof(struct task_struct), GFP_KERNEL) +#define free_task_struct(p) kfree(p) + +/* Kernel stack allocation/freeing. */ +extern unsigned long alloc_kernel_stack(struct task_struct *tsk); +extern void free_kernel_stack(unsigned long stack); + +#endif /* !defined (__LANGUAGE_ASSEMBLY__) */ #endif /* __KERNEL__ */ /* diff --git a/include/asm-mips/reboot.h b/include/asm-mips/reboot.h new file mode 100644 index 000000000..930b49831 --- /dev/null +++ b/include/asm-mips/reboot.h @@ -0,0 +1,17 @@ +/* + * This file is subject to the terms and conditions of the GNU General Public + * License. See the file "COPYING" in the main directory of this archive + * for more details. + * + * Copyright (C) 1997 by Ralf Baechle + * + * Declare variables for rebooting. + */ +#ifndef __ASM_MIPS_REBOOT_H +#define __ASM_MIPS_REBOOT_H + +void (*_machine_restart)(char *command); +void (*_machine_halt)(void); +void (*_machine_power_off)(void); + +#endif /* __ASM_MIPS_REBOOT_H */ diff --git a/include/asm-mips/scatterlist.h b/include/asm-mips/scatterlist.h new file mode 100644 index 000000000..40c763789 --- /dev/null +++ b/include/asm-mips/scatterlist.h @@ -0,0 +1,13 @@ +#ifndef __ASM_MIPS_SCATTERLIST_H +#define __ASM_MIPS_SCATTERLIST_H + +struct scatterlist { + char * address; /* Location data is to be transferred to */ + char * alt_address; /* Location of actual if address is a + * dma indirect buffer. NULL otherwise */ + unsigned int length; +}; + +#define ISA_DMA_THRESHOLD (0x00ffffff) + +#endif /* __ASM_MIPS_SCATTERLIST_H */ diff --git a/include/asm-mips/semaphore.h b/include/asm-mips/semaphore.h index f093fe519..6d527848b 100644 --- a/include/asm-mips/semaphore.h +++ b/include/asm-mips/semaphore.h @@ -14,23 +14,61 @@ struct semaphore { atomic_t count; - atomic_t waiting; + atomic_t waking; struct wait_queue * wait; }; -#define MUTEX ((struct semaphore) { 1, 0, NULL }) -#define MUTEX_LOCKED ((struct semaphore) { 0, 0, NULL }) +#define MUTEX ((struct semaphore) { ATOMIC_INIT(1), ATOMIC_INIT(0), NULL }) +#define MUTEX_LOCKED ((struct semaphore) { ATOMIC_INIT(0), ATOMIC_INIT(0), NULL }) extern void __down(struct semaphore * sem); +extern int __down_interruptible(struct semaphore * sem); extern void __up(struct semaphore * sem); +#define sema_init(sem, val) atomic_set(&((sem)->count), val) + +/* + * These two _must_ execute atomically wrt each other. + * + * This is trivially done with load_locked/store_cond, + * which we have. Let the rest of the losers suck eggs. + */ + +static inline void wake_one_more(struct semaphore * sem) +{ + atomic_inc(&sem->waking); +} + +static inline int waking_non_zero(struct semaphore *sem) +{ + int ret, tmp; + + __asm__ __volatile__( + "1:\tll\t%1,%2\n" + "blez\t%1,2f\n\t" + "subu\t%0,%1,1\n\t" + "sc\t%0,%2\n\t" + "beqz\t%0,1b\n\t" + "2:" + ".text" + : "=r"(ret), "=r"(tmp), "=m"(__atomic_fool_gcc(&sem->waking)) + : "0"(0)); + + return ret; +} + extern inline void down(struct semaphore * sem) { - while (1) { - if (atomic_dec_return(&sem->count) >= 0) - break; + if (atomic_dec_return(&sem->count) < 0) __down(sem); - } +} + +extern inline int down_interruptible(struct semaphore * sem) +{ + int ret = 0; + if (atomic_dec_return(&sem->count) < 0) + ret = __down_interruptible(sem); + return ret; } /* diff --git a/include/asm-mips/sigcontext.h b/include/asm-mips/sigcontext.h index a1f7613f4..3e7346dee 100644 --- a/include/asm-mips/sigcontext.h +++ b/include/asm-mips/sigcontext.h @@ -43,6 +43,7 @@ struct sigcontext { unsigned int sc_badvaddr; /* Unused */ sigset_t sc_sigset; + unsigned long __pad0[3]; /* pad for constant size */ }; #endif diff --git a/include/asm-mips/signal.h b/include/asm-mips/signal.h index ced9ee9e3..d21105928 100644 --- a/include/asm-mips/signal.h +++ b/include/asm-mips/signal.h @@ -20,14 +20,7 @@ #endif #ifdef __ASM_MIPS_SIGNAL_H -/* - * This is what we should really use but the kernel can't handle - * a non-scalar type yet. Since we use 64 signals only anyway we - * just use __u64 and pad another 64 bits in the kernel for now ... - */ -typedef struct { - unsigned int __sigbits[4]; -} sigset_t; +typedef unsigned long sigset_t; #endif /* __ASM_MIPS_SIGNAL_H */ #if !defined (___nsig_defined) && \ @@ -142,6 +135,7 @@ struct sigaction { unsigned int sa_flags; __sighandler_t sa_handler; sigset_t sa_mask; + unsigned int __pad0[3]; /* reserved, keep size constant */ /* Abi says here follows reserved int[2] */ void (*sa_restorer)(void); @@ -150,53 +144,13 @@ struct sigaction { * For 32 bit code we have to pad struct sigaction to get * constant size for the ABI */ - int pad0[1]; /* reserved */ + int __pad1[1]; /* reserved */ #endif }; #ifdef __KERNEL__ #include <asm/sigcontext.h> -/* - * This type is used by the kernel internal for it's sigsets. - */ -typedef unsigned long k_sigset_t; - -extern __inline__ k_sigset_t * -to_k_sigset_t(sigset_t *set) -{ - return (k_sigset_t *) set->__sigbits; -} - -#define copy_sigbits32(set, bits) ((set)->__sigbits[0] = (bits)) - -/* - * Clear a userland sigset_t. - */ -extern __inline__ void -u_sigemptyset (sigset_t *set) -{ - set->__sigbits[0] = set->__sigbits[1] = - set->__sigbits[2] = set->__sigbits[3] = 0; -} - -/* - * Add/delete sigbits from a k_sigset_t. - */ -#define __KSSMASK(nr) (1 << ((nr) - 1)) - -extern __inline__ void -k_sigaddset (k_sigset_t *set, int sig) -{ - *set |= __KSSMASK (sig); -} - -extern __inline__ void -k_sigdelset (k_sigset_t *set, int sig) -{ - *set &= ~__KSSMASK (sig); -} - -#endif /* __KERNEL__ */ +#endif #if defined (__KERNEL__) || defined (__USE_MISC) /* diff --git a/include/asm-mips/smp.h b/include/asm-mips/smp.h index acf771ead..780beff0b 100644 --- a/include/asm-mips/smp.h +++ b/include/asm-mips/smp.h @@ -1,9 +1,6 @@ -/* - * This file is subject to the terms and conditions of the GNU General Public - * License. See the file "COPYING" in the main directory of this archive - * for more details. - * - * Copyright (C) 1996 Ralf Baechle - * - * Linux/MIPS SMP support. Just a dummy to make building possible. - */ +#ifndef __ASM_MIPS_SMP_H +#define __ASM_MIPS_SMP_H + +/* We'll get here eventually.. */ + +#endif /* __ASM_MIPS_SMP_H */ diff --git a/include/asm-mips/smp_lock.h b/include/asm-mips/smp_lock.h index acf771ead..c9482ab7d 100644 --- a/include/asm-mips/smp_lock.h +++ b/include/asm-mips/smp_lock.h @@ -7,3 +7,20 @@ * * Linux/MIPS SMP support. Just a dummy to make building possible. */ +#ifndef __ASM_MIPS_SMPLOCK_H +#define __ASM_MIPS_SMPLOCK_H + +#ifndef __SMP__ + +#define lock_kernel() do { } while(0) +#define unlock_kernel() do { } while(0) +#define release_kernel_lock(task, cpu, depth) ((depth) = 1) +#define reacquire_kernel_lock(task, cpu, depth) do { } while(0) + +#else + +#error "We do not support SMP on MIPS yet" + +#endif /* __SMP__ */ + +#endif /* __ASM_MIPS_SMPLOCK_H */ diff --git a/include/asm-mips/sni.h b/include/asm-mips/sni.h index 304506aee..6a43b65f4 100644 --- a/include/asm-mips/sni.h +++ b/include/asm-mips/sni.h @@ -12,4 +12,75 @@ #define SNI_PORT_BASE 0xb4000000 +/* + * ASIC PCI registers for little endian configuration. + */ +#ifndef __MIPSEL__ +#error "Fix me for big endian" +#endif +#define PCIMT_UCONF 0xbfff0000 +#define PCIMT_IOADTIMEOUT2 0xbfff0008 +#define PCIMT_IOMEMCONF 0xbfff0010 +#define PCIMT_IOMMU 0xbfff0018 +#define PCIMT_IOADTIMEOUT1 0xbfff0020 +#define PCIMT_DMAACCESS 0xbfff0028 +#define PCIMT_DMAHIT 0xbfff0030 +#define PCIMT_ERRSTATUS 0xbfff0038 +#define PCIMT_ERRADDR 0xbfff0040 +#define PCIMT_SYNDROME 0xbfff0048 +#define PCIMT_ITPEND 0xbfff0050 +#define PCIMT_IRQSEL 0xbfff0058 +#define PCIMT_TESTMEM 0xbfff0060 +#define PCIMT_ECCREG 0xbfff0068 +#define PCIMT_CONFIG_ADDRESS 0xbfff0070 +#define PCIMT_ASIC_ID 0xbfff0078 /* read */ +#define PCIMT_SOFT_RESET 0xbfff0078 /* write */ +#define PCIMT_PIA_OE 0xbfff0080 +#define PCIMT_PIA_DATAOUT 0xbfff0088 +#define PCIMT_PIA_DATAIN 0xbfff0090 +#define PCIMT_CACHECONF 0xbfff0098 +#define PCIMT_INVSPACE 0xbfff00a0 +#define PCIMT_PCI_CONF 0xbfff0100 + +/* + * Data port for the PCI bus. + */ +#define PCIMT_CONFIG_DATA 0xb4000cfc + +/* + * Board specific registers + */ +#define PCIMT_CSMSR 0xbfd00000 +#define PCIMT_CSSWITCH 0xbfd10000 +#define PCIMT_CSITPEND 0xbfd20000 +#define PCIMT_AUTO_PO_EN 0xbfd30000 +#define PCIMT_CLR_TEMP 0xbfd40000 +#define PCIMT_AUTO_PO_DIS 0xbfd50000 +#define PCIMT_EXMSR 0xbfd60000 +#define PCIMT_UNUSED1 0xbfd70000 +#define PCIMT_CSWCSM 0xbfd80000 +#define PCIMT_UNUSED2 0xbfd90000 +#define PCIMT_CSLED 0xbfda0000 +#define PCIMT_CSMAPISA 0xbfdb0000 +#define PCIMT_CSRSTBP 0xbfdc0000 +#define PCIMT_CLRPOFF 0xbfdd0000 +#define PCIMT_CSTIMER 0xbfde0000 +#define PCIMT_PWDN 0xbfdf0000 + +/* + * Interrupt 0-16 are reserved for PCI and EISA interrupts. The + * interrupts from 16 are assigned to the other interrupts generated + * by the PCI chipset. + */ +#define PCIMT_IRQ_ETHERNET 16 +#define PCIMT_IRQ_TEMPERATURE 17 +#define PCIMT_IRQ_EISA_NMI 18 +#define PCIMT_IRQ_POWER_OFF 19 +#define PCIMT_IRQ_BUTTON 20 +#define PCIMT_IRQ_INTA 21 +#define PCIMT_IRQ_INTB 22 +#define PCIMT_IRQ_INTC 23 +#define PCIMT_IRQ_INTD 24 +#define PCIMT_IRQ_SCSI 25 + #endif /* __ASM_MIPS_SNI_H */ diff --git a/include/asm-mips/socket.h b/include/asm-mips/socket.h index e5ddb6a17..b00108aae 100644 --- a/include/asm-mips/socket.h +++ b/include/asm-mips/socket.h @@ -11,43 +11,42 @@ */ #define SOL_SOCKET 0xffff -enum -{ - SO_DEBUG = 0x0001, /* Record debugging information. */ - SO_REUSEADDR = 0x0004, /* Allow reuse of local addresses. */ - SO_KEEPALIVE = 0x0008, /* Keep connections alive and send +#define SO_DEBUG 0x0001 /* Record debugging information. */ +#define SO_REUSEADDR 0x0004 /* Allow reuse of local addresses. */ +#define SO_KEEPALIVE 0x0008 /* Keep connections alive and send SIGPIPE when they die. */ - SO_DONTROUTE = 0x0010, /* Don't do local routing. */ - SO_BROADCAST = 0x0020, /* Allow transmission of +#define SO_DONTROUTE 0x0010 /* Don't do local routing. */ +#define SO_BROADCAST 0x0020 /* Allow transmission of broadcast messages. */ - SO_LINGER = 0x0080, /* Block on close of a reliable +#define SO_LINGER 0x0080 /* Block on close of a reliable socket to transmit pending data. */ - SO_OOBINLINE = 0x0100, /* Receive out-of-band data in-band. */ +#define SO_OOBINLINE 0x0100 /* Receive out-of-band data in-band. */ #if 0 -To add: SO_REUSEPORT = 0x0200, /* Allow local address and port reuse. */ +To add: #define SO_REUSEPORT 0x0200 /* Allow local address and port reuse. */ #endif - SO_TYPE = 0x1008, /* Compatible name for SO_STYLE. */ - SO_STYLE = SO_TYPE, /* Synonym */ - SO_ERROR = 0x1007, /* get error status and clear */ - SO_SNDBUF = 0x1001, /* Send buffer size. */ - SO_RCVBUF = 0x1002, /* Receive buffer. */ - SO_SNDLOWAT = 0x1003, /* send low-water mark */ - SO_RCVLOWAT = 0x1004, /* receive low-water mark */ - SO_SNDTIMEO = 0x1005, /* send timeout */ - SO_RCVTIMEO = 0x1006, /* receive timeout */ +#define SO_TYPE 0x1008 /* Compatible name for SO_STYLE. */ +#define SO_STYLE SO_TYPE /* Synonym */ +#define SO_ERROR 0x1007 /* get error status and clear */ +#define SO_SNDBUF 0x1001 /* Send buffer size. */ +#define SO_RCVBUF 0x1002 /* Receive buffer. */ +#define SO_SNDLOWAT 0x1003 /* send low-water mark */ +#define SO_RCVLOWAT 0x1004 /* receive low-water mark */ +#define SO_SNDTIMEO 0x1005 /* send timeout */ +#define SO_RCVTIMEO 0x1006 /* receive timeout */ /* linux-specific, might as well be the same as on i386 */ - SO_NO_CHECK = 11, - SO_PRIORITY = 12, - SO_BSDCOMPAT = 14, -}; +#define SO_NO_CHECK 11 +#define SO_PRIORITY 12 +#define SO_BSDCOMPAT 14 -/* - * Weird. The existing SVr4 port to MIPS use two different definitions for - * SOCK_STREAM and SOCK_DGRAM with swapped values. I choose to be compatible - * with the newer definitions though that looks wrong ... - */ +#define SO_PASSCRED 17 +#define SO_PEERCRED 18 + +/* Security levels - as per NRL IPv6 - don't actually do anything */ +#define SO_SECURITY_AUTHENTICATION 22 +#define SO_SECURITY_ENCRYPTION_TRANSPORT 23 +#define SO_SECURITY_ENCRYPTION_NETWORK 24 /* Types of sockets. */ enum __socket_type diff --git a/include/asm-mips/softirq.h b/include/asm-mips/softirq.h new file mode 100644 index 000000000..8d73fed78 --- /dev/null +++ b/include/asm-mips/softirq.h @@ -0,0 +1,93 @@ +#ifndef __ASM_MIPS_SOFTIRQ_H +#define __ASM_MIPS_SOFTIRQ_H + +/* The locking mechanism for base handlers, to prevent re-entrancy, + * is entirely private to an implementation, it should not be + * referenced at all outside of this file. + */ +extern atomic_t __mips_bh_counter; + +#define get_active_bhs() (bh_mask & bh_active) + +static inline void clear_active_bhs(unsigned long x) +{ + unsigned long temp; + + __asm__ __volatile__( + "1:\tll\t%0,%1\n\t" + "and\t%0,%2\n\t" + "sc\t%0,%1\n\t" + "beqz\t%0,1b" + :"=&r" (temp), + "=m" (bh_active) + :"Ir" (x), + "m" (bh_active)); +} + +extern inline void init_bh(int nr, void (*routine)(void)) +{ + bh_base[nr] = routine; + bh_mask_count[nr] = 0; + bh_mask |= 1 << nr; +} + +extern inline void remove_bh(int nr) +{ + bh_base[nr] = NULL; + bh_mask &= ~(1 << nr); +} + +extern inline void mark_bh(int nr) +{ + set_bit(nr, &bh_active); +} + +/* + * These use a mask count to correctly handle + * nested disable/enable calls + */ +extern inline void disable_bh(int nr) +{ + bh_mask &= ~(1 << nr); + bh_mask_count[nr]++; +} + +extern inline void enable_bh(int nr) +{ + if (!--bh_mask_count[nr]) + bh_mask |= 1 << nr; +} + +/* + * start_bh_atomic/end_bh_atomic also nest + * naturally by using a counter + */ +extern inline void start_bh_atomic(void) +{ +#ifdef __SMP__ + atomic_inc(&__mips_bh_counter); + synchronize_irq(); +#else + atomic_inc(&__mips_bh_counter); +#endif +} + +extern inline void end_bh_atomic(void) +{ + atomic_dec(&__mips_bh_counter); +} + +#ifndef __SMP__ + +/* These are for the irq's testing the lock */ +#define softirq_trylock() (atomic_read(&__mips_bh_counter) ? \ + 0 : \ + ((atomic_set(&__mips_bh_counter,1)),1)) +#define softirq_endlock() (atomic_set(&__mips_bh_counter, 0)) + +#else + +#error FIXME + +#endif /* __SMP__ */ +#endif /* __ASM_MIPS_SOFTIRQ_H */ diff --git a/include/asm-mips/spinlock.h b/include/asm-mips/spinlock.h new file mode 100644 index 000000000..d1f67424f --- /dev/null +++ b/include/asm-mips/spinlock.h @@ -0,0 +1,52 @@ +#ifndef __ASM_MIPS_SPINLOCK_H +#define __ASM_MIPS_SPINLOCK_H + +#ifndef __SMP__ + +typedef struct { } spinlock_t; +#define SPIN_LOCK_UNLOCKED { } + +#define spin_lock_init(lock) do { } while(0) +#define spin_lock(lock) do { } while(0) +#define spin_trylock(lock) do { } while(0) +#define spin_unlock_wait(lock) do { } while(0) +#define spin_unlock(lock) do { } while(0) +#define spin_lock_irq(lock) cli() +#define spin_unlock_irq(lock) sti() + +#define spin_lock_irqsave(lock, flags) save_and_cli(flags) +#define spin_unlock_irqrestore(lock, flags) restore_flags(flags) + +/* + * Read-write spinlocks, allowing multiple readers + * but only one writer. + * + * NOTE! it is quite common to have readers in interrupts + * but no interrupt writers. For those circumstances we + * can "mix" irq-safe locks - any writer needs to get a + * irq-safe write-lock, but readers can get non-irqsafe + * read-locks. + */ +typedef struct { } rwlock_t; +#define RW_LOCK_UNLOCKED { } + +#define read_lock(lock) do { } while(0) +#define read_unlock(lock) do { } while(0) +#define write_lock(lock) do { } while(0) +#define write_unlock(lock) do { } while(0) +#define read_lock_irq(lock) cli() +#define read_unlock_irq(lock) sti() +#define write_lock_irq(lock) cli() +#define write_unlock_irq(lock) sti() + +#define read_lock_irqsave(lock, flags) save_and_cli(flags) +#define read_unlock_irqrestore(lock, flags) restore_flags(flags) +#define write_lock_irqsave(lock, flags) save_and_cli(flags) +#define write_unlock_irqrestore(lock, flags) restore_flags(flags) + +#else + +#error "Nix SMP on MIPS" + +#endif /* SMP */ +#endif /* __ASM_MIPS_SPINLOCK_H */ diff --git a/include/asm-mips/system.h b/include/asm-mips/system.h index 4bb2bf1c7..2d4d27871 100644 --- a/include/asm-mips/system.h +++ b/include/asm-mips/system.h @@ -67,6 +67,23 @@ __asm__ __volatile__( \ : /* no inputs */ \ : "memory") +#define save_and_cli(x) \ +__asm__ __volatile__( \ + ".set\tnoreorder\n\t" \ + ".set\tnoat\n\t" \ + "mfc0\t%0,$12\n\t" \ + "ori\t$1,%0,1\n\t" \ + "xori\t$1,1\n\t" \ + "mtc0\t$1,$12\n\t" \ + "nop\n\t" \ + "nop\n\t" \ + "nop\n\t" \ + ".set\tat\n\t" \ + ".set\treorder" \ + : "=r" (x) \ + : /* no inputs */ \ + : "$1", "memory") + extern void __inline__ restore_flags(int flags) { @@ -235,9 +252,4 @@ extern unsigned long exception_handlers[32]; #define set_except_vector(n,addr) \ exception_handlers[n] = (unsigned long) (addr) -/* - * Reset the machine. - */ -extern void (*hard_reset_now)(void); - #endif /* __ASM_MIPS_SYSTEM_H */ diff --git a/include/asm-mips/termbits.h b/include/asm-mips/termbits.h index 7c981e6f7..5e4604089 100644 --- a/include/asm-mips/termbits.h +++ b/include/asm-mips/termbits.h @@ -158,6 +158,7 @@ struct termios { #define B230400 0010003 #define B460800 0010004 #define CIBAUD 002003600000 /* input baud rate (not used) */ +#define CISPAR 010000000000 /* mark or space (stick) parity */ #define CRTSCTS 020000000000 /* flow control */ #endif diff --git a/include/asm-mips/termios.h b/include/asm-mips/termios.h index e62a60eab..5dfb3a995 100644 --- a/include/asm-mips/termios.h +++ b/include/asm-mips/termios.h @@ -81,6 +81,8 @@ struct termio { #define TIOCM_RNG 0x200 /* ring */ #define TIOCM_RI TIOCM_RNG #define TIOCM_DSR 0x400 /* data set ready */ +#define TIOCM_OUT1 0x2000 +#define TIOCM_OUT2 0x4000 /* line disciplines */ #define N_TTY 0 @@ -89,6 +91,7 @@ struct termio { #define N_PPP 3 #define N_STRIP 4 #define N_AX25 5 +#define N_X25 6 /* X.25 async */ #ifdef __KERNEL__ @@ -97,31 +100,36 @@ struct termio { /* * Translate a "termio" structure into a "termios". Ugh. */ -extern inline void trans_from_termio(struct termio * termio, - struct termios * termios) -{ -#define SET_LOW_BITS(x,y) ((x) = (0xffff0000 & (x)) | (y)) - SET_LOW_BITS(termios->c_iflag, termio->c_iflag); - SET_LOW_BITS(termios->c_oflag, termio->c_oflag); - SET_LOW_BITS(termios->c_cflag, termio->c_cflag); - SET_LOW_BITS(termios->c_lflag, termio->c_lflag); -#undef SET_LOW_BITS - memcpy(termios->c_cc, termio->c_cc, NCC); -} +#define user_termio_to_kernel_termios(termios, termio) \ +({ \ + unsigned short tmp; \ + get_user(tmp, &(termio)->c_iflag); \ + (termios)->c_iflag = (0xffff0000 & ((termios)->c_iflag)) | tmp; \ + get_user(tmp, &(termio)->c_oflag); \ + (termios)->c_oflag = (0xffff0000 & ((termios)->c_oflag)) | tmp; \ + get_user(tmp, &(termio)->c_cflag); \ + (termios)->c_cflag = (0xffff0000 & ((termios)->c_cflag)) | tmp; \ + get_user(tmp, &(termio)->c_lflag); \ + (termios)->c_lflag = (0xffff0000 & ((termios)->c_lflag)) | tmp; \ + get_user((termios)->c_line, &(termio)->c_line); \ + copy_from_user((termios)->c_cc, (termio)->c_cc, NCC); \ +}) /* * Translate a "termios" structure into a "termio". Ugh. */ -extern inline void trans_to_termio(struct termios * termios, - struct termio * termio) -{ - termio->c_iflag = termios->c_iflag; - termio->c_oflag = termios->c_oflag; - termio->c_cflag = termios->c_cflag; - termio->c_lflag = termios->c_lflag; - termio->c_line = termios->c_line; - memcpy(termio->c_cc, termios->c_cc, NCC); -} +#define kernel_termios_to_user_termio(termio, termios) \ +({ \ + put_user((termios)->c_iflag, &(termio)->c_iflag); \ + put_user((termios)->c_oflag, &(termio)->c_oflag); \ + put_user((termios)->c_cflag, &(termio)->c_cflag); \ + put_user((termios)->c_lflag, &(termio)->c_lflag); \ + put_user((termios)->c_line, &(termio)->c_line); \ + copy_to_user((termio)->c_cc, (termios)->c_cc, NCC); \ +}) + +#define user_termios_to_kernel_termios(k, u) copy_from_user(k, u, sizeof(struct termios)) +#define kernel_termios_to_user_termios(u, k) copy_to_user(u, k, sizeof(struct termios)) #endif /* defined(__KERNEL__) */ diff --git a/include/asm-mips/uaccess.h b/include/asm-mips/uaccess.h index d71cb3fca..b650209dd 100644 --- a/include/asm-mips/uaccess.h +++ b/include/asm-mips/uaccess.h @@ -85,6 +85,24 @@ extern inline int verify_area(int type, const void * addr, unsigned long size) #define __put_user(x,ptr) __put_user_nocheck((x),(ptr),sizeof(*(ptr))) #define __get_user(x,ptr) __get_user_nocheck((x),(ptr),sizeof(*(ptr))) +/* + * The "xxx_ret" versions return constant specified in third argument, if + * something bad happens. These macros can be optimized for the + * case of just returning from the function xxx_ret is used. + */ + +#define put_user_ret(x,ptr,ret) ({ \ +if (put_user(x,ptr)) return ret; }) + +#define get_user_ret(x,ptr,ret) ({ \ +if (get_user(x,ptr)) return ret; }) + +#define __put_user_ret(x,ptr,ret) ({ \ +if (__put_user(x,ptr)) return ret; }) + +#define __get_user_ret(x,ptr,ret) ({ \ +if (__get_user(x,ptr)) return ret; }) + struct __large_struct { unsigned long buf[100]; }; #define __m(x) (*(struct __large_struct *)(x)) @@ -132,9 +150,10 @@ __asm__ __volatile__( \ "li\t%0,%4\n\t" \ "jr\t$1\n\t" \ ".set\tat\n\t" \ + ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b,3b\n\t" \ - ".text" \ + ".previous" \ :"=r" (__gu_err), "=r" (__gu_val) \ :"0" (__gu_err), "o" (__m(__gu_addr)), "i" (-EFAULT) \ :"$1"); }) @@ -166,9 +185,10 @@ __asm__ __volatile__( \ "la\t$1,2b\n\t" \ "jr\t$1\n\t" \ ".set\tat\n\t" \ + ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b,3b\n\t" \ - ".text" \ + ".previous" \ :"=r" (__gu_err), "=r" (__gu_val) \ :"o" (__m(__gu_addr)) \ :"$1"); }) @@ -201,9 +221,10 @@ __asm__ __volatile__( \ "li\t%0,%3\n\t" \ "jr\t$1\n\t" \ ".set\tat\n\t" \ + ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b,3b\n\t" \ - ".text" \ + ".previous" \ :"=r" (__pu_err) \ :"r" (__pu_val), "o" (__m(__pu_addr)), "i" (-EFAULT) \ :"$1"); }) @@ -235,15 +256,32 @@ __asm__ __volatile__( \ "la\t$1,2b\n\t" \ "jr\t$1\n\t" \ ".set\tat\n\t" \ + ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b,3b\n\t" \ - ".text" \ + ".previous" \ :"=r" (__pu_err) \ :"r" (__pu_val), "o" (__m(__pu_addr)) \ :"$1"); }) extern void __put_user_unknown(void); +#define copy_to_user_ret(to,from,n,retval) ({ \ +if (copy_to_user(to,from,n)) \ + return retval; \ +}) + +#define copy_from_user_ret(to,from,n,retval) ({ \ +if (copy_from_user(to,from,n)) \ + return retval; \ +}) + +#define __copy_to_user(to,from,n) \ + __copy_user((to),(from),(n)) + +#define __copy_from_user(to,from,n) \ + __copy_user((to),(from),(n)) + #define __clear_user(addr,size) \ ({ \ void *__cu_end; \ @@ -258,9 +296,10 @@ extern void __put_user_unknown(void); "la\t$1,2b\n\t" \ "jr\t$1\n\t" \ ".set\tat\n\t" \ + ".previous\n\t" \ ".section\t__ex_table,\"a\"\n\t" \ STR(PTR)"\t1b,3b\n\t" \ - ".text" \ + ".previous" \ :"=r" (addr), "=r" (__cu_end) \ :"0" (addr), "1" (addr + size - 1), "i" (-EFAULT) \ :"$1","memory"); \ @@ -292,10 +331,7 @@ extern long __strlen_user(const char *); extern inline long strlen_user(const char *str) { - long len = __strlen_user(str); - if (!access_ok(VERIFY_READ, str, len)) - len = 0; - return len; + return access_ok(VERIFY_READ,str,0) ? __strlen_user(str) : 0; } struct exception_table_entry diff --git a/include/asm-mips/unistd.h b/include/asm-mips/unistd.h index c62dad56b..ef2940617 100644 --- a/include/asm-mips/unistd.h +++ b/include/asm-mips/unistd.h @@ -1174,11 +1174,14 @@ #define __NR_socketpair (__NR_Linux + 184) #define __NR_setresuid (__NR_Linux + 185) #define __NR_getresuid (__NR_Linux + 186) +#define __NR_query_module (__NR_Linux + 187) +#define __NR_poll (__NR_Linux + 188) +#define __NR_nfsservctl (__NR_Linux + 189) /* * Offset of the last Linux flavoured syscall */ -#define __NR_Linux_syscalls 186 +#define __NR_Linux_syscalls 189 #ifndef __LANGUAGE_ASSEMBLY__ |