From 3db9dee504fc73776958fc9289c05ca488de2b0d Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:38:29 -0500 Subject: [PATCH] - pre3: - ext2: final truncate piece - fix the innd problem. - use "sfence" for x86 memory barrier when available. - remove the thread-group signal code for now: no feedback. Leave the cleanups in place so that we can add it back in cleanly later, but remove the new features. - ARM update. - released for Al Viro to check the truncate thing --- arch/alpha/kernel/entry.S | 2 +- arch/alpha/kernel/signal.c | 14 +- arch/arm/Makefile | 71 +-- arch/arm/boot/Makefile | 4 +- arch/arm/boot/bootp/Makefile | 2 +- arch/arm/boot/bootp/bootp.lds | 30 + arch/arm/boot/compressed/head-ftvpci.S | 40 ++ arch/arm/boot/compressed/head-nexuspci.S | 101 ---- arch/arm/boot/compressed/head.S | 21 +- arch/arm/boot/compressed/setup-sa1100.S | 8 +- arch/arm/kernel/bios32.c | 232 ++------ arch/arm/kernel/dec21285.c | 43 +- arch/arm/kernel/ecard.c | 4 +- arch/arm/kernel/head-armo.S | 6 +- arch/arm/kernel/process.c | 22 +- arch/arm/kernel/ptrace.c | 34 +- arch/arm/kernel/signal.c | 2 +- arch/arm/lib/Makefile | 6 +- arch/arm/lib/copy_page.S | 20 +- arch/arm/lib/delay.S | 1 - arch/arm/lib/memchr.S | 25 +- arch/arm/lib/memcpy.S | 3 - arch/arm/lib/memset.S | 164 +++--- arch/arm/lib/memzero.S | 156 +++--- arch/arm/lib/strchr.S | 11 +- arch/arm/lib/strncpy_from_user.S | 39 ++ arch/arm/lib/strnlen_user.S | 36 ++ arch/arm/lib/strrchr.S | 10 +- arch/arm/lib/uaccess-armo.S | 7 - arch/arm/lib/uaccess.S | 66 --- arch/arm/mach-footbridge/Makefile | 46 ++ arch/arm/mach-footbridge/arch.c | 152 +++++ arch/arm/mach-footbridge/cats-hw.c | 65 +++ arch/arm/mach-footbridge/cats-pci.c | 37 ++ arch/arm/mach-footbridge/ebsa285-leds.c | 136 +++++ arch/arm/mach-footbridge/ebsa285-pci.c | 39 ++ arch/arm/mach-footbridge/netwinder-hw.c | 620 +++++++++++++++++++++ arch/arm/mach-footbridge/netwinder-leds.c | 136 +++++ arch/arm/mach-footbridge/netwinder-pci.c | 54 ++ arch/arm/mach-footbridge/personal-pci.c | 43 ++ arch/arm/tools/mach-types | 5 + arch/arm/vmlinux-armo.lds.in | 5 +- arch/arm/vmlinux-armv.lds.in | 4 +- arch/i386/kernel/i387.c | 3 + arch/i386/kernel/ptrace.c | 5 + arch/ia64/kernel/signal.c | 2 +- arch/m68k/kernel/signal.c | 2 +- arch/mips/kernel/irixelf.c | 2 +- arch/mips/kernel/irixsig.c | 25 +- arch/mips/kernel/signal.c | 2 +- arch/mips64/kernel/signal.c | 2 +- arch/mips64/kernel/signal32.c | 2 +- arch/ppc/kernel/signal.c | 2 +- arch/s390/kernel/signal.c | 2 +- arch/sh/kernel/signal.c | 2 +- arch/sparc/kernel/signal.c | 2 +- arch/sparc64/kernel/signal.c | 2 +- arch/sparc64/kernel/signal32.c | 2 +- arch/sparc64/solaris/signal.c | 2 +- drivers/char/ftape/lowlevel/ftape-ctl.c | 4 +- drivers/char/ftape/lowlevel/ftape-rw.c | 8 +- drivers/char/ftape/lowlevel/ftape-tracing.h | 2 +- drivers/char/rocket.c | 2 +- fs/buffer.c | 48 ++ fs/coda/upcall.c | 4 +- fs/ext2/inode.c | 8 +- fs/smbfs/sock.c | 8 +- include/asm-arm/arch-arc/irq.h | 2 + include/asm-arm/arch-ebsa110/time.h | 1 + include/asm-arm/arch-ebsa285/hardware.h | 15 +- include/asm-arm/arch-ebsa285/uncompress.h | 1 + include/asm-arm/arch-nexuspci/hardware.h | 2 + include/asm-arm/arch-nexuspci/time.h | 1 + include/asm-arm/arch-nexuspci/uncompress.h | 5 +- include/asm-arm/arch-rpc/irq.h | 9 +- include/asm-arm/current.h | 18 +- include/asm-arm/dma.h | 1 + include/asm-arm/mach/arch.h | 84 +++ include/asm-arm/mach/dma.h | 49 ++ include/asm-arm/mach/map.h | 28 + .../kernel/bios32.h => include/asm-arm/mach/pci.h | 13 +- include/asm-arm/mmu_context.h | 10 + include/asm-arm/pci.h | 15 +- include/asm-arm/pgalloc.h | 9 +- include/asm-arm/proc-armo/assembler.h | 22 + include/asm-arm/proc-armo/cache.h | 11 +- include/asm-arm/proc-armo/locks.h | 88 +-- include/asm-arm/proc-armv/assembler.h | 21 + include/asm-arm/proc-armv/system.h | 30 + include/asm-arm/ptrace.h | 10 +- include/asm-arm/scatterlist.h | 20 +- include/asm-arm/shmparam.h | 5 + include/asm-i386/page.h | 2 +- include/asm-i386/system.h | 7 + include/linux/fs.h | 1 + include/linux/sched.h | 22 +- include/linux/signal.h | 2 + kernel/fork.c | 3 - kernel/ksyms.c | 1 + kernel/signal.c | 161 +----- net/ax25/af_ax25.c | 4 +- 101 files changed, 2349 insertions(+), 989 deletions(-) create mode 100644 arch/arm/boot/bootp/bootp.lds create mode 100644 arch/arm/boot/compressed/head-ftvpci.S delete mode 100644 arch/arm/boot/compressed/head-nexuspci.S rewrite arch/arm/lib/memset.S (90%) rewrite arch/arm/lib/memzero.S (91%) create mode 100644 arch/arm/lib/strncpy_from_user.S create mode 100644 arch/arm/lib/strnlen_user.S create mode 100644 arch/arm/mach-footbridge/Makefile create mode 100644 arch/arm/mach-footbridge/arch.c create mode 100644 arch/arm/mach-footbridge/cats-hw.c create mode 100644 arch/arm/mach-footbridge/cats-pci.c create mode 100644 arch/arm/mach-footbridge/ebsa285-leds.c create mode 100644 arch/arm/mach-footbridge/ebsa285-pci.c create mode 100644 arch/arm/mach-footbridge/netwinder-hw.c create mode 100644 arch/arm/mach-footbridge/netwinder-leds.c create mode 100644 arch/arm/mach-footbridge/netwinder-pci.c create mode 100644 arch/arm/mach-footbridge/personal-pci.c create mode 100644 include/asm-arm/mach/arch.h create mode 100644 include/asm-arm/mach/dma.h create mode 100644 include/asm-arm/mach/map.h rename arch/arm/kernel/bios32.h => include/asm-arm/mach/pci.h (67%) diff --git a/arch/alpha/kernel/entry.S b/arch/alpha/kernel/entry.S index 7dda5b566..5035d2ca3 100644 --- a/arch/alpha/kernel/entry.S +++ b/arch/alpha/kernel/entry.S @@ -833,7 +833,7 @@ sys_call_table: .quad alpha_ni_syscall .quad alpha_ni_syscall /* 50 */ .quad sys_acct - .quad osf_sigpending + .quad sys_sigpending .quad alpha_ni_syscall .quad sys_ioctl .quad alpha_ni_syscall /* 55 */ diff --git a/arch/alpha/kernel/signal.c b/arch/alpha/kernel/signal.c index db8cacbc9..73df1e930 100644 --- a/arch/alpha/kernel/signal.c +++ b/arch/alpha/kernel/signal.c @@ -170,18 +170,6 @@ sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact, return ret; } -asmlinkage int -osf_sigpending(old_sigset_t *set) -{ - sigset_t pending; - - spin_lock_irq(¤t->sigmask_lock); - sigandsets(&pending, ¤t->blocked, ¤t->signal); - spin_unlock_irq(¤t->sigmask_lock); - - return copy_to_user(set, &pending, sizeof(*set)); -} - /* * Atomically swap in the new signal mask, and wait for a signal. */ @@ -729,7 +717,7 @@ do_signal(sigset_t *oldset, struct pt_regs * regs, struct switch_stack * sw, default: lock_kernel(); - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); current->flags |= PF_SIGNALED; do_exit(exit_code); /* NOTREACHED */ diff --git a/arch/arm/Makefile b/arch/arm/Makefile index 81b78feb9..d29cf8a75 100644 --- a/arch/arm/Makefile +++ b/arch/arm/Makefile @@ -32,21 +32,21 @@ endif GZFLAGS = -9 # Ensure this is ld "2.9.4" or later -NEW_LINKER := $(shell if $(LD) --gc-sections --version >/dev/null 2>&1; then echo y; else echo n; fi) +NEW_LINKER := $(shell $(LD) --gc-sections --version >/dev/null 2>&1; echo $$?) -ifneq ($(NEW_LINKER),y) +ifneq ($(NEW_LINKER),0) dummy:; @echo '*** ${VERSION}.${PATCHLEVEL} kernels no longer build correctly with old versions of binutils.' @echo '*** Please upgrade your binutils to 2.9.5.' @false endif # GCC 2.7 uses different options to later compilers; sort out which we have -NEW_GCC := $(shell if $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; then echo n; else echo y; fi) +NEW_GCC := $(shell $(CC) --version 2>&1 | grep '^2\.7' > /dev/null; echo $$?) # # select flags depending on the compiler # -ifeq ($(NEW_GCC),y) +ifneq ($(NEW_GCC),0) CFLAGS += -mshort-load-bytes CFLAGS_PROC_CPU_26 := -mcpu=arm3 -mapcs-26 -Os CFLAGS_PROC_CPU_32v3 := -march=armv3 @@ -54,6 +54,7 @@ CFLAGS_PROC_CPU_32v4 := -march=armv4 CFLAGS_ARM6 := -mtune=arm6 CFLAGS_ARM7 := -mtune=arm7 CFLAGS_ARM720 := -mtune=arm7tdmi +CFLAGS_ARM920 := -mtune=arm9tdmi CFLAGS_SA110 := -mtune=strongarm110 else CFLAGS += -DNO_TEXT_SECTIONS @@ -63,6 +64,7 @@ CFLAGS_PROC_CPU_32v4 := CFLAGS_ARM6 := -m6 CFLAGS_ARM7 := -m6 CFLAGS_ARM720 := -m6 +CFLAGS_ARM920 := -m6 CFLAGS_SA110 := -m6 endif @@ -98,6 +100,9 @@ ifeq ($(CONFIG_CPU_32),y) ifeq ($(CONFIG_CPU_ARM720),y) CFLAGS += $(CFLAGS_ARM720) else + ifeq ($(CONFIG_CPU_ARM920),y) + CFLAGS += $(CFLAGS_ARM920) + else ifeq ($(CONFIG_CPU_SA110),y) CFLAGS += $(CFLAGS_SA110) else @@ -108,6 +113,7 @@ ifeq ($(CONFIG_CPU_32),y) endif endif endif + endif endif LIBGCC := $(shell $(CC) $(CFLAGS) --print-libgcc-file-name) @@ -116,51 +122,60 @@ export LIBGCC MACHINE PROCESSOR TEXTADDR GZFLAGS ifeq ($(CONFIG_ARCH_ARCA5K),y) MACHINE = arc -ARCHDIR = arc endif ifeq ($(CONFIG_ARCH_RPC),y) MACHINE = rpc -ARCHDIR = rpc endif ifeq ($(CONFIG_ARCH_EBSA110),y) MACHINE = ebsa110 -ARCHDIR = ebsa110 endif ifeq ($(CONFIG_ARCH_CLPS7500),y) MACHINE = clps7500 -ARCHDIR = cl7500 +INCDIR = cl7500 endif ifeq ($(CONFIG_FOOTBRIDGE),y) MACHINE = footbridge -ARCHDIR = ebsa285 +INCDIR = ebsa285 endif ifeq ($(CONFIG_ARCH_CO285),y) TEXTADDR = 0x60008000 +MACHINE = footbridge +INCDIR = ebsa285 endif ifeq ($(CONFIG_ARCH_NEXUSPCI),y) MACHINE = nexuspci -ARCHDIR = nexuspci endif ifeq ($(CONFIG_ARCH_SHARK),y) MACHINE = shark -ARCHDIR = shark endif ifeq ($(CONFIG_ARCH_SA1100),y) MACHINE = sa1100 -ARCHDIR = sa1100 endif ifeq ($(CONFIG_ARCH_L7200),y) MACHINE = l7200 -ARCHDIR = l7200 +endif + +ifeq ($(CONFIG_ARCH_INTEGRATOR),y) +MACHINE = integrator +endif + +# Only set INCDIR if its not already defined above +INCDIR ?= $(MACHINE) + +# If we have a machine-specific directory, then include it in the build. +MACHDIR := arch/arm/mach-$(MACHINE) +ifeq ($(MACHDIR),$(wildcard $(MACHDIR))) +SUBDIRS += $(MACHDIR) +CORE_FILES := $(MACHDIR)/$(MACHINE).o $(CORE_FILES) endif HEAD := arch/arm/kernel/head-$(PROCESSOR).o \ @@ -193,36 +208,30 @@ MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot # to date before starting compilation $(patsubst %, _dir_%, $(SUBDIRS)) init/main.o init/version.o : \ - constants \ include/asm-arm/mach-types.h -include/asm-arm/mach-types.h: \ - arch/arm/tools/mach-types \ - arch/arm/tools/gen-mach-types +$(patsubst %, _dir_%, $(SUBDIRS)) : constants + +include/asm-arm/mach-types.h: arch/arm/tools/mach-types \ + arch/arm/tools/gen-mach-types @awk -f arch/arm/tools/gen-mach-types arch/arm/tools/mach-types > $@ -constants: $(TOPDIR)/include/asm-arm/proc-fns.h dummy +constants: dummy @$(MAKE) -C arch/arm/lib constants.h symlinks: archsymlinks archsymlinks: $(RM) include/asm-arm/arch include/asm-arm/proc - (cd include/asm-arm; ln -sf arch-$(ARCHDIR) arch; ln -sf proc-$(PROCESSOR) proc) + (cd include/asm-arm; ln -sf arch-$(INCDIR) arch; ln -sf proc-$(PROCESSOR) proc) vmlinux: arch/arm/vmlinux.lds arch/arm/vmlinux.lds: arch/arm/vmlinux-$(PROCESSOR).lds.in dummy @sed 's/TEXTADDR/$(TEXTADDR)/' <$< >$@ -arch/arm/kernel: dummy - $(MAKE) linuxsubdirs SUBDIRS=arch/arm/kernel - -arch/arm/mm: dummy - $(MAKE) linuxsubdirs SUBDIRS=arch/arm/mm - -arch/arm/lib: dummy - $(MAKE) linuxsubdirs SUBDIRS=arch/arm/lib +arch/arm/kernel arch/arm/mm arch/arm/lib: dummy + $(MAKE) CFLAGS="$(CFLAGS) $(CFLAGS_KERNEL)" $(subst $@, _dir_$@, $@) bzImage zImage zinstall Image bootpImage install: vmlinux @$(MAKEBOOT) $@ @@ -235,7 +244,7 @@ archclean: $(RM) arch/arm/lib/constants.h arch/arm/vmlinux.lds $(RM) include/asm-arm/mach-types.h -archdep: symlinks +archdep: archsymlinks @$(MAKEBOOT) dep # My testing targets (that short circuit a few dependencies) @@ -252,7 +261,7 @@ CFGS= a5k_config ebsa110_config \ brutus_config victor_config \ empeg_config thinclient_config \ assabet_config lart_config \ - cerf_config + cerf_config lusl7200_config $(CFGS): @( \ @@ -266,7 +275,3 @@ $(CFGS): echo "$$CFG does not exist"; \ fi; \ ) - -l7200_config: - $(RM) arch/arm/defconfig - cp arch/arm/def-configs/lusl7200 arch/arm/defconfig diff --git a/arch/arm/boot/Makefile b/arch/arm/boot/Makefile index 2811e80ef..54f13eb03 100644 --- a/arch/arm/boot/Makefile +++ b/arch/arm/boot/Makefile @@ -105,10 +105,10 @@ initrd: @test "$(INITRD)" != "" || (echo You must specify INITRD; exit -1) install: $(CONFIGURE) Image - sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) Image $(TOPDIR)/System.map "$(INSTALL_PATH)" + sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) Image $(TOPDIR)/System.map "$(INSTALL_PATH)" zinstall: $(CONFIGURE) zImage - sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" + sh ./install.sh $(VERSION).$(PATCHLEVEL).$(SUBLEVEL)$(EXTRAVERSION) zImage $(TOPDIR)/System.map "$(INSTALL_PATH)" clean: $(RM) Image zImage bootpImage diff --git a/arch/arm/boot/bootp/Makefile b/arch/arm/boot/bootp/Makefile index c513c8ad3..918e3eb9e 100644 --- a/arch/arm/boot/bootp/Makefile +++ b/arch/arm/boot/bootp/Makefile @@ -23,4 +23,4 @@ initrd.o: $(INITRD) .PHONY: $(INITRD) $(ZSYSTEM) -clean:; $(RM) bootp bootp.lds +clean:; $(RM) bootp diff --git a/arch/arm/boot/bootp/bootp.lds b/arch/arm/boot/bootp/bootp.lds new file mode 100644 index 000000000..0d5a3ce75 --- /dev/null +++ b/arch/arm/boot/bootp/bootp.lds @@ -0,0 +1,30 @@ +OUTPUT_ARCH(arm) +ENTRY(_start) +SECTIONS +{ + . = 0; + _text = .; + .text : { + _stext = .; + _start = .; + init.o(.start) + kernel_start = .; + kernel.o + kernel_len = . - kernel_start; + . = ALIGN(32); + *(.text) + initrd_start = .; + initrd.o + initrd_len = . - initrd_start; + . = ALIGN(32); + _etext = .; + } + + .stab 0 : { *(.stab) } + .stabstr 0 : { *(.stabstr) } + .stab.excl 0 : { *(.stab.excl) } + .stab.exclstr 0 : { *(.stab.exclstr) } + .stab.index 0 : { *(.stab.index) } + .stab.indexstr 0 : { *(.stab.indexstr) } + .comment 0 : { *(.comment) } +} diff --git a/arch/arm/boot/compressed/head-ftvpci.S b/arch/arm/boot/compressed/head-ftvpci.S new file mode 100644 index 000000000..a8c806ef3 --- /dev/null +++ b/arch/arm/boot/compressed/head-ftvpci.S @@ -0,0 +1,40 @@ +/* + * linux/arch/arm/boot/compressed/head-ftvpci.S + * + * Copyright (C) 2000 FutureTV Labs Ltd. + * + * Special startup code for FTV PCI board. + */ + + .section ".start", #alloc, #execinstr +ftv_start: + mcr p15, 0, r0, c7, c5, 0 @ flush I cache + mrc p15, 0, r0, c1, c0 + orr r0, r0, #1 << 12 + mcr p15, 0, r0, c1, c0 @ enable I cache + mov r0, #0 + mcreq p15, 0, r0, c15, c1, 2 @ enable clock switching + + /* check to see if the kernel must be relocated */ + ldr ip, =ftv_start + adr sl, ftv_start + teq ip, sl + beq 2f @ no need to copy + + /* in the wrong place -> presumably, executing out of ROM */ + sub ip, ip, sl @ displacement + ldr lr, =_start @ destination + sub sp, lr, ip @ source + ldr fp, =_edata @ end of copied area +1: ldmia sp!, {r0, r1, r2, r3, r4, r5, r6, r10} + stmia lr!, {r0, r1, r2, r3, r4, r5, r6, r10} + cmp lr, fp + ble 1b + +2: + mov r8, #0 + mov r7, #3 + b 1f +.ltorg +1: + /* fall back into head.S */ diff --git a/arch/arm/boot/compressed/head-nexuspci.S b/arch/arm/boot/compressed/head-nexuspci.S deleted file mode 100644 index 1fd49a95c..000000000 --- a/arch/arm/boot/compressed/head-nexuspci.S +++ /dev/null @@ -1,101 +0,0 @@ -/* - * linux/arch/arm/boot/compressed/head-nexuspci.S - * - * Copyright (C) 1996, 1997, 1998 Philip Blundell - * - * NexusPCI is unusual because we don't have a bootloader -- the kernel is - * run directly out of ROM at the moment. Maybe this will change one day and - * then this file can go away. - * - */ - - .text - -.globl _start -_start: b reset - b undefined - b undefined - b undefined - b undefined - b undefined - b undefined - b undefined - b go_uncompress - -reset: mov r2, #0x20000000 @ LED off - mov r1, #0x1a - str r1, [r2] - - mov r2, #0x10000000 @ SCC init - - mov r1, #42 - strb r1, [r2, #8] - - mov r1, #48 - strb r1, [r2, #8] - - mov r1, #16 - strb r1, [r2, #8] - - mov r1, #0x93 - strb r1, [r2, #0] - mov r1, #0x17 - strb r1, [r2, #0] - - mov r1, #0xbb - strb r1, [r2, #0x4] - - mov r1, #0x78 - strb r1, [r2, #0x10] - - mov r1, #160 - strb r1, [r2, #0x8] - - mov r1, #5 - strb r1, [r2, #0x8] - - ldr r2, =_start - ldr r3, =_edata - mov r8, r2 - mov r0, #0 -1: - ldmia r0!, {r4, r5, r6, r7} - stmia r2!, {r4, r5, r6, r7} - cmp r2, r3 - ble 1b - - ldr r3, =_edata - ldr r1, =_end - mov r2, #0 -1: - strb r2, [r3] - cmp r3, r1 - beq 2f - add r3, r3, #1 - b 1b -2: - add pc, r8, #0x20 - -undefined: ldr r4, =undef_msg -1: ldrb r0, [r4], #1 - movs r0, r0 -2: beq 2b - bl _ll_write_char - b 1b - -undef_msg: .ascii "Undefined instruction (or other problem)\000" - .align 4 - -/* - * Uncompress the kernel - */ -go_uncompress: - mov r0, #0x40000000 - ldr sp, =user_stack - add sp, sp, #4096 - bl decompress_kernel - - mov r2, #0x40000000 - mov r0, #0 - mov r1, #3 - add pc, r2, #0x20 @ call via EXEC entry diff --git a/arch/arm/boot/compressed/head.S b/arch/arm/boot/compressed/head.S index ef9090f72..a2c04e036 100644 --- a/arch/arm/boot/compressed/head.S +++ b/arch/arm/boot/compressed/head.S @@ -85,7 +85,7 @@ start: .word 0x016f2818 @ Magic numbers to help the loader .word start 1: mov r7, r1 @ save architecture ID - mov r8, r0 @ save r0 + mov r8, #0 @ save r0 #ifdef CONFIG_ANGELBOOT /* * Booting from Angel - need to enter SVC mode and disable @@ -198,9 +198,10 @@ cache_on: ldr r1, proc_sa110_type 1: sub r3, r4, #16384 @ Page directory size bic r3, r3, #0xff @ Align the pointer - bic r3, r3, #0x3f + bic r3, r3, #0x3f00 /* - * Initialise the page tables + * Initialise the page tables, turning on the cacheable and bufferable + * bits for the RAM area only. */ mov r0, r3 mov r8, r0, lsr #18 @@ -217,6 +218,20 @@ cache_on: ldr r1, proc_sa110_type add r1, r1, #1048576 teq r0, r2 bne 1b +/* + * If ever we are running from Flash, then we surely want the cache + * to be enabled also for our execution instance... We map 2MB of it + * so there is no map overlap problem for up to 1 MB compressed kernel. + * If the execution is in RAM then we would only be duplicating the above. + */ + mov r1, #0x1e + orr r1, r1, #3 << 10 + mov r2, pc, lsr #20 + orr r1, r1, r2, lsl #20 + add r0, r3, r2, lsl #2 + str r1, [r0], #4 + add r1, r1, #1048576 + str r1, [r0] mov r0, #0 mcr p15, 0, r0, c7, c10, 4 @ drain write buffer diff --git a/arch/arm/boot/compressed/setup-sa1100.S b/arch/arm/boot/compressed/setup-sa1100.S index f7657773b..51e684a43 100644 --- a/arch/arm/boot/compressed/setup-sa1100.S +++ b/arch/arm/boot/compressed/setup-sa1100.S @@ -51,6 +51,12 @@ SCR_loc: .long SYMBOL_NAME(SCR_value) * This is called from decompress_kernel() with the arch_decomp_setup() macro. */ +/* + * void sa1100_setup( int arch_id ); + * + * This is called from decompress_kernel() with the arch_decomp_setup() macro. + */ + ENTRY(sa1100_setup) mov r3, r0 @ keep machine type in r3 @@ -138,7 +144,7 @@ skip_uart: @ The machine type is passed in r0 mov r0, r3 #ifdef CONFIG_SA1100_NANOENGINE - teq r0, #32 @ MACH_TYPE_NANOENGINE + teq r0, #MACH_TYPE_NANOENGINE beq SYMBOL_NAME(bse_setup) #endif diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c index 0b519e9c3..57ec33d3d 100644 --- a/arch/arm/kernel/bios32.c +++ b/arch/arm/kernel/bios32.c @@ -10,16 +10,14 @@ #include #include +#include /* for BUG() */ #include #include - -#include "bios32.h" +#include static int debug_pci; int have_isa_bridge; -extern void hw_init(void); - void pcibios_report_status(u_int status_mask, int warn) { struct pci_dev *dev; @@ -157,6 +155,14 @@ static void __init pci_fixup_ide_bases(struct pci_dev *dev) } } +/* + * Put the DEC21142 to sleep + */ +static void __init pci_fixup_dec21142(struct pci_dev *dev) +{ + pci_write_config_dword(dev, 0x40, 0x80000000); +} + struct pci_fixup pcibios_fixups[] = { { PCI_FIXUP_HEADER, @@ -174,6 +180,10 @@ struct pci_fixup pcibios_fixups[] = { PCI_FIXUP_HEADER, PCI_ANY_ID, PCI_ANY_ID, pci_fixup_ide_bases + }, { + PCI_FIXUP_HEADER, + PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142, + pci_fixup_dec21142 }, { 0 } }; @@ -277,12 +287,11 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) * SERR and PERR reporting - this chip doesn't drive the * parity line correctly. */ -#if 1 /* !testing */ if (dev->vendor == PCI_VENDOR_ID_INTERG && dev->device == PCI_DEVICE_ID_INTERG_2000) busdata->features &= ~(PCI_COMMAND_SERR | PCI_COMMAND_PARITY); -#endif + /* * Calculate the maximum devsel latency. */ @@ -319,18 +328,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus) u8 min_gnt, latency; /* - * architecture specific hacks. I don't really want - * this here, but I don't see any other place for it - * to live. Shame the device doesn't support - * capabilities - */ - if (machine_is_netwinder() && - dev->vendor == PCI_VENDOR_ID_DEC && - dev->device == PCI_DEVICE_ID_DEC_21142) - /* Put the chip to sleep in case the driver isn't loaded */ - pci_write_config_dword(dev, 0x40, 0x80000000); - - /* * Calculate this masters latency timer value. * This is rather primitive - it does not take * account of the number of masters in a system @@ -372,184 +369,23 @@ pcibios_fixup_pbus_ranges(struct pci_bus *bus, struct pbus_set_ranges_data *rang ranges->mem_end -= bus->resource[1]->start; } -static u8 __init no_swizzle(struct pci_dev *dev, u8 *pin) +u8 __init no_swizzle(struct pci_dev *dev, u8 *pin) { return 0; } -/* ebsa285 host-specific stuff */ - -#ifdef CONFIG_ARCH_EBSA285 -static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI }; - -static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin) -{ - return PCI_SLOT(dev->devfn); -} - -static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - if (dev->vendor == PCI_VENDOR_ID_CONTAQ && - dev->device == PCI_DEVICE_ID_CONTAQ_82C693) - switch (PCI_FUNC(dev->devfn)) { - case 1: return 14; - case 2: return 15; - case 3: return 12; - } - - return irqmap_ebsa285[(slot + pin) & 3]; -} - -static struct hw_pci ebsa285_pci __initdata = { - dc21285_init, - 0x9000, - 0x00100000, - ebsa285_swizzle, - ebsa285_map_irq -}; -#endif - -#ifdef CONFIG_ARCH_CATS -/* cats host-specific stuff */ -static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; - -static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - if (dev->irq >= 128) - return dev->irq & 0x1f; - - if (dev->irq >= 1 && dev->irq <= 4) - return irqmap_cats[dev->irq - 1]; - - if (dev->irq != 0) - printk("PCI: device %02x:%02x has unknown irq line %x\n", - dev->bus->number, dev->devfn, dev->irq); - - return -1; -} - -static struct hw_pci cats_pci __initdata = { - dc21285_init, - 0x9000, - 0x00100000, - no_swizzle, - cats_map_irq -}; -#endif - -#ifdef CONFIG_ARCH_NETWINDER -/* netwinder host-specific stuff */ -static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ -#define DEV(v,d) ((v)<<16|(d)) - switch (DEV(dev->vendor, dev->device)) { - case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142): - case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C885): - case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_YELLOWFIN): - return IRQ_NETWINDER_ETHER100; - - case DEV(PCI_VENDOR_ID_WINBOND2, 0x5a5a): - return IRQ_NETWINDER_ETHER10; - - case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553): - return 0; - - case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105): - return IRQ_ISA_HARDDISK1; - - case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000): - case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010): - case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000): - return IRQ_NETWINDER_VGA; - - case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285): - return 0; - - default: - printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n", - dev->bus->number, dev->devfn, - dev->vendor, dev->device); - return 0; - } -} - -static struct hw_pci netwinder_pci __initdata = { - dc21285_init, - 0x9000, - 0x00100000, - no_swizzle, - netwinder_map_irq -}; -#endif - -#ifdef CONFIG_ARCH_PERSONAL_SERVER -static int irqmap_personal_server[] __initdata = { - IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0, - IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI -}; - -static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - unsigned char line; - - pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line); - - if (line > 0x40 && line <= 0x5f) { - /* line corresponds to the bit controlling this interrupt - * in the footbridge. Ignore the first 8 interrupt bits, - * look up the rest in the map. IN0 is bit number 8 - */ - return irqmap_personal_server[(line & 0x1f) - 8]; - } else if (line == 0) { - /* no interrupt */ - return 0; - } else - return irqmap_personal_server[(line - 1) & 3]; -} - -static struct hw_pci personal_server_pci __initdata = { - dc21285_init, - 0x9000, - 0x00100000, - no_swizzle, - personal_server_map_irq -}; - -#endif - -#ifdef CONFIG_ARCH_NEXUSPCI -/* - * Owing to a PCB cockup, issue A backplanes are wired thus: - * - * Slot 1 2 3 4 5 Bridge - * IRQ D C B A A - * A D C B B - * B A D C C - * C B A D D - * - * ID A31 A30 A29 A28 A27 A26 - */ - -static int irqmap_ftv[] __initdata = { IRQ_PCI_A, IRQ_PCI_B, IRQ_PCI_C, IRQ_PCI_D }; - -static int __init ftv_map_irq(struct pci_dev *dev, u8 slot, u8 pin) -{ - return irqmap_ftv[(slot + pin) & 3]; -} - -/* ftv host-specific stuff */ -static struct hw_pci ftv_pci __initdata = { - plx90x0_init, - 0x9000, - 0x00100000, - no_swizzle, - ftv_map_irq -}; -#endif +extern struct hw_pci ebsa285_pci; +extern struct hw_pci cats_pci; +extern struct hw_pci netwinder_pci; +extern struct hw_pci personal_server_pci; +extern struct hw_pci ftv_pci; +extern struct hw_pci integrator_pci; void __init pcibios_init(void) { struct hw_pci *hw_pci = NULL; + struct arm_pci_sysdata sysdata; + int i; do { #ifdef CONFIG_ARCH_EBSA285 @@ -582,15 +418,28 @@ void __init pcibios_init(void) break; } #endif - } while (0); +#ifdef CONFIG_ARCH_INTEGRATOR + if (machine_is_integrator()) { + hw_pci = &integrator_pci; + break; + } +#endif + } while (0); if (hw_pci == NULL) return; + for (i = 0; i < MAX_NR_BUS; i++) { + sysdata.bus[i].features = PCI_COMMAND_FAST_BACK | + PCI_COMMAND_SERR | + PCI_COMMAND_PARITY; + sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST; + } + /* * Set up the host bridge, and scan the bus. */ - hw_pci->init(); + hw_pci->init(&sysdata); /* * Other architectures don't seem to do this... should we? @@ -598,8 +447,7 @@ void __init pcibios_init(void) pcibios_claim_resources(); /* - * Assign any unassigned resources. Note that we really ought to - * have min/max stuff here - max mem address is 0x0fffffff + * Assign any unassigned resources. */ pci_assign_unassigned_resources(); pci_fixup_irqs(hw_pci->swizzle, hw_pci->map_irq); diff --git a/arch/arm/kernel/dec21285.c b/arch/arm/kernel/dec21285.c index 3238b3a3c..37957c6e6 100644 --- a/arch/arm/kernel/dec21285.c +++ b/arch/arm/kernel/dec21285.c @@ -17,7 +17,7 @@ #include #include -#include "bios32.h" +#include #define MAX_SLOTS 21 @@ -252,7 +252,7 @@ static void dc21285_parity_irq(int irq, void *dev_id, struct pt_regs *regs) add_timer(timer); } -void __init dc21285_init(void) +void __init dc21285_init(struct arm_pci_sysdata *sysdata) { unsigned long cntl; unsigned int mem_size; @@ -279,19 +279,26 @@ void __init dc21285_init(void) "central function" : "addin"); if (cfn_mode) { - static struct resource csrmem, csrio; - struct arm_pci_sysdata sysdata; - int i; + static struct resource csrmem, csrio, busmem, busmempf; + struct pci_bus *bus; csrio.flags = IORESOURCE_IO; - csrio.name = "DC21285"; + csrio.name = "Footbridge"; csrmem.flags = IORESOURCE_MEM; - csrmem.name = "DC21285"; + csrmem.name = "Footbridge"; + busmem.flags = IORESOURCE_MEM; + busmem.name = "Footbridge non-prefetch"; + busmempf.flags = IORESOURCE_MEM | IORESOURCE_PREFETCH; + busmempf.name = "Footbridge prefetch"; allocate_resource(&ioport_resource, &csrio, 128, 0xff00, 0xffff, 128, NULL, NULL); allocate_resource(&iomem_resource, &csrmem, 128, 0xf4000000, 0xf8000000, 128, NULL, NULL); + allocate_resource(&iomem_resource, &busmempf, 0x20000000, + 0x00000000, 0x80000000, 0x20000000, NULL, NULL); + allocate_resource(&iomem_resource, &busmem, 0x40000000, + 0x00000000, 0x80000000, 0x40000000, NULL, NULL); /* * Map our SDRAM at a known address in PCI space, just in case @@ -302,24 +309,24 @@ void __init dc21285_init(void) *CSR_PCICACHELINESIZE = 0x00002008; *CSR_PCICSRBASE = csrmem.start; *CSR_PCICSRIOBASE = csrio.start; - *CSR_PCISDRAMBASE = virt_to_bus((void *)PAGE_OFFSET); + *CSR_PCISDRAMBASE = __virt_to_bus(PAGE_OFFSET); *CSR_PCIROMBASE = 0; *CSR_PCICMD = pci_cmd | (1 << 31) | (1 << 29) | (1 << 28) | (1 << 24); - for (i = 0; i < MAX_NR_BUS; i++) { - sysdata.bus[i].features = PCI_COMMAND_FAST_BACK | - PCI_COMMAND_SERR | - PCI_COMMAND_PARITY; - sysdata.bus[i].maxdevsel = PCI_STATUS_DEVSEL_FAST; - } - - pci_scan_bus(0, &dc21285_ops, &sysdata); + bus = pci_scan_bus(0, &dc21285_ops, sysdata); + /* + * bus->resource[0] is the IO resource for this bus + * bus->resource[1] is the mem resource for this bus + * bus->resource[2] is the prefetch mem resource for this bus + */ + bus->resource[1] = &busmem; + bus->resource[2] = &busmempf; - pci_cmd |= sysdata.bus[0].features; + pci_cmd |= sysdata->bus[0].features; printk("PCI: Fast back to back transfers %sabled\n", - (sysdata.bus[0].features & PCI_COMMAND_FAST_BACK) ? + (sysdata->bus[0].features & PCI_COMMAND_FAST_BACK) ? "en" : "dis"); /* diff --git a/arch/arm/kernel/ecard.c b/arch/arm/kernel/ecard.c index 6d9b425ea..38fd2a69c 100644 --- a/arch/arm/kernel/ecard.c +++ b/arch/arm/kernel/ecard.c @@ -318,7 +318,7 @@ ecard_task(void * unused) * We don't want /any/ signals, not even SIGKILL */ sigfillset(&tsk->blocked); - sigemptyset(&tsk->signal); + sigemptyset(&tsk->pending.signal); recalc_sigpending(tsk); strcpy(tsk->comm, "kecardd"); @@ -335,7 +335,7 @@ ecard_task(void * unused) req = xchg(&ecard_req, NULL); if (req == NULL) { - sigemptyset(&tsk->signal); + sigemptyset(&tsk->pending.signal); interruptible_sleep_on(&ecard_wait); } } while (req == NULL); diff --git a/arch/arm/kernel/head-armo.S b/arch/arm/kernel/head-armo.S index f0360a3d9..86211a923 100644 --- a/arch/arm/kernel/head-armo.S +++ b/arch/arm/kernel/head-armo.S @@ -72,6 +72,7 @@ detect_arch_type: mov pc, lr detect_proc_type: + mov ip, lr mov r2, #0xea000000 @ Point undef instr to continuation adr r0, continue - 12 orr r0, r2, r0, lsr #2 @@ -80,8 +81,9 @@ detect_proc_type: ldr r0, arm2_id swp r2, r2, [r1] @ check for swp (ARM2 can't) ldr r0, arm250_id - mrc 15, 0, r0, c0, c0 @ check for CP#15 (ARM250 can't) + mrc 15, 0, r3, c0, c0 @ check for CP#15 (ARM250 can't) + mov r0, r3 continue: mov r2, #0xeb000000 @ Make undef vector loop sub r2, r2, #2 str r2, [r1, #4] - mov pc, lr + mov pc, ip diff --git a/arch/arm/kernel/process.c b/arch/arm/kernel/process.c index 478810936..3456df4fd 100644 --- a/arch/arm/kernel/process.c +++ b/arch/arm/kernel/process.c @@ -280,8 +280,8 @@ void exit_thread(void) void flush_thread(void) { - memset(¤t->thread.debug, 0, sizeof(current->thread.debug)); - memset(¤t->thread.fpstate, 0, sizeof(current->thread.fpstate)); + memset(¤t->thread.debug, 0, sizeof(struct debug_info)); + memset(¤t->thread.fpstate, 0, sizeof(union fp_state)); current->used_math = 0; current->flags &= ~PF_USEDFPU; } @@ -326,19 +326,21 @@ int dump_fpu (struct pt_regs *regs, struct user_fp *fp) */ void dump_thread(struct pt_regs * regs, struct user * dump) { + struct task_struct *tsk = current; + dump->magic = CMAGIC; - dump->start_code = current->mm->start_code; + dump->start_code = tsk->mm->start_code; dump->start_stack = regs->ARM_sp & ~(PAGE_SIZE - 1); - dump->u_tsize = (current->mm->end_code - current->mm->start_code) >> PAGE_SHIFT; - dump->u_dsize = (current->mm->brk - current->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT; + dump->u_tsize = (tsk->mm->end_code - tsk->mm->start_code) >> PAGE_SHIFT; + dump->u_dsize = (tsk->mm->brk - tsk->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT; dump->u_ssize = 0; - dump->u_debugreg[0] = current->thread.debug.bp[0].address; - dump->u_debugreg[1] = current->thread.debug.bp[1].address; - dump->u_debugreg[2] = current->thread.debug.bp[0].insn; - dump->u_debugreg[3] = current->thread.debug.bp[1].insn; - dump->u_debugreg[4] = current->thread.debug.nsaved; + dump->u_debugreg[0] = tsk->thread.debug.bp[0].address; + dump->u_debugreg[1] = tsk->thread.debug.bp[1].address; + dump->u_debugreg[2] = tsk->thread.debug.bp[0].insn; + dump->u_debugreg[3] = tsk->thread.debug.bp[1].insn; + dump->u_debugreg[4] = tsk->thread.debug.nsaved; if (dump->start_stack < 0x04000000) dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT; diff --git a/arch/arm/kernel/ptrace.c b/arch/arm/kernel/ptrace.c index e45e03fcb..008b79018 100644 --- a/arch/arm/kernel/ptrace.c +++ b/arch/arm/kernel/ptrace.c @@ -61,9 +61,18 @@ static inline long get_stack_long(struct task_struct *task, int offset) static inline int put_stack_long(struct task_struct *task, int offset, long data) { - get_user_regs(task)->uregs[offset] = data; + struct pt_regs newregs, *regs = get_user_regs(task); + int ret = -EINVAL; + + newregs = *regs; + newregs.uregs[offset] = data; + + if (valid_user_regs(&newregs)) { + regs->uregs[offset] = data; + ret = 0; + } - return 0; + return ret; } static inline int @@ -406,7 +415,7 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat if ((addr & 3) || addr < 0 || addr >= sizeof(struct user)) break; - if (addr < sizeof (struct pt_regs)) + if (addr < sizeof(struct pt_regs)) ret = put_stack_long(child, (int)addr >> 2, data); break; @@ -499,12 +508,19 @@ static int do_ptrace(int request, struct task_struct *child, long addr, long dat * Set all gp regs in the child. */ case PTRACE_SETREGS: { - struct pt_regs *regs = get_user_regs(child); - - ret = 0; - if (copy_from_user(regs, (void *)data, - sizeof(struct pt_regs))) - ret = -EFAULT; + struct pt_regs newregs; + + ret = -EFAULT; + if (copy_from_user(&newregs, (void *)data, + sizeof(struct pt_regs)) == 0) { + struct pt_regs *regs = get_user_regs(child); + + ret = -EINVAL; + if (valid_user_regs(&newregs)) { + *regs = newregs; + ret = 0; + } + } break; } diff --git a/arch/arm/kernel/signal.c b/arch/arm/kernel/signal.c index 5c2e240b7..4b6dbe03a 100644 --- a/arch/arm/kernel/signal.c +++ b/arch/arm/kernel/signal.c @@ -587,7 +587,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index cfa371d5e..bc483bdc9 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -9,9 +9,9 @@ USE_STANDARD_AS_RULE := true L_TARGET := lib.a L_OBJS := changebit.o csumipv6.o csumpartial.o csumpartialcopy.o \ csumpartialcopyuser.o clearbit.o copy_page.o findbit.o \ - memchr.o memcpy.o memset.o memzero.o setbit.o strchr.o \ - strrchr.o testchangebit.o testclearbit.o testsetbit.o \ - uaccess.o + memchr.o memcpy.o memset.o memzero.o setbit.o \ + strncpy_from_user.o strnlen_user.o strchr.o strrchr.o \ + testchangebit.o testclearbit.o testsetbit.o uaccess.o O_TARGET := lib.o O_OBJS := backtrace.o delay.o diff --git a/arch/arm/lib/copy_page.S b/arch/arm/lib/copy_page.S index 16c43268a..e557e35b3 100644 --- a/arch/arm/lib/copy_page.S +++ b/arch/arm/lib/copy_page.S @@ -10,26 +10,26 @@ #include #include "constants.h" - .text + .text + .align 5 /* * StrongARM optimised copy_page routine - * now 1.72bytes/cycle, was 1.60 bytes/cycle - * (50MHz bus -> 86MB/s) + * now 1.78bytes/cycle, was 1.60 bytes/cycle (50MHz bus -> 89MB/s) + * Note that we probably achieve closer to the 100MB/s target with + * the core clock switching. */ - ENTRY(copy_page) stmfd sp!, {r4, lr} @ 2 mov r2, #PAGE_SZ/64 @ 1 -1: ldmia r1!, {r3, r4, ip, lr} @ 4 - subs r2, r2, #1 @ 1 - stmia r0!, {r3, r4, ip, lr} @ 4 ldmia r1!, {r3, r4, ip, lr} @ 4+1 - stmia r0!, {r3, r4, ip, lr} @ 4 +1: stmia r0!, {r3, r4, ip, lr} @ 4 ldmia r1!, {r3, r4, ip, lr} @ 4+1 stmia r0!, {r3, r4, ip, lr} @ 4 ldmia r1!, {r3, r4, ip, lr} @ 4+1 stmia r0!, {r3, r4, ip, lr} @ 4 + ldmia r1!, {r3, r4, ip, lr} @ 4 + subs r2, r2, #1 @ 1 + stmia r0!, {r3, r4, ip, lr} @ 4 + ldmneia r1!, {r3, r4, ip, lr} @ 4 bne 1b @ 1 LOADREGS(fd, sp!, {r4, pc}) @ 3 - - diff --git a/arch/arm/lib/delay.S b/arch/arm/lib/delay.S index 72dab5a95..5c33878d0 100644 --- a/arch/arm/lib/delay.S +++ b/arch/arm/lib/delay.S @@ -40,4 +40,3 @@ ENTRY(__delay) subs r0, r0, #1 bcs SYMBOL_NAME(__delay) RETINSTR(mov,pc,lr) - diff --git a/arch/arm/lib/memchr.S b/arch/arm/lib/memchr.S index d52abe57f..af98017c6 100644 --- a/arch/arm/lib/memchr.S +++ b/arch/arm/lib/memchr.S @@ -1,24 +1,21 @@ /* * linux/arch/arm/lib/memchr.S * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-2000 Russell King * * ASM optimised string functions - * */ #include #include -#include "constants.h" - .text + .text + .align 5 ENTRY(memchr) - str lr, [sp, #-4]! -1: ldrb r3, [r0], #1 - teq r3, r1 - beq 2f - subs r2, r2, #1 - bpl 1b -2: movne r0, #0 - subeq r0, r0, #1 - LOADREGS(fd, sp!, {pc}) - +1: ldrb r3, [r0], #1 + teq r3, r1 + beq 2f + subs r2, r2, #1 + bpl 1b +2: movne r0, #0 + subeq r0, r0, #1 + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/memcpy.S b/arch/arm/lib/memcpy.S index ae5307d4b..87c13f5d8 100644 --- a/arch/arm/lib/memcpy.S +++ b/arch/arm/lib/memcpy.S @@ -4,7 +4,6 @@ * Copyright (C) 1995-1999 Russell King * * ASM optimised string functions - * */ #include #include @@ -314,5 +313,3 @@ ENTRY(memmove) b 24b .align - - diff --git a/arch/arm/lib/memset.S b/arch/arm/lib/memset.S dissimilarity index 90% index b7202e867..286d492b9 100644 --- a/arch/arm/lib/memset.S +++ b/arch/arm/lib/memset.S @@ -1,88 +1,76 @@ -/* - * linux/arch/arm/lib/memset.S - * - * Copyright (C) 1995-1999 Russell King - * - * ASM optimised string functions - * - */ -#include -#include -#include "constants.h" - - .text - .align 5 -ENTRY(memset) - mov r3, r0 - cmp r2, #16 - blt 6f - ands ip, r3, #3 - beq 1f - cmp ip, #2 - strltb r1, [r3], #1 @ Align destination - strleb r1, [r3], #1 - strb r1, [r3], #1 - rsb ip, ip, #4 - sub r2, r2, ip -1: orr r1, r1, r1, lsl #8 - orr r1, r1, r1, lsl #16 - cmp r2, #256 - blt 4f - stmfd sp!, {r4, r5, lr} - mov r4, r1 - mov r5, r1 - mov lr, r1 - mov ip, r2, lsr #6 - sub r2, r2, ip, lsl #6 -2: stmia r3!, {r1, r4, r5, lr} @ 64 bytes at a time. - stmia r3!, {r1, r4, r5, lr} - stmia r3!, {r1, r4, r5, lr} - stmia r3!, {r1, r4, r5, lr} - subs ip, ip, #1 - bne 2b - teq r2, #0 - LOADREGS(eqfd, sp!, {r4, r5, pc}) @ Now <64 bytes to go. - tst r2, #32 - stmneia r3!, {r1, r4, r5, lr} - stmneia r3!, {r1, r4, r5, lr} - tst r2, #16 - stmneia r3!, {r1, r4, r5, lr} - ldmia sp!, {r4, r5} -3: tst r2, #8 - stmneia r3!, {r1, lr} - tst r2, #4 - strne r1, [r3], #4 - tst r2, #2 - strneb r1, [r3], #1 - strneb r1, [r3], #1 - tst r2, #1 - strneb r1, [r3], #1 - LOADREGS(fd, sp!, {pc}) - -4: movs ip, r2, lsr #3 - beq 3b - sub r2, r2, ip, lsl #3 - str lr, [sp, #-4]! - mov lr, r1 - subs ip, ip, #4 -5: stmgeia r3!, {r1, lr} - stmgeia r3!, {r1, lr} - stmgeia r3!, {r1, lr} - stmgeia r3!, {r1, lr} - subges ip, ip, #4 - bge 5b - tst ip, #2 - stmneia r3!, {r1, lr} - stmneia r3!, {r1, lr} - tst ip, #1 - stmneia r3!, {r1, lr} - teq r2, #0 - LOADREGS(eqfd, sp!, {pc}) - b 3b - -6: subs r2, r2, #1 - strgeb r1, [r3], #1 - bgt 6b - RETINSTR(mov, pc, lr) - - +/* + * linux/arch/arm/lib/memset.S + * + * Copyright (C) 1995-2000 Russell King + * + * ASM optimised string functions + */ +#include +#include + + .text + .align 5 + .word 0 + +1: subs r2, r2, #4 @ 1 do we have enough + blt 5f @ 1 bytes to align with? + cmp r3, #2 @ 1 + strltb r1, [r0], #1 @ 1 + strleb r1, [r0], #1 @ 1 + strb r1, [r0], #1 @ 1 + add r2, r2, r3 @ 1 (r2 = r2 - (4 - r3)) +/* + * The pointer is now aligned and the length is adjusted. Try doing the + * memzero again. + */ + +ENTRY(memset) + ands r3, r0, #3 @ 1 unaligned? + bne 1b @ 1 +/* + * we know that the pointer in r0 is aligned to a word boundary. + */ + orr r1, r1, r1, lsl #8 + orr r1, r1, r1, lsl #16 + mov r3, r1 + cmp r2, #16 + blt 4f +/* + * We need an extra register for this loop - save the return address and + * use the LR + */ + str lr, [sp, #-4]! + mov ip, r1 + mov lr, r1 + +2: subs r2, r2, #64 + stmgeia r0!, {r1, r3, ip, lr} @ 64 bytes at a time. + stmgeia r0!, {r1, r3, ip, lr} + stmgeia r0!, {r1, r3, ip, lr} + stmgeia r0!, {r1, r3, ip, lr} + bgt 2b + LOADREGS(eqfd, sp!, {pc}) @ Now <64 bytes to go. +/* + * No need to correct the count; we're only testing bits from now on + */ + tst r2, #32 + stmneia r0!, {r1, r3, ip, lr} + stmneia r0!, {r1, r3, ip, lr} + tst r2, #16 + stmneia r0!, {r1, r3, ip, lr} + ldr lr, [sp], #4 + +4: tst r2, #8 + stmneia r0!, {r1, r3} + tst r2, #4 + strne r1, [r0], #4 +/* + * When we get here, we've got less than 4 bytes to zero. We + * may have an unaligned pointer as well. + */ +5: tst r2, #2 + strneb r1, [r0], #1 + strneb r1, [r0], #1 + tst r2, #1 + strneb r1, [r0], #1 + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/memzero.S b/arch/arm/lib/memzero.S dissimilarity index 91% index 59ec36574..c0a8d1906 100644 --- a/arch/arm/lib/memzero.S +++ b/arch/arm/lib/memzero.S @@ -1,80 +1,76 @@ -/* - * linux/arch/arm/lib/memzero.S - * - * Copyright (C) 1995-1999 Russell King - */ -#include -#include -#include "constants.h" - - .text - -/* - * Prototype: void memzero(void *d, size_t n) - */ -1: @ 4 <= r1 - cmp ip, #2 @ 1 - strltb r2, [r0], #1 @ 1 - strleb r2, [r0], #1 @ 1 - strb r2, [r0], #1 @ 1 - rsb ip, ip, #4 @ 1 - sub r1, r1, ip @ 1 - cmp r1, #3 @ 1 - bgt 2f @ 1 @ +8 - b 4f @ 1 @ +9 - - .align 5 - -ENTRY(__memzero) - mov r2, #0 @ 1 - cmp r1, #4 @ 1 - blt 4f @ 1 @ = 3 - - @ r1 >= 4 - - ands ip, r0, #3 @ 1 - bne 1b @ 1 @ = 5 - -2: @ r1 >= 4 && (r0 & 3) = 0 @ = 5 or 11 - - str lr, [sp, #-4]! @ 1 - mov r3, #0 @ 1 - mov ip, #0 @ 1 - mov lr, #0 @ 1 - - @ 4 <= r1 <= 32 @ = 9 or 15 - -3: subs r1, r1, #32 @ 1 - stmgeia r0!, {r2, r3, ip, lr} @ 4 - stmgeia r0!, {r2, r3, ip, lr} @ 4 - bgt 3b @ 1 - LOADREGS(eqfd, sp!, {pc}) @ 1/2 - - @ -28 <= r1 <= -1 - - cmp r1, #-16 @ 1 - stmgeia r0!, {r2, r3, ip, lr} @ 4 - ldr lr, [sp], #4 @ 1 - addlts r1, r1, #16 @ 1 - RETINSTR(moveq,pc,lr) @ 1 - - @ -12 <= r1 <= -1 - - cmp r1, #-8 @ 1 - stmgeia r0!, {r2, r3} @ 2 - addlts r1, r1, #8 @ 1 - RETINSTR(moveq,pc,lr) @ 1 - - @ -4 <= r1 <= -1 - - cmp r1, #-4 @ 1 - strge r2, [r0], #4 @ 1 - adds r1, r1, #4 @ 1 - RETINSTR(moveq,pc,lr) @ 1 - -4: @ 1 <= r1 <= 3 - cmp r1, #2 @ 1 - strgtb r2, [r0], #1 @ 1 - strgeb r2, [r0], #1 @ 1 - strb r2, [r0], #1 @ 1 - RETINSTR(mov,pc,lr) @ 1 +/* + * linux/arch/arm/lib/memzero.S + * + * Copyright (C) 1995-2000 Russell King + */ +#include +#include + + .text + .align 5 + .word 0 +/* + * Align the pointer in r0. r3 contains the number of bytes that we are + * mis-aligned by, and r1 is the number of bytes. If r1 < 4, then we + * don't bother; we use byte stores instead. + */ +1: subs r1, r1, #4 @ 1 do we have enough + blt 5f @ 1 bytes to align with? + cmp r3, #2 @ 1 + strltb r2, [r0], #1 @ 1 + strleb r2, [r0], #1 @ 1 + strb r2, [r0], #1 @ 1 + add r1, r1, r3 @ 1 (r1 = r1 - (4 - r3)) +/* + * The pointer is now aligned and the length is adjusted. Try doing the + * memzero again. + */ + +ENTRY(__memzero) + mov r2, #0 @ 1 + ands r3, r0, #3 @ 1 unaligned? + bne 1b @ 1 +/* + * r3 = 0, and we know that the pointer in r0 is aligned to a word boundary. + */ + cmp r1, #16 @ 1 we can skip this chunk if we + blt 4f @ 1 have < 16 bytes +/* + * We need an extra register for this loop - save the return address and + * use the LR + */ + str lr, [sp, #-4]! @ 1 + mov ip, r2 @ 1 + mov lr, r2 @ 1 + +3: subs r1, r1, #64 @ 1 write 32 bytes out per loop + stmgeia r0!, {r2, r3, ip, lr} @ 4 + stmgeia r0!, {r2, r3, ip, lr} @ 4 + stmgeia r0!, {r2, r3, ip, lr} @ 4 + stmgeia r0!, {r2, r3, ip, lr} @ 4 + bgt 3b @ 1 + LOADREGS(eqfd, sp!, {pc}) @ 1/2 quick exit +/* + * No need to correct the count; we're only testing bits from now on + */ + tst r1, #32 @ 1 + stmneia r0!, {r2, r3, ip, lr} @ 4 + stmneia r0!, {r2, r3, ip, lr} @ 4 + tst r1, #16 @ 1 16 bytes or more? + stmneia r0!, {r2, r3, ip, lr} @ 4 + ldr lr, [sp], #4 @ 1 + +4: tst r1, #8 @ 1 8 bytes or more? + stmneia r0!, {r2, r3} @ 2 + tst r1, #4 @ 1 4 bytes or more? + strne r2, [r0], #4 @ 1 +/* + * When we get here, we've got less than 4 bytes to zero. We + * may have an unaligned pointer as well. + */ +5: tst r1, #2 @ 1 2 bytes or more? + strneb r2, [r0], #1 @ 1 + strneb r2, [r0], #1 @ 1 + tst r1, #1 @ 1 a byte left over + strneb r2, [r0], #1 @ 1 + RETINSTR(mov,pc,lr) @ 1 diff --git a/arch/arm/lib/strchr.S b/arch/arm/lib/strchr.S index fbde2483f..e00d16cac 100644 --- a/arch/arm/lib/strchr.S +++ b/arch/arm/lib/strchr.S @@ -1,19 +1,16 @@ /* * linux/arch/arm/lib/strchr.S * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-2000 Russell King * * ASM optimised string functions - * */ #include #include -#include "constants.h" .text + .align 5 ENTRY(strchr) - str lr, [sp, #-4]! - mov r3, #0 1: ldrb r2, [r0], #1 teq r2, r1 teqne r2, #0 @@ -21,6 +18,4 @@ ENTRY(strchr) teq r2, #0 moveq r0, #0 subne r0, r0, #1 - LOADREGS(fd, sp!, {pc}) - - + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/strncpy_from_user.S b/arch/arm/lib/strncpy_from_user.S new file mode 100644 index 000000000..4e96f9f2d --- /dev/null +++ b/arch/arm/lib/strncpy_from_user.S @@ -0,0 +1,39 @@ +/* + * linux/arch/arm/lib/strncpy_from_user.S + * + * Copyright (C) 1995-2000 Russell King + */ +#include +#include +#include + + .text + .align 5 + +/* + * Copy a string from user space to kernel space. + * r0 = dst, r1 = src, r2 = byte length + * returns the number of characters copied (strlen of copied string), + * -EFAULT on exception, or "len" if we fill the whole buffer + */ +ENTRY(__arch_strncpy_from_user) + save_lr + mov ip, r1 +1: subs r2, r2, #1 +USER( ldrplbt r3, [r1], #1) + bmi 2f + strb r3, [r0], #1 + teq r3, #0 + bne 1b + sub r1, r1, #1 @ take NUL character out of count +2: sub r0, r1, ip + restore_pc + + .section .fixup,"ax" + .align 0 +9001: mov r3, #0 + strb r3, [r0, #0] @ null terminate + mov r0, #-EFAULT + restore_pc + .previous + diff --git a/arch/arm/lib/strnlen_user.S b/arch/arm/lib/strnlen_user.S new file mode 100644 index 000000000..9542c7c01 --- /dev/null +++ b/arch/arm/lib/strnlen_user.S @@ -0,0 +1,36 @@ +/* + * linux/arch/arm/lib/strnlen_user.S + * + * Copyright (C) 1995-2000 Russell King + */ +#include +#include +#include + + .text + .align 5 + +/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n) + * Purpose : get length of a string in user memory + * Params : str - address of string in user memory + * Returns : length of string *including terminator* + * or zero on exception, or n + 1 if too long + */ +ENTRY(__arch_strnlen_user) + save_lr + mov r2, r0 +1: +USER( ldrbt r3, [r0], #1) + teq r3, #0 + beq 2f + subs r1, r1, #1 + bne 1b + add r0, r0, #1 +2: sub r0, r0, r2 + restore_pc + + .section .fixup,"ax" + .align 0 +9001: mov r0, #0 + restore_pc + .previous diff --git a/arch/arm/lib/strrchr.S b/arch/arm/lib/strrchr.S index c9145d7af..84bc65171 100644 --- a/arch/arm/lib/strrchr.S +++ b/arch/arm/lib/strrchr.S @@ -1,18 +1,16 @@ /* * linux/arch/arm/lib/strrchr.S * - * Copyright (C) 1995-1999 Russell King + * Copyright (C) 1995-2000 Russell King * * ASM optimised string functions - * */ #include #include -#include "constants.h" .text + .align 5 ENTRY(strrchr) - str lr, [sp, #-4]! mov r3, #0 1: ldrb r2, [r0], #1 teq r2, r1 @@ -20,6 +18,4 @@ ENTRY(strrchr) teq r2, #0 bne 1b mov r0, r3 - LOADREGS(fd, sp!, {pc}) - - + RETINSTR(mov,pc,lr) diff --git a/arch/arm/lib/uaccess-armo.S b/arch/arm/lib/uaccess-armo.S index 695fdf0c1..d80ae336f 100644 --- a/arch/arm/lib/uaccess-armo.S +++ b/arch/arm/lib/uaccess-armo.S @@ -11,13 +11,6 @@ .text -#define USER(x...) \ -9999: x; \ - .section __ex_table,"a"; \ - .align 3; \ - .long 9999b,9001f; \ - .previous - .globl SYMBOL_NAME(uaccess_user) SYMBOL_NAME(uaccess_user): .word uaccess_user_put_byte diff --git a/arch/arm/lib/uaccess.S b/arch/arm/lib/uaccess.S index f2ea3231d..508f25209 100644 --- a/arch/arm/lib/uaccess.S +++ b/arch/arm/lib/uaccess.S @@ -13,13 +13,6 @@ .text -#define USER(x...) \ -9999: x; \ - .section __ex_table,"a"; \ - .align 3; \ - .long 9999b,9001f; \ - .previous - #define PAGE_SHIFT 12 /* Prototype: int __arch_copy_to_user(void *to, const char *from, size_t n) @@ -590,62 +583,3 @@ USER( strnebt r2, [r0], #1) 9001: LOADREGS(fd,sp!, {r0, pc}) .previous -/* Prototype: unsigned long __arch_strnlen_user(const char *str, long n) - * Purpose : get length of a string in user memory - * Params : str - address of string in user memory - * Returns : length of string *including terminator* - * or zero on exception, or n + 1 if too long - */ -ENTRY(__arch_strnlen_user) - str lr, [sp, #-4]! - mov r2, r0 -1: -USER( ldrbt r3, [r0], #1) - teq r3, #0 - beq 2f - subs r1, r1, #1 - bne 1b - add r0, r0, #1 -2: sub r0, r0, r2 - LOADREGS(fd,sp!, {pc}) - - .section .fixup,"ax" - .align 0 -9001: mov r0, #0 - LOADREGS(fd,sp!,{pc}) - .previous - -/* Prototype: size_t __arch_strncpy_from_user(char *dst, char *src, size_t len) - * Purpose : copy a string from user memory to kernel memory - * Params : dst - kernel memory destination - * : src - user memory source - * : len - maximum length of string - * Returns : number of characters copied - */ -ENTRY(__arch_strncpy_from_user) - str lr, [sp, #-4]! - add ip, r1, #1 -1: subs r2, r2, #1 - bmi 2f -USER( ldrbt r3, [r1], #1) - strb r3, [r0], #1 - teq r3, #0 - bne 1b - sub r0, r1, ip - LOADREGS(fd, sp!, {pc}) -2: sub ip, ip, #1 - sub r0, r1, ip - LOADREGS(fd, sp!, {pc}) - - .section .fixup,"ax" - .align 0 -9001: mov ip, #0 -1: strb ip, [r0], #1 - subs r2, r2, #1 - bpl 1b - mov r0, #-EFAULT - LOADREGS(fd, sp!, {pc}) - .previous - - .align - diff --git a/arch/arm/mach-footbridge/Makefile b/arch/arm/mach-footbridge/Makefile new file mode 100644 index 000000000..cd6e604ca --- /dev/null +++ b/arch/arm/mach-footbridge/Makefile @@ -0,0 +1,46 @@ +# +# Makefile for the linux kernel. +# +# Note! Dependencies are done automagically by 'make dep', which also +# removes any old dependencies. DON'T put your own dependencies here +# unless it's something special (ie not a .c file). + +O_TARGET := footbridge.o + +# Object file lists. + +obj-y := #arch.o dma.o mm.o +obj-m := +obj-n := +obj- := + +export-objs := netwinder-hw.o + +ifeq ($(CONFIG_PCI),y) +obj-$(CONFIG_ARCH_CATS) += cats-pci.o +obj-$(CONFIG_ARCH_EBSA285) += ebsa285-pci.o +obj-$(CONFIG_ARCH_NETWINDER) += netwinder-pci.o +obj-$(CONFIG_ARCH_PERSONAL_SERVER) += personal-pci.o +endif + +ifeq ($(CONFIG_LEDS),y) +#obj-$(CONFIG_ARCH_CO285) += ebsa285-leds.o +#obj-$(CONFIG_ARCH_EBSA285) += ebsa285-leds.o +#obj-$(CONFIG_ARCH_NETWINDER) += netwinder-leds.o +endif + +#obj-$(CONFIG_ARCH_CATS) += cats-hw.o +#obj-$(CONFIG_ARCH_NETWINDER) += netwinder-hw.o + +# Files that are both resident and modular; remove from modular. + +obj-m := $(filter-out $(obj-y), $(obj-m)) + +# Translate to Rules.make lists. + +O_OBJS := $(filter-out $(export-objs), $(obj-y)) +OX_OBJS := $(filter $(export-objs), $(obj-y)) +M_OBJS := $(sort $(filter-out $(export-objs), $(obj-m))) +MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) + +include $(TOPDIR)/Rules.make diff --git a/arch/arm/mach-footbridge/arch.c b/arch/arm/mach-footbridge/arch.c new file mode 100644 index 000000000..e4cf0d77f --- /dev/null +++ b/arch/arm/mach-footbridge/arch.c @@ -0,0 +1,152 @@ +/* + * linux/arch/arm/mach-footbridge/arch.c + * + * Architecture specific fixups. This is where any + * parameters in the params struct are fixed up, or + * any additional architecture specific information + * is pulled from the params struct. + */ +#include +#include +#include +#include +#include + +#include +#include +#include +#include + +#include + +extern void setup_initrd(unsigned int start, unsigned int size); +extern void setup_ramdisk(int doload, int prompt, int start, unsigned int rd_sz); +extern void __init footbridge_map_io(void); + +#ifdef CONFIG_ARCH_EBSA285 + +static void __init +fixup_ebsa285(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ + ORIG_X = params->u1.s.video_x; + ORIG_Y = params->u1.s.video_y; + ORIG_VIDEO_COLS = params->u1.s.video_num_cols; + ORIG_VIDEO_LINES = params->u1.s.video_num_rows; +} + +MACHINE_START(EBSA285, "EBSA285") + MAINTAINER("Russell King") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + VIDEO(0x000a0000, 0x000bffff) + FIXUP(fixup_ebsa285) + MAPIO(footbridge_map_io) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_NETWINDER +/* + * Older NeTTroms either do not provide a parameters + * page, or they don't supply correct information in + * the parameter page. + */ +static void __init +fixup_netwinder(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ +#ifdef CONFIG_ISAPNP + extern int isapnp_disable; + + /* + * We must not use the kernels ISAPnP code + * on the NetWinder - it will reset the settings + * for the WaveArtist chip and render it inoperable. + */ + isapnp_disable = 1; +#endif + + if (params->u1.s.nr_pages != 0x02000 && + params->u1.s.nr_pages != 0x04000 && + params->u1.s.nr_pages != 0x08000 && + params->u1.s.nr_pages != 0x10000) { + printk(KERN_WARNING "Warning: bad NeTTrom parameters " + "detected, using defaults\n"); + + params->u1.s.nr_pages = 0x2000; /* 32MB */ + params->u1.s.ramdisk_size = 0; + params->u1.s.flags = FLAG_READONLY; + params->u1.s.initrd_start = 0; + params->u1.s.initrd_size = 0; + params->u1.s.rd_start = 0; + } +} + +MACHINE_START(NETWINDER, "Rebel-NetWinder") + MAINTAINER("Russell King/Rebel.com") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + VIDEO(0x000a0000, 0x000bffff) + DISABLE_PARPORT(0) + DISABLE_PARPORT(2) + FIXUP(fixup_netwinder) + MAPIO(footbridge_map_io) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_CATS +/* + * CATS uses soft-reboot by default, since + * hard reboots fail on early boards. + */ +static void __init +fixup_cats(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ + ORIG_VIDEO_LINES = 25; + ORIG_VIDEO_POINTS = 16; + ORIG_Y = 24; +} + +MACHINE_START(CATS, "Chalice-CATS") + MAINTAINER("Philip Blundell") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + SOFT_REBOOT + FIXUP(fixup_cats) + MAPIO(footbridge_map_io) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_CO285 + +static void __init +fixup_coebsa285(struct machine_desc *desc, struct param_struct *params, + char **cmdline, struct meminfo *mi) +{ + extern unsigned long boot_memory_end; + extern char boot_command_line[]; + + mi->nr_banks = 1; + mi->bank[0].start = PHYS_OFFSET; + mi->bank[0].size = boot_memory_end; + mi->bank[0].node = 0; + + *cmdline = boot_command_line; +} + +MACHINE_START(CO285, "co-EBSA285") + MAINTAINER("Mark van Doesburg") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0x7cf00000) + FIXUP(fixup_coebsa285) + MAPIO(footbridge_map_io) +MACHINE_END +#endif + +#ifdef CONFIG_ARCH_PERSONAL_SERVER +MACHINE_START(PERSONAL_SERVER, "Compaq-PersonalServer") + MAINTAINER("Jamey Hicks / George France") + BOOT_MEM(0x00000000, DC21285_ARMCSR_BASE, 0xfe000000) + BOOT_PARAMS(0x00000100) + MAPIO(footbridge_map_io) +MACHINE_END +#endif diff --git a/arch/arm/mach-footbridge/cats-hw.c b/arch/arm/mach-footbridge/cats-hw.c new file mode 100644 index 000000000..160b0307f --- /dev/null +++ b/arch/arm/mach-footbridge/cats-hw.c @@ -0,0 +1,65 @@ +/* + * linux/arch/arm/mach-footbridge/cats-hw.c + * + * CATS machine fixup + * + * Copyright (C) 1998, 1999 Russell King, Phil Blundell + */ +#include +#include +#include +#include + +#include +#include + +#define CFG_PORT 0x370 +#define INDEX_PORT (CFG_PORT) +#define DATA_PORT (CFG_PORT + 1) + +static int __init cats_hw_init(void) +{ + if (machine_is_cats()) { + /* Set Aladdin to CONFIGURE mode */ + outb(0x51, CFG_PORT); + outb(0x23, CFG_PORT); + + /* Select logical device 3 */ + outb(0x07, INDEX_PORT); + outb(0x03, DATA_PORT); + + /* Set parallel port to DMA channel 3, ECP+EPP1.9, + enable EPP timeout */ + outb(0x74, INDEX_PORT); + outb(0x03, DATA_PORT); + + outb(0xf0, INDEX_PORT); + outb(0x0f, DATA_PORT); + + outb(0xf1, INDEX_PORT); + outb(0x07, DATA_PORT); + + /* Select logical device 4 */ + outb(0x07, INDEX_PORT); + outb(0x04, DATA_PORT); + + /* UART1 high speed mode */ + outb(0xf0, INDEX_PORT); + outb(0x02, DATA_PORT); + + /* Select logical device 5 */ + outb(0x07, INDEX_PORT); + outb(0x05, DATA_PORT); + + /* UART2 high speed mode */ + outb(0xf0, INDEX_PORT); + outb(0x02, DATA_PORT); + + /* Set Aladdin to RUN mode */ + outb(0xbb, CFG_PORT); + } + + return 0; +} + +__initcall(cats_hw_init); diff --git a/arch/arm/mach-footbridge/cats-pci.c b/arch/arm/mach-footbridge/cats-pci.c new file mode 100644 index 000000000..1f9e198ba --- /dev/null +++ b/arch/arm/mach-footbridge/cats-pci.c @@ -0,0 +1,37 @@ +/* + * linux/arch/arm/mach-footbridge/cats-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include +#include +#include + +#include +#include + +/* cats host-specific stuff */ +static int irqmap_cats[] __initdata = { IRQ_PCI, IRQ_IN0, IRQ_IN1, IRQ_IN3 }; + +static int __init cats_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (dev->irq >= 128) + return dev->irq & 0x1f; + + if (dev->irq >= 1 && dev->irq <= 4) + return irqmap_cats[dev->irq - 1]; + + if (dev->irq != 0) + printk("PCI: device %02x:%02x has unknown irq line %x\n", + dev->bus->number, dev->devfn, dev->irq); + + return -1; +} + +struct hw_pci cats_pci __initdata = { + init: dc21285_init, + swizzle: no_swizzle, + map_irq: cats_map_irq, +}; diff --git a/arch/arm/mach-footbridge/ebsa285-leds.c b/arch/arm/mach-footbridge/ebsa285-leds.c new file mode 100644 index 000000000..0855da985 --- /dev/null +++ b/arch/arm/mach-footbridge/ebsa285-leds.c @@ -0,0 +1,136 @@ +/* + * linux/arch/arm/mach-footbridge/ebsa285-leds.c + * + * Copyright (C) 1998-1999 Russell King + * + * EBSA-285 control routines. + * + * The EBSA-285 uses the leds as follows: + * - Green - toggles state every 50 timer interrupts + * - Amber - On if system is not idle + * - Red - currently unused + * + * Changelog: + * 02-05-1999 RMK Various cleanups + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 +static char led_state; +static char hw_led_state; + +static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED; + +static void ebsa285_leds_event(led_event_t evt) +{ + unsigned long flags; + + spin_lock_irqsave(&leds_lock, flags); + + switch (evt) { + case led_start: + hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN; +#ifndef CONFIG_LEDS_CPU + hw_led_state |= XBUS_LED_AMBER; +#endif + led_state |= LED_STATE_ENABLED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = XBUS_LED_RED | XBUS_LED_GREEN | XBUS_LED_AMBER; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= XBUS_LED_GREEN; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= XBUS_LED_AMBER; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~XBUS_LED_AMBER; + break; +#endif + + case led_halted: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~XBUS_LED_RED; + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~XBUS_LED_GREEN; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= XBUS_LED_GREEN; + break; + + case led_amber_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~XBUS_LED_AMBER; + break; + + case led_amber_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= XBUS_LED_AMBER; + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~XBUS_LED_RED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= XBUS_LED_RED; + break; + + default: + break; + } + + if (led_state & LED_STATE_ENABLED) + *XBUS_LEDS = hw_led_state; + + spin_unlock_irqrestore(&leds_lock, flags); +} + +static int __init leds_init(void) +{ + if (machine_is_ebsa285() || machine_is_co285()) + leds_event = ebsa285_leds_event; + + leds_event(led_start); + + return 0; +} + +__initcall(leds_init); diff --git a/arch/arm/mach-footbridge/ebsa285-pci.c b/arch/arm/mach-footbridge/ebsa285-pci.c new file mode 100644 index 000000000..304079040 --- /dev/null +++ b/arch/arm/mach-footbridge/ebsa285-pci.c @@ -0,0 +1,39 @@ +/* + * linux/arch/arm/mach-footbridge/ebsa285-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include +#include +#include + +#include +#include + +static int irqmap_ebsa285[] __initdata = { IRQ_IN3, IRQ_IN1, IRQ_IN0, IRQ_PCI }; + +static u8 __init ebsa285_swizzle(struct pci_dev *dev, u8 *pin) +{ + return PCI_SLOT(dev->devfn); +} + +static int __init ebsa285_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + if (dev->vendor == PCI_VENDOR_ID_CONTAQ && + dev->device == PCI_DEVICE_ID_CONTAQ_82C693) + switch (PCI_FUNC(dev->devfn)) { + case 1: return 14; + case 2: return 15; + case 3: return 12; + } + + return irqmap_ebsa285[(slot + pin) & 3]; +} + +struct hw_pci ebsa285_pci __initdata = { + init: dc21285_init, + swizzle: ebsa285_swizzle, + map_irq: ebsa285_map_irq, +}; diff --git a/arch/arm/mach-footbridge/netwinder-hw.c b/arch/arm/mach-footbridge/netwinder-hw.c new file mode 100644 index 000000000..c1b9c9b10 --- /dev/null +++ b/arch/arm/mach-footbridge/netwinder-hw.c @@ -0,0 +1,620 @@ +/* + * linux/arch/arm/mach-footbridge/netwinder-hw.c + * + * Netwinder machine fixup + * + * Copyright (C) 1998, 1999 Russell King, Phil Blundell + */ +#include +#include +#include +#include +#include +#include + +#include +#include +#include + +#define IRDA_IO_BASE 0x180 +#define GP1_IO_BASE 0x338 +#define GP2_IO_BASE 0x33a + + +#ifdef CONFIG_LEDS +#define DEFAULT_LEDS 0 +#else +#define DEFAULT_LEDS GPIO_GREEN_LED +#endif + +/* + * Winbond WB83977F accessibility stuff + */ +static inline void wb977_open(void) +{ + outb(0x87, 0x370); + outb(0x87, 0x370); +} + +static inline void wb977_close(void) +{ + outb(0xaa, 0x370); +} + +static inline void wb977_wb(int reg, int val) +{ + outb(reg, 0x370); + outb(val, 0x371); +} + +static inline void wb977_ww(int reg, int val) +{ + outb(reg, 0x370); + outb(val >> 8, 0x371); + outb(reg + 1, 0x370); + outb(val, 0x371); +} + +#define wb977_device_select(dev) wb977_wb(0x07, dev) +#define wb977_device_disable() wb977_wb(0x30, 0x00) +#define wb977_device_enable() wb977_wb(0x30, 0x01) + +/* + * This is a lock for accessing ports GP1_IO_BASE and GP2_IO_BASE + */ +spinlock_t gpio_lock = SPIN_LOCK_UNLOCKED; + +static unsigned int current_gpio_op = 0; +static unsigned int current_gpio_io = 0; +static unsigned int current_cpld = 0; + +void gpio_modify_op(int mask, int set) +{ + unsigned int new_gpio, changed; + + new_gpio = (current_gpio_op & ~mask) | set; + changed = new_gpio ^ current_gpio_op; + current_gpio_op = new_gpio; + + if (changed & 0xff) + outb(new_gpio, GP1_IO_BASE); + if (changed & 0xff00) + outb(new_gpio >> 8, GP2_IO_BASE); +} + +static inline void __gpio_modify_io(int mask, int in) +{ + unsigned int new_gpio, changed; + int port; + + new_gpio = (current_gpio_io & ~mask) | in; + changed = new_gpio ^ current_gpio_io; + current_gpio_io = new_gpio; + + changed >>= 1; + new_gpio >>= 1; + + wb977_device_select(7); + + for (port = 0xe1; changed && port < 0xe8; changed >>= 1) { + wb977_wb(port, new_gpio & 1); + + port += 1; + new_gpio >>= 1; + } + + wb977_device_select(8); + + for (port = 0xe8; changed && port < 0xec; changed >>= 1) { + wb977_wb(port, new_gpio & 1); + + port += 1; + new_gpio >>= 1; + } +} + +void gpio_modify_io(int mask, int in) +{ + /* Open up the SuperIO chip */ + wb977_open(); + + __gpio_modify_io(mask, in); + + /* Close up the EFER gate */ + wb977_close(); +} + +int gpio_read(void) +{ + return inb(GP1_IO_BASE) | inb(GP2_IO_BASE) << 8; +} + +/* + * Initialise the Winbond W83977F global registers + */ +static inline void wb977_init_global(void) +{ + /* + * Enable R/W config registers + */ + wb977_wb(0x26, 0x40); + + /* + * Power down FDC (not used) + */ + wb977_wb(0x22, 0xfe); + + /* + * GP12, GP11, CIRRX, IRRXH, GP10 + */ + wb977_wb(0x2a, 0xc1); + + /* + * GP23, GP22, GP21, GP20, GP13 + */ + wb977_wb(0x2b, 0x6b); + + /* + * GP17, GP16, GP15, GP14 + */ + wb977_wb(0x2c, 0x55); +} + +/* + * Initialise the Winbond W83977F printer port + */ +static inline void wb977_init_printer(void) +{ + wb977_device_select(1); + + /* + * mode 1 == EPP + */ + wb977_wb(0xf0, 0x01); +} + +/* + * Initialise the Winbond W83977F keyboard controller + */ +static inline void wb977_init_keyboard(void) +{ + wb977_device_select(5); + + /* + * Keyboard controller address + */ + wb977_ww(0x60, 0x0060); + wb977_ww(0x62, 0x0064); + + /* + * Keyboard IRQ 1, active high, edge trigger + */ + wb977_wb(0x70, 1); + wb977_wb(0x71, 0x02); + + /* + * Mouse IRQ 5, active high, edge trigger + */ + wb977_wb(0x72, 5); + wb977_wb(0x73, 0x02); + + /* + * KBC 8MHz + */ + wb977_wb(0xf0, 0x40); + + /* + * Enable device + */ + wb977_device_enable(); +} + +/* + * Initialise the Winbond W83977F Infra-Red device + */ +static inline void wb977_init_irda(void) +{ + wb977_device_select(6); + + /* + * IR base address + */ + wb977_ww(0x60, IRDA_IO_BASE); + + /* + * IRDA IRQ 6, active high, edge trigger + */ + wb977_wb(0x70, 6); + wb977_wb(0x71, 0x02); + + /* + * RX DMA - ISA DMA 0 + */ + wb977_wb(0x74, 0x00); + + /* + * TX DMA - Disable Tx DMA + */ + wb977_wb(0x75, 0x04); + + /* + * Append CRC, Enable bank selection + */ + wb977_wb(0xf0, 0x03); + + /* + * Enable device + */ + wb977_device_enable(); +} + +/* + * Initialise Winbond W83977F general purpose IO + */ +static inline void wb977_init_gpio(void) +{ + unsigned long flags; + + /* + * Set up initial I/O definitions + */ + current_gpio_io = -1; + __gpio_modify_io(-1, GPIO_DONE | GPIO_WDTIMER); + + wb977_device_select(7); + + /* + * Group1 base address + */ + wb977_ww(0x60, GP1_IO_BASE); + wb977_ww(0x62, 0); + wb977_ww(0x64, 0); + + /* + * GP10 (Orage button) IRQ 10, active high, edge trigger + */ + wb977_wb(0x70, 10); + wb977_wb(0x71, 0x02); + + /* + * GP10: Debounce filter enabled, IRQ, input + */ + wb977_wb(0xe0, 0x19); + + /* + * Enable Group1 + */ + wb977_device_enable(); + + wb977_device_select(8); + + /* + * Group2 base address + */ + wb977_ww(0x60, GP2_IO_BASE); + + /* + * Clear watchdog timer regs + * - timer disable + */ + wb977_wb(0xf2, 0x00); + + /* + * - disable LED, no mouse nor keyboard IRQ + */ + wb977_wb(0xf3, 0x00); + + /* + * - timer counting, disable power LED, disable timeouot + */ + wb977_wb(0xf4, 0x00); + + /* + * Enable group2 + */ + wb977_device_enable(); + + /* + * Set Group1/Group2 outputs + */ + spin_lock_irqsave(&gpio_lock, flags); + gpio_modify_op(-1, GPIO_RED_LED | GPIO_FAN); + spin_unlock_irqrestore(&gpio_loc, flags); +} + +/* + * Initialise the Winbond W83977F chip. + */ +static void __init wb977_init(void) +{ + request_region(0x370, 2, "W83977AF configuration"); + + /* + * Open up the SuperIO chip + */ + wb977_open(); + + /* + * Initialise the global registers + */ + wb977_init_global(); + + /* + * Initialise the various devices in + * the multi-IO chip. + */ + wb977_init_printer(); + wb977_init_keyboard(); + wb977_init_irda(); + wb977_init_gpio(); + + /* + * Close up the EFER gate + */ + wb977_close(); +} + +void cpld_modify(int mask, int set) +{ + int msk; + + current_cpld = (current_cpld & ~mask) | set; + + gpio_modify_io(GPIO_DATA | GPIO_IOCLK | GPIO_IOLOAD, 0); + gpio_modify_op(GPIO_IOLOAD, 0); + + for (msk = 8; msk; msk >>= 1) { + int bit = current_cpld & msk; + + gpio_modify_op(GPIO_DATA | GPIO_IOCLK, bit ? GPIO_DATA : 0); + gpio_modify_op(GPIO_IOCLK, GPIO_IOCLK); + } + + gpio_modify_op(GPIO_IOCLK|GPIO_DATA, 0); + gpio_modify_op(GPIO_IOLOAD|GPIO_DSCLK, GPIO_IOLOAD|GPIO_DSCLK); + gpio_modify_op(GPIO_IOLOAD, 0); +} + +static void __init cpld_init(void) +{ + unsigned long flags; + + spin_lock_irqsave(&gpio_lock, flags); + cpld_modify(-1, CPLD_UNMUTE | CPLD_7111_DISABLE); + spin_unlock_irqrestore(&gpio_lock, flags); +} + +static unsigned char rwa_unlock[] __initdata = +{ 0x00, 0x00, 0x6a, 0xb5, 0xda, 0xed, 0xf6, 0xfb, 0x7d, 0xbe, 0xdf, 0x6f, 0x37, 0x1b, + 0x0d, 0x86, 0xc3, 0x61, 0xb0, 0x58, 0x2c, 0x16, 0x8b, 0x45, 0xa2, 0xd1, 0xe8, 0x74, + 0x3a, 0x9d, 0xce, 0xe7, 0x73, 0x39 }; + +#ifndef DEBUG +#define dprintk(x...) +#else +#define dprintk(x...) printk(x) +#endif + +#define WRITE_RWA(r,v) do { outb((r), 0x279); udelay(10); outb((v), 0xa79); } while (0) + +static inline void rwa010_unlock(void) +{ + int i; + + WRITE_RWA(2, 2); + mdelay(10); + + for (i = 0; i < sizeof(rwa_unlock); i++) { + outb(rwa_unlock[i], 0x279); + udelay(10); + } +} + +static inline void rwa010_read_ident(void) +{ + unsigned char si[9]; + int i, j; + + WRITE_RWA(3, 0); + WRITE_RWA(0, 128); + + outb(1, 0x279); + + mdelay(1); + + dprintk("Identifier: "); + for (i = 0; i < 9; i++) { + si[i] = 0; + for (j = 0; j < 8; j++) { + int bit; + udelay(250); + inb(0x203); + udelay(250); + bit = inb(0x203); + dprintk("%02X ", bit); + bit = (bit == 0xaa) ? 1 : 0; + si[i] |= bit << j; + } + dprintk("(%02X) ", si[i]); + } + dprintk("\n"); +} + +static inline void rwa010_global_init(void) +{ + WRITE_RWA(6, 2); // Assign a card no = 2 + + dprintk("Card no = %d\n", inb(0x203)); + + /* disable the modem section of the chip */ + WRITE_RWA(7, 3); + WRITE_RWA(0x30, 0); + + /* disable the cdrom section of the chip */ + WRITE_RWA(7, 4); + WRITE_RWA(0x30, 0); + + /* disable the MPU-401 section of the chip */ + WRITE_RWA(7, 2); + WRITE_RWA(0x30, 0); +} + +static inline void rwa010_game_port_init(void) +{ + int i; + + WRITE_RWA(7, 5); + + dprintk("Slider base: "); + WRITE_RWA(0x61, 1); + i = inb(0x203); + + WRITE_RWA(0x60, 2); + dprintk("%02X%02X (201)\n", inb(0x203), i); + + WRITE_RWA(0x30, 1); +} + +static inline void rwa010_waveartist_init(int base, int irq, int dma) +{ + int i; + + WRITE_RWA(7, 0); + + dprintk("WaveArtist base: "); + WRITE_RWA(0x61, base); + i = inb(0x203); + + WRITE_RWA(0x60, base >> 8); + dprintk("%02X%02X (%X),", inb(0x203), i, base); + + WRITE_RWA(0x70, irq); + dprintk(" irq: %d (%d),", inb(0x203), irq); + + WRITE_RWA(0x74, dma); + dprintk(" dma: %d (%d)\n", inb(0x203), dma); + + WRITE_RWA(0x30, 1); +} + +static inline void rwa010_soundblaster_init(int sb_base, int al_base, int irq, int dma) +{ + int i; + + WRITE_RWA(7, 1); + + dprintk("SoundBlaster base: "); + WRITE_RWA(0x61, sb_base); + i = inb(0x203); + + WRITE_RWA(0x60, sb_base >> 8); + dprintk("%02X%02X (%X),", inb(0x203), i, sb_base); + + dprintk(" irq: "); + WRITE_RWA(0x70, irq); + dprintk("%d (%d),", inb(0x203), irq); + + dprintk(" 8-bit DMA: "); + WRITE_RWA(0x74, dma); + dprintk("%d (%d)\n", inb(0x203), dma); + + dprintk("AdLib base: "); + WRITE_RWA(0x63, al_base); + i = inb(0x203); + + WRITE_RWA(0x62, al_base >> 8); + dprintk("%02X%02X (%X)\n", inb(0x203), i, al_base); + + WRITE_RWA(0x30, 1); +} + +static void rwa010_soundblaster_reset(void) +{ + int i; + + outb(1, 0x226); + udelay(3); + outb(0, 0x226); + + for (i = 0; i < 5; i++) { + if (inb(0x22e) & 0x80) + break; + mdelay(1); + } + if (i == 5) + printk("SoundBlaster: DSP reset failed\n"); + + dprintk("SoundBlaster DSP reset: %02X (AA)\n", inb(0x22a)); + + for (i = 0; i < 5; i++) { + if ((inb(0x22c) & 0x80) == 0) + break; + mdelay(1); + } + + if (i == 5) + printk("SoundBlaster: DSP not ready\n"); + else { + outb(0xe1, 0x22c); + + dprintk("SoundBlaster DSP id: "); + i = inb(0x22a); + udelay(1); + i |= inb(0x22a) << 8; + dprintk("%04X\n", i); + + for (i = 0; i < 5; i++) { + if ((inb(0x22c) & 0x80) == 0) + break; + mdelay(1); + } + + if (i == 5) + printk("SoundBlaster: could not turn speaker off\n"); + + outb(0xd3, 0x22c); + } + + /* turn on OPL3 */ + outb(5, 0x38a); + outb(1, 0x38b); +} + +static void __init rwa010_init(void) +{ + rwa010_unlock(); + rwa010_read_ident(); + rwa010_global_init(); + rwa010_game_port_init(); + rwa010_waveartist_init(0x250, 3, 7); + rwa010_soundblaster_init(0x220, 0x388, 3, 1); + rwa010_soundblaster_reset(); +} + +EXPORT_SYMBOL(gpio_lock); +EXPORT_SYMBOL(gpio_modify_op); +EXPORT_SYMBOL(gpio_modify_io); +EXPORT_SYMBOL(cpld_modify); + +/* + * Initialise any other hardware after we've got the PCI bus + * initialised. We may need the PCI bus to talk to this other + * hardware. + */ +static int __init nw_hw_init(void) +{ + if (machine_is_netwinder()) { + unsigned long flags; + + wb977_init(); + cpld_init(); + rwa010_init(); + + spin_lock_irqsave(&gpio_lock, flags); + gpio_modify_op(GPIO_RED_LED|GPIO_GREEN_LED, DEFAULT_LEDS); + spin_unlock_irqrestore(&gpio_lock, flags); + } + return 0; +} + +__initcall(nw_hw_init); diff --git a/arch/arm/mach-footbridge/netwinder-leds.c b/arch/arm/mach-footbridge/netwinder-leds.c new file mode 100644 index 000000000..9d39073ab --- /dev/null +++ b/arch/arm/mach-footbridge/netwinder-leds.c @@ -0,0 +1,136 @@ +/* + * linux/arch/arm/mach-footbridge/netwinder-leds.c + * + * Copyright (C) 1998-1999 Russell King + * + * NetWinder LED control routines. + * + * The Netwinder uses the leds as follows: + * - Green - toggles state every 50 timer interrupts + * - Red - On if the system is not idle + * + * Changelog: + * 02-05-1999 RMK Various cleanups + */ +#include +#include +#include +#include + +#include +#include +#include +#include + +#define LED_STATE_ENABLED 1 +#define LED_STATE_CLAIMED 2 +static char led_state; +static char hw_led_state; + +static spinlock_t leds_lock = SPIN_LOCK_UNLOCKED; +extern spinlock_t gpio_lock; + +static void netwinder_leds_event(led_event_t evt) +{ + unsigned long flags; + + spin_lock_irqsave(&leds_lock, flags); + + switch (evt) { + case led_start: + led_state |= LED_STATE_ENABLED; + hw_led_state = GPIO_GREEN_LED; + break; + + case led_stop: + led_state &= ~LED_STATE_ENABLED; + break; + + case led_claim: + led_state |= LED_STATE_CLAIMED; + hw_led_state = 0; + break; + + case led_release: + led_state &= ~LED_STATE_CLAIMED; + hw_led_state = 0; + break; + +#ifdef CONFIG_LEDS_TIMER + case led_timer: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state ^= GPIO_GREEN_LED; + break; +#endif + +#ifdef CONFIG_LEDS_CPU + case led_idle_start: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state &= ~GPIO_RED_LED; + break; + + case led_idle_end: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= GPIO_RED_LED; + break; +#endif + + case led_halted: + if (!(led_state & LED_STATE_CLAIMED)) + hw_led_state |= GPIO_RED_LED; + break; + + case led_green_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= GPIO_GREEN_LED; + break; + + case led_green_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~GPIO_GREEN_LED; + break; + + case led_amber_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= GPIO_GREEN_LED | GPIO_RED_LED; + break; + + case led_amber_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~(GPIO_GREEN_LED | GPIO_RED_LED); + break; + + case led_red_on: + if (led_state & LED_STATE_CLAIMED) + hw_led_state |= GPIO_RED_LED; + break; + + case led_red_off: + if (led_state & LED_STATE_CLAIMED) + hw_led_state &= ~GPIO_RED_LED; + break; + + default: + break; + } + + spin_unlock_irqrestore(&leds_lock, flags); + + if (led_state & LED_STATE_ENABLED) { + spin_lock_irqsave(&gpio_lock, flags); + gpio_modify_op(GPIO_RED_LED | GPIO_GREEN_LED, hw_led_state); + spin_unlock_irqrestore(&gpio_lock, flags); + } +} + +static int __init leds_init(void) +{ + if (machine_is_netwinder()) + leds_event = netwinder_leds_event; + + leds_event(led_start); + + return 0; +} + +__initcall(leds_init); diff --git a/arch/arm/mach-footbridge/netwinder-pci.c b/arch/arm/mach-footbridge/netwinder-pci.c new file mode 100644 index 000000000..6bad74680 --- /dev/null +++ b/arch/arm/mach-footbridge/netwinder-pci.c @@ -0,0 +1,54 @@ +/* + * linux/arch/arm/mach-footbridge/netwinder-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include +#include +#include + +#include +#include + +/* netwinder host-specific stuff */ +static int __init netwinder_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ +#define DEV(v,d) ((v)<<16|(d)) + switch (DEV(dev->vendor, dev->device)) { + case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21142): + case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_53C885): + case DEV(PCI_VENDOR_ID_NCR, PCI_DEVICE_ID_NCR_YELLOWFIN): + return IRQ_NETWINDER_ETHER100; + + case DEV(PCI_VENDOR_ID_WINBOND2, 0x5a5a): + return IRQ_NETWINDER_ETHER10; + + case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_83C553): + return 0; + + case DEV(PCI_VENDOR_ID_WINBOND, PCI_DEVICE_ID_WINBOND_82C105): + return IRQ_ISA_HARDDISK1; + + case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2000): + case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_2010): + case DEV(PCI_VENDOR_ID_INTERG, PCI_DEVICE_ID_INTERG_5000): + return IRQ_NETWINDER_VGA; + + case DEV(PCI_VENDOR_ID_DEC, PCI_DEVICE_ID_DEC_21285): + return 0; + + default: + printk(KERN_ERR "PCI: %02X:%02X [%04X:%04X] unknown device\n", + dev->bus->number, dev->devfn, + dev->vendor, dev->device); + return 0; + } +} + +struct hw_pci netwinder_pci __initdata = { + init: dc21285_init, + swizzle: no_swizzle, + map_irq: netwinder_map_irq, +}; diff --git a/arch/arm/mach-footbridge/personal-pci.c b/arch/arm/mach-footbridge/personal-pci.c new file mode 100644 index 000000000..8d810a22f --- /dev/null +++ b/arch/arm/mach-footbridge/personal-pci.c @@ -0,0 +1,43 @@ +/* + * linux/arch/arm/mach-footbridge/personal-pci.c + * + * PCI bios-type initialisation for PCI machines + * + * Bits taken from various places. + */ +#include +#include +#include + +#include +#include + +static int irqmap_personal_server[] __initdata = { + IRQ_IN0, IRQ_IN1, IRQ_IN2, IRQ_IN3, 0, 0, 0, + IRQ_DOORBELLHOST, IRQ_DMA1, IRQ_DMA2, IRQ_PCI +}; + +static int __init personal_server_map_irq(struct pci_dev *dev, u8 slot, u8 pin) +{ + unsigned char line; + + pci_read_config_byte(dev, PCI_INTERRUPT_LINE, &line); + + if (line > 0x40 && line <= 0x5f) { + /* line corresponds to the bit controlling this interrupt + * in the footbridge. Ignore the first 8 interrupt bits, + * look up the rest in the map. IN0 is bit number 8 + */ + return irqmap_personal_server[(line & 0x1f) - 8]; + } else if (line == 0) { + /* no interrupt */ + return 0; + } else + return irqmap_personal_server[(line - 1) & 3]; +} + +struct hw_pci personal_server_pci __initdata = { + init: dc21285_init, + swizzle: no_swizzle, + map_irq: personal_server_map_irq, +}; diff --git a/arch/arm/tools/mach-types b/arch/arm/tools/mach-types index b922786e3..f3d1fb0b1 100644 --- a/arch/arm/tools/mach-types +++ b/arch/arm/tools/mach-types @@ -37,6 +37,11 @@ graphicsclient SA1100_GRAPHICSCLIENT GRAPHICSCLIENT 29 xp860 SA1100_XP860 XP860 30 cerf SA1100_CERF CERF 31 nanoengine SA1100_NANOENGINE NANOENGINE 32 +fpic SA1100_FPIC FPIC 33 +extenex1 SA1100_EXTENEX1 EXTENEX1 34 +sherman SA1100_SHERMAN SHERMAN 35 +accelent_sa SA1100_ACCELENT ACCELENT_SA 36 +accelent_l7200 ARCH_L7200_ACCELENT ACCELENT_L7200 37 # The following are unallocated empeg SA1100_EMPEG EMPEG diff --git a/arch/arm/vmlinux-armo.lds.in b/arch/arm/vmlinux-armo.lds.in index 656779195..5353e7f8f 100644 --- a/arch/arm/vmlinux-armo.lds.in +++ b/arch/arm/vmlinux-armo.lds.in @@ -79,9 +79,10 @@ SECTIONS .bss : { - __bss_start = .; /* BSS */ + __bss_start = .; /* BSS */ *(.bss) - _end = . ; + *(COMMON) + _end = . ; } /* Stabs debugging sections. */ diff --git a/arch/arm/vmlinux-armv.lds.in b/arch/arm/vmlinux-armv.lds.in index 4ef7377bb..b54f2bd92 100644 --- a/arch/arm/vmlinux-armv.lds.in +++ b/arch/arm/vmlinux-armv.lds.in @@ -42,8 +42,8 @@ SECTIONS *(.text.lock) /* out-of-line lock text */ *(.rodata) *(.kstrtab) - . = ALIGN(16); /* Exception table */ - __start___ex_table = .; + . = ALIGN(16); + __start___ex_table = .; /* Exception table */ *(__ex_table) __stop___ex_table = .; diff --git a/arch/i386/kernel/i387.c b/arch/i386/kernel/i387.c index b71cf06f6..b264c54a3 100644 --- a/arch/i386/kernel/i387.c +++ b/arch/i386/kernel/i387.c @@ -279,6 +279,7 @@ static inline int save_i387_fsave( struct _fpstate *buf ) { struct task_struct *tsk = current; + unlazy_fpu( tsk ); tsk->thread.i387.fsave.status = tsk->thread.i387.fsave.swd; if ( __copy_to_user( buf, &tsk->thread.i387.fsave, sizeof(struct i387_fsave_struct) ) ) @@ -291,6 +292,8 @@ static inline int save_i387_fxsave( struct _fpstate *buf ) struct task_struct *tsk = current; int err = 0; + unlazy_fpu( tsk ); + if ( convert_fxsr_to_user( buf, &tsk->thread.i387.fxsave ) ) return -1; diff --git a/arch/i386/kernel/ptrace.c b/arch/i386/kernel/ptrace.c index 0bafdc7e2..c2621dd3c 100644 --- a/arch/i386/kernel/ptrace.c +++ b/arch/i386/kernel/ptrace.c @@ -99,6 +99,11 @@ static int putreg(struct task_struct *child, case EFL: value &= FLAG_MASK; value |= get_stack_long(child, EFL_OFFSET) & ~FLAG_MASK; + break; + case EIP: + /* Mark us as not being in a system call, so that no restart issues happen */ + put_stack_long(child, 4*ORIG_EAX - sizeof(struct pt_regs), -1); + break; } if (regno > GS*4) regno -= 2*4; diff --git a/arch/ia64/kernel/signal.c b/arch/ia64/kernel/signal.c index ca0f7a981..12f312672 100644 --- a/arch/ia64/kernel/signal.c +++ b/arch/ia64/kernel/signal.c @@ -570,7 +570,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/m68k/kernel/signal.c b/arch/m68k/kernel/signal.c index d67617bea..fa13dc390 100644 --- a/arch/m68k/kernel/signal.c +++ b/arch/m68k/kernel/signal.c @@ -1137,7 +1137,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/mips/kernel/irixelf.c b/arch/mips/kernel/irixelf.c index 3329e5e84..5f63b0910 100644 --- a/arch/mips/kernel/irixelf.c +++ b/arch/mips/kernel/irixelf.c @@ -1127,7 +1127,7 @@ static int irix_core_dump(long signr, struct pt_regs * regs, struct file *file) notes[0].datasz = sizeof(prstatus); notes[0].data = &prstatus; prstatus.pr_info.si_signo = prstatus.pr_cursig = signr; - prstatus.pr_sigpend = current->signal.sig[0]; + prstatus.pr_sigpend = current->pending.signal.sig[0]; prstatus.pr_sighold = current->blocked.sig[0]; psinfo.pr_pid = prstatus.pr_pid = current->pid; psinfo.pr_ppid = prstatus.pr_ppid = current->p_pptr->pid; diff --git a/arch/mips/kernel/irixsig.c b/arch/mips/kernel/irixsig.c index 7254ee95d..6f6556da4 100644 --- a/arch/mips/kernel/irixsig.c +++ b/arch/mips/kernel/irixsig.c @@ -264,7 +264,7 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); @@ -429,24 +429,7 @@ irix_sigaction(int sig, const struct sigaction *act, asmlinkage int irix_sigpending(irix_sigset_t *set) { - int err; - - if (verify_area(VERIFY_WRITE, set, sizeof(*set)) < 0) - return -EFAULT; - - /* fill in "set" with signals pending but blocked. */ - spin_lock_irq(¤t->sigmask_lock); - err = __put_user(current->blocked.sig[0] & current->signal.sig[0], - &set->sig[0]); - err |= __put_user(current->blocked.sig[1] & current->signal.sig[1], - &set->sig[1]); - err |= __put_user(current->blocked.sig[2] & current->signal.sig[2], - &set->sig[2]); - err |= __put_user(current->blocked.sig[3] & current->signal.sig[3], - &set->sig[3]); - spin_unlock_irq(¤t->sigmask_lock); - - return err; + return do_sigpending(set, sizeof(*set)); } asmlinkage int irix_sigprocmask(int how, irix_sigset_t *new, irix_sigset_t *old) @@ -605,7 +588,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, expire = schedule_timeout(expire); for (i=0; i<=4; i++) - tmp |= (current->signal.sig[i] & kset.sig[i]); + tmp |= (current->pending.signal.sig[i] & kset.sig[i]); if (tmp) break; @@ -622,7 +605,7 @@ asmlinkage int irix_sigpoll_sys(unsigned long *set, struct irix5_siginfo *info, for(sig = 1; i <= 65 /* IRIX_NSIG */; sig++) { if (sigismember (&kset, sig)) continue; - if (sigismember (¤t->signal, sig)) { + if (sigismember (¤t->pending.signal, sig)) { /* XXX need more than this... */ if (info) info->sig = sig; diff --git a/arch/mips/kernel/signal.c b/arch/mips/kernel/signal.c index 5a9992141..ad66fcb6c 100644 --- a/arch/mips/kernel/signal.c +++ b/arch/mips/kernel/signal.c @@ -662,7 +662,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/mips64/kernel/signal.c b/arch/mips64/kernel/signal.c index 81daadab8..15b2fc60b 100644 --- a/arch/mips64/kernel/signal.c +++ b/arch/mips64/kernel/signal.c @@ -695,7 +695,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/mips64/kernel/signal32.c b/arch/mips64/kernel/signal32.c index 1988b681c..04f89ba2a 100644 --- a/arch/mips64/kernel/signal32.c +++ b/arch/mips64/kernel/signal32.c @@ -773,7 +773,7 @@ printk("%s: delivering signal.\n", current->comm); /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index 79847fa0d..31e381b17 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c @@ -646,7 +646,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs) default: lock_kernel(); - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/s390/kernel/signal.c b/arch/s390/kernel/signal.c index fd1a5e58a..a4df59c65 100644 --- a/arch/s390/kernel/signal.c +++ b/arch/s390/kernel/signal.c @@ -528,7 +528,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) default: lock_kernel(); - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/sh/kernel/signal.c b/arch/sh/kernel/signal.c index 9bdddc9d9..fe2f1b319 100644 --- a/arch/sh/kernel/signal.c +++ b/arch/sh/kernel/signal.c @@ -672,7 +672,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset) /* FALLTHRU */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/sparc/kernel/signal.c b/arch/sparc/kernel/signal.c index bcad13dbc..012d19eff 100644 --- a/arch/sparc/kernel/signal.c +++ b/arch/sparc/kernel/signal.c @@ -1282,7 +1282,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, #endif /* fall through */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/sparc64/kernel/signal.c b/arch/sparc64/kernel/signal.c index d1e7e4215..043524ea9 100644 --- a/arch/sparc64/kernel/signal.c +++ b/arch/sparc64/kernel/signal.c @@ -784,7 +784,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs, #endif /* fall through */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/sparc64/kernel/signal32.c b/arch/sparc64/kernel/signal32.c index efad55a1c..51b1e41a8 100644 --- a/arch/sparc64/kernel/signal32.c +++ b/arch/sparc64/kernel/signal32.c @@ -1420,7 +1420,7 @@ asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs * regs, #endif /* fall through */ default: - sigaddset(¤t->signal, signr); + sigaddset(¤t->pending.signal, signr); recalc_sigpending(current); current->flags |= PF_SIGNALED; do_exit(exit_code); diff --git a/arch/sparc64/solaris/signal.c b/arch/sparc64/solaris/signal.c index a399238f5..d7de503be 100644 --- a/arch/sparc64/solaris/signal.c +++ b/arch/sparc64/solaris/signal.c @@ -311,7 +311,7 @@ asmlinkage int solaris_sigpending(int which, u32 set) switch (which) { case 1: /* sigpending */ spin_lock_irq(¤t->sigmask_lock); - sigandsets(&s, ¤t->blocked, ¤t->signal); + sigandsets(&s, ¤t->blocked, ¤t->pending.signal); recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); break; diff --git a/drivers/char/ftape/lowlevel/ftape-ctl.c b/drivers/char/ftape/lowlevel/ftape-ctl.c index 6ec456f00..4196458d0 100644 --- a/drivers/char/ftape/lowlevel/ftape-ctl.c +++ b/drivers/char/ftape/lowlevel/ftape-ctl.c @@ -794,8 +794,8 @@ void ftape_disable(void) i, *ft_buffer[i]->address); } } - if (sigtestsetmask(¤t->signal, _DONT_BLOCK) && - !(sigtestsetmask(¤t->signal, _NEVER_BLOCK)) && + if (sigtestsetmask(¤t->pending.signal, _DONT_BLOCK) && + !(sigtestsetmask(¤t->pending.signal, _NEVER_BLOCK)) && ftape_tape_running) { TRACE(ft_t_warn, "Interrupted by fatal signal and tape still running"); diff --git a/drivers/char/ftape/lowlevel/ftape-rw.c b/drivers/char/ftape/lowlevel/ftape-rw.c index 2ae96344e..2c14f468e 100644 --- a/drivers/char/ftape/lowlevel/ftape-rw.c +++ b/drivers/char/ftape/lowlevel/ftape-rw.c @@ -433,7 +433,7 @@ int ftape_dumb_stop(void) result = ftape_ready_wait(ftape_timeout.pause,&status); } } while (ftape_tape_running - && !(sigtestsetmask(¤t->signal, _NEVER_BLOCK))); + && !(sigtestsetmask(¤t->pending.signal, _NEVER_BLOCK))); #ifndef TESTING ft_location.known = 0; #endif @@ -661,7 +661,7 @@ static int seek_forward(int segment_id, int fast) * to find a way to skip an EMPTY_SEGMENT. !!! FIXME !!! */ if (ftape_read_id() < 0 || !ft_location.known || - sigtestsetmask(¤t->signal, _DONT_BLOCK)) { + sigtestsetmask(¤t->pending.signal, _DONT_BLOCK)) { ft_location.known = 0; if (!ftape_tape_running || ++failures > FT_SECTORS_PER_SEGMENT) { @@ -776,7 +776,7 @@ static int skip_reverse(int segment_id, int *pstatus) fast_seek(count, 1); logical_forward(); if (ftape_read_id() < 0 || !ft_location.known || - (sigtestsetmask(¤t->signal, _DONT_BLOCK))) { + (sigtestsetmask(¤t->pending.signal, _DONT_BLOCK))) { if ((!ftape_tape_running && !ft_location.known) || ++failures > FT_SECTORS_PER_SEGMENT) { TRACE_ABORT(-EIO, ft_t_err, @@ -1002,7 +1002,7 @@ int ftape_start_tape(int segment_id, int sector_offset) while (result < 0 && retry++ <= 5 && !ft_failure && - !(sigtestsetmask(¤t->signal, _DONT_BLOCK))) { + !(sigtestsetmask(¤t->pending.signal, _DONT_BLOCK))) { if (retry && start_offset < 5) { start_offset ++; diff --git a/drivers/char/ftape/lowlevel/ftape-tracing.h b/drivers/char/ftape/lowlevel/ftape-tracing.h index e0f7e0f4f..77af02f69 100644 --- a/drivers/char/ftape/lowlevel/ftape-tracing.h +++ b/drivers/char/ftape/lowlevel/ftape-tracing.h @@ -171,7 +171,7 @@ extern void ftape_trace_log (const char *file, const char *name); * but rather into ftape-rw.h (maybe) */ #define FT_SIGNAL_EXIT(sig_mask) \ - if (sigtestsetmask(¤t->signal, sig_mask)) { \ + if (sigtestsetmask(¤t->pending.signal, sig_mask)) { \ TRACE_ABORT(-EINTR, \ ft_t_warn, \ "interrupted by non-blockable signal"); \ diff --git a/drivers/char/rocket.c b/drivers/char/rocket.c index af94b4b3f..3d754212e 100644 --- a/drivers/char/rocket.c +++ b/drivers/char/rocket.c @@ -218,7 +218,7 @@ int copy_to_user(void *to_user, const void *from, unsigned long len) static inline int signal_pending(struct task_struct *p) { - return (p->signal & (~p->blocked != 0)); + return (p->signal & ~p->blocked) != 0; } #else diff --git a/fs/buffer.c b/fs/buffer.c index 05f52aa2d..b9120655e 100644 --- a/fs/buffer.c +++ b/fs/buffer.c @@ -1721,6 +1721,54 @@ int generic_commit_write(struct file *file, struct page *page, return 0; } +/* + * If it would be '74 that would go into libc... + */ +int mem_is_zero(char *p, unsigned len) +{ + while (len--) + if (*p++) + return 0; + return 1; +} + +int block_zero_page(struct address_space *mapping, loff_t from, unsigned length) +{ + unsigned long index = from >> PAGE_CACHE_SHIFT; + unsigned offset = from & (PAGE_CACHE_SIZE-1); + struct inode *inode = (struct inode *)mapping->host; + struct page *page; + char *kaddr; + int err; + + if (!length) + return 0; + + page = read_cache_page(mapping, index, + (filler_t *)mapping->a_ops->readpage, NULL); + err = PTR_ERR(page); + if (ERR_PTR(page)) + goto out; + lock_page(page); + err = -EIO; + if (!Page_Uptodate(page)) + goto unlock; + kaddr = (char*)kmap(page); + err = 0; + if (mem_is_zero(kaddr+offset, length)) + goto unmap; + memset(kaddr+offset, 0, length); + flush_dcache_page(page); + __block_commit_write(inode, page, offset, offset+length); +unmap: + kunmap(page); +unlock: + UnlockPage(page); + page_cache_release(page); +out: + return err; +} + int block_write_full_page(struct page *page, get_block_t *get_block) { struct inode *inode = (struct inode*)page->mapping->host; diff --git a/fs/coda/upcall.c b/fs/coda/upcall.c index 206c9d8b0..416f330ce 100644 --- a/fs/coda/upcall.c +++ b/fs/coda/upcall.c @@ -634,8 +634,8 @@ static inline unsigned long coda_waitfor_upcall(struct upc_req *vmp) if ( !coda_hard && vmp->uc_opcode != CODA_CLOSE && signal_pending(current) ) { /* if this process really wants to die, let it go */ - if ( sigismember(&(current->signal), SIGKILL) || - sigismember(&(current->signal), SIGINT) ) + if ( sigismember(&(current->pending.signal), SIGKILL) || + sigismember(&(current->pending.signal), SIGINT) ) break; /* signal is present: after timeout always return really smart idea, probably useless ... */ diff --git a/fs/ext2/inode.c b/fs/ext2/inode.c index 9c2abac55..a6567685e 100644 --- a/fs/ext2/inode.c +++ b/fs/ext2/inode.c @@ -904,6 +904,7 @@ void ext2_truncate (struct inode * inode) int nr = 0; int n; long iblock; + unsigned blocksize, tail; if (!(S_ISREG(inode->i_mode) || S_ISDIR(inode->i_mode) || S_ISLNK(inode->i_mode))) @@ -913,8 +914,13 @@ void ext2_truncate (struct inode * inode) ext2_discard_prealloc(inode); - iblock = (inode->i_size + inode->i_sb->s_blocksize-1) + blocksize = inode->i_sb->s_blocksize; + iblock = (inode->i_size + blocksize-1) >> EXT2_BLOCK_SIZE_BITS(inode->i_sb); + tail = (iblock << EXT2_BLOCK_SIZE_BITS(inode->i_sb)) - inode->i_size; + + if (block_zero_page(inode->i_mapping, inode->i_size, tail) != 0) + return; n = ext2_block_to_path(inode, iblock, offsets); if (n == 0) diff --git a/fs/smbfs/sock.c b/fs/smbfs/sock.c index 01ae6ec87..66dbd9efb 100644 --- a/fs/smbfs/sock.c +++ b/fs/smbfs/sock.c @@ -641,7 +641,7 @@ smb_request(struct smb_sb_info *server) DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]); spin_lock_irqsave(¤t->sigmask_lock, flags); - sigpipe = sigismember(¤t->signal, SIGPIPE); + sigpipe = sigismember(¤t->pending.signal, SIGPIPE); old_set = current->blocked; siginitsetinv(¤t->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP)); recalc_sigpending(current); @@ -659,7 +659,7 @@ smb_request(struct smb_sb_info *server) /* read/write errors are handled by errno */ spin_lock_irqsave(¤t->sigmask_lock, flags); if (result == -EPIPE && !sigpipe) - sigdelset(¤t->signal, SIGPIPE); + sigdelset(¤t->pending.signal, SIGPIPE); current->blocked = old_set; recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); @@ -821,7 +821,7 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command, goto bad_conn; spin_lock_irqsave(¤t->sigmask_lock, flags); - sigpipe = sigismember(¤t->signal, SIGPIPE); + sigpipe = sigismember(¤t->pending.signal, SIGPIPE); old_set = current->blocked; siginitsetinv(¤t->blocked, sigmask(SIGKILL)|sigmask(SIGSTOP)); recalc_sigpending(current); @@ -841,7 +841,7 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command, /* read/write errors are handled by errno */ spin_lock_irqsave(¤t->sigmask_lock, flags); if (result == -EPIPE && !sigpipe) - sigdelset(¤t->signal, SIGPIPE); + sigdelset(¤t->pending.signal, SIGPIPE); current->blocked = old_set; recalc_sigpending(current); spin_unlock_irqrestore(¤t->sigmask_lock, flags); diff --git a/include/asm-arm/arch-arc/irq.h b/include/asm-arm/arch-arc/irq.h index 61997a1b2..f62b4e012 100644 --- a/include/asm-arm/arch-arc/irq.h +++ b/include/asm-arm/arch-arc/irq.h @@ -168,5 +168,7 @@ static __inline__ void irq_init_irq(void) } } + irq_mask[IRQ_KEYBOARDTX].noautoenable = 1; + init_FIQ(); } diff --git a/include/asm-arm/arch-ebsa110/time.h b/include/asm-arm/arch-ebsa110/time.h index dbddeb1b9..ee620371c 100644 --- a/include/asm-arm/arch-ebsa110/time.h +++ b/include/asm-arm/arch-ebsa110/time.h @@ -46,6 +46,7 @@ static void timer_interrupt(int irq, void *dev_id, struct pt_regs *regs) #endif do_leds(); do_timer(regs); + do_profile(regs); } /* diff --git a/include/asm-arm/arch-ebsa285/hardware.h b/include/asm-arm/arch-ebsa285/hardware.h index ae5817d9e..5d1455fb8 100644 --- a/include/asm-arm/arch-ebsa285/hardware.h +++ b/include/asm-arm/arch-ebsa285/hardware.h @@ -15,20 +15,13 @@ /* Virtual Physical Size * 0xff800000 0x40000000 1MB X-Bus * 0xff000000 0x7c000000 1MB PCI I/O space - * * 0xfe000000 0x42000000 1MB CSR * 0xfd000000 0x78000000 1MB Outbound write flush (not supported) * 0xfc000000 0x79000000 1MB PCI IACK/special space - * * 0xfb000000 0x7a000000 16MB PCI Config type 1 * 0xfa000000 0x7b000000 16MB PCI Config type 0 - * * 0xf9000000 0x50000000 1MB Cache flush - * 0xf8000000 0x41000000 16MB Flash memory - * - * 0xe1000000 unmapped (to catch bad ISA/PCI) - * - * 0xe0000000 0x80000000 16MB ISA memory + * 0xf0000000 0x80000000 16MB ISA memory */ #define XBUS_SIZE 0x00100000 #define XBUS_BASE 0xff800000 @@ -54,9 +47,6 @@ #define FLUSH_SIZE 0x00100000 #define FLUSH_BASE 0xf9000000 -#define FLASH_SIZE 0x01000000 -#define FLASH_BASE 0xf8000000 - #define PCIMEM_SIZE 0x01000000 #define PCIMEM_BASE 0xf0000000 @@ -67,9 +57,6 @@ #define PCIMEM_SIZE 0x80000000 #define PCIMEM_BASE 0x80000000 -#define FLASH_SIZE 0x01000000 -#define FLASH_BASE 0x7f000000 - #define FLUSH_SIZE 0x00100000 #define FLUSH_BASE 0x7e000000 diff --git a/include/asm-arm/arch-ebsa285/uncompress.h b/include/asm-arm/arch-ebsa285/uncompress.h index ab103585c..f227dccfe 100644 --- a/include/asm-arm/arch-ebsa285/uncompress.h +++ b/include/asm-arm/arch-ebsa285/uncompress.h @@ -3,6 +3,7 @@ * * Copyright (C) 1996-1999 Russell King */ +#include /* * Note! This could cause problems on the NetWinder diff --git a/include/asm-arm/arch-nexuspci/hardware.h b/include/asm-arm/arch-nexuspci/hardware.h index 364edd010..13ba3957b 100644 --- a/include/asm-arm/arch-nexuspci/hardware.h +++ b/include/asm-arm/arch-nexuspci/hardware.h @@ -63,4 +63,6 @@ #define INTCONT_LED 0x1a #define INTCONT_PCI_RESET 0x1c +#define UNCACHEABLE_ADDR STATUS_BASE + #endif diff --git a/include/asm-arm/arch-nexuspci/time.h b/include/asm-arm/arch-nexuspci/time.h index b1ff948a1..54872be9f 100644 --- a/include/asm-arm/arch-nexuspci/time.h +++ b/include/asm-arm/arch-nexuspci/time.h @@ -46,6 +46,7 @@ extern __inline__ void setup_timer(void) __raw_writeb(0x10, DUART_BASE + 0x14); timer_irq.handler = timer_interrupt; + timer_irq.flags = SA_SHIRQ; setup_arm_irq(IRQ_TIMER, &timer_irq); } diff --git a/include/asm-arm/arch-nexuspci/uncompress.h b/include/asm-arm/arch-nexuspci/uncompress.h index e03ea93b3..54cdda053 100644 --- a/include/asm-arm/arch-nexuspci/uncompress.h +++ b/include/asm-arm/arch-nexuspci/uncompress.h @@ -22,8 +22,11 @@ void _ll_write_char(char c) */ static void puts(const char *s) { - while (*s) + while (*s) { + if (*s == '\n') + _ll_write_char('\r'); _ll_write_char(*(s++)); + } } /* diff --git a/include/asm-arm/arch-rpc/irq.h b/include/asm-arm/arch-rpc/irq.h index c7d98b0c0..edcda432e 100644 --- a/include/asm-arm/arch-rpc/irq.h +++ b/include/asm-arm/arch-rpc/irq.h @@ -152,21 +152,22 @@ static __inline__ void irq_init_irq(void) irq_desc[irq].unmask = rpc_unmask_irq_b; break; - case 16 ... 22: + case 16 ... 21: irq_desc[irq].valid = 1; + irq_desc[irq].noautoenable = 1; irq_desc[irq].mask_ack = rpc_mask_irq_dma; irq_desc[irq].mask = rpc_mask_irq_dma; irq_desc[irq].unmask = rpc_unmask_irq_dma; break; - case 32 ... 40: + case 32 ... 39: irq_desc[irq].valid = 1; irq_desc[irq].mask_ack = ecard_disableirq; irq_desc[irq].mask = ecard_disableirq; irq_desc[irq].unmask = ecard_enableirq; break; - case 64 ... 72: + case 64 ... 71: irq_desc[irq].valid = 1; irq_desc[irq].mask_ack = rpc_mask_irq_fiq; irq_desc[irq].mask = rpc_mask_irq_fiq; @@ -175,5 +176,7 @@ static __inline__ void irq_init_irq(void) } } + irq_desc[IRQ_KEYBOARDTX].noautoenable = 1; + init_FIQ(); } diff --git a/include/asm-arm/current.h b/include/asm-arm/current.h index b2b83ebb7..3a06c2a8a 100644 --- a/include/asm-arm/current.h +++ b/include/asm-arm/current.h @@ -1,30 +1,16 @@ #ifndef _ASMARM_CURRENT_H #define _ASMARM_CURRENT_H -static inline unsigned long get_sp(void) -{ - unsigned long sp; - __asm__ ("mov %0,sp" : "=r" (sp)); - return sp; -} - /* Old compilers seem to generate bad code if we allow `current' to be non volatile. */ #if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ > 90) static inline struct task_struct *get_current(void) __attribute__ (( __const__ )); -#define __VOLATILE_CURRENT -#else -#define __VOLATILE_CURRENT volatile #endif static inline struct task_struct *get_current(void) { - struct task_struct *ts; - __asm__ __VOLATILE_CURRENT ( - "bic %0, sp, #0x1f00 @ get_current - bic %0, %0, #0x00ff" - : "=r" (ts)); - return ts; + register unsigned long sp asm ("sp"); + return (struct task_struct *)(sp & ~0x1fff); } #define current (get_current()) diff --git a/include/asm-arm/dma.h b/include/asm-arm/dma.h index 78c65b599..04dacb2b4 100644 --- a/include/asm-arm/dma.h +++ b/include/asm-arm/dma.h @@ -7,6 +7,7 @@ typedef unsigned int dmach_t; #include #include #include +#include #include /* diff --git a/include/asm-arm/mach/arch.h b/include/asm-arm/mach/arch.h new file mode 100644 index 000000000..a0e0e6502 --- /dev/null +++ b/include/asm-arm/mach/arch.h @@ -0,0 +1,84 @@ +/* + * linux/include/asm-arm/mach/arch.h + * + * Copyright (C) 2000 Russell King + */ + +/* + * The size of struct machine_desc + * (for assembler code) + */ +#define SIZEOF_MACHINE_DESC 44 + +#ifndef __ASSEMBLY__ + +struct machine_desc { + /* + * Note! The first four elements are used + * by assembler code in head-armv.S + */ + unsigned int nr; /* architecture number */ + unsigned int phys_ram; /* start of physical ram */ + unsigned int phys_io; /* start of physical io */ + unsigned int virt_io; /* start of virtual io */ + + const char *name; /* architecture name */ + unsigned int param_offset; /* parameter page */ + + unsigned int video_start; /* start of video RAM */ + unsigned int video_end; /* end of video RAM */ + + unsigned int reserve_lp0 :1; /* never has lp0 */ + unsigned int reserve_lp1 :1; /* never has lp1 */ + unsigned int reserve_lp2 :1; /* never has lp2 */ + unsigned int broken_hlt :1; /* hlt is broken */ + unsigned int soft_reboot :1; /* soft reboot */ + void (*fixup)(struct machine_desc *, + struct param_struct *, char **, + struct meminfo *); + void (*map_io)(void);/* IO mapping function */ +}; + +/* + * Set of macros to define architecture features. This is built into + * a table by the linker. + */ +#define MACHINE_START(_type,_name) \ +const struct machine_desc __mach_desc_##_type \ + __attribute__((__section__(".arch.info"))) = { \ + nr: MACH_TYPE_##_type##, \ + name: _name, + +#define MAINTAINER(n) + +#define BOOT_MEM(_pram,_pio,_vio) \ + phys_ram: _pram, \ + phys_io: _pio, \ + virt_io: _vio, + +#define BOOT_PARAMS(_params) \ + param_offset: _params, + +#define VIDEO(_start,_end) \ + video_start: _start, \ + video_end: _end, + +#define DISABLE_PARPORT(_n) \ + reserve_lp##_n##: 1, + +#define BROKEN_HLT \ + broken_hlt: 1, + +#define SOFT_REBOOT \ + soft_reboot: 1, + +#define FIXUP(_func) \ + fixup: _func, + +#define MAPIO(_func) \ + map_io: _func, + +#define MACHINE_END \ +}; + +#endif diff --git a/include/asm-arm/mach/dma.h b/include/asm-arm/mach/dma.h new file mode 100644 index 000000000..64a5e7680 --- /dev/null +++ b/include/asm-arm/mach/dma.h @@ -0,0 +1,49 @@ +/* + * linux/arch/arm/kernel/dma.h + * + * Copyright (C) 1998-2000 Russell King + * + * This header file describes the interface between the generic DMA handler + * (dma.c) and the architecture-specific DMA backends (dma-*.c) + */ + +struct dma_struct; +typedef struct dma_struct dma_t; + +struct dma_ops { + int (*request)(dmach_t, dma_t *); /* optional */ + void (*free)(dmach_t, dma_t *); /* optional */ + void (*enable)(dmach_t, dma_t *); /* mandatory */ + void (*disable)(dmach_t, dma_t *); /* mandatory */ + int (*residue)(dmach_t, dma_t *); /* optional */ + int (*setspeed)(dmach_t, dma_t *, int); /* optional */ + char *type; +}; + +struct dma_struct { + struct scatterlist buf; /* single DMA */ + int sgcount; /* number of DMA SG */ + struct scatterlist *sg; /* DMA Scatter-Gather List */ + + unsigned int active:1; /* Transfer active */ + unsigned int invalid:1; /* Address/Count changed */ + unsigned int using_sg:1; /* using scatter list? */ + dmamode_t dma_mode; /* DMA mode */ + int speed; /* DMA speed */ + + unsigned int lock; /* Device is allocated */ + const char *device_id; /* Device name */ + + unsigned int dma_base; /* Controller base address */ + int dma_irq; /* Controller IRQ */ + int state; /* Controller state */ + struct scatterlist cur_sg; /* Current controller buffer */ + + struct dma_ops *d_ops; +}; + +/* Prototype: void arch_dma_init(dma) + * Purpose : Initialise architecture specific DMA + * Params : dma - pointer to array of DMA structures + */ +void arch_dma_init(dma_t *dma); diff --git a/include/asm-arm/mach/map.h b/include/asm-arm/mach/map.h new file mode 100644 index 000000000..87cfab919 --- /dev/null +++ b/include/asm-arm/mach/map.h @@ -0,0 +1,28 @@ +/* + * linux/include/asm-arm/map.h + * + * Copyright (C) 1999-2000 Russell King + * + * Page table mapping constructs and function prototypes + */ +struct map_desc { + unsigned long virtual; + unsigned long physical; + unsigned long length; + int domain:4, + prot_read:1, + prot_write:1, + cacheable:1, + bufferable:1, + last:1; +}; + +#define LAST_DESC \ + { last: 1 } + +struct meminfo; + +extern void create_memmap_holes(struct meminfo *); +extern void memtable_init(struct meminfo *); +extern void iotable_init(struct map_desc *); +extern void setup_io_desc(void); diff --git a/arch/arm/kernel/bios32.h b/include/asm-arm/mach/pci.h similarity index 67% rename from arch/arm/kernel/bios32.h rename to include/asm-arm/mach/pci.h index 421ec6a79..b7aa9c752 100644 --- a/arch/arm/kernel/bios32.h +++ b/include/asm-arm/mach/pci.h @@ -1,3 +1,6 @@ +/* + * linux/include/asm-arm/mach/pci.h + */ #define MAX_NR_BUS 2 struct arm_bus_sysdata { @@ -22,12 +25,12 @@ struct arm_pci_sysdata { }; struct hw_pci { - void (*init)(void); - unsigned long io_start; - unsigned long mem_start; + void (*init)(struct arm_pci_sysdata *); u8 (*swizzle)(struct pci_dev *dev, u8 *pin); int (*map_irq)(struct pci_dev *dev, u8 slot, u8 pin); }; -void __init dc21285_init(void); -void __init plx90x0_init(void); +extern u8 no_swizzle(struct pci_dev *dev, u8 *pin); + +void __init dc21285_init(struct arm_pci_sysdata *); +void __init plx90x0_init(struct arm_pci_sysdata *); diff --git a/include/asm-arm/mmu_context.h b/include/asm-arm/mmu_context.h index f358628a9..dcf495a08 100644 --- a/include/asm-arm/mmu_context.h +++ b/include/asm-arm/mmu_context.h @@ -17,9 +17,19 @@ #define destroy_context(mm) do { } while(0) #define init_new_context(tsk,mm) 0 +/* + * This is called when "tsk" is about to enter lazy TLB mode. + * + * mm: describes the currently active mm context + * tsk: task which is entering lazy tlb + * cpu: cpu number which is entering lazy tlb + * + * tsk->mm will be NULL + */ static inline void enter_lazy_tlb(struct mm_struct *mm, struct task_struct *tsk, unsigned cpu) { } + /* * This is the actual mm switch as far as the scheduler * is concerned. No registers are touched. diff --git a/include/asm-arm/pci.h b/include/asm-arm/pci.h index 2a2fcc947..63c1ee9cf 100644 --- a/include/asm-arm/pci.h +++ b/include/asm-arm/pci.h @@ -93,8 +93,10 @@ pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int directi { int i; - for (i = 0; i < nents; i++, sg++) + for (i = 0; i < nents; i++, sg++) { consistent_sync(sg->address, sg->length, direction); + sg->dma_address = virt_to_bus(sg->address); + } return nents; } @@ -136,7 +138,7 @@ pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nelems, int d int i; for (i = 0; i < nelems; i++, sg++) - consistent_sync(sg->address, sg->length, 3); + consistent_sync(sg->address, sg->length, direction); } /* Return whether the given PCI device DMA address mask can @@ -149,15 +151,6 @@ extern inline int pci_dma_supported(struct pci_dev *hwdev, dma_addr_t mask) return 1; } -/* These macros should be used after a pci_map_sg call has been done - * to get bus addresses of each of the SG entries and their lengths. - * You should only work with the number of sg entries pci_map_sg - * returns, or alternatively stop on the first sg_dma_len(sg) which - * is 0. - */ -#define sg_dma_address(sg) (virt_to_bus((sg)->address)) -#define sg_dma_len(sg) ((sg)->length) - #endif /* __KERNEL__ */ #endif diff --git a/include/asm-arm/pgalloc.h b/include/asm-arm/pgalloc.h index a16a0d54c..30bbdb42c 100644 --- a/include/asm-arm/pgalloc.h +++ b/include/asm-arm/pgalloc.h @@ -13,11 +13,10 @@ */ #include -extern __inline__ void flush_tlb_pgtables(struct mm_struct *mm, - unsigned long start, - unsigned long end) -{ -} +/* + * ARM processors do not cache TLB tables in RAM. + */ +#define flush_tlb_pgtables(mm,start,end) do { } while (0) /* * Page table cache stuff diff --git a/include/asm-arm/proc-armo/assembler.h b/include/asm-arm/proc-armo/assembler.h index 42b23aa89..78436f96a 100644 --- a/include/asm-arm/proc-armo/assembler.h +++ b/include/asm-arm/proc-armo/assembler.h @@ -78,3 +78,25 @@ .macro restore_irqs, oldcpsr @ This be restore_irqs .endm + +/* + * These two are used to save LR/restore PC over a user-based access. + * The old 26-bit architecture requires that we do. On 32-bit + * architecture, we can safely ignore this requirement. + */ + .macro save_lr + str lr, [sp, #-4]! + .endm + + .macro restore_pc + ldmfd sp!, {pc}^ + .endm + +#define USER(x...) \ +9999: x; \ + .section __ex_table,"a"; \ + .align 3; \ + .long 9999b,9001f; \ + .previous + + diff --git a/include/asm-arm/proc-armo/cache.h b/include/asm-arm/proc-armo/cache.h index ca99bcf82..672ab82ee 100644 --- a/include/asm-arm/proc-armo/cache.h +++ b/include/asm-arm/proc-armo/cache.h @@ -1,14 +1,21 @@ /* - * Cache flushing... + * Cache handling for 26-bit ARM processors. */ #define flush_cache_all() do { } while (0) #define flush_cache_mm(mm) do { } while (0) #define flush_cache_range(mm,start,end) do { } while (0) #define flush_cache_page(vma,vmaddr) do { } while (0) #define flush_page_to_ram(page) do { } while (0) + +#define invalidate_dcache_range(start,end) do { } while (0) +#define clean_dcache_range(start,end) do { } while (0) +#define flush_dcache_range(start,end) do { } while (0) #define flush_dcache_page(page) do { } while (0) -#define flush_icache_page(vma,page) do { } while (0) +#define clean_dcache_entry(_s) do { } while (0) +#define clean_cache_entry(_start) do { } while (0) + #define flush_icache_range(start,end) do { } while (0) +#define flush_icache_page(vma,page) do { } while (0) /* DAG: ARM3 will flush cache on MEMC updates anyway? so don't bother */ #define clean_cache_area(_start,_size) do { } while (0) diff --git a/include/asm-arm/proc-armo/locks.h b/include/asm-arm/proc-armo/locks.h index fcf0cab01..c460bfebb 100644 --- a/include/asm-arm/proc-armo/locks.h +++ b/include/asm-arm/proc-armo/locks.h @@ -15,20 +15,20 @@ ({ \ __asm__ __volatile__ ( \ "@ atomic down operation\n" \ -" mov r0, pc\n" \ -" orr lr, r0, #0x08000000\n" \ +" mov ip, pc\n" \ +" orr lr, ip, #0x08000000\n" \ " teqp lr, #0\n" \ " ldr lr, [%0]\n" \ -" and r0, r0, #0x0c000003\n" \ +" and ip, ip, #0x0c000003\n" \ " subs lr, lr, #1\n" \ " str lr, [%0]\n" \ -" orrmi r0, r0, #0x80000000 @ set N\n" \ -" teqp r0, #0\n" \ -" movmi r0, %0\n" \ +" orrmi ip, ip, #0x80000000 @ set N\n" \ +" teqp ip, #0\n" \ +" movmi ip, %0\n" \ " blmi " SYMBOL_NAME_STR(fail) \ : \ : "r" (ptr) \ - : "r0", "lr", "cc"); \ + : "ip", "lr", "cc"); \ }) #define __down_op_ret(ptr,fail) \ @@ -36,22 +36,22 @@ unsigned int result; \ __asm__ __volatile__ ( \ " @ down_op_ret\n" \ -" mov r0, pc\n" \ -" orr lr, r0, #0x08000000\n" \ +" mov ip, pc\n" \ +" orr lr, ip, #0x08000000\n" \ " teqp lr, #0\n" \ " ldr lr, [%1]\n" \ -" and r0, r0, #0x0c000003\n" \ +" and ip, ip, #0x0c000003\n" \ " subs lr, lr, #1\n" \ " str lr, [%1]\n" \ -" orrmi r0, r0, #0x80000000 @ set N\n" \ -" teqp r0, #0\n" \ -" movmi r0, %1\n" \ -" movpl r0, #0\n" \ +" orrmi ip, ip, #0x80000000 @ set N\n" \ +" teqp ip, #0\n" \ +" movmi ip, %1\n" \ +" movpl ip, #0\n" \ " blmi " SYMBOL_NAME_STR(fail) "\n" \ -" mov %0, r0" \ +" mov %0, ip" \ : "=&r" (result) \ : "r" (ptr) \ - : "r0", "lr", "cc"); \ + : "ip", "lr", "cc"); \ result; \ }) @@ -59,20 +59,20 @@ ({ \ __asm__ __volatile__ ( \ "@ up_op\n" \ -" mov r0, pc\n" \ -" orr lr, r0, #0x08000000\n" \ +" mov ip, pc\n" \ +" orr lr, ip, #0x08000000\n" \ " teqp lr, #0\n" \ " ldr lr, [%0]\n" \ -" and r0, r0, #0x0c000003\n" \ +" and ip, ip, #0x0c000003\n" \ " adds lr, lr, #1\n" \ " str lr, [%0]\n" \ -" orrle r0, r0, #0x80000000 @ set N - should this be mi ??? DAG ! \n" \ -" teqp r0, #0\n" \ -" movmi r0, %0\n" \ +" orrle ip, ip, #0x80000000 @ set N - should this be mi ??? DAG ! \n" \ +" teqp ip, #0\n" \ +" movmi ip, %0\n" \ " blmi " SYMBOL_NAME_STR(wake) \ : \ : "r" (ptr) \ - : "r0", "lr", "cc"); \ + : "ip", "lr", "cc"); \ }) /* @@ -89,22 +89,22 @@ ({ \ __asm__ __volatile__( \ "@ down_op_write\n" \ -" mov r0, pc\n" \ -" orr lr, r0, #0x08000000\n" \ +" mov ip, pc\n" \ +" orr lr, ip, #0x08000000\n" \ " teqp lr, #0\n" \ -" and r0, r0, #0x0c000003\n" \ +" and ip, ip, #0x0c000003\n" \ \ " ldr lr, [%0]\n" \ " subs lr, lr, %1\n" \ " str lr, [%0]\n" \ \ -" orreq r0, r0, #0x40000000 @ set Z \n"\ -" teqp r0, #0\n" \ -" movne r0, %0\n" \ +" orreq ip, ip, #0x40000000 @ set Z \n"\ +" teqp ip, #0\n" \ +" movne ip, %0\n" \ " blne " SYMBOL_NAME_STR(fail) \ : \ : "r" (ptr), "I" (RW_LOCK_BIAS) \ - : "r0", "lr", "cc"); \ + : "ip", "lr", "cc"); \ }) /* Increments by RW_LOCK_BIAS, wakes if value >= 0 */ @@ -112,22 +112,22 @@ ({ \ __asm__ __volatile__( \ "@ up_op_read\n" \ -" mov r0, pc\n" \ -" orr lr, r0, #0x08000000\n" \ +" mov ip, pc\n" \ +" orr lr, ip, #0x08000000\n" \ " teqp lr, #0\n" \ \ " ldr lr, [%0]\n" \ -" and r0, r0, #0x0c000003\n" \ +" and ip, ip, #0x0c000003\n" \ " adds lr, lr, %1\n" \ " str lr, [%0]\n" \ \ -" orrcs r0, r0, #0x20000000 @ set C\n" \ -" teqp r0, #0\n" \ -" movcs r0, %0\n" \ +" orrcs ip, ip, #0x20000000 @ set C\n" \ +" teqp ip, #0\n" \ +" movcs ip, %0\n" \ " blcs " SYMBOL_NAME_STR(wake) \ : \ : "r" (ptr), "I" (RW_LOCK_BIAS) \ - : "r0", "lr", "cc"); \ + : "ip", "lr", "cc"); \ }) #define __down_op_read(ptr,fail) \ @@ -137,22 +137,22 @@ ({ \ __asm__ __volatile__( \ "@ up_op_read\n" \ -" mov r0, pc\n" \ -" orr lr, r0, #0x08000000\n" \ +" mov ip, pc\n" \ +" orr lr, ip, #0x08000000\n" \ " teqp lr, #0\n" \ \ " ldr lr, [%0]\n" \ -" and r0, r0, #0x0c000003\n" \ +" and ip, ip, #0x0c000003\n" \ " adds lr, lr, %1\n" \ " str lr, [%0]\n" \ \ -" orreq r0, r0, #0x40000000 @ Set Z \n" \ -" teqp r0, #0\n" \ -" moveq r0, %0\n" \ +" orreq ip, ip, #0x40000000 @ Set Z \n" \ +" teqp ip, #0\n" \ +" moveq ip, %0\n" \ " bleq " SYMBOL_NAME_STR(wake) \ : \ : "r" (ptr), "I" (1) \ - : "r0", "lr", "cc"); \ + : "ip", "lr", "cc"); \ }) #endif diff --git a/include/asm-arm/proc-armv/assembler.h b/include/asm-arm/proc-armv/assembler.h index aaec7f9c7..6dcd0c307 100644 --- a/include/asm-arm/proc-armv/assembler.h +++ b/include/asm-arm/proc-armv/assembler.h @@ -47,3 +47,24 @@ .macro restore_irqs, oldcpsr msr cpsr_c, \oldcpsr .endm + +/* + * These two are used to save LR/restore PC over a user-based access. + * The old 26-bit architecture requires that we do. On 32-bit + * architecture, we can safely ignore this requirement. + */ + .macro save_lr + .endm + + .macro restore_pc + mov pc, lr + .endm + +#define USER(x...) \ +9999: x; \ + .section __ex_table,"a"; \ + .align 3; \ + .long 9999b,9001f; \ + .previous + + diff --git a/include/asm-arm/proc-armv/system.h b/include/asm-arm/proc-armv/system.h index e05e6356f..cd0730d3b 100644 --- a/include/asm-arm/proc-armv/system.h +++ b/include/asm-arm/proc-armv/system.h @@ -109,6 +109,36 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */ }) /* + * Enable FIQs + */ +#define __stf() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ stf\n" \ +" bic %0, %0, #64\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory"); \ + }) + +/* + * Disable FIQs + */ +#define __clf() \ + ({ \ + unsigned long temp; \ + __asm__ __volatile__( \ + "mrs %0, cpsr @ clf\n" \ +" orr %0, %0, #64\n" \ +" msr cpsr_c, %0" \ + : "=r" (temp) \ + : \ + : "memory"); \ + }) + +/* * save current IRQ & FIQ state */ #define __save_flags(x) \ diff --git a/include/asm-arm/ptrace.h b/include/asm-arm/ptrace.h index 3126767a4..ae4927937 100644 --- a/include/asm-arm/ptrace.h +++ b/include/asm-arm/ptrace.h @@ -3,11 +3,6 @@ #include -#define PTRACE_GETREGS 12 -#define PTRACE_SETREGS 13 -#define PTRACE_GETFPREGS 14 -#define PTRACE_SETFPREGS 15 - #ifndef __ASSEMBLY__ #define pc_pointer(v) \ ((v) & ~PCMASK) @@ -16,6 +11,11 @@ (pc_pointer((regs)->ARM_pc)) #ifdef __KERNEL__ +#define PTRACE_GETREGS 12 +#define PTRACE_SETREGS 13 +#define PTRACE_GETFPREGS 14 +#define PTRACE_SETFPREGS 15 + extern void show_regs(struct pt_regs *); #define predicate(x) (x & 0xf0000000) diff --git a/include/asm-arm/scatterlist.h b/include/asm-arm/scatterlist.h index 7d0175507..73260c410 100644 --- a/include/asm-arm/scatterlist.h +++ b/include/asm-arm/scatterlist.h @@ -1,13 +1,25 @@ #ifndef _ASMARM_SCATTERLIST_H #define _ASMARM_SCATTERLIST_H +#include + 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; + char *address; /* virtual address */ + char *alt_address; /* indirect dma address, or NULL */ + dma_addr_t dma_address; /* dma address */ + unsigned int length; /* length */ }; +/* + * These macros should be used after a pci_map_sg call has been done + * to get bus addresses of each of the SG entries and their lengths. + * You should only work with the number of sg entries pci_map_sg + * returns, or alternatively stop on the first sg_dma_len(sg) which + * is 0. + */ +#define sg_dma_address(sg) ((sg)->dma_address) +#define sg_dma_len(sg) ((sg)->length) + #define ISA_DMA_THRESHOLD (0xffffffff) #endif /* _ASMARM_SCATTERLIST_H */ diff --git a/include/asm-arm/shmparam.h b/include/asm-arm/shmparam.h index 0b94f747d..4359852cc 100644 --- a/include/asm-arm/shmparam.h +++ b/include/asm-arm/shmparam.h @@ -3,6 +3,11 @@ #include +/* + * This should be the size of the virtually indexed cache/ways, + * or page size, whichever is greater since the cache aliases + * every size/ways bytes. + */ #define SHMLBA PAGE_SIZE /* attach addr a multiple of this */ #endif /* _ASMARM_SHMPARAM_H */ diff --git a/include/asm-i386/page.h b/include/asm-i386/page.h index 7a070fa53..03b2ba400 100644 --- a/include/asm-i386/page.h +++ b/include/asm-i386/page.h @@ -75,7 +75,7 @@ typedef struct { unsigned long pgprot; } pgprot_t; * amount of physical memory you can use to about 950MB. * * If you want more physical memory than this then see the CONFIG_HIGHMEM4G - * amd CONFIG_HIGHMEM64G options in the kernel configuration. + * and CONFIG_HIGHMEM64G options in the kernel configuration. */ #define __PAGE_OFFSET (0xC0000000) diff --git a/include/asm-i386/system.h b/include/asm-i386/system.h index 563e53b77..3ae0df618 100644 --- a/include/asm-i386/system.h +++ b/include/asm-i386/system.h @@ -267,8 +267,15 @@ static inline unsigned long __cmpxchg(volatile void *ptr, unsigned long old, * I expect future Intel CPU's to have a weaker ordering, * but I'd also expect them to finally get their act together * and add some real memory barriers if so. + * + * The Pentium III does add a real memory barrier with the + * sfence instruction, so we use that where appropriate. */ +#ifndef CONFIG_X86_XMM #define mb() __asm__ __volatile__ ("lock; addl $0,0(%%esp)": : :"memory") +#else +#define mb() __asm__ __volatile__ ("sfence": : :"memory") +#endif #define rmb() mb() #define wmb() __asm__ __volatile__ ("": : :"memory") #define set_mb(var, value) do { xchg(&var, value); } while (0) diff --git a/include/linux/fs.h b/include/linux/fs.h index 6f52059c7..17f2502cc 100644 --- a/include/linux/fs.h +++ b/include/linux/fs.h @@ -1162,6 +1162,7 @@ extern int block_sync_page(struct page *); int generic_block_bmap(struct address_space *, long, get_block_t *); int generic_commit_write(struct file *, struct page *, unsigned, unsigned); +int block_zero_page(struct address_space *mapping, loff_t, unsigned); extern int generic_file_mmap(struct file *, struct vm_area_struct *); extern ssize_t generic_file_read(struct file *, char *, size_t, loff_t *); diff --git a/include/linux/sched.h b/include/linux/sched.h index 2d22dd614..1530af1cc 100644 --- a/include/linux/sched.h +++ b/include/linux/sched.h @@ -234,7 +234,6 @@ struct mm_struct { struct signal_struct { atomic_t count; struct k_sigaction action[_NSIG]; - struct sigpending pending; spinlock_t siglock; }; @@ -242,7 +241,6 @@ struct signal_struct { #define INIT_SIGNALS { \ ATOMIC_INIT(1), \ { {{0,}}, }, \ - { NULL, &init_signals.pending.head, }, \ SPIN_LOCK_UNLOCKED } /* @@ -582,7 +580,7 @@ static inline int signal_pending(struct task_struct *p) * Re-calculate pending state from the set of locally pending * signals, globally pending signals, and blocked signals. */ -static inline int has_pending_signals(sigset_t *p1, sigset_t *p2, sigset_t *blocked) +static inline int has_pending_signals(sigset_t *signal, sigset_t *blocked) { unsigned long ready; long i; @@ -590,20 +588,20 @@ static inline int has_pending_signals(sigset_t *p1, sigset_t *p2, sigset_t *bloc switch (_NSIG_WORDS) { default: for (i = _NSIG_WORDS, ready = 0; --i >= 0 ;) - ready |= (p1->sig[i] | p2->sig[i]) &~ blocked->sig[i]; + ready |= signal->sig[i] &~ blocked->sig[i]; break; - case 4: ready = (p1->sig[3] | p2->sig[3]) &~ blocked->sig[3]; - ready |= (p1->sig[2] | p2->sig[2]) &~ blocked->sig[2]; - ready |= (p1->sig[1] | p2->sig[1]) &~ blocked->sig[1]; - ready |= (p1->sig[0] | p2->sig[0]) &~ blocked->sig[0]; + case 4: ready = signal->sig[3] &~ blocked->sig[3]; + ready |= signal->sig[2] &~ blocked->sig[2]; + ready |= signal->sig[1] &~ blocked->sig[1]; + ready |= signal->sig[0] &~ blocked->sig[0]; break; - case 2: ready = (p1->sig[1] | p2->sig[1]) &~ blocked->sig[1]; - ready |= (p1->sig[0] | p2->sig[0]) &~ blocked->sig[0]; + case 2: ready = signal->sig[1] &~ blocked->sig[1]; + ready |= signal->sig[0] &~ blocked->sig[0]; break; - case 1: ready = (p1->sig[0] | p2->sig[0]) &~ blocked->sig[0]; + case 1: ready = signal->sig[0] &~ blocked->sig[0]; } return ready != 0; } @@ -614,7 +612,7 @@ static inline int has_pending_signals(sigset_t *p1, sigset_t *p2, sigset_t *bloc static inline void recalc_sigpending(struct task_struct *t) { - t->sigpending = has_pending_signals(&t->pending.signal, &t->sig->pending.signal, &t->blocked); + t->sigpending = has_pending_signals(&t->pending.signal, &t->blocked); } /* True if we are on the alternate signal stack. */ diff --git a/include/linux/signal.h b/include/linux/signal.h index b3c5eb4c2..2da2daa79 100644 --- a/include/linux/signal.h +++ b/include/linux/signal.h @@ -218,6 +218,8 @@ static inline void init_sigpending(struct sigpending *sig) sig->tail = &sig->head; } +extern long do_sigpending(void *, unsigned long); + #endif /* __KERNEL__ */ #endif /* _LINUX_SIGNAL_H */ diff --git a/kernel/fork.c b/kernel/fork.c index 8ef76f185..07e0e9685 100644 --- a/kernel/fork.c +++ b/kernel/fork.c @@ -512,9 +512,6 @@ static inline int copy_sighand(unsigned long clone_flags, struct task_struct * t return -1; spin_lock_init(&sig->siglock); atomic_set(&sig->count, 1); - - init_sigpending(&sig->pending); - memcpy(tsk->sig->action, current->sig->action, sizeof(tsk->sig->action)); return 0; } diff --git a/kernel/ksyms.c b/kernel/ksyms.c index 35c089c80..7d7290c22 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -203,6 +203,7 @@ EXPORT_SYMBOL(block_prepare_write); EXPORT_SYMBOL(block_sync_page); EXPORT_SYMBOL(cont_prepare_write); EXPORT_SYMBOL(generic_commit_write); +EXPORT_SYMBOL(block_zero_page); EXPORT_SYMBOL(generic_block_bmap); EXPORT_SYMBOL(generic_file_read); EXPORT_SYMBOL(do_generic_file_read); diff --git a/kernel/signal.c b/kernel/signal.c index caa59d512..d0319aee6 100644 --- a/kernel/signal.c +++ b/kernel/signal.c @@ -50,31 +50,30 @@ void __init signals_init(void) static int next_signal(struct task_struct *tsk, sigset_t *mask) { - unsigned long i, *s1, *s2, *m, x; + unsigned long i, *s, *m, x; int sig = 0; - s1 = tsk->pending.signal.sig; - s2 = tsk->sig->pending.signal.sig; + s = tsk->pending.signal.sig; m = mask->sig; switch (_NSIG_WORDS) { default: - for (i = 0; i < _NSIG_WORDS; ++i, ++s1, ++s2, ++m) - if ((x = (*s1 | *s2) &~ *m) != 0) { + for (i = 0; i < _NSIG_WORDS; ++i, ++s, ++m) + if ((x = *s &~ *m) != 0) { sig = ffz(~x) + i*_NSIG_BPW + 1; break; } break; - case 2: if ((x = (s1[0] | s2[0]) &~ m[0]) != 0) + case 2: if ((x = s[0] &~ m[0]) != 0) sig = 1; - else if ((x = (s1[1] | s2[1]) &~ m[1]) != 0) + else if ((x = s[1] &~ m[1]) != 0) sig = _NSIG_BPW + 1; else break; sig += ffz(~x); break; - case 1: if ((x = (*s1 | *s2) &~ *m) != 0) + case 1: if ((x = *s &~ *m) != 0) sig = ffz(~x) + 1; break; } @@ -108,7 +107,6 @@ flush_signals(struct task_struct *t) { t->sigpending = 0; flush_sigqueue(&t->pending); - flush_sigqueue(&t->pending); } void exit_sighand(struct task_struct *tsk) @@ -118,10 +116,8 @@ void exit_sighand(struct task_struct *tsk) spin_lock_irq(&tsk->sigmask_lock); if (sig) { tsk->sig = NULL; - if (atomic_dec_and_test(&sig->count)) { - flush_sigqueue(&sig->pending); + if (atomic_dec_and_test(&sig->count)) kmem_cache_free(sigact_cachep, sig); - } } tsk->sigpending = 0; flush_sigqueue(&tsk->pending); @@ -256,8 +252,7 @@ printk("SIG dequeue (%s:%d): %d ", current->comm, current->pid, if (sig) { if (!collect_signal(sig, ¤t->pending, info)) - if (!collect_signal(sig, ¤t->sig->pending, info)) - sig = 0; + sig = 0; /* XXX: Once POSIX.1b timers are in, if si_code == SI_TIMER, we need to xchg out the timer overrun values. */ @@ -303,7 +298,7 @@ static int rm_from_queue(int sig, struct sigpending *s) */ static int rm_sig_from_queue(int sig, struct task_struct *t) { - return rm_from_queue(sig, &t->pending) | rm_from_queue(sig, &t->sig->pending); + return rm_from_queue(sig, &t->pending); } /* @@ -494,69 +489,6 @@ static inline void signal_wake_up(struct task_struct *t) #endif /* CONFIG_SMP */ } -/* - * Send a thread-group-wide signal. - * - * Just add it to the shared signal queue. And - * make sure to inform everybody. - */ -static int send_tg_sig_info(int sig, struct siginfo *info, struct task_struct *p) -{ - int retval, type; - struct task_struct *tsk; - - if (sig < 0 || sig > _NSIG) - return -EINVAL; - - if (bad_signal(sig, info, p)) - return -EPERM; - - if (!sig || !p->sig) - return 0; - - /* Have we already delivered this non-queued signal? */ - if (sig < SIGRTMIN && sigismember(&p->sig->pending.signal, sig)) - return 0; - - /* Add the signal to the global queue */ - retval = send_signal(sig, info, &p->sig->pending); - if (retval < 0) - return retval; - - type = signal_type(sig, p->sig); - - /* Inform all threads about it.. */ - tsk = p; - do { - unsigned long flags; - - /* Zombie? Ignore */ - if (!tsk->sig) - continue; - - spin_lock_irqsave(&tsk->sigmask_lock, flags); - handle_stop_signal(sig, tsk); - - /* Blocked? */ - if (sigismember(&tsk->blocked, sig)) - goto next; - - /* Is the signal ignored by this thread? */ - switch (type) { - case 0: - goto next; - case -1: /* affects all threads? */ - sigaddset(&tsk->pending.signal, sig); - } - - /* Go, girl, go! */ - signal_wake_up(tsk); -next: - spin_unlock_irqrestore(&tsk->sigmask_lock, flags); - } while ((tsk = next_thread(tsk)) != p); - return 0; -} - static int deliver_signal(int sig, struct siginfo *info, struct task_struct *t) { int retval = send_signal(sig, info, &t->pending); @@ -716,34 +648,6 @@ kill_proc_info(int sig, struct siginfo *info, pid_t pid) /* - * Send a signal to a thread group.. - * - * If the pid is the thread group ID, we consider this - * a "thread group" signal. Otherwise it degenerates into - * a thread-specific signal. - */ -static int kill_tg_info(int sig, struct siginfo *info, pid_t pid) -{ - int error; - struct task_struct *p; - - read_lock(&tasklist_lock); - p = find_task_by_pid(pid); - error = -ESRCH; - if (p) { - /* Is it the leader? Otherwise it degenerates into a per-thread thing */ - if (p->tgid == pid) { - spin_lock(&p->sig->siglock); - error = send_tg_sig_info(sig, info, p); - spin_unlock(&p->sig->siglock); - } else - error = send_sig_info(sig, info, p); - } - read_unlock(&tasklist_lock); - return error; -} - -/* * kill_something_info() interprets pid in interesting ways just like kill(2). * * POSIX specifies that kill(-1,sig) is unspecified, but what we have @@ -772,7 +676,7 @@ static int kill_something_info(int sig, struct siginfo *info, int pid) } else if (pid < 0) { return kill_pg_info(sig, info, -pid); } else { - return kill_tg_info(sig, info, pid); + return kill_proc_info(sig, info, pid); } } @@ -975,26 +879,29 @@ out: return error; } -asmlinkage long -sys_rt_sigpending(sigset_t *set, size_t sigsetsize) +long do_sigpending(void *set, unsigned long sigsetsize) { - int error = -EINVAL; + long error = -EINVAL; sigset_t pending; - /* XXX: Don't preclude handling different sized sigset_t's. */ - if (sigsetsize != sizeof(sigset_t)) + if (sigsetsize > sizeof(sigset_t)) goto out; spin_lock_irq(¤t->sigmask_lock); - sigorsets(&pending, ¤t->pending.signal, ¤t->sig->pending.signal); - sigandsets(&pending, ¤t->blocked, &pending); + sigandsets(&pending, ¤t->blocked, ¤t->pending.signal); spin_unlock_irq(¤t->sigmask_lock); error = -EFAULT; - if (!copy_to_user(set, &pending, sizeof(*set))) + if (!copy_to_user(set, &pending, sigsetsize)) error = 0; out: return error; +} + +asmlinkage long +sys_rt_sigpending(sigset_t *set, size_t sigsetsize) +{ + return do_sigpending(set, sigsetsize); } asmlinkage long @@ -1098,7 +1005,7 @@ sys_rt_sigqueueinfo(int pid, int sig, siginfo_t *uinfo) info.si_signo = sig; /* POSIX.1b doesn't mention process groups. */ - return kill_tg_info(sig, &info, pid); + return kill_proc_info(sig, &info, pid); } int @@ -1218,6 +1125,12 @@ out: return error; } +asmlinkage long +sys_sigpending(old_sigset_t *set) +{ + return do_sigpending(set, sizeof(*set)); +} + #if !defined(__alpha__) /* Alpha has its own versions with special arguments. */ @@ -1270,22 +1183,6 @@ out: return error; } -asmlinkage long -sys_sigpending(old_sigset_t *set) -{ - int error; - old_sigset_t pending; - - spin_lock_irq(¤t->sigmask_lock); - pending = current->blocked.sig[0] & (current->pending.signal.sig[0] | current->sig->pending.signal.sig[0]); - spin_unlock_irq(¤t->sigmask_lock); - - error = -EFAULT; - if (!copy_to_user(set, &pending, sizeof(*set))) - error = 0; - return error; -} - #ifndef __sparc__ asmlinkage long sys_rt_sigaction(int sig, const struct sigaction *act, struct sigaction *oact, diff --git a/net/ax25/af_ax25.c b/net/ax25/af_ax25.c index 8723b1263..fc8910f2d 100644 --- a/net/ax25/af_ax25.c +++ b/net/ax25/af_ax25.c @@ -1598,8 +1598,8 @@ static int ax25_ioctl(struct socket *sock, unsigned int cmd, unsigned long arg) if (sk != NULL) { if (sk->stamp.tv_sec == 0) return -ENOENT; - return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) : -EFAULT : 0; - } + return copy_to_user((void *)arg, &sk->stamp, sizeof(struct timeval)) ? -EFAULT : 0; + } return -EINVAL; case SIOCAX25ADDUID: /* Add a uid to the uid/call map table */ -- 2.11.4.GIT