Commit 3db9dee5 authored by Linus Torvalds's avatar Linus Torvalds

- 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
parent e6c596f3
......@@ -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 */
......
......@@ -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(&current->sigmask_lock);
sigandsets(&pending, &current->blocked, &current->signal);
spin_unlock_irq(&current->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(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
/* NOTREACHED */
......
......@@ -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
......@@ -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
......
......@@ -23,4 +23,4 @@ initrd.o: $(INITRD)
.PHONY: $(INITRD) $(ZSYSTEM)
clean:; $(RM) bootp bootp.lds
clean:; $(RM) bootp
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) }
}
/*
* 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 */
/*
* 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
......@@ -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
......
......@@ -45,6 +45,12 @@ SCR_loc: .long SYMBOL_NAME(SCR_value)
#define GPIO_2_9 0x3fc
/*
* void sa1100_setup( int arch_id );
*
* This is called from decompress_kernel() with the arch_decomp_setup() macro.
*/
/*
* void sa1100_setup( int arch_id );
*
......@@ -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
......
......@@ -10,16 +10,14 @@
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/page.h> /* for BUG() */
#include <asm/irq.h>
#include <asm/mach-types.h>
#include "bios32.h"
#include <asm/mach/pci.h>
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.
*/
......@@ -318,18 +327,6 @@ void __init pcibios_fixup_bus(struct pci_bus *bus)
u16 cmd;
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
......@@ -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);
......
......@@ -17,7 +17,7 @@
#include <asm/irq.h>
#include <asm/system.h>
#include "bios32.h"
#include <asm/mach/pci.h>
#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");
/*
......
......@@ -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);
......
......@@ -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
......@@ -280,8 +280,8 @@ void exit_thread(void)
void flush_thread(void)
{
memset(&current->thread.debug, 0, sizeof(current->thread.debug));
memset(&current->thread.fpstate, 0, sizeof(current->thread.fpstate));
memset(&current->thread.debug, 0, sizeof(struct debug_info));
memset(&current->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;
......
......@@ -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;
}
......
......@@ -587,7 +587,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs, int syscall)
/* FALLTHRU */
default:
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -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
......
......@@ -10,26 +10,26 @@
#include <asm/assembler.h>
#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
......@@ -40,4 +40,3 @@ ENTRY(__delay)
subs r0, r0, #1
bcs SYMBOL_NAME(__delay)
RETINSTR(mov,pc,lr)
/*
* linux/arch/arm/lib/memchr.S
*
* Copyright (C) 1995-1999 Russell King
* Copyright (C) 1995-2000 Russell King
*
* ASM optimised string functions
*
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#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)
......@@ -4,7 +4,6 @@
* Copyright (C) 1995-1999 Russell King
*
* ASM optimised string functions
*
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
......@@ -314,5 +313,3 @@ ENTRY(memmove)
b 24b
.align
/*
* linux/arch/arm/lib/memset.S
*
* Copyright (C) 1995-1999 Russell King
* Copyright (C) 1995-2000 Russell King
*
* ASM optimised string functions
*
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#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})
.text
.align 5
.word 0
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
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.
*/
6: subs r2, r2, #1
strgeb r1, [r3], #1
bgt 6b
RETINSTR(mov, pc, lr)
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)
/*
* linux/arch/arm/lib/memzero.S
*
* Copyright (C) 1995-1999 Russell King
* Copyright (C) 1995-2000 Russell King
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include "constants.h"
.text
.text
.align 5
.word 0
/*
* Prototype: void memzero(void *d, size_t n)
* 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.
*/
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
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
/*
* linux/arch/arm/lib/strchr.S
*
* Copyright (C) 1995-1999 Russell King
* Copyright (C) 1995-2000 Russell King
*
* ASM optimised string functions
*
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#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)
/*
* linux/arch/arm/lib/strncpy_from_user.S
*
* Copyright (C) 1995-2000 Russell King
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/errno.h>
.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
/*
* linux/arch/arm/lib/strnlen_user.S
*
* Copyright (C) 1995-2000 Russell King
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#include <asm/errno.h>
.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
/*
* linux/arch/arm/lib/strrchr.S
*
* Copyright (C) 1995-1999 Russell King
* Copyright (C) 1995-2000 Russell King
*
* ASM optimised string functions
*
*/
#include <linux/linkage.h>
#include <asm/assembler.h>
#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)
......@@ -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
......
......@@ -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
#
# 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
/*
* 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 <linux/config.h>
#include <linux/tty.h>
#include <linux/delay.h>
#include <linux/pm.h>
#include <linux/init.h>
#include <asm/dec21285.h>
#include <asm/elf.h>
#include <asm/setup.h>
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
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
/*
* linux/arch/arm/mach-footbridge/cats-hw.c
*
* CATS machine fixup
*
* Copyright (C) 1998, 1999 Russell King, Phil Blundell
*/
#include <linux/sched.h>
#include <linux/ioport.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <asm/io.h>
#include <asm/mach-types.h>
#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);
/*
* linux/arch/arm/mach-footbridge/cats-pci.c
*
* PCI bios-type initialisation for PCI machines
*
* Bits taken from various places.
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
/* 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,
};
/*
* 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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <asm/hardware.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/system.h>
#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);
/*
* linux/arch/arm/mach-footbridge/ebsa285-pci.c
*
* PCI bios-type initialisation for PCI machines
*
* Bits taken from various places.
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
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,
};
This diff is collapsed.
/*
* 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 <linux/module.h>
#include <linux/kernel.h>
#include <linux/init.h>
#include <linux/spinlock.h>
#include <asm/hardware.h>
#include <asm/leds.h>
#include <asm/mach-types.h>
#include <asm/system.h>
#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);
/*
* linux/arch/arm/mach-footbridge/netwinder-pci.c
*
* PCI bios-type initialisation for PCI machines
*
* Bits taken from various places.
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
/* 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,
};
/*
* linux/arch/arm/mach-footbridge/personal-pci.c
*
* PCI bios-type initialisation for PCI machines
*
* Bits taken from various places.
*/
#include <linux/kernel.h>
#include <linux/pci.h>
#include <linux/init.h>
#include <asm/irq.h>
#include <asm/mach/pci.h>
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,
};
......@@ -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
......
......@@ -79,9 +79,10 @@ SECTIONS
.bss : {
__bss_start = .; /* BSS */
__bss_start = .; /* BSS */
*(.bss)
_end = . ;
*(COMMON)
_end = . ;
}
/* Stabs debugging sections. */
......
......@@ -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 = .;
......
......@@ -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;
......
......@@ -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;
......
......@@ -570,7 +570,7 @@ ia64_do_signal (sigset_t *oldset, struct sigscratch *scr, long in_syscall)
/* FALLTHRU */
default:
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -1137,7 +1137,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */
default:
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -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;
......
......@@ -264,7 +264,7 @@ asmlinkage int do_irix_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */
default:
sigaddset(&current->signal, signr);
sigaddset(&current->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(&current->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(&current->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 (&current->signal, sig)) {
if (sigismember (&current->pending.signal, sig)) {
/* XXX need more than this... */
if (info)
info->sig = sig;
......
......@@ -662,7 +662,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */
default:
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -695,7 +695,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs *regs)
/* FALLTHRU */
default:
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -773,7 +773,7 @@ printk("%s: delivering signal.\n", current->comm);
/* FALLTHRU */
default:
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -646,7 +646,7 @@ int do_signal(sigset_t *oldset, struct pt_regs *regs)
default:
lock_kernel();
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -528,7 +528,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
default:
lock_kernel();
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -672,7 +672,7 @@ int do_signal(struct pt_regs *regs, sigset_t *oldset)
/* FALLTHRU */
default:
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -1282,7 +1282,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
#endif
/* fall through */
default:
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -784,7 +784,7 @@ asmlinkage int do_signal(sigset_t *oldset, struct pt_regs * regs,
#endif
/* fall through */
default:
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -1420,7 +1420,7 @@ asmlinkage int do_signal32(sigset_t *oldset, struct pt_regs * regs,
#endif
/* fall through */
default:
sigaddset(&current->signal, signr);
sigaddset(&current->pending.signal, signr);
recalc_sigpending(current);
current->flags |= PF_SIGNALED;
do_exit(exit_code);
......
......@@ -311,7 +311,7 @@ asmlinkage int solaris_sigpending(int which, u32 set)
switch (which) {
case 1: /* sigpending */
spin_lock_irq(&current->sigmask_lock);
sigandsets(&s, &current->blocked, &current->signal);
sigandsets(&s, &current->blocked, &current->pending.signal);
recalc_sigpending(current);
spin_unlock_irq(&current->sigmask_lock);
break;
......
......@@ -794,8 +794,8 @@ void ftape_disable(void)
i, *ft_buffer[i]->address);
}
}
if (sigtestsetmask(&current->signal, _DONT_BLOCK) &&
!(sigtestsetmask(&current->signal, _NEVER_BLOCK)) &&
if (sigtestsetmask(&current->pending.signal, _DONT_BLOCK) &&
!(sigtestsetmask(&current->pending.signal, _NEVER_BLOCK)) &&
ftape_tape_running) {
TRACE(ft_t_warn,
"Interrupted by fatal signal and tape still running");
......
......@@ -433,7 +433,7 @@ int ftape_dumb_stop(void)
result = ftape_ready_wait(ftape_timeout.pause,&status);
}
} while (ftape_tape_running
&& !(sigtestsetmask(&current->signal, _NEVER_BLOCK)));
&& !(sigtestsetmask(&current->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(&current->signal, _DONT_BLOCK)) {
sigtestsetmask(&current->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(&current->signal, _DONT_BLOCK))) {
(sigtestsetmask(&current->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(&current->signal, _DONT_BLOCK))) {
!(sigtestsetmask(&current->pending.signal, _DONT_BLOCK))) {
if (retry && start_offset < 5) {
start_offset ++;
......
......@@ -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(&current->signal, sig_mask)) { \
if (sigtestsetmask(&current->pending.signal, sig_mask)) { \
TRACE_ABORT(-EINTR, \
ft_t_warn, \
"interrupted by non-blockable signal"); \
......
......@@ -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
......
......@@ -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;
......
......@@ -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 ... */
......
......@@ -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)
......
......@@ -641,7 +641,7 @@ smb_request(struct smb_sb_info *server)
DEBUG1("len = %d cmd = 0x%X\n", len, buffer[8]);
spin_lock_irqsave(&current->sigmask_lock, flags);
sigpipe = sigismember(&current->signal, SIGPIPE);
sigpipe = sigismember(&current->pending.signal, SIGPIPE);
old_set = current->blocked;
siginitsetinv(&current->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(&current->sigmask_lock, flags);
if (result == -EPIPE && !sigpipe)
sigdelset(&current->signal, SIGPIPE);
sigdelset(&current->pending.signal, SIGPIPE);
current->blocked = old_set;
recalc_sigpending(current);
spin_unlock_irqrestore(&current->sigmask_lock, flags);
......@@ -821,7 +821,7 @@ smb_trans2_request(struct smb_sb_info *server, __u16 trans2_command,
goto bad_conn;
spin_lock_irqsave(&current->sigmask_lock, flags);
sigpipe = sigismember(&current->signal, SIGPIPE);
sigpipe = sigismember(&current->pending.signal, SIGPIPE);
old_set = current->blocked;
siginitsetinv(&current->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(&current->sigmask_lock, flags);
if (result == -EPIPE && !sigpipe)
sigdelset(&current->signal, SIGPIPE);
sigdelset(&current->pending.signal, SIGPIPE);
current->blocked = old_set;
recalc_sigpending(current);
spin_unlock_irqrestore(&current->sigmask_lock, flags);
......
......@@ -168,5 +168,7 @@ static __inline__ void irq_init_irq(void)
}
}
irq_mask[IRQ_KEYBOARDTX].noautoenable = 1;
init_FIQ();
}
......@@ -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);
}
/*
......
......@@ -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
......
......@@ -3,6 +3,7 @@
*
* Copyright (C) 1996-1999 Russell King
*/
#include <asm/mach-types.h>
/*
* Note! This could cause problems on the NetWinder
......
......@@ -63,4 +63,6 @@
#define INTCONT_LED 0x1a
#define INTCONT_PCI_RESET 0x1c
#define UNCACHEABLE_ADDR STATUS_BASE
#endif
......@@ -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);
}
......@@ -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++));
}
}
/*
......
......@@ -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();
}
#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())
......
......@@ -7,6 +7,7 @@ typedef unsigned int dmach_t;
#include <linux/spinlock.h>
#include <asm/system.h>
#include <asm/memory.h>
#include <asm/scatterlist.h>
#include <asm/arch/dma.h>
/*
......
/*
* 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
/*
* 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);
/*
* 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);
/*
* 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 *);
......@@ -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.
......
......@@ -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
......@@ -13,11 +13,10 @@
*/
#include <asm/proc/cache.h>
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
......
......@@ -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
/*
* 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)
......
......@@ -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
......@@ -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
......@@ -108,6 +108,36 @@ extern unsigned long cr_alignment; /* defined in entry-armv.S */
: "memory"); \
})
/*
* 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
*/
......
......@@ -3,11 +3,6 @@
#include <asm/proc/ptrace.h>
#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)
......
#ifndef _ASMARM_SCATTERLIST_H
#define _ASMARM_SCATTERLIST_H
#include <asm/types.h>
struct scatterlist {
char * address; /* Location data is to be transferred to */
char * alt_address; /* Location of actual if address is a
* dma indirect buffer. NULL otherwise */
unsigned int length;
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 */
......@@ -3,6 +3,11 @@
#include <asm/proc/shmparam.h>
/*
* 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 */
......@@ -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)
......
......@@ -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)
......
......@@ -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 *);
......
......@@ -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. */
......
......@@ -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 */
......@@ -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;
}
......
......@@ -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);
......
......@@ -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, &current->pending, info))
if (!collect_signal(sig, &current->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);
......@@ -715,34 +647,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).
*
......@@ -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 @@ sys_rt_sigprocmask(int how, sigset_t *set, sigset_t *oset, size_t sigsetsize)
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(&current->sigmask_lock);
sigorsets(&pending, &current->pending.signal, &current->sig->pending.signal);
sigandsets(&pending, &current->blocked, &pending);
sigandsets(&pending, &current->blocked, &current->pending.signal);
spin_unlock_irq(&current->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 @@ do_sigaltstack (const stack_t *uss, stack_t *uoss, unsigned long sp)
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 @@ sys_sigprocmask(int how, old_sigset_t *set, old_sigset_t *oset)
return error;
}
asmlinkage long
sys_sigpending(old_sigset_t *set)
{
int error;
old_sigset_t pending;
spin_lock_irq(&current->sigmask_lock);
pending = current->blocked.sig[0] & (current->pending.signal.sig[0] | current->sig->pending.signal.sig[0]);
spin_unlock_irq(&current->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,
......
This diff is collapsed.
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment