diff options
author | Ralf Baechle <ralf@linux-mips.org> | 2000-02-18 00:24:27 +0000 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2000-02-18 00:24:27 +0000 |
commit | b9558d5f86c471a125abf1fb3a3882fb053b1f8c (patch) | |
tree | 707b53ec64e740a7da87d5f36485e3cd9b1c794e /arch/mips | |
parent | b3ac367c7a3e6047abe74817db27e34e759f279f (diff) |
Merge with Linux 2.3.41.
Diffstat (limited to 'arch/mips')
-rw-r--r-- | arch/mips/defconfig | 12 | ||||
-rw-r--r-- | arch/mips/defconfig-ip22 | 12 | ||||
-rw-r--r-- | arch/mips/kernel/semaphore.c | 111 | ||||
-rw-r--r-- | arch/mips/kernel/syscalls.h | 3 | ||||
-rw-r--r-- | arch/mips/kernel/sysmips.c | 3 | ||||
-rw-r--r-- | arch/mips/mm/fault.c | 11 | ||||
-rw-r--r-- | arch/mips/sni/Makefile | 4 | ||||
-rw-r--r-- | arch/mips/sni/dma.c | 56 |
8 files changed, 198 insertions, 14 deletions
diff --git a/arch/mips/defconfig b/arch/mips/defconfig index 1154cd149..57872bd51 100644 --- a/arch/mips/defconfig +++ b/arch/mips/defconfig @@ -88,7 +88,6 @@ CONFIG_KMOD=y # CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_XD is not set -CONFIG_PARIDE_PARPORT=m # CONFIG_PARIDE is not set # CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set @@ -260,10 +259,12 @@ CONFIG_PSMOUSE=y # # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set +# CONFIG_BFS_FS_WRITE is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set @@ -274,14 +275,20 @@ CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_MINIX_FS is not set # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y +# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set # CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set # # Network File Systems @@ -300,10 +307,7 @@ CONFIG_LOCKD=y # Partition Types # # CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set # CONFIG_NLS is not set # diff --git a/arch/mips/defconfig-ip22 b/arch/mips/defconfig-ip22 index 1154cd149..57872bd51 100644 --- a/arch/mips/defconfig-ip22 +++ b/arch/mips/defconfig-ip22 @@ -88,7 +88,6 @@ CONFIG_KMOD=y # CONFIG_BLK_DEV_MD is not set # CONFIG_BLK_DEV_RAM is not set # CONFIG_BLK_DEV_XD is not set -CONFIG_PARIDE_PARPORT=m # CONFIG_PARIDE is not set # CONFIG_BLK_DEV_IDE_MODES is not set # CONFIG_BLK_DEV_HD is not set @@ -260,10 +259,12 @@ CONFIG_PSMOUSE=y # # CONFIG_QUOTA is not set CONFIG_AUTOFS_FS=y +CONFIG_AUTOFS4_FS=y # CONFIG_ADFS_FS is not set # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_BFS_FS is not set +# CONFIG_BFS_FS_WRITE is not set # CONFIG_FAT_FS is not set # CONFIG_MSDOS_FS is not set # CONFIG_UMSDOS_FS is not set @@ -274,14 +275,20 @@ CONFIG_ISO9660_FS=y # CONFIG_JOLIET is not set # CONFIG_MINIX_FS is not set # CONFIG_NTFS_FS is not set +# CONFIG_NTFS_RW is not set # CONFIG_HPFS_FS is not set CONFIG_PROC_FS=y +# CONFIG_DEVPTS_FS is not set # CONFIG_QNX4FS_FS is not set +# CONFIG_QNX4FS_RW is not set # CONFIG_ROMFS_FS is not set CONFIG_EXT2_FS=y # CONFIG_SYSV_FS is not set +# CONFIG_SYSV_FS_WRITE is not set # CONFIG_UDF_FS is not set +# CONFIG_UDF_RW is not set # CONFIG_UFS_FS is not set +# CONFIG_UFS_FS_WRITE is not set # # Network File Systems @@ -300,10 +307,7 @@ CONFIG_LOCKD=y # Partition Types # # CONFIG_PARTITION_ADVANCED is not set -CONFIG_MSDOS_PARTITION=y CONFIG_SGI_PARTITION=y -# CONFIG_ULTRIX_PARTITION is not set -# CONFIG_SUN_PARTITION is not set # CONFIG_NLS is not set # diff --git a/arch/mips/kernel/semaphore.c b/arch/mips/kernel/semaphore.c index d62b355e1..1f47bd929 100644 --- a/arch/mips/kernel/semaphore.c +++ b/arch/mips/kernel/semaphore.c @@ -127,3 +127,114 @@ int __down_trylock(struct semaphore * sem) { return waking_non_zero_trylock(sem); } + +/* + * RW Semaphores + */ +void +__down_read(struct rw_semaphore *sem, int count) +{ + DOWN_VAR; + + retry_down: + if (count < 0) { + /* Wait for the lock to become unbiased. Readers + are non-exclusive. */ + + /* This takes care of granting the lock. */ + up_read(sem); + + add_wait_queue(&sem->wait, &wait); + while (atomic_read(&sem->count) < 0) { + set_task_state(tsk, TASK_UNINTERRUPTIBLE); + if (atomic_read(&sem->count) >= 0) + break; + schedule(); + } + + remove_wait_queue(&sem->wait, &wait); + tsk->state = TASK_RUNNING; + + mb(); + count = atomic_dec_return(&sem->count); + if (count <= 0) + goto retry_down; + } else { + add_wait_queue(&sem->wait, &wait); + + while (1) { + if (test_and_clear_bit(0, &sem->granted)) + break; + set_task_state(tsk, TASK_UNINTERRUPTIBLE); + if ((sem->granted & 1) == 0) + schedule(); + } + + remove_wait_queue(&sem->wait, &wait); + tsk->state = TASK_RUNNING; + } +} + +void +__down_write(struct rw_semaphore *sem, int count) +{ + DOWN_VAR; + + retry_down: + if (count + RW_LOCK_BIAS < 0) { + up_write(sem); + + add_wait_queue_exclusive(&sem->wait, &wait); + + while (atomic_read(&sem->count) < 0) { + set_task_state(tsk, (TASK_UNINTERRUPTIBLE + | TASK_EXCLUSIVE)); + if (atomic_read(&sem->count) >= RW_LOCK_BIAS) + break; + schedule(); + } + + remove_wait_queue(&sem->wait, &wait); + tsk->state = TASK_RUNNING; + + mb(); + count = atomic_sub_return(RW_LOCK_BIAS, &sem->count); + if (count != 0) + goto retry_down; + } else { + /* Put ourselves at the end of the list. */ + add_wait_queue_exclusive(&sem->write_bias_wait, &wait); + + while (1) { + if (test_and_clear_bit(1, &sem->granted)) + break; + set_task_state(tsk, (TASK_UNINTERRUPTIBLE + | TASK_EXCLUSIVE)); + if ((sem->granted & 2) == 0) + schedule(); + } + + remove_wait_queue(&sem->write_bias_wait, &wait); + tsk->state = TASK_RUNNING; + + /* If the lock is currently unbiased, awaken the sleepers. + FIXME: This wakes up the readers early in a bit of a + stampede -> bad! */ + if (atomic_read(&sem->count) >= 0) + wake_up(&sem->wait); + } +} + +void +__rwsem_wake(struct rw_semaphore *sem, unsigned long readers) +{ + if (readers) { + if (test_and_set_bit(0, &sem->granted)) + BUG(); + wake_up(&sem->wait); + } else { + if (test_and_set_bit(1, &sem->granted)) + BUG(); + wake_up(&sem->write_bias_wait); + } +} diff --git a/arch/mips/kernel/syscalls.h b/arch/mips/kernel/syscalls.h index 66aa9ff50..84ab41425 100644 --- a/arch/mips/kernel/syscalls.h +++ b/arch/mips/kernel/syscalls.h @@ -1,4 +1,4 @@ -/* $Id: syscalls.h,v 1.20 2000/02/04 07:40:23 ralf Exp $ +/* $Id: syscalls.h,v 1.21 2000/02/05 06:47:08 ralf Exp $ * * 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 @@ -231,3 +231,4 @@ SYS(sys_ftruncate64, 2) SYS(sys_stat64, 3) SYS(sys_lstat64, 3) SYS(sys_fstat64, 3) /* 4215 */ +SYS(sys_pivot_root, 2) diff --git a/arch/mips/kernel/sysmips.c b/arch/mips/kernel/sysmips.c index 870cdac2d..a854c915f 100644 --- a/arch/mips/kernel/sysmips.c +++ b/arch/mips/kernel/sysmips.c @@ -7,7 +7,7 @@ * * Copyright (C) 1995, 1996, 1997 by Ralf Baechle * - * $Id: sysmips.c,v 1.7 1999/10/09 00:00:58 ralf Exp $ + * $Id: sysmips.c,v 1.8 2000/02/05 06:47:08 ralf Exp $ */ #include <linux/errno.h> #include <linux/linkage.h> @@ -72,6 +72,7 @@ sys_sysmips(int cmd, int arg1, int arg2, int arg3) if (len == 0 || len > __NEW_UTS_LEN) goto out; + /* Fiiiixmeeee... */ copy_from_user(system_utsname.nodename, name, len); system_utsname.nodename[len] = '\0'; retval = 0; diff --git a/arch/mips/mm/fault.c b/arch/mips/mm/fault.c index cfcfc9c8b..263f2c919 100644 --- a/arch/mips/mm/fault.c +++ b/arch/mips/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.14 1999/12/04 03:59:00 ralf Exp $ +/* $Id: fault.c,v 1.15 2000/02/04 07:40:23 ralf Exp $ * * 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 @@ -47,6 +47,7 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, struct vm_area_struct * vma; struct task_struct *tsk = current; struct mm_struct *mm = tsk->mm; + int si_code = SEGV_MAPERR; unsigned long fixup; /* @@ -74,6 +75,8 @@ asmlinkage void do_page_fault(struct pt_regs *regs, unsigned long write, * we can handle it.. */ good_area: + si_code = SEGV_ACCERR; + if (write) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; @@ -106,6 +109,7 @@ bad_area: up(&mm->mmap_sem); if (user_mode(regs)) { + struct siginfo si; tsk->thread.cp0_badvaddr = address; tsk->thread.error_code = write; #if 0 @@ -117,7 +121,10 @@ bad_area: (unsigned long) regs->cp0_epc, (unsigned long) regs->regs[31]); #endif - force_sig(SIGSEGV, tsk); + si.si_signo = SIGSEGV; + si.si_code = si_code; + si.si_addr = (void *) address; + force_sig_info(SIGSEGV, &si, tsk); return; } diff --git a/arch/mips/sni/Makefile b/arch/mips/sni/Makefile index f3bb81704..b5091e159 100644 --- a/arch/mips/sni/Makefile +++ b/arch/mips/sni/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.3 1998/10/28 12:38:16 ralf Exp $ +# $Id: Makefile,v 1.3 1999/01/04 16:03:57 ralf Exp $ # # Makefile for the SNI specific part of the kernel # @@ -14,7 +14,7 @@ all: sni.o O_TARGET := sni.o -O_OBJS := int-handler.o io.o pci.o pcimt_scache.o reset.o setup.o +O_OBJS := dma.o int-handler.o io.o pci.o pcimt_scache.o reset.o setup.o int-handler.o: int-handler.S diff --git a/arch/mips/sni/dma.c b/arch/mips/sni/dma.c new file mode 100644 index 000000000..26a7c0f0b --- /dev/null +++ b/arch/mips/sni/dma.c @@ -0,0 +1,56 @@ +/* $Id: dma.c,v 1.1 2000/02/16 21:21:58 ralf Exp $ + * + * Dynamic DMA mapping support. + * + * On RM200 there is no hardware dynamic DMA address translation, + * so consistent alloc/free are merely page allocation/freeing. + * The rest of the dynamic DMA mapping interface is implemented + * in <asm/pci.h>. + * + * These routines assume that the RM has all it's memory at physical + * addresses of < 512mb. + */ +#include <linux/types.h> +#include <linux/mm.h> +#include <linux/string.h> +#include <linux/pci.h> +#include <asm/io.h> + +/* Pure 2^n version of get_order */ +extern __inline__ int __get_order(unsigned long size) +{ + int order; + + size = (size-1) >> (PAGE_SHIFT-1); + order = -1; + do { + size >>= 1; + order++; + } while (size); + return order; +} + +void *pci_alloc_consistent(struct pci_dev *hwdev, size_t size, + dma_addr_t *dma_handle) +{ + void *ret; + int gfp = GFP_ATOMIC; + int order = __get_order(size); + + if (hwdev == NULL || hwdev->dma_mask != 0xffffffff) + gfp |= GFP_DMA; + ret = (void *)__get_free_pages(gfp, order); + + if (ret != NULL) { + memset(ret, 0, size); + *dma_handle = virt_to_bus(ret); + } + dma_cache_wback_inv(ret, PAGE_SIZE << order); + return KSEG1ADDR(ret); +} + +void pci_free_consistent(struct pci_dev *hwdev, size_t size, + void *vaddr, dma_addr_t dma_handle) +{ + free_pages((unsigned long)vaddr, __get_order(size)); +} |