From 33206b5f49735400e5d645f80e4b71172ff3c592 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:33:38 -0500 Subject: [PATCH] Import 2.3.99pre4-2 --- Makefile | 6 +- Rules.make | 2 +- arch/alpha/boot/Makefile | 4 +- arch/alpha/kernel/Makefile | 4 +- arch/arm/kernel/Makefile | 4 +- arch/arm/lib/Makefile | 2 +- arch/arm/mm/Makefile | 2 +- arch/i386/kernel/Makefile | 2 +- arch/i386/lib/Makefile | 2 +- arch/i386/math-emu/Makefile | 2 +- arch/ia64/boot/Makefile | 4 +- arch/ia64/dig/Makefile | 4 +- arch/ia64/ia32/Makefile | 4 +- arch/ia64/kdb/Makefile | 2 +- arch/ia64/kernel/Makefile | 4 +- arch/ia64/lib/Makefile | 2 +- arch/ia64/sn/Makefile | 4 +- arch/ia64/sn/sn1/Makefile | 4 +- arch/m68k/fpsp040/Makefile | 2 +- arch/m68k/ifpsp060/Makefile | 2 +- arch/m68k/kernel/Makefile | 2 +- arch/m68k/lib/Makefile | 2 +- arch/m68k/math-emu/Makefile | 2 +- arch/m68k/sun3/Makefile | 2 +- arch/ppc/boot/Makefile | 4 +- arch/ppc/chrpboot/Makefile | 4 +- arch/ppc/lib/Makefile | 2 +- arch/ppc/mbxboot/Makefile | 4 +- arch/sh/kernel/Makefile | 4 +- arch/sh/lib/Makefile | 2 +- arch/sparc/config.in | 2 +- arch/sparc/kernel/Makefile | 10 +- arch/sparc/kernel/ioport.c | 50 +- arch/sparc/kernel/setup.c | 9 +- arch/sparc/lib/Makefile | 4 +- arch/sparc/math-emu/Makefile | 4 +- arch/sparc/mm/Makefile | 15 +- arch/sparc64/config.in | 2 +- arch/sparc64/kernel/Makefile | 12 +- arch/sparc64/kernel/entry.S | 39 +- arch/sparc64/kernel/etrap.S | 309 +++++------ arch/sparc64/kernel/ioctl32.c | 21 +- arch/sparc64/kernel/rtrap.S | 253 ++++----- arch/sparc64/kernel/semaphore.c | 10 +- arch/sparc64/kernel/smp.c | 96 ++-- arch/sparc64/kernel/sparc64_ksyms.c | 9 +- arch/sparc64/lib/Makefile | 8 +- arch/sparc64/lib/bitops.S | 110 ++++ arch/sparc64/lib/blockops.S | 42 +- arch/sparc64/mm/Makefile | 4 +- arch/sparc64/mm/fault.c | 6 +- arch/sparc64/mm/ultra.S | 22 +- arch/sparc64/prom/Makefile | 4 +- arch/sparc64/solaris/Makefile | 4 +- arch/sparc64/solaris/socksys.c | 3 +- drivers/char/cpia_usb.c | 1 - drivers/net/eepro100.c | 14 +- drivers/net/tokenring/Config.in | 4 +- drivers/parport/parport_sunbpp.c | 4 +- drivers/scsi/esp.c | 9 +- drivers/scsi/esp.h | 4 +- drivers/scsi/hosts.h | 2 + drivers/scsi/scsi.c | 2 + drivers/usb/Config.in | 6 +- drivers/usb/evdev.c | 50 +- drivers/usb/hub.c | 1 + drivers/usb/input.c | 67 ++- drivers/usb/joydev.c | 65 ++- drivers/usb/mousedev.c | 134 ++--- drivers/usb/serial/usb-serial.h | 1 + drivers/usb/usb-debug.c | 1 + drivers/usb/usb-ohci.c | 13 +- fs/inode.c | 5 +- include/asm-sparc/io.h | 27 +- include/asm-sparc/page.h | 19 +- include/asm-sparc/pgtable.h | 8 +- include/asm-sparc64/asm_offsets.h | 12 +- include/asm-sparc64/bitops.h | 188 +------ include/asm-sparc64/io.h | 64 ++- include/asm-sparc64/pgalloc.h | 26 +- include/asm-sparc64/pgtable.h | 71 +-- include/asm-sparc64/processor.h | 6 +- include/asm-sparc64/system.h | 14 +- include/linux/input.h | 8 +- include/linux/mm.h | 6 +- include/linux/netfilter_ipv4/ip_queue.h | 36 +- include/linux/swap.h | 2 + include/net/sock.h | 2 +- mm/filemap.c | 59 +-- net/bridge/br_input.c | 6 +- net/core/skbuff.c | 2 +- net/ipv4/netfilter/ip_conntrack_proto_icmp.c | 1 + net/ipv4/netfilter/ip_conntrack_proto_tcp.c | 1 + net/ipv4/netfilter/ip_conntrack_proto_udp.c | 1 + net/ipv4/netfilter/ip_fw_compat_masq.c | 1 + net/ipv4/netfilter/ip_queue.c | 514 ++++++------------- net/ipx/af_spx.c | 6 +- 97 files changed, 1301 insertions(+), 1300 deletions(-) create mode 100644 arch/sparc64/lib/bitops.S diff --git a/Makefile b/Makefile index 3b4be0eff5bf..4dedcf39a9ec 100644 --- a/Makefile +++ b/Makefile @@ -88,7 +88,7 @@ CPPFLAGS += -D__SMP__ endif CFLAGS := $(CPPFLAGS) -Wall -Wstrict-prototypes -O2 -fomit-frame-pointer -AFLAGS := $(CPPFLAGS) -D__ASSEMBLY__ -traditional +AFLAGS := -D__ASSEMBLY__ $(CPPFLAGS) # use '-fno-strict-aliasing', but only if the compiler can take it CFLAGS += $(shell if $(CC) -fno-strict-aliasing -S -o /dev/null -xc /dev/null >/dev/null 2>&1; then echo "-fno-strict-aliasing"; fi) @@ -185,9 +185,9 @@ include arch/$(ARCH)/Makefile export NETWORKS DRIVERS LIBS HEAD LDFLAGS LINKFLAGS MAKEBOOT ASFLAGS .S.s: - $(CPP) $(AFLAGS) -o $*.s $< + $(CPP) $(AFLAGS) -traditional -o $*.s $< .S.o: - $(CC) $(AFLAGS) -c -o $*.o $< + $(CC) $(AFLAGS) -traditional -c -o $*.o $< Version: dummy @rm -f include/linux/compile.h diff --git a/Rules.make b/Rules.make index b1dd7c429c7f..d3e51bbecb28 100644 --- a/Rules.make +++ b/Rules.make @@ -48,7 +48,7 @@ first_rule: sub_dirs $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -S $< -o $@ %.i: %.c - $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -E $< > $@ + $(CPP) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) $< > $@ %.o: %.c $(CC) $(CFLAGS) $(EXTRA_CFLAGS) $(CFLAGS_$@) -c -o $@ $< diff --git a/arch/alpha/boot/Makefile b/arch/alpha/boot/Makefile index ee2ac0ac0d22..6bd6cb03f348 100644 --- a/arch/alpha/boot/Makefile +++ b/arch/alpha/boot/Makefile @@ -11,9 +11,9 @@ LINKFLAGS = -static -T bootloader.lds #-N -relax .S.s: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -E -o $*.o $< + $(CPP) $(AFLAGS) -traditional -o $*.o $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< + $(CC) $(AFLAGS) -traditional -c -o $*.o $< OBJECTS = head.o main.o BPOBJECTS = head.o bootp.o diff --git a/arch/alpha/kernel/Makefile b/arch/alpha/kernel/Makefile index 9d87b6e0c218..3a0a4ec0bf2e 100644 --- a/arch/alpha/kernel/Makefile +++ b/arch/alpha/kernel/Makefile @@ -8,9 +8,9 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.s: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -E -o $*.s $< + $(CPP) $(AFLAGS) -o $*.s $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $< + $(CC) $(AFLAGS) -c -o $*.o $< O_TARGET := kernel.o O_OBJS := entry.o traps.o process.o osf_sys.o irq.o irq_alpha.o \ diff --git a/arch/arm/kernel/Makefile b/arch/arm/kernel/Makefile index c454c1350602..6cc5652e0226 100644 --- a/arch/arm/kernel/Makefile +++ b/arch/arm/kernel/Makefile @@ -59,12 +59,12 @@ MX_OBJS := $(sort $(filter $(export-objs), $(obj-m))) all: kernel.o $(HEAD_OBJ) init_task.o $(HEAD_OBJ): $(HEAD_OBJ:.o=.S) - $(CC) -D__ASSEMBLY__ $(AFLAGS) -DTEXTADDR=$(TEXTADDR) -traditional -c $(HEAD_OBJ:.o=.S) -o $@ + $(CC) $(AFLAGS) -DTEXTADDR=$(TEXTADDR) -traditional -c $(HEAD_OBJ:.o=.S) -o $@ include $(TOPDIR)/Rules.make .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_$@) -c -o $*.o $< + $(CC) $(AFLAGS) $(AFLAGS_$@) -c -o $*.o $< # Spell out some dependencies that `make dep' doesn't spot entry-armv.o: calls.S ../lib/constants.h diff --git a/arch/arm/lib/Makefile b/arch/arm/lib/Makefile index 510a3845173d..5f48f951abf3 100644 --- a/arch/arm/lib/Makefile +++ b/arch/arm/lib/Makefile @@ -37,7 +37,7 @@ L_OBJS += $(L_OBJS_$(MACHINE)) include $(TOPDIR)/Rules.make .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< + $(CC) $(AFLAGS) -traditional -c -o $*.o $< constants.h: getconsdata.o extractconstants.pl $(PERL) extractconstants.pl $(OBJDUMP) > $@ diff --git a/arch/arm/mm/Makefile b/arch/arm/mm/Makefile index 1c02473bbd36..26d7f1058644 100644 --- a/arch/arm/mm/Makefile +++ b/arch/arm/mm/Makefile @@ -34,7 +34,7 @@ endif include $(TOPDIR)/Rules.make .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) $(AFLAGS_$@) -traditional -c -o $*.o $< + $(CC) $(AFLAGS) $(AFLAGS_$@) -traditional -c -o $*.o $< # Special dependencies fault-armv.o: fault-common.c diff --git a/arch/i386/kernel/Makefile b/arch/i386/kernel/Makefile index 525bb2c07c8b..64b3d095166a 100644 --- a/arch/i386/kernel/Makefile +++ b/arch/i386/kernel/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + $(CC) $(AFLAGS) -traditional -c $< -o $*.o all: kernel.o head.o init_task.o diff --git a/arch/i386/lib/Makefile b/arch/i386/lib/Makefile index 5c824c08ce06..2394245a67c8 100644 --- a/arch/i386/lib/Makefile +++ b/arch/i386/lib/Makefile @@ -3,7 +3,7 @@ # .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + $(CC) $(AFLAGS) -traditional -c $< -o $*.o L_TARGET = lib.a L_OBJS = checksum.o old-checksum.o delay.o \ diff --git a/arch/i386/math-emu/Makefile b/arch/i386/math-emu/Makefile index 68b327a2acd5..5564d87125f4 100644 --- a/arch/i386/math-emu/Makefile +++ b/arch/i386/math-emu/Makefile @@ -10,7 +10,7 @@ PARANOID = -DPARANOID CFLAGS := $(CFLAGS) $(PARANOID) $(DEBUG) -fno-builtin $(MATH_EMULATION) .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) $(PARANOID) -c $< + $(CC) $(AFLAGS) $(PARANOID) -c $< # From 'C' language sources: C_OBJS =fpu_entry.o errors.o \ diff --git a/arch/ia64/boot/Makefile b/arch/ia64/boot/Makefile index cba4fad66250..5228d6c57eaf 100644 --- a/arch/ia64/boot/Makefile +++ b/arch/ia64/boot/Makefile @@ -11,9 +11,9 @@ LINKFLAGS = -static -T bootloader.lds .S.s: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -E -o $*.o $< + $(CPP) $(AFLAGS) -traditional -o $*.o $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< + $(CC) $(AFLAGS) -traditional -c -o $*.o $< OBJECTS = bootloader.o TARGETS = diff --git a/arch/ia64/dig/Makefile b/arch/ia64/dig/Makefile index cfc48eec1d49..8d0544ee52cf 100644 --- a/arch/ia64/dig/Makefile +++ b/arch/ia64/dig/Makefile @@ -6,9 +6,9 @@ # .S.s: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -E -o $*.s $< + $(CPP) $(AFLAGS) -o $*.s $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $< + $(CC) $(AFLAGS) -c -o $*.o $< all: dig.a diff --git a/arch/ia64/ia32/Makefile b/arch/ia64/ia32/Makefile index 674a6eb6e3aa..82017941c3c2 100644 --- a/arch/ia64/ia32/Makefile +++ b/arch/ia64/ia32/Makefile @@ -3,9 +3,9 @@ # .S.s: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -E -o $*.s $< + $(CPP) $(AFLAGS) -o $*.s $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $< + $(CC) $(AFLAGS) -c -o $*.o $< all: ia32.o diff --git a/arch/ia64/kdb/Makefile b/arch/ia64/kdb/Makefile index 0b29d6b35004..2e8db3fc4f72 100644 --- a/arch/ia64/kdb/Makefile +++ b/arch/ia64/kdb/Makefile @@ -13,7 +13,7 @@ MOD_SUB_DIRS := $(SUB_DIRS) ALL_SUB_DIRS := $(SUB_DIRS) .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + $(CC) $(AFLAGS) -traditional -c $< -o $*.o L_TARGET = kdb.a L_OBJS = kdbsupport.o kdb_io.o kdb_bt.o kdb_traps.o diff --git a/arch/ia64/kernel/Makefile b/arch/ia64/kernel/Makefile index 7a2fcd21404a..6631d33c31d1 100644 --- a/arch/ia64/kernel/Makefile +++ b/arch/ia64/kernel/Makefile @@ -8,9 +8,9 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.s: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -E -o $*.s $< + $(CPP) $(AFLAGS) -o $*.s $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $< + $(CC) $(AFLAGS) -c -o $*.o $< all: kernel.o head.o init_task.o diff --git a/arch/ia64/lib/Makefile b/arch/ia64/lib/Makefile index 88a4aadd4797..376d0d6d4087 100644 --- a/arch/ia64/lib/Makefile +++ b/arch/ia64/lib/Makefile @@ -3,7 +3,7 @@ # .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $@ + $(CC) $(AFLAGS) -c $< -o $@ OBJS = __divdi3.o __divsi3.o __udivdi3.o __udivsi3.o \ __moddi3.o __modsi3.o __umoddi3.o __umodsi3.o \ diff --git a/arch/ia64/sn/Makefile b/arch/ia64/sn/Makefile index 3c881096778f..b35ce21ff9c8 100644 --- a/arch/ia64/sn/Makefile +++ b/arch/ia64/sn/Makefile @@ -10,9 +10,9 @@ CFLAGS := $(CFLAGS) -DCONFIG_SGI_SN1 -DSN1 -DSN -DSOFTSDV \ AFLAGS := $(AFLAGS) -DCONFIG_SGI_SN1 -DSN1 -DSOFTSDV .S.s: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -E -o $*.s $< + $(CPP) $(AFLAGS) -o $*.s $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $< + $(CC) $(AFLAGS) -c -o $*.o $< all: sn.a diff --git a/arch/ia64/sn/sn1/Makefile b/arch/ia64/sn/sn1/Makefile index 23758c473cf3..fbb8e83ab51f 100644 --- a/arch/ia64/sn/sn1/Makefile +++ b/arch/ia64/sn/sn1/Makefile @@ -10,9 +10,9 @@ CFLAGS := $(CFLAGS) -DCONFIG_SGI_SN1 -DSN1 -DSN -DSOFTSDV \ AFLAGS := $(AFLAGS) -DCONFIG_SGI_SN1 -DSN1 -DSOFTSDV .S.s: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -E -o $*.s $< + $(CPP) $(AFLAGS) -o $*.s $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $< + $(CC) $(AFLAGS) -c -o $*.o $< all: sn1.a diff --git a/arch/m68k/fpsp040/Makefile b/arch/m68k/fpsp040/Makefile index bbfc0b174181..acd06e79a879 100644 --- a/arch/m68k/fpsp040/Makefile +++ b/arch/m68k/fpsp040/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< + $(CC) $(AFLAGS) -traditional -c -o $*.o $< OS_TARGET := fpsp.o diff --git a/arch/m68k/ifpsp060/Makefile b/arch/m68k/ifpsp060/Makefile index 7836197a6546..9dce0a568183 100644 --- a/arch/m68k/ifpsp060/Makefile +++ b/arch/m68k/ifpsp060/Makefile @@ -5,7 +5,7 @@ # for more details. .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< + $(CC) $(AFLAGS) -traditional -c -o $*.o $< OS_TARGET := ifpsp.o diff --git a/arch/m68k/kernel/Makefile b/arch/m68k/kernel/Makefile index c51e43802d49..afd9e4040837 100644 --- a/arch/m68k/kernel/Makefile +++ b/arch/m68k/kernel/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + $(CC) $(AFLAGS) -traditional -c $< -o $*.o ifndef CONFIG_SUN3 all: head.o kernel.o diff --git a/arch/m68k/lib/Makefile b/arch/m68k/lib/Makefile index 22fe6cb6d1c3..b9480aeb619a 100644 --- a/arch/m68k/lib/Makefile +++ b/arch/m68k/lib/Makefile @@ -3,7 +3,7 @@ # .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $@ + $(CC) $(AFLAGS) -traditional -c $< -o $@ L_TARGET = lib.a L_OBJS = ashrdi3.o lshrdi3.o checksum.o memcpy.o memcmp.o memset.o semaphore.o diff --git a/arch/m68k/math-emu/Makefile b/arch/m68k/math-emu/Makefile index 0e22edc961b0..78d295d6bb12 100644 --- a/arch/m68k/math-emu/Makefile +++ b/arch/m68k/math-emu/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.o: - $(CC) $(EXTRA_CFLAGS) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + $(CC) $(EXTRA_CFLAGS) $(AFLAGS) -traditional -c $< -o $*.o #EXTRA_CFLAGS=-DFPU_EMU_DEBUG diff --git a/arch/m68k/sun3/Makefile b/arch/m68k/sun3/Makefile index 9a34b30345fc..577667e5c14f 100644 --- a/arch/m68k/sun3/Makefile +++ b/arch/m68k/sun3/Makefile @@ -8,7 +8,7 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -Wa,-m68020 -c $< -o $*.o + $(CC) $(AFLAGS) -traditional -Wa,-m68020 -c $< -o $*.o O_TARGET := sun3.o O_OBJS := config.o idprom.o mmu_emu.o sun3ints.o leds.o dvma.o sbus.o intersil.o diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index 60420556591b..33fa87999524 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -16,9 +16,9 @@ .c.o: $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -D__BOOTER__ -c -o $*.o $< .S.s: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -E -o $*.o $< + $(CPP) $(AFLAGS) -traditional -o $*.o $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< + $(CC) $(AFLAGS) -traditional -c -o $*.o $< ZOFF = 0 ZSZ = 0 diff --git a/arch/ppc/chrpboot/Makefile b/arch/ppc/chrpboot/Makefile index 216b289ed71c..e988ce9de1ac 100644 --- a/arch/ppc/chrpboot/Makefile +++ b/arch/ppc/chrpboot/Makefile @@ -12,9 +12,9 @@ .c.o: $(CC) $(CFLAGS) -DKERNELBASE=$(KERNELBASE) -c -o $*.o $< .S.s: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -E -o $*.o $< + $(CPP) $(AFLAGS) -traditional -o $*.o $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< + $(CC) $(AFLAGS) -traditional -c -o $*.o $< CFLAGS = $(CPPFLAGS) -O -fno-builtin -DSTDC_HEADERS LD_ARGS = -Ttext 0x00400000 diff --git a/arch/ppc/lib/Makefile b/arch/ppc/lib/Makefile index e454e952dc0b..b6a16900c719 100644 --- a/arch/ppc/lib/Makefile +++ b/arch/ppc/lib/Makefile @@ -3,7 +3,7 @@ # .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -c $< -o $*.o + $(CC) $(AFLAGS) -c $< -o $*.o O_TARGET = lib.o O_OBJS = checksum.o string.o strcase.o diff --git a/arch/ppc/mbxboot/Makefile b/arch/ppc/mbxboot/Makefile index fb46859a1875..6f9fd0135be2 100644 --- a/arch/ppc/mbxboot/Makefile +++ b/arch/ppc/mbxboot/Makefile @@ -16,9 +16,9 @@ .c.o: $(CC) $(CFLAGS) -DINITRD_OFFSET=$(IOFF) -DINITRD_SIZE=$(ISZ) -DZIMAGE_OFFSET=$(ZOFF) -DZIMAGE_SIZE=$(ZSZ) -c -o $*.o $< .S.s: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -E -o $*.o $< + $(CPP) $(AFLAGS) -traditional -o $*.o $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c -o $*.o $< + $(CC) $(AFLAGS) -traditional -c -o $*.o $< ZOFF = 0 ZSZ = 0 diff --git a/arch/sh/kernel/Makefile b/arch/sh/kernel/Makefile index efa2fb1094e1..8996a13dc36a 100644 --- a/arch/sh/kernel/Makefile +++ b/arch/sh/kernel/Makefile @@ -7,7 +7,7 @@ # .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + $(CC) $(AFLAGS) -traditional -c $< -o $*.o O_TARGET := kernel.o O_OBJS := process.o signal.o entry.o traps.o irq.o irq_onchip.o \ @@ -29,7 +29,7 @@ all: kernel.o head.o init_task.o entry.o: entry.S head.o: head.S - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $*.S -o $*.o + $(CC) $(AFLAGS) -traditional -c $*.S -o $*.o clean: diff --git a/arch/sh/lib/Makefile b/arch/sh/lib/Makefile index 5f7d687559f9..7af24f1c3c0a 100644 --- a/arch/sh/lib/Makefile +++ b/arch/sh/lib/Makefile @@ -3,7 +3,7 @@ # .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + $(CC) $(AFLAGS) -traditional -c $< -o $*.o L_TARGET = lib.a L_OBJS = delay.o memcpy.o memset.o memmove.o memchr.o old-checksum.o \ diff --git a/arch/sparc/config.in b/arch/sparc/config.in index e7f158ba3dd6..279afb38f9c5 100644 --- a/arch/sparc/config.in +++ b/arch/sparc/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.91 2000/03/24 10:00:05 davem Exp $ +# $Id: config.in,v 1.92 2000/03/29 11:56:48 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # diff --git a/arch/sparc/kernel/Makefile b/arch/sparc/kernel/Makefile index 0d93f3a2b6ad..bd9181933e42 100644 --- a/arch/sparc/kernel/Makefile +++ b/arch/sparc/kernel/Makefile @@ -8,10 +8,10 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.s: - $(CPP) -D__ASSEMBLY__ $(AFLAGS) -ansi $< -o $*.s + $(CPP) $(AFLAGS) -ansi $< -o $*.s .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $< -o $*.o + $(CC) $(AFLAGS) -ansi -c $< -o $*.o all: kernel.o head.o init_task.o @@ -47,7 +47,7 @@ O_OBJS += ebus.o endif head.o: head.S - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $*.S -o $*.o + $(CC) $(AFLAGS) -ansi -c $*.S -o $*.o check_asm: dummy @echo "/* Automatically generated. Do not edit. */" > asm_offsets.h @@ -62,7 +62,7 @@ check_asm: dummy @echo "#undef __SMP__" >> tmp.c @echo "#undef CONFIG_SMP" >> tmp.c @echo "#include " >> tmp.c - $(CC) $(CPPFLAGS) -E tmp.c -o tmp.i + $(CPP) $(CPPFLAGS) tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm.c @echo "#include " >> check_asm.c @echo "#undef __SMP__" >> check_asm.c @@ -87,7 +87,7 @@ check_asm: dummy @echo "#undef CONFIG_SMP" >> tmp.c @echo "#define CONFIG_SMP 1" >> tmp.c @echo "#include " >> tmp.c - $(CC) $(CPPFLAGS) -D__SMP__ -E tmp.c -o tmp.i + $(CPP) $(CPPFLAGS) -D__SMP__ tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm.c @echo "#include " >> check_asm.c @echo "#undef CONFIG_SMP" >> check_asm.c diff --git a/arch/sparc/kernel/ioport.c b/arch/sparc/kernel/ioport.c index b1ed3c2afb44..20c141a00294 100644 --- a/arch/sparc/kernel/ioport.c +++ b/arch/sparc/kernel/ioport.c @@ -1,4 +1,4 @@ -/* $Id: ioport.c,v 1.36 2000/03/16 08:22:53 anton Exp $ +/* $Id: ioport.c,v 1.37 2000/03/28 06:38:19 davem Exp $ * ioport.c: Simple io mapping allocator. * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -581,6 +581,7 @@ dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int dir { if (direction == PCI_DMA_NONE) BUG(); + /* IIep is write-through, not flushing. */ return virt_to_bus(ptr); } @@ -591,11 +592,15 @@ dma_addr_t pci_map_single(struct pci_dev *hwdev, void *ptr, size_t size, int dir * After this call, reads by the cpu to the buffer are guarenteed to see * whatever the device wrote there. */ -void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, int direction) +void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t ba, size_t size, + int direction) { if (direction == PCI_DMA_NONE) BUG(); - /* Nothing to do... */ + if (direction != PCI_DMA_TODEVICE) { + mmu_inval_dma_area((unsigned long)bus_to_virt(ba), + (size + PAGE_SIZE-1) & PAGE_MASK); + } } /* Map a set of buffers described by scatterlist in streaming @@ -613,13 +618,14 @@ void pci_unmap_single(struct pci_dev *hwdev, dma_addr_t dma_addr, size_t size, i * Device ownership issues as mentioned above for pci_map_single are * the same here. */ -int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) +int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, + int direction) { int n; if (direction == PCI_DMA_NONE) BUG(); - + /* IIep is write-through, not flushing. */ for (n = 0; n < nents; n++) { sg->dvma_address = virt_to_bus(sg->address); sg->dvma_length = sg->length; @@ -632,15 +638,24 @@ int pci_map_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int dir * Again, cpu read rules concerning calls here are the same as for * pci_unmap_single() above. */ -void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nhwents, int direction) +void pci_unmap_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, + int direction) { + int n; + if (direction == PCI_DMA_NONE) BUG(); - /* Nothing to do... */ + if (direction != PCI_DMA_TODEVICE) { + for (n = 0; n < nents; n++) { + mmu_inval_dma_area((unsigned long)sg->address, + (sg->length + PAGE_SIZE-1) & PAGE_MASK); + sg++; + } + } } /* Make physical memory consistent for a single - * streaming mode DMA translation after a transfer. + * streaming mode DMA translation before or after a transfer. * * If you perform a pci_map_single() but wish to interrogate the * buffer using the cpu, yet do not wish to teardown the PCI dma @@ -652,8 +667,10 @@ void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t ba, size_t size, int { if (direction == PCI_DMA_NONE) BUG(); - mmu_inval_dma_area((unsigned long)bus_to_virt(ba), - (size + PAGE_SIZE-1) & PAGE_MASK); + if (direction != PCI_DMA_TODEVICE) { + mmu_inval_dma_area((unsigned long)bus_to_virt(ba), + (size + PAGE_SIZE-1) & PAGE_MASK); + } } /* Make physical memory consistent for a set of streaming @@ -664,13 +681,16 @@ void pci_dma_sync_single(struct pci_dev *hwdev, dma_addr_t ba, size_t size, int */ void pci_dma_sync_sg(struct pci_dev *hwdev, struct scatterlist *sg, int nents, int direction) { + int n; + if (direction == PCI_DMA_NONE) BUG(); - while (nents) { - --nents; - mmu_inval_dma_area((unsigned long)sg->address, - (sg->dvma_length + PAGE_SIZE-1) & PAGE_MASK); - sg++; + if (direction != PCI_DMA_TODEVICE) { + for (n = 0; n < nents; n++) { + mmu_inval_dma_area((unsigned long)sg->address, + (sg->length + PAGE_SIZE-1) & PAGE_MASK); + sg++; + } } } #endif CONFIG_PCI diff --git a/arch/sparc/kernel/setup.c b/arch/sparc/kernel/setup.c index 5966e04d75de..8c70c9f75551 100644 --- a/arch/sparc/kernel/setup.c +++ b/arch/sparc/kernel/setup.c @@ -1,4 +1,4 @@ -/* $Id: setup.c,v 1.116 2000/03/15 23:26:22 anton Exp $ +/* $Id: setup.c,v 1.117 2000/03/27 12:14:54 davem Exp $ * linux/arch/sparc/kernel/setup.c * * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) @@ -45,6 +45,8 @@ #include #include +#undef PROM_DEBUG_CONSOLE + struct screen_info screen_info = { 0, 0, /* orig-x, orig-y */ 0, /* unused */ @@ -282,6 +284,7 @@ struct tt_entry *sparc_ttable; struct pt_regs fake_swapper_regs = { 0, 0, 0, 0, { 0, } }; +#ifdef PROM_DEBUG_CONSOLE static void prom_cons_write(struct console *con, const char *str, unsigned count) { while (count--) @@ -291,6 +294,7 @@ static void prom_cons_write(struct console *con, const char *str, unsigned count static struct console prom_console = { "PROM", prom_cons_write, 0, 0, 0, 0, 0, CON_PRINTBUFFER, 0, 0, 0 }; +#endif extern void paging_init(void); @@ -345,6 +349,9 @@ void __init setup_arch(char **cmdline_p) printk("UNKNOWN!\n"); break; }; +#ifdef PROM_DEBUG_CONSOLE + register_console(&prom_console); +#endif #ifdef CONFIG_DUMMY_CONSOLE conswitchp = &dummy_con; diff --git a/arch/sparc/lib/Makefile b/arch/sparc/lib/Makefile index 8c3e8e4a9f7f..f5e316534fe7 100644 --- a/arch/sparc/lib/Makefile +++ b/arch/sparc/lib/Makefile @@ -13,10 +13,10 @@ lib.a: $(OBJS) sync .S.s: - $(CPP) -D__ASSEMBLY__ $(AFLAGS) -ansi -DST_DIV0=0x2 $< -o $*.s + $(CPP) $(AFLAGS) -ansi -DST_DIV0=0x2 $< -o $*.s .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -DST_DIV0=0x2 -c $< -o $*.o + $(CC) $(AFLAGS) -ansi -DST_DIV0=0x2 -c $< -o $*.o dep: diff --git a/arch/sparc/math-emu/Makefile b/arch/sparc/math-emu/Makefile index e8880cd078b1..3c4195085692 100644 --- a/arch/sparc/math-emu/Makefile +++ b/arch/sparc/math-emu/Makefile @@ -11,10 +11,10 @@ O_TARGET := math-emu.o O_OBJS := math.o ashldi3.o .S.s: - $(CPP) -D__ASSEMBLY__ $(AFLAGS) -ansi $< -o $*.s + $(CPP) $(AFLAGS) -ansi $< -o $*.s .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $< -o $*.o + $(CC) $(AFLAGS) -ansi -c $< -o $*.o CFLAGS += -I. -I$(TOPDIR)/include/math-emu -w diff --git a/arch/sparc/mm/Makefile b/arch/sparc/mm/Makefile index 00a4f35d24e5..440e4fc61167 100644 --- a/arch/sparc/mm/Makefile +++ b/arch/sparc/mm/Makefile @@ -7,6 +7,9 @@ # # Note 2! The CFLAGS definition is now in the main makefile... +.S.o: + $(CC) $(AFLAGS) -ansi -c -o $*.o $< + O_TARGET := mm.o O_OBJS := fault.o init.o loadmmu.o generic.o extable.o btfixup.o ifeq ($(CONFIG_SUN4),y) @@ -21,15 +24,3 @@ O_OBJS += sun4c.o endif include $(TOPDIR)/Rules.make - -hypersparc.o: hypersparc.S - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o hypersparc.o hypersparc.S - -viking.o: viking.S - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o viking.o viking.S - -tsunami.o: tsunami.S - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o tsunami.o tsunami.S - -swift.o: swift.S - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c -o swift.o swift.S diff --git a/arch/sparc64/config.in b/arch/sparc64/config.in index 69c41b467673..27e5549c0e78 100644 --- a/arch/sparc64/config.in +++ b/arch/sparc64/config.in @@ -1,4 +1,4 @@ -# $Id: config.in,v 1.106 2000/03/24 10:00:09 davem Exp $ +# $Id: config.in,v 1.107 2000/03/29 11:56:51 davem Exp $ # For a description of the syntax of this configuration file, # see the Configure script. # diff --git a/arch/sparc64/kernel/Makefile b/arch/sparc64/kernel/Makefile index 124776f51f4e..5e37c94b4e77 100644 --- a/arch/sparc64/kernel/Makefile +++ b/arch/sparc64/kernel/Makefile @@ -8,10 +8,10 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.s: - $(CPP) -D__ASSEMBLY__ $(AFLAGS) -ansi $< -o $*.s + $(CPP) $(AFLAGS) -ansi $< -o $*.s .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $< -o $*.o + $(CC) $(AFLAGS) -ansi -c $< -o $*.o all: kernel.o head.o init_task.o @@ -54,7 +54,7 @@ endif head.o: head.S ttable.S itlb_base.S dtlb_base.S dtlb_backend.S dtlb_prot.S \ etrap.S rtrap.S winfixup.S entry.S - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $*.S -o $*.o + $(CC) $(AFLAGS) -ansi -c $*.S -o $*.o # # This is just to get the dependencies... @@ -84,7 +84,7 @@ check_asm: dummy @echo "#undef __SMP__" >> tmp.c @echo "#undef CONFIG_SMP" >> tmp.c @echo "#include " >> tmp.c - $(CC) $(CPPFLAGS) -E tmp.c -o tmp.i + $(CPP) $(CPPFLAGS) tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm.c @echo "#include " >> check_asm.c @echo "#undef __SMP__" >> check_asm.c @@ -113,7 +113,7 @@ check_asm: dummy @echo "#undef CONFIG_SMP" >> tmp.c @echo "#define CONFIG_SMP 1" >> tmp.c @echo "#include " >> tmp.c - $(CC) $(CPPFLAGS) -D__SMP__ -E tmp.c -o tmp.i + $(CPP) $(CPPFLAGS) -D__SMP__ tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm.c @echo "#include " >> check_asm.c @echo "#undef CONFIG_SMP" >> check_asm.c @@ -138,7 +138,7 @@ check_asm: dummy @rm -f check_asm check_asm.c @echo -e "\n#else /* SPIN_LOCK_DEBUG */\n" >> asm_offsets.h @echo "#include " > tmp.c - $(CC) $(CPPFLAGS) -D__SMP__ -DSPIN_LOCK_DEBUG -E tmp.c -o tmp.i + $(CPP) $(CPPFLAGS) -D__SMP__ -DSPIN_LOCK_DEBUG tmp.c -o tmp.i @echo "/* Automatically generated. Do not edit. */" > check_asm.c @echo "#include " >> check_asm.c @echo "#undef CONFIG_SMP" >> check_asm.c diff --git a/arch/sparc64/kernel/entry.S b/arch/sparc64/kernel/entry.S index 2ab8b70d4c0b..529703dfc797 100644 --- a/arch/sparc64/kernel/entry.S +++ b/arch/sparc64/kernel/entry.S @@ -1,4 +1,4 @@ -/* $Id: entry.S,v 1.113 2000/03/06 22:33:42 davem Exp $ +/* $Id: entry.S,v 1.115 2000/03/29 09:55:30 davem Exp $ * arch/sparc64/kernel/entry.S: Sparc64 trap low-level entry points. * * Copyright (C) 1995,1997 David S. Miller (davem@caip.rutgers.edu) @@ -998,12 +998,12 @@ linux_sparc_syscall32: mov %i5, %o5 ! IEU1 srl %i2, 0, %o2 ! IEU0 Group - mov %i0, %l5 ! IEU1 - andcc %l0, 0x20, %g0 ! IEU1 Group + andcc %l0, 0x20, %g0 ! IEU0 Group bne,pn %icc, linux_syscall_trace32 ! CTI - srl %i3, 0, %o3 ! IEU0 + mov %i0, %l5 ! IEU1 call %l7 ! CTI Group brk forced - add %o7, 3f-.-4, %o7 ! IEU0 + srl %i3, 0, %o3 ! IEU0 + ba,a,pt %xcc, 3f /* Linux native and SunOS system calls enter here... */ .align 32 @@ -1032,30 +1032,31 @@ linux_sparc_syscall: mov %i0, %l5 ! IEU0 2: call %l7 ! CTI Group brk forced mov %i5, %o5 ! IEU0 + nop + 3: stx %o0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] ret_sys_call: #ifdef SYSCALL_TRACING call syscall_trace_exit add %sp, STACK_BIAS + REGWIN_SZ, %o1 #endif - ldx [%curptr + AOFF_task_flags], %l6 + ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE], %g3 + ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC], %l1 ! pc = npc sra %o0, 0, %o0 mov %ulo(TSTATE_XCARRY | TSTATE_ICARRY), %g2 - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE], %g3 cmp %o0, -ENOIOCTLCMD sllx %g2, 32, %g2 bgeu,pn %xcc, 1f - andcc %l6, 0x20, %l6 - /* System call success, clear Carry condition code. */ - andn %g3, %g2, %g3 + andcc %l0, 0x20, %l6 + andn %g3, %g2, %g3 /* System call success, clear Carry condition code. */ stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE] bne,pn %icc, linux_syscall_trace2 - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC], %l1 ! pc = npc - add %l1, 0x4, %l2 !npc = npc+4 + add %l1, 0x4, %l2 ! npc = npc+4 stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] - b,pt %xcc, rtrap_clr_l6 + ba,pt %xcc, rtrap_clr_l6 stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] + 1: /* System call failure, set Carry condition code. * Also, get abs(errno) to return to the process. @@ -1066,15 +1067,14 @@ ret_sys_call: mov 1, %l6 stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TSTATE] bne,pn %icc, linux_syscall_trace2 - ldx [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC], %l1 ! pc = npc - add %l1, 0x4, %l2 !npc = npc+4 - + add %l1, 0x4, %l2 !npc = npc+4 stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] + b,pt %xcc, rtrap stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] linux_syscall_trace2: call syscall_trace - add %l1, 0x4, %l2 /* npc = npc+4 */ + nop stx %l1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TPC] ba,pt %xcc, rtrap stx %l2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_TNPC] @@ -1082,6 +1082,9 @@ linux_syscall_trace2: .align 32 .globl __flushw_user __flushw_user: + rdpr %otherwin, %g1 + brz,pn %g1, 2f + clr %g2 1: save %sp, -128, %sp rdpr %otherwin, %g1 brnz,pt %g1, 1b @@ -1090,4 +1093,4 @@ __flushw_user: brnz,pt %g2, 1b restore %g0, %g0, %g0 2: retl - mov %g3, %o7 + nop diff --git a/arch/sparc64/kernel/etrap.S b/arch/sparc64/kernel/etrap.S index d243a43b3af6..b0a8f766d317 100644 --- a/arch/sparc64/kernel/etrap.S +++ b/arch/sparc64/kernel/etrap.S @@ -1,4 +1,4 @@ -/* $Id: etrap.S,v 1.42 1999/07/30 09:35:18 davem Exp $ +/* $Id: etrap.S,v 1.43 2000/03/29 09:55:30 davem Exp $ * etrap.S: Preparing for entry into the kernel on Sparc V9. * * Copyright (C) 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -13,6 +13,8 @@ #include #define TASK_REGOFF ((PAGE_SIZE<<1)-TRACEREG_SZ-REGWIN_SZ) +#define ETRAP_PSTATE1 (PSTATE_RMO | PSTATE_PRIV) +#define ETRAP_PSTATE2 (PSTATE_RMO | PSTATE_PEF | PSTATE_PRIV | PSTATE_IE) /* * On entry, %g7 is return address - 0x4. @@ -20,148 +22,167 @@ */ .text - .align 32 - .globl etrap, etrap_irq, etraptl1 - .globl scetrap - -etrap: rdpr %pil, %g2 ! Single Group -etrap_irq: rdpr %tstate, %g1 ! Single Group - sllx %g2, 20, %g3 ! IEU0 Group - andcc %g1, TSTATE_PRIV, %g0 ! IEU1 - or %g1, %g3, %g1 ! IEU0 Group - bne,a,pn %xcc, 1f ! CTI - sub %sp, REGWIN_SZ + TRACEREG_SZ - STACK_BIAS, %g2 ! IEU1 - sethi %hi(TASK_REGOFF), %g2 ! IEU0 Group - sethi %hi(TSTATE_PEF), %g3 ! IEU1 - or %g2, %lo(TASK_REGOFF), %g2 ! IEU0 Group - and %g1, %g3, %g3 ! IEU1 - brnz,pn %g3, 1f ! CTI+IEU1 Group - add %g6, %g2, %g2 ! IEU0 - wr %g0, 0, %fprs ! Single Group+4bubbles -1: rdpr %tpc, %g3 ! Single Group - stx %g1, [%g2 + REGWIN_SZ + PT_V9_TSTATE] ! Store Group - rdpr %tnpc, %g1 ! Single Group - stx %g3, [%g2 + REGWIN_SZ + PT_V9_TPC] ! Store Group - rd %y, %g3 ! Single Group+4bubbles - stx %g1, [%g2 + REGWIN_SZ + PT_V9_TNPC] ! Store Group - st %g3, [%g2 + REGWIN_SZ + PT_V9_Y] ! Store Group - save %g2, -STACK_BIAS, %sp ! The ordering here is ! Single Group - rdpr %pstate, %g1 ! critical, see winfixup ! Single Group+9bubbles - andn %g6, 0x1f, %l6 ! IEU0 Group - bne,pn %xcc, 3f ! CTI - mov PRIMARY_CONTEXT, %l4 ! IEU1 - rdpr %canrestore, %g3 ! Single Group+4bubbles - rdpr %wstate, %g2 ! Single Group+4bubbles - wrpr %g0, 7, %cleanwin ! Single Group+4bubbles - wrpr %g0, 0, %canrestore ! Single Group+4bubbles - sll %g2, 3, %g2 ! IEU0 Group - mov 1, %l5 ! IEU1 - stb %l5, [%l6 + AOFF_task_thread + AOFF_thread_fpdepth] ! Store - wrpr %g3, 0, %otherwin ! Single Group+4bubbles - wrpr %g2, 0, %wstate ! Single Group+4bubbles - stxa %g0, [%l4] ASI_DMMU ! Store Group - flush %l6 ! Single Group+9bubbles - wr %g0, ASI_AIUS, %asi ! Single Group+4bubbles -2: wrpr %g0, 0x0, %tl ! Single Group+4bubbles - andn %g1, PSTATE_MM, %l1 ! IEU0 Group - mov %g4, %l4 ! IEU1 - mov %g5, %l5 ! IEU0 Group - mov %g7, %l2 ! IEU1 - wrpr %l1, (PSTATE_AG|PSTATE_RMO), %pstate ! Single Group+4bubbles - stx %g1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G1] ! Store Group - stx %g2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G2] ! Store Group - stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G3] ! Store Group - stx %g4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G4] ! Store Group - stx %g5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G5] ! Store Group - stx %g6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G6] ! Store Group - stx %g7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G7] ! Store Group - stx %i0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] ! Store Group - stx %i1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] ! Store Group - stx %i2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I2] ! Store Group - stx %i3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I3] ! Store Group - stx %i4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I4] ! Store Group - sethi %uhi(PAGE_OFFSET), %g4 ! IEU0 - stx %i5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I5] ! Store Group - stx %i6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I6] ! Store Group - sllx %g4, 32, %g4 ! IEU0 - stx %i7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I7] ! Store Group - wrpr %l1, (PSTATE_IE|PSTATE_AG|PSTATE_RMO), %pstate ! Single Group+4bubbles - jmpl %l2 + 0x4, %g0 ! CTI Group - mov %l6, %g6 ! IEU0 - -3: ldub [%l6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5 ! Load Group - add %l6, AOFF_task_thread + AOFF_thread_fpsaved + 1, %l4 ! IEU0 - srl %l5, 1, %l3 ! IEU0 Group - add %l5, 2, %l5 ! IEU1 - stb %l5, [%l6 + AOFF_task_thread + AOFF_thread_fpdepth] ! Store - ba,pt %xcc, 2b ! CTI - stb %g0, [%l4 + %l3] ! Store Group - -etraptl1: rdpr %tstate, %g1 ! Single Group+4bubbles - sub %sp, REGWIN_SZ + TRACEREG_SZ - STACK_BIAS, %g2 ! IEU1 - ba,pt %xcc, 1b ! CTI Group - andcc %g1, TSTATE_PRIV, %g0 ! IEU0 - -scetrap: rdpr %pil, %g2 ! Single Group - rdpr %tstate, %g1 ! Single Group - sllx %g2, 20, %g3 ! IEU0 Group - andcc %g1, TSTATE_PRIV, %g0 ! IEU1 - or %g1, %g3, %g1 ! IEU0 Group - bne,a,pn %xcc, 1f ! CTI - sub %sp, REGWIN_SZ + TRACEREG_SZ - STACK_BIAS, %g2 ! IEU1 - sethi %hi(TASK_REGOFF), %g2 ! IEU0 Group - sethi %hi(TSTATE_PEF), %g3 ! IEU1 - or %g2, %lo(TASK_REGOFF), %g2 ! IEU0 Group - and %g1, %g3, %g3 ! IEU1 - brnz,pn %g3, 1f ! CTI+IEU1 Group - add %g6, %g2, %g2 ! IEU0 - wr %g0, 0, %fprs ! Single Group+4bubbles -1: rdpr %tpc, %g3 ! Single Group - stx %g1, [%g2 + REGWIN_SZ + PT_V9_TSTATE] ! Store Group - rdpr %tnpc, %g1 ! Single Group - stx %g3, [%g2 + REGWIN_SZ + PT_V9_TPC] ! Store Group - stx %g1, [%g2 + REGWIN_SZ + PT_V9_TNPC] ! Store Group - st %g0, [%g2 + REGWIN_SZ + PT_V9_Y] ! Store Group - save %g2, -STACK_BIAS, %sp ! The ordering here is ! Single Group - rdpr %pstate, %g1 ! critical, see winfixup ! Single Group+9bubbles - andn %g6, 0x1f, %l6 ! IEU0 Group - bne,pn %xcc, 2f ! CTI - mov PRIMARY_CONTEXT, %l4 ! IEU1 - rdpr %canrestore, %g3 ! Single Group+4bubbles - rdpr %wstate, %g2 ! Single Group+4bubbles - wrpr %g0, 7, %cleanwin ! Single Group+4bubbles - wrpr %g0, 0, %canrestore ! Single Group+4bubbles - sll %g2, 3, %g2 ! IEU0 Group - wrpr %g3, 0, %otherwin ! Single Group+4bubbles - wrpr %g2, 0, %wstate ! Single Group+4bubbles - stxa %g0, [%l4] ASI_DMMU ! Store Group - flush %l6 ! Single Group+9bubbles - wr %g0, ASI_AIUS, %asi ! Single Group+4bubbles -2: wrpr %g0, 0x0, %tl ! Single Group+4bubbles - andn %g1, PSTATE_MM, %l1 ! IEU0 Group - mov %g4, %l4 ! IEU1 - mov %g5, %l5 ! IEU0 Group - mov %g7, %l2 ! IEU1 - wrpr %l1, (PSTATE_AG|PSTATE_RMO), %pstate ! Single Group+4bubbles - stx %g1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G1] ! Store Group - stx %g2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G2] ! Store Group - stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G3] ! Store Group - stx %g4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G4] ! Store Group - stx %g5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G5] ! Store Group - stx %g6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G6] ! Store Group - stx %g7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G7] ! Store Group - stx %i0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] ! Store Group - stx %i1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] ! Store Group - stx %i2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I2] ! Store Group - stx %i3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I3] ! Store Group - stx %i4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I4] ! Store Group - sethi %uhi(PAGE_OFFSET), %g4 ! IEU0 - stx %i5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I5] ! Store Group - stx %i6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I6] ! Store Group - sllx %g4, 32, %g4 ! IEU0 - stx %i7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I7] ! Store Group - wrpr %l1, (PSTATE_IE|PSTATE_AG|PSTATE_RMO), %pstate ! Single Group+4bubbles - jmpl %l2 + 0x4, %g0 ! CTI Group - mov %l6, %g6 ! IEU0 + .align 64 + .globl etrap, etrap_irq, etraptl1 + +etrap: rdpr %pil, %g2 ! Single Group +etrap_irq: rdpr %tstate, %g1 ! Single Group + sllx %g2, 20, %g3 ! IEU0 Group + andcc %g1, TSTATE_PRIV, %g0 ! IEU1 + or %g1, %g3, %g1 ! IEU0 Group + bne,pn %xcc, 1f ! CTI + sub %sp, REGWIN_SZ+TRACEREG_SZ-STACK_BIAS, %g2 ! IEU1 + wrpr %g0, 7, %cleanwin ! Single Group+4bubbles + + sethi %hi(TASK_REGOFF), %g2 ! IEU0 Group + sethi %hi(TSTATE_PEF), %g3 ! IEU1 + or %g2, %lo(TASK_REGOFF), %g2 ! IEU0 Group + and %g1, %g3, %g3 ! IEU1 + brnz,pn %g3, 1f ! CTI+IEU1 Group + add %g6, %g2, %g2 ! IEU0 + wr %g0, 0, %fprs ! Single Group+4bubbles +1: rdpr %tpc, %g3 ! Single Group + + stx %g1, [%g2 + REGWIN_SZ + PT_V9_TSTATE] ! Store Group + rdpr %tnpc, %g1 ! Single Group + stx %g3, [%g2 + REGWIN_SZ + PT_V9_TPC] ! Store Group + rd %y, %g3 ! Single Group+4bubbles + stx %g1, [%g2 + REGWIN_SZ + PT_V9_TNPC] ! Store Group + st %g3, [%g2 + REGWIN_SZ + PT_V9_Y] ! Store Group + save %g2, -STACK_BIAS, %sp ! Ordering here is critical ! Single Group + mov %g6, %l6 ! IEU0 Group + + bne,pn %xcc, 3f ! CTI + mov PRIMARY_CONTEXT, %l4 ! IEU1 + rdpr %canrestore, %g3 ! Single Group+4bubbles + rdpr %wstate, %g2 ! Single Group+4bubbles + wrpr %g0, 0, %canrestore ! Single Group+4bubbles + sll %g2, 3, %g2 ! IEU0 Group + mov 1, %l5 ! IEU1 + stb %l5, [%l6 + AOFF_task_thread + AOFF_thread_fpdepth] ! Store + + wrpr %g3, 0, %otherwin ! Single Group+4bubbles + wrpr %g2, 0, %wstate ! Single Group+4bubbles + stxa %g0, [%l4] ASI_DMMU ! Store Group + flush %l6 ! Single Group+9bubbles + wr %g0, ASI_AIUS, %asi ! Single Group+4bubbles +2: wrpr %g0, 0x0, %tl ! Single Group+4bubbles + mov %g4, %l4 ! IEU1 + mov %g5, %l5 ! IEU0 Group + + mov %g7, %l2 ! IEU1 + wrpr %g0, ETRAP_PSTATE1, %pstate ! Single Group+4bubbles + stx %g1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G1] ! Store Group + stx %g2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G2] ! Store Group + stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G3] ! Store Group + stx %g4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G4] ! Store Group + stx %g5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G5] ! Store Group + stx %g6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G6] ! Store Group + + stx %g7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G7] ! Store Group + stx %i0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] ! Store Group + stx %i1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] ! Store Group + stx %i2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I2] ! Store Group + stx %i3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I3] ! Store Group + stx %i4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I4] ! Store Group + sethi %uhi(PAGE_OFFSET), %g4 ! IEU0 + stx %i5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I5] ! Store Group + + stx %i6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I6] ! Store Group + sllx %g4, 32, %g4 ! IEU0 + stx %i7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I7] ! Store Group + wrpr %g0, ETRAP_PSTATE2, %pstate ! Single Group+4bubbles + jmpl %l2 + 0x4, %g0 ! CTI Group + mov %l6, %g6 ! IEU0 + nop + nop + +3: ldub [%l6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5 ! Load Group + add %l6, AOFF_task_thread + AOFF_thread_fpsaved + 1, %l4 ! IEU0 + srl %l5, 1, %l3 ! IEU0 Group + add %l5, 2, %l5 ! IEU1 + stb %l5, [%l6 + AOFF_task_thread + AOFF_thread_fpdepth] ! Store + ba,pt %xcc, 2b ! CTI + stb %g0, [%l4 + %l3] ! Store Group + nop + +etraptl1: rdpr %tstate, %g1 ! Single Group+4bubbles + sub %sp, REGWIN_SZ + TRACEREG_SZ - STACK_BIAS, %g2 ! IEU1 + ba,pt %xcc, 1b ! CTI Group + andcc %g1, TSTATE_PRIV, %g0 ! IEU0 + + .align 64 + .globl scetrap +scetrap: rdpr %pil, %g2 ! Single Group + rdpr %tstate, %g1 ! Single Group + sllx %g2, 20, %g3 ! IEU0 Group + andcc %g1, TSTATE_PRIV, %g0 ! IEU1 + or %g1, %g3, %g1 ! IEU0 Group + bne,pn %xcc, 1f ! CTI + sub %sp, (REGWIN_SZ+TRACEREG_SZ-STACK_BIAS), %g2 ! IEU1 + wrpr %g0, 7, %cleanwin ! Single Group+4bubbles + + sllx %g1, 51, %g3 ! IEU0 Group + sethi %hi(TASK_REGOFF), %g2 ! IEU1 + or %g2, %lo(TASK_REGOFF), %g2 ! IEU0 Group + brlz,pn %g3, 1f ! CTI+IEU1 + add %g6, %g2, %g2 ! IEU0 Group + wr %g0, 0, %fprs ! Single Group+4bubbles +1: rdpr %tpc, %g3 ! Single Group + stx %g1, [%g2 + REGWIN_SZ + PT_V9_TSTATE] ! Store Group + + rdpr %tnpc, %g1 ! Single Group + stx %g3, [%g2 + REGWIN_SZ + PT_V9_TPC] ! Store Group + stx %g1, [%g2 + REGWIN_SZ + PT_V9_TNPC] ! Store Group + save %g2, -STACK_BIAS, %sp ! Ordering here is critical ! Single Group + mov %g6, %l6 ! IEU0 Group + bne,pn %xcc, 2f ! CTI + mov ASI_P, %l7 ! IEU1 + rdpr %canrestore, %g3 ! Single Group+4bubbles + + rdpr %wstate, %g2 ! Single Group+4bubbles + wrpr %g0, 0, %canrestore ! Single Group+4bubbles + sll %g2, 3, %g2 ! IEU0 Group + mov PRIMARY_CONTEXT, %l4 ! IEU1 + wrpr %g3, 0, %otherwin ! Single Group+4bubbles + wrpr %g2, 0, %wstate ! Single Group+4bubbles + stxa %g0, [%l4] ASI_DMMU ! Store + flush %l6 ! Single Group+9bubbles + + mov ASI_AIUS, %l7 ! IEU0 Group +2: mov %g4, %l4 ! IEU1 + mov %g5, %l5 ! IEU0 Group + add %g7, 0x4, %l2 ! IEU1 + wrpr %g0, ETRAP_PSTATE1, %pstate ! Single Group+4bubbles + stx %g1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G1] ! Store Group + stx %g2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G2] ! Store Group + sllx %l7, 24, %l7 ! IEU0 + + stx %g3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G3] ! Store Group + rdpr %cwp, %l0 ! Single Group + stx %g4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G4] ! Store Group + stx %g5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G5] ! Store Group + stx %g6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G6] ! Store Group + stx %g7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_G7] ! Store Group + or %l7, %l0, %l7 ! IEU0 + sethi %hi(TSTATE_RMO | TSTATE_PEF), %l0 ! IEU1 + + or %l7, %l0, %l7 ! IEU0 Group + wrpr %l2, %tnpc ! Single Group+4bubbles + wrpr %l7, (TSTATE_PRIV | TSTATE_IE), %tstate ! Single Group+4bubbles + stx %i0, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I0] ! Store Group + stx %i1, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I1] ! Store Group + stx %i2, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I2] ! Store Group + stx %i3, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I3] ! Store Group + stx %i4, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I4] ! Store Group + + sethi %uhi(PAGE_OFFSET), %g4 ! IEU0 + stx %i5, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I5] ! Store Group + stx %i6, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I6] ! Store Group + sllx %g4, 32, %g4 ! IEU0 + mov %l6, %g6 ! IEU1 + stx %i7, [%sp + STACK_BIAS + REGWIN_SZ + PT_V9_I7] ! Store Group + done + nop #undef TASK_REGOFF diff --git a/arch/sparc64/kernel/ioctl32.c b/arch/sparc64/kernel/ioctl32.c index 254e2eb8af3b..ef07fca85ebc 100644 --- a/arch/sparc64/kernel/ioctl32.c +++ b/arch/sparc64/kernel/ioctl32.c @@ -1,4 +1,4 @@ -/* $Id: ioctl32.c,v 1.85 2000/03/23 05:25:41 davem Exp $ +/* $Id: ioctl32.c,v 1.87 2000/03/30 02:09:07 davem Exp $ * ioctl32.c: Conversion between 32bit and 64bit native ioctls. * * Copyright (C) 1997-2000 Jakub Jelinek (jakub@redhat.com) @@ -2716,6 +2716,25 @@ COMPATIBLE_IOCTL(SG_GET_TIMEOUT) COMPATIBLE_IOCTL(SG_EMULATED_HOST) COMPATIBLE_IOCTL(SG_SET_TRANSFORM) COMPATIBLE_IOCTL(SG_GET_TRANSFORM) +COMPATIBLE_IOCTL(SG_SET_RESERVED_SIZE) +COMPATIBLE_IOCTL(SG_GET_RESERVED_SIZE) +COMPATIBLE_IOCTL(SG_GET_SCSI_ID) +COMPATIBLE_IOCTL(SG_SET_FORCE_LOW_DMA) +COMPATIBLE_IOCTL(SG_GET_LOW_DMA) +COMPATIBLE_IOCTL(SG_SET_FORCE_PACK_ID) +COMPATIBLE_IOCTL(SG_GET_PACK_ID) +COMPATIBLE_IOCTL(SG_GET_NUM_WAITING) +COMPATIBLE_IOCTL(SG_SET_DEBUG) +COMPATIBLE_IOCTL(SG_GET_SG_TABLESIZE) +COMPATIBLE_IOCTL(SG_GET_COMMAND_Q) +COMPATIBLE_IOCTL(SG_SET_COMMAND_Q) +COMPATIBLE_IOCTL(SG_GET_VERSION_NUM) +COMPATIBLE_IOCTL(SG_NEXT_CMD_LEN) +COMPATIBLE_IOCTL(SG_SCSI_RESET) +COMPATIBLE_IOCTL(SG_IO) +COMPATIBLE_IOCTL(SG_GET_REQUEST_TABLE) +COMPATIBLE_IOCTL(SG_SET_KEEP_ORPHAN) +COMPATIBLE_IOCTL(SG_GET_KEEP_ORPHAN) /* PPP stuff */ COMPATIBLE_IOCTL(PPPIOCGFLAGS) COMPATIBLE_IOCTL(PPPIOCSFLAGS) diff --git a/arch/sparc64/kernel/rtrap.S b/arch/sparc64/kernel/rtrap.S index d059a5a282b7..1c9b6ac3f7fd 100644 --- a/arch/sparc64/kernel/rtrap.S +++ b/arch/sparc64/kernel/rtrap.S @@ -1,4 +1,4 @@ -/* $Id: rtrap.S,v 1.48 2000/02/09 11:15:07 davem Exp $ +/* $Id: rtrap.S,v 1.49 2000/03/29 09:55:31 davem Exp $ * rtrap.S: Preparing for return from trap on Sparc V9. * * Copyright (C) 1997,1998 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -14,194 +14,207 @@ #include #define PTREGS_OFF (STACK_BIAS + REGWIN_SZ) +#define RTRAP_PSTATE (PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV|PSTATE_IE) +#define RTRAP_PSTATE_IRQOFF (PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV) +#define RTRAP_PSTATE_AG_IRQOFF (PSTATE_RMO|PSTATE_PEF|PSTATE_PRIV|PSTATE_AG) + +#if 0 +#define RTRAP_CHECK call rtrap_check; add %sp, (STACK_BIAS+REGWIN_SZ), %o0; +#else +#define RTRAP_CHECK +#endif .text + .align 32 +__handle_softirq: + call do_softirq + nop + ba,a,pt %xcc, __handle_softirq_continue + nop +__handle_preemption: + call schedule + nop + ba,pt %xcc, __handle_preemption_continue + nop +__handle_user_windows: + wrpr %g0, RTRAP_PSTATE, %pstate + call fault_in_user_windows + add %sp, STACK_BIAS + REGWIN_SZ, %g0 + ba,a,pt %xcc, __handle_user_windows_continue +__handle_perfctrs: + /* Don't forget to preserve user window invariants. */ + wrpr %g0, RTRAP_PSTATE, %pstate + call update_perfctrs + nop + wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate + ldub [%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2 + brz,pt %o2, __handle_perfctrs_continue + sethi %hi(TSTATE_PEF), %l6 + wrpr %g0, RTRAP_PSTATE, %pstate + + call fault_in_user_windows + add %sp, STACK_BIAS + REGWIN_SZ, %o0 + ba,pt %xcc, __handle_perfctrs_continue + nop +__handle_userfpu: + rd %fprs, %l5 + andcc %l5, FPRS_FEF, %g0 + be,a,pn %icc, __handle_userfpu_continue + andn %l1, %l6, %l1 + ba,a,pt %xcc, __handle_userfpu_continue +__handle_signal: + clr %o0 + mov %l5, %o2 + mov %l6, %o3 + call do_signal + add %sp, STACK_BIAS + REGWIN_SZ, %o1 + ba,pt %xcc, __handle_signal_continue + clr %l6 + nop + + .align 64 .globl rtrap_clr_l6, rtrap rtrap_clr_l6: clr %l6 - /* Fall through */ rtrap: lduw [%g6 + AOFF_task_processor], %l0 sethi %hi(softirq_state), %l2 or %l2, %lo(softirq_state), %l2 sllx %l0, 6, %l0 ldx [%l2 + %l0], %l1 srlx %l1, 32, %l2 - andcc %l1, %l2, %g0 - be,pt %icc, 2f - nop - call do_softirq - nop -2: ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 + + bne,pn %icc, __handle_softirq + ldx [%sp + PTREGS_OFF + PT_V9_TSTATE], %l1 +__handle_softirq_continue: sethi %hi(0xf << 20), %l4 andcc %l1, TSTATE_PRIV, %l3 - and %l1, %l4, %l4 - rdpr %pstate, %l7 - andn %l1, %l4, %l1 - be,pt %icc, to_user - andn %l7, PSTATE_IE, %l7 + bne,pn %icc, to_kernel + andn %l1, %l4, %l1 +to_user: ldx [%g6 + AOFF_task_need_resched], %l0 + + brnz,pn %l0, __handle_preemption +__handle_preemption_continue: + lduw [%g6 + AOFF_task_sigpending], %l0 + brnz,pn %l0, __handle_signal + nop +__handle_signal_continue: +check_user_wins: + wrpr %g0, RTRAP_PSTATE_IRQOFF, %pstate + ldub [%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2 + brnz,pn %o2, __handle_user_windows + sethi %hi(TSTATE_PEF), %l6 + +__handle_user_windows_continue: + RTRAP_CHECK + ldub [%g6 + AOFF_task_thread + AOFF_thread_flags], %l5 + andcc %l5, SPARC_FLAG_PERFCTR, %g0 + bne,pn %xcc, __handle_perfctrs +__handle_perfctrs_continue: + andcc %l1, %l6, %g0 + bne,pn %xcc, __handle_userfpu + stb %g0, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth] ! This is neccessary for non-syscall rtraps only +__handle_userfpu_continue: - ldub [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5 - brz,pt %l5, rt_continue - srl %l5, 1, %o0 - add %g6, AOFF_task_thread + AOFF_thread_fpsaved, %l6 - ldub [%l6 + %o0], %l2 - sub %l5, 2, %l5 - add %g6, AOFF_task_thread + AOFF_thread_gsr, %o1 - andcc %l2, (FPRS_FEF|FPRS_DU), %g0 - be,pt %icc, 2f - and %l2, FPRS_DL, %l6 - andcc %l2, FPRS_FEF, %g0 - be,pn %icc, 5f - sll %o0, 3, %o5 - rd %fprs, %g5 - wr %g5, FPRS_FEF, %fprs - ldub [%o1 + %o0], %g5 - add %g6, AOFF_task_thread + AOFF_thread_xfsr, %o1 - membar #StoreLoad | #LoadLoad - sll %o0, 8, %o2 - add %g6, AOFF_task_fpregs, %o3 - brz,pn %l6, 1f - add %g6, AOFF_task_fpregs+0x40, %o4 - ldda [%o3 + %o2] ASI_BLK_P, %f0 - ldda [%o4 + %o2] ASI_BLK_P, %f16 -1: andcc %l2, FPRS_DU, %g0 - be,pn %icc, 1f - wr %g5, 0, %gsr - add %o2, 0x80, %o2 - ldda [%o3 + %o2] ASI_BLK_P, %f32 - ldda [%o4 + %o2] ASI_BLK_P, %f48 -1: membar #Sync - ldx [%o1 + %o5], %fsr -2: stb %l5, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth] rt_continue: ldx [%sp + PTREGS_OFF + PT_V9_G1], %g1 ldx [%sp + PTREGS_OFF + PT_V9_G2], %g2 + ldx [%sp + PTREGS_OFF + PT_V9_G3], %g3 - mov %g6, %o5 ldx [%sp + PTREGS_OFF + PT_V9_G4], %g4 ldx [%sp + PTREGS_OFF + PT_V9_G5], %g5 ldx [%sp + PTREGS_OFF + PT_V9_G6], %g6 ldx [%sp + PTREGS_OFF + PT_V9_G7], %g7 - - wrpr %l7, PSTATE_AG, %pstate + wrpr %g0, RTRAP_PSTATE_AG_IRQOFF, %pstate ldx [%sp + PTREGS_OFF + PT_V9_I0], %i0 ldx [%sp + PTREGS_OFF + PT_V9_I1], %i1 + ldx [%sp + PTREGS_OFF + PT_V9_I2], %i2 ldx [%sp + PTREGS_OFF + PT_V9_I3], %i3 ldx [%sp + PTREGS_OFF + PT_V9_I4], %i4 ldx [%sp + PTREGS_OFF + PT_V9_I5], %i5 ldx [%sp + PTREGS_OFF + PT_V9_I6], %i6 - ldx [%sp + PTREGS_OFF + PT_V9_I7], %i7 - ld [%sp + PTREGS_OFF + PT_V9_Y], %o3 ldx [%sp + PTREGS_OFF + PT_V9_TPC], %l2 ldx [%sp + PTREGS_OFF + PT_V9_TNPC], %o2 + + ld [%sp + PTREGS_OFF + PT_V9_Y], %o3 wr %o3, %g0, %y srl %l4, 20, %l4 wrpr %l4, 0x0, %pil wrpr %g0, 0x1, %tl - wrpr %l1, %g0, %tstate wrpr %l2, %g0, %tpc wrpr %o2, %g0, %tnpc + brnz,pn %l3, kern_rtt mov PRIMARY_CONTEXT, %l7 ldxa [%l7 + %l7] ASI_DMMU, %l0 stxa %l0, [%l7] ASI_DMMU - flush %o5 - + flush %g6 rdpr %wstate, %l1 rdpr %otherwin, %l2 srl %l1, 3, %l1 + wrpr %l2, %g0, %canrestore wrpr %l1, %g0, %wstate wrpr %g0, %g0, %otherwin restore rdpr %canrestore, %g1 - wrpr %g1, 0x0, %cleanwin retry + nop + kern_rtt: restore retry -to_user: ldx [%g6 + AOFF_task_need_resched], %l0 - wrpr %l7, PSTATE_IE, %pstate - orcc %g0, %l0, %g0 - be,a,pt %xcc, check_signal - - lduw [%g6 + AOFF_task_sigpending], %l0 - call schedule - nop - lduw [%g6 + AOFF_task_sigpending], %l0 -check_signal: brz,a,pt %l0, check_user_wins - nop - clr %o0 - mov %l5, %o2 - mov %l6, %o3 - call do_signal - add %sp, STACK_BIAS + REGWIN_SZ, %o1 - clr %l6 - - /* We must not take any traps between here and the actual - * return to user-space. If we do we risk having windows - * saved to the thread struct between the test and the - * actual return from trap. --DaveM - */ -check_user_wins: - wrpr %l7, 0x0, %pstate - ldub [%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2 - brz,pt %o2, 1f - sethi %hi(TSTATE_PEF), %l6 +to_kernel: ldub [%g6 + AOFF_task_thread + AOFF_thread_fpdepth], %l5 + brz,pt %l5, rt_continue + srl %l5, 1, %o0 + add %g6, AOFF_task_thread + AOFF_thread_fpsaved, %l6 + ldub [%l6 + %o0], %l2 + sub %l5, 2, %l5 - wrpr %l7, PSTATE_IE, %pstate - call fault_in_user_windows - add %sp, STACK_BIAS + REGWIN_SZ, %o0 - /* It is OK to leave interrupts on now because if - * fault_in_user_windows has returned it has left us - * with a clean user stack state. - */ -1: -#if 0 - call rtrap_check - add %sp, STACK_BIAS + REGWIN_SZ, %o0 -#endif - ldub [%g6 + AOFF_task_thread + AOFF_thread_flags], %l5 - andcc %l5, SPARC_FLAG_PERFCTR, %g0 - be,pt %xcc, 1f - nop + add %g6, AOFF_task_thread + AOFF_thread_gsr, %o1 + andcc %l2, (FPRS_FEF|FPRS_DU), %g0 + be,pt %icc, 2f + and %l2, FPRS_DL, %l6 + andcc %l2, FPRS_FEF, %g0 + be,pn %icc, 5f + sll %o0, 3, %o5 + rd %fprs, %g5 - /* Don't forget to preserve user window invariants. */ - wrpr %l7, PSTATE_IE, %pstate - call update_perfctrs - nop - wrpr %l7, 0x0, %pstate - ldub [%g6 + AOFF_task_thread + AOFF_thread_w_saved], %o2 - brz,pt %o2, 1f - sethi %hi(TSTATE_PEF), %l6 - wrpr %l7, PSTATE_IE, %pstate - call fault_in_user_windows - add %sp, STACK_BIAS + REGWIN_SZ, %o0 + wr %g5, FPRS_FEF, %fprs + ldub [%o1 + %o0], %g5 + add %g6, AOFF_task_thread + AOFF_thread_xfsr, %o1 + membar #StoreLoad | #LoadLoad + sll %o0, 8, %o2 + add %g6, AOFF_task_fpregs, %o3 + brz,pn %l6, 1f + add %g6, AOFF_task_fpregs+0x40, %o4 -1: - andcc %l1, %l6, %g0 - be,pt %xcc, rt_continue - stb %g0, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth] ! This is neccessary for non-syscall rtraps only + ldda [%o3 + %o2] ASI_BLK_P, %f0 + ldda [%o4 + %o2] ASI_BLK_P, %f16 +1: andcc %l2, FPRS_DU, %g0 + be,pn %icc, 1f + wr %g5, 0, %gsr + add %o2, 0x80, %o2 + ldda [%o3 + %o2] ASI_BLK_P, %f32 + ldda [%o4 + %o2] ASI_BLK_P, %f48 - rd %fprs, %l5 - andcc %l5, FPRS_FEF, %g0 - be,a,pn %icc, rt_continue - andn %l1, %l6, %l1 +1: membar #Sync + ldx [%o1 + %o5], %fsr +2: stb %l5, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth] ba,pt %xcc, rt_continue nop - 5: wr %g0, FPRS_FEF, %fprs membar #StoreLoad | #LoadLoad sll %o0, 8, %o2 + add %g6, AOFF_task_fpregs+0x80, %o3 add %g6, AOFF_task_fpregs+0xc0, %o4 ldda [%o3 + %o2] ASI_BLK_P, %f32 ldda [%o4 + %o2] ASI_BLK_P, %f48 -1: membar #Sync + membar #Sync wr %g0, FPRS_DU, %fprs ba,pt %xcc, rt_continue stb %l5, [%g6 + AOFF_task_thread + AOFF_thread_fpdepth] diff --git a/arch/sparc64/kernel/semaphore.c b/arch/sparc64/kernel/semaphore.c index 88ab813f383d..0919089ef18d 100644 --- a/arch/sparc64/kernel/semaphore.c +++ b/arch/sparc64/kernel/semaphore.c @@ -1,4 +1,4 @@ -/* $Id: semaphore.c,v 1.2 1999/12/23 17:12:03 jj Exp $ +/* $Id: semaphore.c,v 1.3 2000/03/27 10:38:46 davem Exp $ * Generic semaphore code. Buyer beware. Do your own * specific changes in */ @@ -203,7 +203,7 @@ void down_read_failed_biased(struct rw_semaphore *sem) add_wait_queue(&sem->wait, &wait); /* put ourselves at the head of the list */ for (;;) { - if (clear_le_bit(0, &sem->granted)) + if (test_and_clear_le_bit(0, &sem->granted)) break; set_task_state(tsk, TASK_UNINTERRUPTIBLE); if (!test_le_bit(0, &sem->granted)) @@ -221,7 +221,7 @@ void down_write_failed_biased(struct rw_semaphore *sem) add_wait_queue_exclusive(&sem->write_bias_wait, &wait); /* put ourselves at the end of the list */ for (;;) { - if (clear_le_bit(1, &sem->granted)) + if (test_and_clear_le_bit(1, &sem->granted)) break; set_task_state(tsk, TASK_UNINTERRUPTIBLE | TASK_EXCLUSIVE); if (!test_le_bit(1, &sem->granted)) @@ -286,11 +286,11 @@ void down_write_failed(struct rw_semaphore *sem) void __rwsem_wake(struct rw_semaphore *sem, unsigned long readers) { if (readers) { - if (set_le_bit(0, &sem->granted)) + if (test_and_set_le_bit(0, &sem->granted)) BUG(); wake_up(&sem->wait); } else { - if (set_le_bit(1, &sem->granted)) + if (test_and_set_le_bit(1, &sem->granted)) BUG(); wake_up(&sem->write_bias_wait); } diff --git a/arch/sparc64/kernel/smp.c b/arch/sparc64/kernel/smp.c index 0d5f615cf338..e9a180d2a340 100644 --- a/arch/sparc64/kernel/smp.c +++ b/arch/sparc64/kernel/smp.c @@ -469,52 +469,83 @@ void smp_flush_tlb_all(void) */ void smp_flush_tlb_mm(struct mm_struct *mm) { - u32 ctx = CTX_HWBITS(mm->context); - - if (mm == current->active_mm && - atomic_read(&mm->mm_users) == 1 && - (mm->cpu_vm_mask == (1UL << smp_processor_id()))) - goto local_flush_and_out; + if (CTX_VALID(mm->context)) { + u32 ctx = CTX_HWBITS(mm->context); + int cpu = smp_processor_id(); + + if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) { + /* See smp_flush_tlb_page for info about this. */ + mm->cpu_vm_mask = (1UL << cpu); + goto local_flush_and_out; + } - smp_cross_call(&xcall_flush_tlb_mm, ctx, 0, 0); + smp_cross_call(&xcall_flush_tlb_mm, ctx, 0, 0); -local_flush_and_out: - __flush_tlb_mm(ctx, SECONDARY_CONTEXT); + local_flush_and_out: + __flush_tlb_mm(ctx, SECONDARY_CONTEXT); + } } void smp_flush_tlb_range(struct mm_struct *mm, unsigned long start, unsigned long end) { - u32 ctx = CTX_HWBITS(mm->context); + if (CTX_VALID(mm->context)) { + u32 ctx = CTX_HWBITS(mm->context); + int cpu = smp_processor_id(); - start &= PAGE_MASK; - end &= PAGE_MASK; - if(mm == current->active_mm && - atomic_read(&mm->mm_users) == 1 && - (mm->cpu_vm_mask == (1UL << smp_processor_id()))) - goto local_flush_and_out; + start &= PAGE_MASK; + end &= PAGE_MASK; - smp_cross_call(&xcall_flush_tlb_range, ctx, start, end); + if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) { + mm->cpu_vm_mask = (1UL << cpu); + goto local_flush_and_out; + } + + smp_cross_call(&xcall_flush_tlb_range, ctx, start, end); -local_flush_and_out: - __flush_tlb_range(ctx, start, SECONDARY_CONTEXT, end, PAGE_SIZE, (end-start)); + local_flush_and_out: + __flush_tlb_range(ctx, start, SECONDARY_CONTEXT, end, PAGE_SIZE, (end-start)); + } } void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page) { - u32 ctx = CTX_HWBITS(mm->context); - - page &= PAGE_MASK; - if(mm == current->active_mm && - atomic_read(&mm->mm_users) == 1 && - (mm->cpu_vm_mask == (1UL << smp_processor_id()))) { - goto local_flush_and_out; - } + if (CTX_VALID(mm->context)) { + u32 ctx = CTX_HWBITS(mm->context); + int cpu = smp_processor_id(); + + page &= PAGE_MASK; + if (mm == current->active_mm && atomic_read(&mm->mm_users) == 1) { + /* By virtue of being the current address space, and + * having the only reference to it, the following operation + * is safe. + * + * It would not be a win to perform the xcall tlb flush in + * this case, because even if we switch back to one of the + * other processors in cpu_vm_mask it is almost certain that + * all TLB entries for this context will be replaced by the + * time that happens. + */ + mm->cpu_vm_mask = (1UL << cpu); + goto local_flush_and_out; + } else { + /* By virtue of running under the mm->page_table_lock, + * and mmu_context.h:switch_mm doing the same, the following + * operation is safe. + */ + if (mm->cpu_vm_mask == (1UL << cpu)) + goto local_flush_and_out; + } - smp_cross_call(&xcall_flush_tlb_page, ctx, page, 0); + /* OK, we have to actually perform the cross call. Most likely + * this is a cloned mm or kswapd is kicking out pages for a task + * which has run recently on another cpu. + */ + smp_cross_call(&xcall_flush_tlb_page, ctx, page, 0); -local_flush_and_out: - __flush_tlb_page(ctx, page, SECONDARY_CONTEXT); + local_flush_and_out: + __flush_tlb_page(ctx, page, SECONDARY_CONTEXT); + } } /* CPU capture. */ @@ -603,13 +634,16 @@ static inline void sparc64_do_profile(unsigned long pc, unsigned long o7) extern int rwlock_impl_begin, rwlock_impl_end; extern int atomic_impl_begin, atomic_impl_end; extern int __memcpy_begin, __memcpy_end; + extern int __bitops_begin, __bitops_end; if ((pc >= (unsigned long) &atomic_impl_begin && pc < (unsigned long) &atomic_impl_end) || (pc >= (unsigned long) &rwlock_impl_begin && pc < (unsigned long) &rwlock_impl_end) || (pc >= (unsigned long) &__memcpy_begin && - pc < (unsigned long) &__memcpy_end)) + pc < (unsigned long) &__memcpy_end) || + (pc >= (unsigned long) &__bitops_begin && + pc < (unsigned long) &__bitops_end)) pc = o7; pc -= (unsigned long) &_stext; diff --git a/arch/sparc64/kernel/sparc64_ksyms.c b/arch/sparc64/kernel/sparc64_ksyms.c index 26e11085d94e..fc7a8cfe57fd 100644 --- a/arch/sparc64/kernel/sparc64_ksyms.c +++ b/arch/sparc64/kernel/sparc64_ksyms.c @@ -1,4 +1,4 @@ -/* $Id: sparc64_ksyms.c,v 1.79 2000/03/17 14:41:18 davem Exp $ +/* $Id: sparc64_ksyms.c,v 1.80 2000/03/27 10:38:47 davem Exp $ * arch/sparc64/kernel/sparc64_ksyms.c: Sparc64 specific ksyms support. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -170,6 +170,13 @@ EXPORT_SYMBOL_NOVERS(__rwsem_wake); EXPORT_SYMBOL_PRIVATE(atomic_add); EXPORT_SYMBOL_PRIVATE(atomic_sub); +/* Atomic bit operations. */ +EXPORT_SYMBOL_PRIVATE(test_and_set_bit); +EXPORT_SYMBOL_PRIVATE(test_and_clear_bit); +EXPORT_SYMBOL_PRIVATE(test_and_change_bit); +EXPORT_SYMBOL_PRIVATE(test_and_set_le_bit); +EXPORT_SYMBOL_PRIVATE(test_and_clear_le_bit); + EXPORT_SYMBOL(ivector_table); EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); diff --git a/arch/sparc64/lib/Makefile b/arch/sparc64/lib/Makefile index f3067cad6833..e70e28e5297b 100644 --- a/arch/sparc64/lib/Makefile +++ b/arch/sparc64/lib/Makefile @@ -1,4 +1,4 @@ -# $Id: Makefile,v 1.20 2000/01/19 04:06:03 davem Exp $ +# $Id: Makefile,v 1.21 2000/03/27 10:38:41 davem Exp $ # Makefile for Sparc library files.. # @@ -7,7 +7,7 @@ CFLAGS := $(CFLAGS) OBJS = PeeCeeI.o blockops.o debuglocks.o strlen.o strncmp.o \ memscan.o strncpy_from_user.o strlen_user.o memcmp.o checksum.o \ VIScopy.o VISbzero.o VISmemset.o VIScsum.o VIScsumcopy.o \ - VIScsumcopyusr.o VISsave.o atomic.o rwlock.o + VIScsumcopyusr.o VISsave.o atomic.o rwlock.o bitops.o lib.a: $(OBJS) $(AR) rcs lib.a $(OBJS) @@ -17,10 +17,10 @@ VIScopy.o: VIScopy.S VIS.h VISbzero.o: VISbzero.S VIS.h .S.s: - $(CPP) -D__ASSEMBLY__ $(AFLAGS) -ansi $< -o $*.s + $(CPP) $(AFLAGS) -ansi $< -o $*.s .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $< -o $*.o + $(CC) $(AFLAGS) -ansi -c $< -o $*.o dep: diff --git a/arch/sparc64/lib/bitops.S b/arch/sparc64/lib/bitops.S new file mode 100644 index 000000000000..f964e455069e --- /dev/null +++ b/arch/sparc64/lib/bitops.S @@ -0,0 +1,110 @@ +/* $Id: bitops.S,v 1.1 2000/03/27 10:38:41 davem Exp $ + * bitops.S: Sparc64 atomic bit operations. + * + * Copyright (C) 2000 David S. Miller (davem@redhat.com) + */ + +#include + + .text + .align 64 + .globl __bitops_begin +__bitops_begin: + + .globl __test_and_set_bit +__test_and_set_bit: /* %o0=nr, %o1=addr */ + srlx %o0, 6, %g1 + mov 1, %g5 + sllx %g1, 3, %g3 + and %o0, 63, %g2 + sllx %g5, %g2, %g5 + add %o1, %g3, %o1 + ldx [%o1], %g7 +1: andcc %g7, %g5, %o0 + bne,pn %xcc, 2f + xor %g7, %g5, %g1 + casx [%o1], %g7, %g1 + cmp %g7, %g1 + bne,a,pn %xcc, 1b + ldx [%o1], %g7 +2: retl + nop + + .globl __test_and_clear_bit +__test_and_clear_bit: /* %o0=nr, %o1=addr */ + srlx %o0, 6, %g1 + mov 1, %g5 + sllx %g1, 3, %g3 + and %o0, 63, %g2 + sllx %g5, %g2, %g5 + add %o1, %g3, %o1 + ldx [%o1], %g7 +1: andcc %g7, %g5, %o0 + be,pn %xcc, 2f + xor %g7, %g5, %g1 + casx [%o1], %g7, %g1 + cmp %g7, %g1 + bne,a,pn %xcc, 1b + ldx [%o1], %g7 +2: retl + nop + + .globl __test_and_change_bit +__test_and_change_bit: /* %o0=nr, %o1=addr */ + srlx %o0, 6, %g1 + mov 1, %g5 + sllx %g1, 3, %g3 + and %o0, 63, %g2 + sllx %g5, %g2, %g5 + add %o1, %g3, %o1 + ldx [%o1], %g7 +1: and %g7, %g5, %o0 + xor %g7, %g5, %g1 + casx [%o1], %g7, %g1 + cmp %g7, %g1 + bne,a,pn %xcc, 1b + ldx [%o1], %g7 +2: retl + nop + nop + + .globl __test_and_set_le_bit +__test_and_set_le_bit: /* %o0=nr, %o1=addr */ + srlx %o0, 5, %g1 + mov 1, %g5 + sllx %g1, 2, %g3 + and %o0, 31, %g2 + sllx %g5, %g2, %g5 + add %o1, %g3, %o1 + lduwa [%o1] ASI_PL, %g7 +1: andcc %g7, %g5, %o0 + bne,pn %icc, 2f + xor %g7, %g5, %g1 + casa [%o1] ASI_PL, %g7, %g1 + cmp %g7, %g1 + bne,a,pn %icc, 1b + lduwa [%o1] ASI_PL, %g7 +2: retl + nop + + .globl __test_and_clear_le_bit +__test_and_clear_le_bit: /* %o0=nr, %o1=addr */ + srlx %o0, 5, %g1 + mov 1, %g5 + sllx %g1, 2, %g3 + and %o0, 31, %g2 + sllx %g5, %g2, %g5 + add %o1, %g3, %o1 + lduwa [%o1] ASI_PL, %g7 +1: andcc %g7, %g5, %o0 + be,pn %icc, 2f + xor %g7, %g5, %g1 + casa [%o1] ASI_PL, %g7, %g1 + cmp %g7, %g1 + bne,a,pn %icc, 1b + lduwa [%o1] ASI_PL, %g7 +2: retl + nop + + .globl __bitops_end +__bitops_end: diff --git a/arch/sparc64/lib/blockops.S b/arch/sparc64/lib/blockops.S index ea3019857fe2..9c6a8beba3fa 100644 --- a/arch/sparc64/lib/blockops.S +++ b/arch/sparc64/lib/blockops.S @@ -1,4 +1,4 @@ -/* $Id: blockops.S,v 1.23 2000/03/26 09:13:50 davem Exp $ +/* $Id: blockops.S,v 1.24 2000/03/27 10:38:41 davem Exp $ * blockops.S: UltraSparc block zero optimized routines. * * Copyright (C) 1996, 1998, 1999, 2000 David S. Miller (davem@redhat.com) @@ -122,7 +122,11 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ stxa %g2, [%o3] ASI_DTLB_DATA_ACCESS membar #Sync - membar #LoadStore | #StoreStore | #StoreLoad + ldub [%g6 + AOFF_task_thread + AOFF_thread_use_blkcommit], %g2 + cmp %g2, 0 + bne,pn %xcc, copy_page_using_blkcommit + nop + ldda [%o1] ASI_BLK_P, %f0 add %o1, 0x40, %o1 ldda [%o1] ASI_BLK_P, %f16 @@ -152,6 +156,7 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ stda %f0, [%o0] ASI_BLK_P add %o0, 0x40, %o0 stda %f16, [%o0] ASI_BLK_P +copy_user_page_continue: membar #Sync VISExit @@ -166,6 +171,39 @@ copy_user_page: /* %o0=dest, %o1=src, %o2=vaddr */ jmpl %o7 + 0x8, %g0 wrpr %g3, 0x0, %pstate +copy_page_using_blkcommit: + membar #LoadStore | #StoreStore | #StoreLoad + ldda [%o1] ASI_BLK_P, %f0 + add %o1, 0x40, %o1 + ldda [%o1] ASI_BLK_P, %f16 + add %o1, 0x40, %o1 + sethi %hi(8192), %o2 +1: TOUCH(f0, f2, f4, f6, f8, f10, f12, f14) + ldda [%o1] ASI_BLK_P, %f32 + stda %f48, [%o0] ASI_BLK_COMMIT_P + add %o1, 0x40, %o1 + sub %o2, 0x40, %o2 + add %o0, 0x40, %o0 + TOUCH(f16, f18, f20, f22, f24, f26, f28, f30) + ldda [%o1] ASI_BLK_P, %f0 + stda %f48, [%o0] ASI_BLK_COMMIT_P + add %o1, 0x40, %o1 + sub %o2, 0x40, %o2 + add %o0, 0x40, %o0 + TOUCH(f32, f34, f36, f38, f40, f42, f44, f46) + ldda [%o1] ASI_BLK_P, %f16 + stda %f48, [%o0] ASI_BLK_COMMIT_P + sub %o2, 0x40, %o2 + add %o1, 0x40, %o1 + cmp %o2, 0x80 + bne,pt %xcc, 1b + add %o0, 0x40, %o0 + membar #Sync + stda %f0, [%o0] ASI_BLK_COMMIT_P + add %o0, 0x40, %o0 + ba,pt %xcc, copy_user_page_continue + stda %f16, [%o0] ASI_BLK_COMMIT_P + .align 32 .globl clear_page .type clear_page,@function diff --git a/arch/sparc64/mm/Makefile b/arch/sparc64/mm/Makefile index d97c47778caf..039195944beb 100644 --- a/arch/sparc64/mm/Makefile +++ b/arch/sparc64/mm/Makefile @@ -8,10 +8,10 @@ # Note 2! The CFLAGS definition is now in the main makefile... .S.s: - $(CPP) -D__ASSEMBLY__ $(AFLAGS) -ansi $< -o $*.s + $(CPP) $(AFLAGS) -ansi $< -o $*.s .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $< -o $*.o + $(CC) $(AFLAGS) -ansi -c $< -o $*.o O_TARGET := mm.o O_OBJS := ultra.o fault.o init.o generic.o extable.o modutil.o diff --git a/arch/sparc64/mm/fault.c b/arch/sparc64/mm/fault.c index dea3a5ab6212..0d8152887dce 100644 --- a/arch/sparc64/mm/fault.c +++ b/arch/sparc64/mm/fault.c @@ -1,4 +1,4 @@ -/* $Id: fault.c,v 1.44 2000/03/26 09:13:51 davem Exp $ +/* $Id: fault.c,v 1.45 2000/03/27 10:38:51 davem Exp $ * arch/sparc64/mm/fault.c: Page fault handlers for the 64-bit Sparc. * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -285,6 +285,9 @@ good_area: if (fault_code & FAULT_CODE_WRITE) { if (!(vma->vm_flags & VM_WRITE)) goto bad_area; + if ((vma->vm_flags & VM_EXEC) != 0 && + vma->vm_file != NULL) + current->thread.use_blkcommit = 1; } else { /* Allow reads even for write-only mappings */ if (!(vma->vm_flags & (VM_READ | VM_EXEC))) @@ -342,5 +345,6 @@ do_sigbus: fault_done: /* These values are no longer needed, clear them. */ current->thread.fault_code = 0; + current->thread.use_blkcommit = 0; current->thread.fault_address = 0; } diff --git a/arch/sparc64/mm/ultra.S b/arch/sparc64/mm/ultra.S index 6d92ab7693fb..1c3714e5ba52 100644 --- a/arch/sparc64/mm/ultra.S +++ b/arch/sparc64/mm/ultra.S @@ -1,4 +1,4 @@ -/* $Id: ultra.S,v 1.40 2000/03/26 09:13:51 davem Exp $ +/* $Id: ultra.S,v 1.41 2000/03/27 10:38:51 davem Exp $ * ultra.S: Don't expand these all over the place... * * Copyright (C) 1997, 2000 David S. Miller (davem@redhat.com) @@ -206,7 +206,6 @@ iflush2:sub %o1, 0x20, %g3 ba,a,pt %xcc, 3b .align 32 - .globl __prefill_dtlb __prefill_dtlb: rdpr %pstate, %g7 wrpr %g7, PSTATE_IE, %pstate @@ -216,8 +215,6 @@ __prefill_dtlb: flush %g6 retl wrpr %g7, %pstate - - .globl __prefill_itlb __prefill_itlb: rdpr %pstate, %g7 wrpr %g7, PSTATE_IE, %pstate @@ -228,6 +225,23 @@ __prefill_itlb: retl wrpr %g7, %pstate + .globl update_mmu_cache +update_mmu_cache: /* %o0=vma, %o1=address, %o2=pte */ + ldub [%g6 + AOFF_task_thread + AOFF_thread_fault_code], %o3 + srlx %o1, 13, %o1 + ldx [%o0 + 0x0], %o4 /* XXX vma->vm_mm */ + brz,pn %o3, 1f + sllx %o1, 13, %o0 + ldx [%o4 + AOFF_mm_context], %o5 + andcc %o3, FAULT_CODE_DTLB, %g0 + mov %o2, %o1 + and %o5, 0x3ff, %o5 + bne,pt %xcc, __prefill_dtlb + or %o0, %o5, %o0 + ba,a,pt %xcc, __prefill_itlb +1: retl + nop + #ifdef __SMP__ /* These are all called by the slaves of a cross call, at * trap level 1, with interrupts fully disabled. diff --git a/arch/sparc64/prom/Makefile b/arch/sparc64/prom/Makefile index 42906da28032..88ca5251b5b0 100644 --- a/arch/sparc64/prom/Makefile +++ b/arch/sparc64/prom/Makefile @@ -18,10 +18,10 @@ promlib.a: $(OBJS) sync .S.s: - $(CPP) -D__ASSEMBLY__ $(AFLAGS) -ansi $< -o $*.s + $(CPP) $(AFLAGS) -ansi $< -o $*.s .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -ansi -c $< -o $*.o + $(CC) $(AFLAGS) -ansi -c $< -o $*.o dep: $(CPP) $(CPPFLAGS) -M *.c > .depend diff --git a/arch/sparc64/solaris/Makefile b/arch/sparc64/solaris/Makefile index 5e5a6aff8421..51598f7273ce 100644 --- a/arch/sparc64/solaris/Makefile +++ b/arch/sparc64/solaris/Makefile @@ -15,10 +15,10 @@ CPPFLAGS = $(MODFLAGS) endif .S.s: - $(CPP) -D__ASSEMBLY__ $(AFLAGS) $(CPPFLAGS) -ansi $< -o $*.s + $(CPP) $(AFLAGS) $(CPPFLAGS) -ansi $< -o $*.s .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) $(CPPFLAGS) -ansi -c $< -o $*.o + $(CC) $(AFLAGS) $(CPPFLAGS) -ansi -c $< -o $*.o ifneq ($(CONFIG_SOLARIS_EMUL),y) do_it_all: diff --git a/arch/sparc64/solaris/socksys.c b/arch/sparc64/solaris/socksys.c index 89f7716096ce..220e549ac658 100644 --- a/arch/sparc64/solaris/socksys.c +++ b/arch/sparc64/solaris/socksys.c @@ -1,4 +1,4 @@ -/* $Id: socksys.c,v 1.12 2000/02/17 05:50:11 davem Exp $ +/* $Id: socksys.c,v 1.13 2000/03/29 11:56:54 davem Exp $ * socksys.c: /dev/inet/ stuff for Solaris emulation. * * Copyright (C) 1997 Jakub Jelinek (jj@sunsite.mff.cuni.cz) @@ -17,6 +17,7 @@ #include #include #include +#include #include #include diff --git a/drivers/char/cpia_usb.c b/drivers/char/cpia_usb.c index 696d79af9f48..6b67fbc81de1 100644 --- a/drivers/char/cpia_usb.c +++ b/drivers/char/cpia_usb.c @@ -21,7 +21,6 @@ * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. */ -#include #include #include #include diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c index aac1b73dd28b..128128bcb637 100644 --- a/drivers/net/eepro100.c +++ b/drivers/net/eepro100.c @@ -38,7 +38,7 @@ static const char *version = "eepro100.c:v1.09j-t 9/29/99 Donald Becker http://cesdis.gsfc.nasa.gov/linux/drivers/eepro100.html\n" -"eepro100.c: $Revision: 1.28 $ 2000/03/28 Modified by Andrey V. Savochkin and others\n"; +"eepro100.c: $Revision: 1.29 $ 2000/03/30 Modified by Andrey V. Savochkin and others\n"; /* A few user-configurable values that apply to all boards. First set is undocumented and spelled per Intel recommendations. */ @@ -93,6 +93,7 @@ static int debug = -1; /* The debug level */ #error You must compile this driver with "-O". #endif +#include #include #include #if defined(MODVERSIONS) @@ -353,6 +354,14 @@ enum pci_flags_bit { }; #ifndef USE_IO +/* Currently alpha headers define in/out macros. + Undefine them. 2000/03/30 SAW */ +#undef inb +#undef inw +#undef inl +#undef outb +#undef outw +#undef outl #define inb readb #define inw readw #define inl readl @@ -460,8 +469,7 @@ struct speedo_mc_block { unsigned int tx; dma_addr_t frame_dma; unsigned int len; - char fill[16 - sizeof(struct speedo_mc_block *) - sizeof(unsigned int) - sizeof(dma_addr_t) - sizeof(unsigned int)]; - struct descriptor frame; + struct descriptor frame __attribute__ ((__aligned__(16))); }; /* Elements of the dump_statistics block. This block must be lword aligned. */ diff --git a/drivers/net/tokenring/Config.in b/drivers/net/tokenring/Config.in index 316b638c2a41..44c53682c06a 100644 --- a/drivers/net/tokenring/Config.in +++ b/drivers/net/tokenring/Config.in @@ -14,7 +14,9 @@ if [ "$CONFIG_TR" != "n" ]; then if [ "$CONFIG_TMS380TR" != "n" ]; then dep_tristate ' Generic TMS380 PCI support' CONFIG_TMSPCI $CONFIG_TMS380TR dep_tristate ' Madge Smart 16/4 PCI Mk2 support' CONFIG_ABYSS $CONFIG_TMS380TR - dep_tristate ' Madge Smart 16/4 Ringnode MicroChannel' CONFIG_MADGEMC $CONFIG_TMS380TR + if [ "$CONFIG_MCA" = "y" ]; then + dep_tristate ' Madge Smart 16/4 Ringnode MicroChannel' CONFIG_MADGEMC $CONFIG_TMS380TR + fi fi dep_tristate ' SMC ISA/MCA adapter support' CONFIG_SMCTR $CONFIG_TR fi diff --git a/drivers/parport/parport_sunbpp.c b/drivers/parport/parport_sunbpp.c index c1cdd3d9abe0..6cafbc11a289 100644 --- a/drivers/parport/parport_sunbpp.c +++ b/drivers/parport/parport_sunbpp.c @@ -1,4 +1,4 @@ -/* $Id: parport_sunbpp.c,v 1.9 1999/10/14 05:59:43 ecd Exp $ +/* $Id: parport_sunbpp.c,v 1.10 2000/03/27 01:47:56 anton Exp $ * Parallel-port routines for Sun architecture * * Author: Derrick J. Brashear @@ -335,6 +335,8 @@ static int __init init_one_port(struct sbus_dev *sdev) return 0; } + p->size = size; + dprintk(("init_one_port: request_irq(%08x:%p:%x:%s:%p) ", p->irq, parport_sunbpp_interrupt, SA_SHIRQ, p->name, p)); if ((err = request_irq(p->irq, parport_sunbpp_interrupt, diff --git a/drivers/scsi/esp.c b/drivers/scsi/esp.c index fccfb59c8636..1dcc8acb8921 100644 --- a/drivers/scsi/esp.c +++ b/drivers/scsi/esp.c @@ -1,4 +1,4 @@ -/* $Id: esp.c,v 1.92 2000/02/18 13:49:58 davem Exp $ +/* $Id: esp.c,v 1.94 2000/03/30 02:09:10 davem Exp $ * esp.c: EnhancedScsiProcessor Sun SCSI driver code. * * Copyright (C) 1995, 1998 David S. Miller (davem@caip.rutgers.edu) @@ -4348,6 +4348,13 @@ static void esp_intr(int irq, void *dev_id, struct pt_regs *pregs) spin_unlock_irqrestore(&esp->lock, flags); } +int esp_revoke(Scsi_Device* SDptr) +{ + struct esp *esp = (struct esp *) SDptr->host->hostdata; + esp->targets_present &= ~(1 << SDptr->id); + return 0; +} + #ifdef MODULE Scsi_Host_Template driver_template = SCSI_SPARC_ESP; diff --git a/drivers/scsi/esp.h b/drivers/scsi/esp.h index dfbfb9e53170..9bebad41bad5 100644 --- a/drivers/scsi/esp.h +++ b/drivers/scsi/esp.h @@ -1,4 +1,4 @@ -/* $Id: esp.h,v 1.27 1999/12/15 14:12:52 davem Exp $ +/* $Id: esp.h,v 1.28 2000/03/30 01:33:17 davem Exp $ * esp.h: Defines and structures for the Sparc ESP (Enhanced SCSI * Processor) driver under Linux. * @@ -398,12 +398,14 @@ extern int esp_abort(Scsi_Cmnd *); extern int esp_reset(Scsi_Cmnd *, unsigned int); extern int esp_proc_info(char *buffer, char **start, off_t offset, int length, int hostno, int inout); +extern int esp_revoke(Scsi_Device* SDptr); #define SCSI_SPARC_ESP { \ proc_name: "esp", \ proc_info: &esp_proc_info, \ name: "Sun ESP 100/100a/200", \ detect: esp_detect, \ + revoke: esp_revoke, \ info: esp_info, \ command: esp_command, \ queuecommand: esp_queue, \ diff --git a/drivers/scsi/hosts.h b/drivers/scsi/hosts.h index 685925e7defd..f7e546fa6038 100644 --- a/drivers/scsi/hosts.h +++ b/drivers/scsi/hosts.h @@ -96,6 +96,8 @@ typedef struct SHT */ int (* detect)(struct SHT *); + int (*revoke)(Scsi_Device *); + /* Used with loadable modules to unload the host structures. Note: * there is a default action built into the modules code which may * be sufficient for most host adapters. Thus you may not have to supply diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index 9fa8bc444718..87236abbbf19 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -1866,6 +1866,8 @@ static int proc_scsi_gen_write(struct file * file, const char * buf, * Nobody is using this device any more. * Free all of the command structures. */ + if (HBA_ptr->hostt->revoke) + HBA_ptr->hostt->revoke(scd); devfs_unregister (scd->de); scsi_release_commandblocks(scd); diff --git a/drivers/usb/Config.in b/drivers/usb/Config.in index 4471f96c9ad9..ee001d0154bb 100644 --- a/drivers/usb/Config.in +++ b/drivers/usb/Config.in @@ -8,6 +8,9 @@ tristate 'Support for USB' CONFIG_USB if [ ! "$CONFIG_USB" = "n" ]; then bool ' USB verbose debug messages' CONFIG_USB_DEBUG +comment 'Miscellaneous USB options' + bool ' Preliminary USB device filesystem' CONFIG_USB_DEVICEFS + comment 'USB Controllers' if [ "$CONFIG_USB_UHCI_ALT" != "y" ]; then dep_tristate ' UHCI (Intel PIIX4, VIA, ...) support' CONFIG_USB_UHCI $CONFIG_USB @@ -17,9 +20,6 @@ comment 'USB Controllers' fi dep_tristate ' OHCI (Compaq, iMacs, OPTi, SiS, ALi, ...) support' CONFIG_USB_OHCI $CONFIG_USB -comment 'Miscellaneous USB options' - bool ' Preliminary USB device filesystem' CONFIG_USB_DEVICEFS - comment 'USB Devices' dep_tristate ' USB Printer support' CONFIG_USB_PRINTER $CONFIG_USB dep_tristate ' USB Scanner support' CONFIG_USB_SCANNER $CONFIG_USB diff --git a/drivers/usb/evdev.c b/drivers/usb/evdev.c index 9cca9fdf6eba..ac332a053901 100644 --- a/drivers/usb/evdev.c +++ b/drivers/usb/evdev.c @@ -29,9 +29,9 @@ */ #define EVDEV_MINOR_BASE 64 +#define EVDEV_MINORS 32 #define EVDEV_BUFFER_SIZE 64 -#include #include #include #include @@ -39,11 +39,11 @@ #include struct evdev { - char name[32]; int used; + int minor; struct input_handle handle; - struct miscdevice misc; wait_queue_head_t wait; + devfs_handle_t devfs; struct evdev_list *list; }; @@ -56,8 +56,7 @@ struct evdev_list { struct evdev_list *next; }; -static unsigned long evdev_miscbits = 0; -static struct evdev *evdev_base[BITS_PER_LONG]; +static struct evdev *evdev_table[BITS_PER_LONG] = { NULL, /* ... */ }; static void evdev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { @@ -101,8 +100,8 @@ static int evdev_release(struct inode * inode, struct file * file) *listptr = (*listptr)->next; if (!--list->evdev->used) { - clear_bit(list->evdev->misc.minor - EVDEV_MINOR_BASE, &evdev_miscbits); - misc_deregister(&list->evdev->misc); + input_unregister_minor(list->evdev->devfs); + evdev_table[list->evdev->minor] = NULL; kfree(list->evdev); } @@ -117,7 +116,7 @@ static int evdev_open(struct inode * inode, struct file * file) struct evdev_list *list; int i = MINOR(inode->i_rdev) - EVDEV_MINOR_BASE; - if (i > BITS_PER_LONG || !test_bit(i, &evdev_miscbits)) + if (i > EVDEV_MINORS || !evdev_table[i]) return -ENODEV; if (!(list = kmalloc(sizeof(struct evdev_list), GFP_KERNEL))) @@ -125,9 +124,9 @@ static int evdev_open(struct inode * inode, struct file * file) memset(list, 0, sizeof(struct evdev_list)); - list->evdev = evdev_base[i]; - list->next = evdev_base[i]->list; - evdev_base[i]->list = list; + list->evdev = evdev_table[i]; + list->next = evdev_table[i]->list; + evdev_table[i]->list = list; file->private_data = list; @@ -205,22 +204,22 @@ static struct file_operations evdev_fops = { static int evdev_connect(struct input_handler *handler, struct input_dev *dev) { struct evdev *evdev; + int minor; - if (!(evdev = kmalloc(sizeof(struct evdev), GFP_KERNEL))) + for (minor = 0; minor < EVDEV_MINORS && evdev_table[minor]; minor++); + if (evdev_table[minor]) { + printk(KERN_ERR "evdev: no more free evdev devices\n"); return -1; + } + if (!(evdev = kmalloc(sizeof(struct evdev), GFP_KERNEL))) + return -1; memset(evdev, 0, sizeof(struct evdev)); init_waitqueue_head(&evdev->wait); - evdev->misc.minor = ffz(evdev_miscbits); - set_bit(evdev->misc.minor, &evdev_miscbits); - evdev_base[evdev->misc.minor] = evdev; - - sprintf(evdev->name, "evdev%d", evdev->misc.minor); - evdev->misc.name = evdev->name; - evdev->misc.minor += EVDEV_MINOR_BASE; - evdev->misc.fops = &evdev_fops; + evdev->minor = minor; + evdev_table[minor] = evdev; evdev->handle.dev = dev; evdev->handle.handler = handler; @@ -228,11 +227,10 @@ static int evdev_connect(struct input_handler *handler, struct input_dev *dev) evdev->used = 1; - misc_register(&evdev->misc); input_open_device(&evdev->handle); + evdev->devfs = input_register_minor("event%d", minor, EVDEV_MINOR_BASE); - printk("%s: Event device for input%d on misc%d - /dev/input%d\n", - evdev->name, dev->number, evdev->misc.minor, evdev->misc.minor - EVDEV_MINOR_BASE); + printk("event%d: Event device for input%d\n", minor, dev->number); return 0; } @@ -244,8 +242,8 @@ static void evdev_disconnect(struct input_handle *handle) input_close_device(handle); if (!--evdev->used) { - clear_bit(evdev->misc.minor - EVDEV_MINOR_BASE, &evdev_miscbits); - misc_deregister(&evdev->misc); + input_unregister_minor(evdev->devfs); + evdev_table[evdev->minor] = NULL; kfree(evdev); } } @@ -254,6 +252,8 @@ static struct input_handler evdev_handler = { event: evdev_event, connect: evdev_connect, disconnect: evdev_disconnect, + fops: &evdev_fops, + minor: EVDEV_MINOR_BASE, }; static int __init evdev_init(void) diff --git a/drivers/usb/hub.c b/drivers/usb/hub.c index fafac9b882f2..8c76969d742f 100644 --- a/drivers/usb/hub.c +++ b/drivers/usb/hub.c @@ -6,6 +6,7 @@ * (C) Copyright 1999 Gregory P. Smith */ +#include #include #include #include diff --git a/drivers/usb/input.c b/drivers/usb/input.c index e370927b3db1..01cceeacffbf 100644 --- a/drivers/usb/input.c +++ b/drivers/usb/input.c @@ -45,9 +45,12 @@ EXPORT_SYMBOL(input_close_device); EXPORT_SYMBOL(input_event); #endif +#define INPUT_MAJOR 13 + static struct input_dev *input_dev = NULL; static struct input_handler *input_handler = NULL; - +static struct input_handler *input_table[8] = { NULL, /* ... */ }; +static devfs_handle_t input_devfs_handle = NULL; static int input_number = 0; void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value) @@ -223,6 +226,13 @@ void input_register_handler(struct input_handler *handler) { struct input_dev *dev = input_dev; +/* + * Add minors if needed. + */ + + if (handler->fops != NULL) + input_table[handler->minor >> 5] = handler; + /* * Add the handler. */ @@ -263,6 +273,12 @@ void input_unregister_handler(struct input_handler *handler) *handlerptr = (*handlerptr)->next; +/* + * Remove minors. + */ + + if (handler->fops != NULL) + input_table[handler->minor >> 5] = NULL; } void input_open_device(struct input_handle *handle) @@ -302,3 +318,52 @@ void input_close_device(struct input_handle *handle) handleptr = &((*handleptr)->hnext); *handleptr = (*handleptr)->hnext; } + +static int input_open_file(struct inode *inode, struct file *file) +{ + struct input_handler *handler = input_table[MINOR(inode->i_rdev) >> 5]; + + if (!handler || !handler->fops || !handler->fops->open) + return -ENODEV; + + file->f_op = handler->fops; + + return handler->fops->open(inode, file); +} + +static struct file_operations input_fops = { + open: input_open_file, +}; + +devfs_handle_t input_register_minor(char *name, int minor, int minor_base) +{ + char devfs_name[16]; + sprintf(devfs_name, name, minor); + return devfs_register(input_devfs_handle, devfs_name, 0, DEVFS_FL_DEFAULT, INPUT_MAJOR, minor + minor_base, + S_IFCHR | S_IRUGO | S_IWUSR, 0, 0, &input_fops, NULL); +} + +void input_unregister_minor(devfs_handle_t handle) +{ + devfs_unregister(handle); +} + +static int __init input_init(void) +{ + if (devfs_register_chrdev(INPUT_MAJOR, "input", &input_fops)) { + printk(KERN_ERR "input: unable to register char major %d", INPUT_MAJOR); + return -EBUSY; + } + input_devfs_handle = devfs_mk_dir(NULL, "input", 5, NULL); + return 0; +} + +static void __exit input_exit(void) +{ + devfs_unregister(input_devfs_handle); + if (devfs_unregister_chrdev(INPUT_MAJOR, "input")) + printk(KERN_ERR "input: can't unregister char major %d", INPUT_MAJOR); +} + +module_init(input_init); +module_exit(input_exit); diff --git a/drivers/usb/joydev.c b/drivers/usb/joydev.c index 9b54300e2f9c..9992abbe2391 100644 --- a/drivers/usb/joydev.c +++ b/drivers/usb/joydev.c @@ -45,15 +45,17 @@ #include #include -#define JOYDEV_MAJOR 15 +#define JOYDEV_MINOR_BASE 0 +#define JOYDEV_MINORS 32 #define JOYDEV_BUFFER_SIZE 64 struct joydev { - char name[32]; int used; - struct input_handle handle; int minor; + char name[32]; + struct input_handle handle; wait_queue_head_t wait; + devfs_handle_t devfs; struct joydev *next; struct joydev_list *list; struct js_corr corr[ABS_MAX]; @@ -76,11 +78,10 @@ struct joydev_list { struct joydev_list *next; }; -static unsigned long joydev_minors = 0; -static struct joydev *joydev_base[BITS_PER_LONG]; +static struct joydev *joydev_table[BITS_PER_LONG]; MODULE_AUTHOR("Vojtech Pavlik "); -MODULE_SUPPORTED_DEVICE("js"); +MODULE_SUPPORTED_DEVICE("input/js"); static int joydev_correct(int value, struct js_corr *corr) { @@ -166,7 +167,8 @@ static int joydev_release(struct inode * inode, struct file * file) *listptr = (*listptr)->next; if (!--list->joydev->used) { - clear_bit(list->joydev->minor, &joydev_minors); + input_unregister_minor(list->joydev->devfs); + joydev_table[list->joydev->minor] = NULL; kfree(list->joydev); } @@ -179,22 +181,18 @@ static int joydev_release(struct inode * inode, struct file * file) static int joydev_open(struct inode *inode, struct file *file) { struct joydev_list *list; - int i = MINOR(inode->i_rdev); + int i = MINOR(inode->i_rdev) - JOYDEV_MINOR_BASE; - if (MAJOR(inode->i_rdev) != JOYSTICK_MAJOR) - return -EINVAL; - - if (i > BITS_PER_LONG || !test_bit(i, &joydev_minors)) + if (i > JOYDEV_MINORS || !joydev_table[i]) return -ENODEV; if (!(list = kmalloc(sizeof(struct joydev_list), GFP_KERNEL))) return -ENOMEM; - memset(list, 0, sizeof(struct joydev_list)); - list->joydev = joydev_base[i]; - list->next = joydev_base[i]->list; - joydev_base[i]->list = list; + list->joydev = joydev_table[i]; + list->next = joydev_table[i]->list; + joydev_table[i]->list = list; file->private_data = list; @@ -373,27 +371,30 @@ static struct file_operations joydev_fops = { static int joydev_connect(struct input_handler *handler, struct input_dev *dev) { struct joydev *joydev; - int i, j; + int i, j, minor; if (!(test_bit(EV_KEY, dev->evbit) && test_bit(EV_ABS, dev->evbit) && test_bit(ABS_X, dev->absbit) && test_bit(ABS_Y, dev->absbit) && (test_bit(BTN_TRIGGER, dev->keybit) || test_bit(BTN_A, dev->keybit) || test_bit(BTN_1, dev->keybit)))) return -1; - if (!(joydev = kmalloc(sizeof(struct joydev), GFP_KERNEL))) + for (minor = 0; minor < JOYDEV_MINORS && joydev_table[minor]; minor++); + if (joydev_table[minor]) { + printk(KERN_ERR "joydev: no more free joydev devices\n"); return -1; + } + if (!(joydev = kmalloc(sizeof(struct joydev), GFP_KERNEL))) + return -1; memset(joydev, 0, sizeof(struct joydev)); init_waitqueue_head(&joydev->wait); - if (joydev_minors == -1) { - printk("Can't register new joystick - 32 devices already taken.\n"); - return -1; - } - sprintf(joydev->name, "joydev%d", joydev->minor); + joydev->minor = minor; + joydev_table[minor] = joydev; + joydev->handle.dev = dev; joydev->handle.handler = handler; joydev->handle.private = joydev; @@ -421,10 +422,6 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev) joydev->nkey++; } - joydev->minor = ffz(joydev_minors); - set_bit(joydev->minor, &joydev_minors); - joydev_base[joydev->minor] = joydev; - for (i = 0; i < joydev->nabs; i++) { j = joydev->abspam[i]; if (dev->absmax[j] == dev->absmin[j]) { @@ -440,8 +437,9 @@ static int joydev_connect(struct input_handler *handler, struct input_dev *dev) } input_open_device(&joydev->handle); + joydev->devfs = input_register_minor("js%d", minor, JOYDEV_MINOR_BASE); - printk("%s: Joystick device for input%d on /dev/js%d\n", joydev->name, dev->number, joydev->minor); + printk("js%d: Joystick device for input%d\n", minor, dev->number); return 0; } @@ -453,7 +451,8 @@ static void joydev_disconnect(struct input_handle *handle) input_close_device(handle); if (!--joydev->used) { - clear_bit(joydev->minor, &joydev_minors); + input_unregister_minor(joydev->devfs); + joydev_table[joydev->minor] = NULL; kfree(joydev); } } @@ -462,14 +461,12 @@ static struct input_handler joydev_handler = { event: joydev_event, connect: joydev_connect, disconnect: joydev_disconnect, + fops: &joydev_fops, + minor: JOYDEV_MINOR_BASE, }; static int __init joydev_init(void) { - if (register_chrdev(JOYDEV_MAJOR, "js", &joydev_fops)) { - printk(KERN_ERR "joydev: unable to get major %d for joystick\n", JOYDEV_MAJOR); - return -EBUSY; - } input_register_handler(&joydev_handler); return 0; } @@ -477,8 +474,6 @@ static int __init joydev_init(void) static void __exit joydev_exit(void) { input_unregister_handler(&joydev_handler); - if (unregister_chrdev(JOYSTICK_MAJOR, "js")) - printk(KERN_ERR "js: can't unregister device\n"); } module_init(joydev_init); diff --git a/drivers/usb/mousedev.c b/drivers/usb/mousedev.c index bfdc4ab3d7d7..cf3c7fead460 100644 --- a/drivers/usb/mousedev.c +++ b/drivers/usb/mousedev.c @@ -29,8 +29,8 @@ */ #define MOUSEDEV_MINOR_BASE 32 +#define MOUSEDEV_MINORS 32 -#include #include #include #include @@ -46,12 +46,11 @@ #endif struct mousedev { - char name[32]; int used; - struct input_handle handle; - struct miscdevice misc; + int minor; wait_queue_head_t wait; struct mousedev_list *list; + devfs_handle_t devfs; }; struct mousedev_list { @@ -71,12 +70,7 @@ struct mousedev_list { static unsigned char mousedev_genius_seq[] = { 0xe8, 3, 0xe6, 0xe6, 0xe6 }; static unsigned char mousedev_imps_seq[] = { 0xf3, 200, 0xf3, 100, 0xf3, 80 }; -#ifdef CONFIG_INPUT_MOUSEDEV_MIX -static struct mousedev mousedev_single; -#else -static unsigned long mousedev_miscbits = 0; -static struct mousedev *mousedev_base[BITS_PER_LONG]; -#endif +static struct mousedev *mousedev_table[BITS_PER_LONG]; static void mousedev_event(struct input_handle *handle, unsigned int type, unsigned int code, int value) { @@ -163,13 +157,11 @@ static int mousedev_release(struct inode * inode, struct file * file) listptr = &((*listptr)->next); *listptr = (*listptr)->next; -#ifndef CONFIG_INPUT_MOUSEDEV_MIX if (!--list->mousedev->used) { - clear_bit(list->mousedev->misc.minor - MOUSEDEV_MINOR_BASE, &mousedev_miscbits); - misc_deregister(&list->mousedev->misc); + input_unregister_minor(list->mousedev->devfs); + mousedev_table[list->mousedev->minor] = NULL; kfree(list->mousedev); } -#endif kfree(list); @@ -180,29 +172,20 @@ static int mousedev_release(struct inode * inode, struct file * file) static int mousedev_open(struct inode * inode, struct file * file) { struct mousedev_list *list; - -#ifndef CONFIG_INPUT_MOUSEDEV_MIX int i = MINOR(inode->i_rdev) - MOUSEDEV_MINOR_BASE; - if (i > BITS_PER_LONG || !test_bit(i, &mousedev_miscbits)) + + if (i > MOUSEDEV_MINORS || !mousedev_table[i]) return -ENODEV; -#endif if (!(list = kmalloc(sizeof(struct mousedev_list), GFP_KERNEL))) return -ENOMEM; memset(list, 0, sizeof(struct mousedev_list)); - -#ifdef CONFIG_INPUT_MOUSEDEV_MIX - list->mousedev = &mousedev_single; - list->next = mousedev_single.list; - mousedev_single.list = list; -#else - list->mousedev = mousedev_base[i]; - list->next = mousedev_base[i]->list; - mousedev_base[i]->list = list; + list->mousedev = mousedev_table[i]; + list->next = mousedev_table[i]->list; + mousedev_table[i]->list = list; list->mousedev->used++; -#endif file->private_data = list; @@ -359,6 +342,9 @@ struct file_operations mousedev_fops = { static int mousedev_connect(struct input_handler *handler, struct input_dev *dev) { + struct mousedev *mousedev; + struct input_handle *handle; + int minor = 0; if (!test_bit(EV_KEY, dev->evbit) || (!test_bit(BTN_LEFT, dev->keybit) && !test_bit(BTN_TOUCH, dev->keybit))) @@ -367,109 +353,77 @@ static int mousedev_connect(struct input_handler *handler, struct input_dev *dev if ((!test_bit(EV_REL, dev->evbit) || !test_bit(REL_X, dev->relbit)) && (!test_bit(EV_ABS, dev->evbit) || !test_bit(ABS_X, dev->absbit))) return -1; - -#ifdef CONFIG_INPUT_MOUSEDEV_MIX - { - struct input_handle *handle; - - if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL))) - return -1; - memset(handle, 0, sizeof(struct input_handle)); - - handle->dev = dev; - handle->handler = handler; - handle->private = &mousedev_single; - - input_open_device(handle); - - printk("mousedev.c: Adding mouse: input%d\n", dev->number); +#ifndef CONFIG_INPUT_MOUSEDEV_MIX + for (minor = 0; minor < MOUSEDEV_MINORS && mousedev_table[minor]; minor++); + if (mousedev_table[minor]) { + printk(KERN_ERR "mousedev: no more free mousedev devices\n"); + return -1; } #else - { - struct mousedev *mousedev; + if (!mousedev_table[minor]) { +#endif if (!(mousedev = kmalloc(sizeof(struct mousedev), GFP_KERNEL))) return -1; - memset(mousedev, 0, sizeof(struct mousedev)); + init_waitqueue_head(&mousedev->wait); - mousedev->misc.minor = ffz(mousedev_miscbits); - set_bit(mousedev->misc.minor, &mousedev_miscbits); - mousedev_base[mousedev->misc.minor] = mousedev; + mousedev->devfs = input_register_minor("mouse%d", minor, MOUSEDEV_MINOR_BASE); - sprintf(mousedev->name, "mousedev%d", mousedev->misc.minor); - mousedev->misc.name = mousedev->name; - mousedev->misc.minor += MOUSEDEV_MINOR_BASE; - mousedev->misc.fops = &mousedev_fops; +#ifdef CONFIG_INPUT_MOUSEDEV_MIX + } else mousedev = mousedev_table[minor]; +#endif - mousedev->handle.dev = dev; - mousedev->handle.handler = handler; - mousedev->handle.private = mousedev; + if (!(handle = kmalloc(sizeof(struct input_handle), GFP_KERNEL))) { + if (!mousedev->used) kfree(mousedev); + return -1; + } + memset(handle, 0, sizeof(struct input_handle)); - init_waitqueue_head(&mousedev->wait); + mousedev->used++; + mousedev->minor = minor; + mousedev_table[minor] = mousedev; - mousedev->used = 1; + handle->dev = dev; + handle->handler = handler; + handle->private = mousedev; - misc_register(&mousedev->misc); - input_open_device(&mousedev->handle); + input_open_device(handle); - printk("%s: PS/2 mouse device for input%d on misc%d\n", - mousedev->name, dev->number, mousedev->misc.minor); - } -#endif + printk("mouse%d: PS/2 mouse device for input%d\n", minor, dev->number); return 0; } static void mousedev_disconnect(struct input_handle *handle) { -#ifdef CONFIG_INPUT_MOUSEDEV_MIX - printk("mousedev.c: Removing mouse: input%d\n", handle->dev->number); - input_close_device(handle); - kfree(handle); -#else struct mousedev *mousedev = handle->private; input_close_device(handle); + kfree(handle); if (!--mousedev->used) { - clear_bit(mousedev->misc.minor - MOUSEDEV_MINOR_BASE, &mousedev_miscbits); - misc_deregister(&mousedev->misc); + input_unregister_minor(mousedev->devfs); + mousedev_table[mousedev->minor] = NULL; kfree(mousedev); } -#endif } static struct input_handler mousedev_handler = { event: mousedev_event, connect: mousedev_connect, disconnect: mousedev_disconnect, + fops: &mousedev_fops, + minor: MOUSEDEV_MINOR_BASE, }; static int __init mousedev_init(void) { input_register_handler(&mousedev_handler); - -#ifdef CONFIG_INPUT_MOUSEDEV_MIX - memset(&mousedev_single, 0, sizeof(struct mousedev)); - - init_waitqueue_head(&mousedev_single.wait); - mousedev_single.misc.minor = MOUSEDEV_MINOR_BASE; - mousedev_single.misc.name = "mousedev"; - mousedev_single.misc.fops = &mousedev_fops; - - misc_register(&mousedev_single.misc); - - printk("mousedev: PS/2 mouse device on misc%d\n", mousedev_single.misc.minor); -#endif - return 0; } static void __exit mousedev_exit(void) { -#ifdef CONFIG_INPUT_MOUSEDEV_MIX - misc_deregister(&mousedev_single.misc); -#endif input_unregister_handler(&mousedev_handler); } diff --git a/drivers/usb/serial/usb-serial.h b/drivers/usb/serial/usb-serial.h index 667b6ed06d81..a4dcaa5aefd9 100644 --- a/drivers/usb/serial/usb-serial.h +++ b/drivers/usb/serial/usb-serial.h @@ -17,6 +17,7 @@ #ifndef __LINUX_USB_SERIAL_H #define __LINUX_USB_SERIAL_H +#include #define SERIAL_TTY_MAJOR 188 /* Nice legal number now */ #define SERIAL_TTY_MINORS 16 /* Actually we are allowed 255, but this is good for now */ diff --git a/drivers/usb/usb-debug.c b/drivers/usb/usb-debug.c index 47ff79266566..e8da9e376588 100644 --- a/drivers/usb/usb-debug.c +++ b/drivers/usb/usb-debug.c @@ -4,6 +4,7 @@ * I just want these out of the way where they aren't in your * face, but so that you can still use them.. */ +#include #include #include #include diff --git a/drivers/usb/usb-ohci.c b/drivers/usb/usb-ohci.c index b134107da0d2..1e07014f2b46 100644 --- a/drivers/usb/usb-ohci.c +++ b/drivers/usb/usb-ohci.c @@ -1475,7 +1475,7 @@ static int rh_unlink_urb (urb_t * urb) /* reset the HC not the BUS */ -static void hc_reset (ohci_t * ohci) +static int hc_reset (ohci_t * ohci) { int timeout = 30; int smm_timeout = 50; /* 0,5 sec */ @@ -1487,7 +1487,7 @@ static void hc_reset (ohci_t * ohci) wait_ms (10); if (--smm_timeout == 0) { err("USB HC TakeOver failed!"); - break; + return -1; } } } @@ -1501,11 +1501,12 @@ static void hc_reset (ohci_t * ohci) while ((readl (&ohci->regs->cmdstatus) & 0x01) != 0) { /* 10us Reset */ if (--timeout == 0) { err("USB HC reset timed out!"); - return; + return -1; } udelay (1); } ohci->disabled = 0; + return 0; } /*-------------------------------------------------------------------------*/ @@ -1707,7 +1708,11 @@ static int hc_found_ohci (struct pci_dev *dev, int irq, void * mem_base) INIT_LIST_HEAD (&ohci->ohci_hcd_list); list_add (&ohci->ohci_hcd_list, &ohci_hcd_list); - hc_reset (ohci); + if (hc_reset (ohci) < 0) { + hc_release_ohci (ohci); + return -ENODEV; + } + writel (ohci->hc_control = OHCI_USB_RESET, &ohci->regs->control); wait_ms (10); usb_register_bus (ohci->bus); diff --git a/fs/inode.c b/fs/inode.c index c4915bba111f..73406ae0aa74 100644 --- a/fs/inode.c +++ b/fs/inode.c @@ -686,11 +686,12 @@ void iput(struct inode *inode) inode->i_state|=I_FREEING; spin_unlock(&inode_lock); + if (inode->i_data.nrpages) + truncate_inode_pages(&inode->i_data, 0); + destroy = 1; if (op && op->delete_inode) { void (*delete)(struct inode *) = op->delete_inode; - if (inode->i_data.nrpages) - truncate_inode_pages(&inode->i_data, 0); /* s_op->delete_inode internally recalls clear_inode() */ delete(inode); } else diff --git a/include/asm-sparc/io.h b/include/asm-sparc/io.h index 71610a59fc2d..cafd6867405d 100644 --- a/include/asm-sparc/io.h +++ b/include/asm-sparc/io.h @@ -1,5 +1,5 @@ /* - * $Id: io.h,v 1.25 2000/01/22 07:35:46 zaitcev Exp $ + * $Id: io.h,v 1.26 2000/03/30 01:43:26 davem Exp $ */ #ifndef __SPARC_IO_H #define __SPARC_IO_H @@ -49,6 +49,31 @@ extern __inline__ void writel(unsigned int b, unsigned long addr) { *(volatile unsigned long*)addr = flip_dword(b); } +/* Now the 'raw' versions. */ +extern __inline__ unsigned long __raw_readb(unsigned long addr) { + return *(volatile unsigned char*)addr; +} + +extern __inline__ unsigned long __raw_readw(unsigned long addr) { + return *(volatile unsigned short*)addr; +} + +extern __inline__ unsigned long __raw_readl(unsigned long addr) { + return *(volatile unsigned long*)addr; +} + +extern __inline__ void __raw_writeb(unsigned char b, unsigned long addr) { + *(volatile unsigned char*)addr = b; +} + +extern __inline__ void __raw_writew(unsigned short b, unsigned long addr) { + *(volatile unsigned short*)addr = b; +} + +extern __inline__ void __raw_writel(unsigned int b, unsigned long addr) { + *(volatile unsigned long*)addr = b; +} + /* * I/O space operations * diff --git a/include/asm-sparc/page.h b/include/asm-sparc/page.h index 0fc2aa2470da..379c8cc97ac5 100644 --- a/include/asm-sparc/page.h +++ b/include/asm-sparc/page.h @@ -1,4 +1,4 @@ -/* $Id: page.h,v 1.51 2000/03/15 07:19:25 davem Exp $ +/* $Id: page.h,v 1.52 2000/03/28 06:07:25 anton Exp $ * page.h: Various defines and such for MMU operations on the Sparc for * the Linux kernel. * @@ -32,11 +32,20 @@ #ifndef __ASSEMBLY__ -#define BUG() do { printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; } while (0) - -#define PAGE_BUG(page) do { \ - BUG(); \ +#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) +/* We need the mb()'s so we don't trigger a compiler bug - Anton */ +#define BUG() do { \ + mb(); \ + __builtin_trap(); \ + mb(); \ +} while(0) +#else +#define BUG() do { \ + printk("kernel BUG at %s:%d!\n", __FILE__, __LINE__); *(int *)0=0; \ } while (0) +#endif + +#define PAGE_BUG(page) BUG() #define clear_page(page) memset((void *)(page), 0, PAGE_SIZE) #define copy_page(to,from) memcpy((void *)(to), (void *)(from), PAGE_SIZE) diff --git a/include/asm-sparc/pgtable.h b/include/asm-sparc/pgtable.h index 8925923b0de3..04b34e5e92b2 100644 --- a/include/asm-sparc/pgtable.h +++ b/include/asm-sparc/pgtable.h @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.93 2000/03/21 01:04:53 anton Exp $ */ +/* $Id: pgtable.h,v 1.94 2000/03/28 06:07:25 anton Exp $ */ #ifndef _SPARC_PGTABLE_H #define _SPARC_PGTABLE_H @@ -96,12 +96,18 @@ BTFIXUPDEF_SIMM13(user_ptrs_per_pgd) #define VMALLOC_START (0xfe300000) #define VMALLOC_END ~0x0UL +#if (__GNUC__ > 2) || (__GNUC__ == 2 && __GNUC_MINOR__ >= 8) +#define pte_ERROR(e) __builtin_trap() +#define pmd_ERROR(e) __builtin_trap() +#define pgd_ERROR(e) __builtin_trap() +#else #define pte_ERROR(e) \ printk("%s:%d: bad pte %08lx.\n", __FILE__, __LINE__, pte_val(e)) #define pmd_ERROR(e) \ printk("%s:%d: bad pmd %08lx.\n", __FILE__, __LINE__, pmd_val(e)) #define pgd_ERROR(e) \ printk("%s:%d: bad pgd %08lx.\n", __FILE__, __LINE__, pgd_val(e)) +#endif BTFIXUPDEF_INT(page_none) BTFIXUPDEF_INT(page_shared) diff --git a/include/asm-sparc64/asm_offsets.h b/include/asm-sparc64/asm_offsets.h index f1565f7cebf6..8a5eb124685e 100644 --- a/include/asm-sparc64/asm_offsets.h +++ b/include/asm-sparc64/asm_offsets.h @@ -268,8 +268,8 @@ #define ASIZ_thread_fpdepth 0x00000001 #define AOFF_thread_fault_code 0x0000000e #define ASIZ_thread_fault_code 0x00000001 -#define AOFF_thread___pad1 0x0000000f -#define ASIZ_thread___pad1 0x00000001 +#define AOFF_thread_use_blkcommit 0x0000000f +#define ASIZ_thread_use_blkcommit 0x00000001 #define AOFF_thread_fault_address 0x00000010 #define ASIZ_thread_fault_address 0x00000008 #define AOFF_thread_fpsaved 0x00000018 @@ -562,8 +562,8 @@ #define ASIZ_thread_fpdepth 0x00000001 #define AOFF_thread_fault_code 0x0000000e #define ASIZ_thread_fault_code 0x00000001 -#define AOFF_thread___pad1 0x0000000f -#define ASIZ_thread___pad1 0x00000001 +#define AOFF_thread_use_blkcommit 0x0000000f +#define ASIZ_thread_use_blkcommit 0x00000001 #define AOFF_thread_fault_address 0x00000010 #define ASIZ_thread_fault_address 0x00000008 #define AOFF_thread_fpsaved 0x00000018 @@ -854,8 +854,8 @@ #define ASIZ_thread_fpdepth 0x00000001 #define AOFF_thread_fault_code 0x0000000e #define ASIZ_thread_fault_code 0x00000001 -#define AOFF_thread___pad1 0x0000000f -#define ASIZ_thread___pad1 0x00000001 +#define AOFF_thread_use_blkcommit 0x0000000f +#define ASIZ_thread_use_blkcommit 0x00000001 #define AOFF_thread_fault_address 0x00000010 #define ASIZ_thread_fault_address 0x00000008 #define AOFF_thread_fpsaved 0x00000018 diff --git a/include/asm-sparc64/bitops.h b/include/asm-sparc64/bitops.h index 6a6ec52b186d..512d16410cc1 100644 --- a/include/asm-sparc64/bitops.h +++ b/include/asm-sparc64/bitops.h @@ -1,4 +1,4 @@ -/* $Id: bitops.h,v 1.27 2000/02/09 03:28:33 davem Exp $ +/* $Id: bitops.h,v 1.28 2000/03/27 10:38:56 davem Exp $ * bitops.h: Bit string operations on the V9. * * Copyright 1996, 1997 David S. Miller (davem@caip.rutgers.edu) @@ -8,132 +8,17 @@ #define _SPARC64_BITOPS_H #include -#include /* For the little endian spaces. */ -/* These can all be exported to userland, because the atomic - * primitives used are not privileged. - */ - -/* Set bit 'nr' in 64-bit quantity at address 'addr' where bit '0' - * is in the highest of the eight bytes and bit '63' is the high bit - * within the first byte. Sparc is BIG-Endian. Unless noted otherwise - * all bit-ops return 0 if bit was previously clear and != 0 otherwise. - */ +extern long __test_and_set_bit(unsigned long nr, void *addr); +extern long __test_and_clear_bit(unsigned long nr, void *addr); +extern long __test_and_change_bit(unsigned long nr, void *addr); -extern __inline__ int test_and_set_bit(unsigned long nr, void *addr) -{ - unsigned long * m = ((unsigned long *) addr) + (nr >> 6); - unsigned long oldbit; - - __asm__ __volatile__(" -1: ldx [%2], %%g7 - andcc %%g7, %1, %0 - bne,pn %%xcc, 2f - xor %%g7, %1, %%g5 - casx [%2], %%g7, %%g5 - cmp %%g7, %%g5 - bne,pn %%xcc, 1b - nop -2: -" : "=&r" (oldbit) - : "HIr" (1UL << (nr & 63)), "r" (m) - : "g5", "g7", "cc", "memory"); - return oldbit != 0; -} - -extern __inline__ void set_bit(unsigned long nr, void *addr) -{ - unsigned long * m = ((unsigned long *) addr) + (nr >> 6); - - __asm__ __volatile__(" -1: ldx [%1], %%g7 - andcc %%g7, %0, %%g0 - bne,pn %%xcc, 2f - xor %%g7, %0, %%g5 - casx [%1], %%g7, %%g5 - cmp %%g7, %%g5 - bne,pn %%xcc, 1b - nop -2: -" : /* no outputs */ - : "HIr" (1UL << (nr & 63)), "r" (m) - : "g5", "g7", "cc", "memory"); -} - -extern __inline__ int test_and_clear_bit(unsigned long nr, void *addr) -{ - unsigned long * m = ((unsigned long *) addr) + (nr >> 6); - unsigned long oldbit; - - __asm__ __volatile__(" -1: ldx [%2], %%g7 - andcc %%g7, %1, %0 - be,pn %%xcc, 2f - xor %%g7, %1, %%g5 - casx [%2], %%g7, %%g5 - cmp %%g7, %%g5 - bne,pn %%xcc, 1b - nop -2: -" : "=&r" (oldbit) - : "HIr" (1UL << (nr & 63)), "r" (m) - : "g5", "g7", "cc", "memory"); - return oldbit != 0; -} - -extern __inline__ void clear_bit(unsigned long nr, void *addr) -{ - unsigned long * m = ((unsigned long *) addr) + (nr >> 6); - - __asm__ __volatile__(" -1: ldx [%1], %%g7 - andcc %%g7, %0, %%g0 - be,pn %%xcc, 2f - xor %%g7, %0, %%g5 - casx [%1], %%g7, %%g5 - cmp %%g7, %%g5 - bne,pn %%xcc, 1b - nop -2: -" : /* no outputs */ - : "HIr" (1UL << (nr & 63)), "r" (m) - : "g5", "g7", "cc", "memory"); -} - -extern __inline__ int test_and_change_bit(unsigned long nr, void *addr) -{ - unsigned long * m = ((unsigned long *) addr) + (nr >> 6); - unsigned long oldbit; - - __asm__ __volatile__(" -1: ldx [%2], %%g7 - and %%g7, %1, %0 - xor %%g7, %1, %%g5 - casx [%2], %%g7, %%g5 - cmp %%g7, %%g5 - bne,pn %%xcc, 1b - nop -" : "=&r" (oldbit) - : "HIr" (1UL << (nr & 63)), "r" (m) - : "g5", "g7", "cc", "memory"); - return oldbit != 0; -} - -extern __inline__ void change_bit(unsigned long nr, void *addr) -{ - unsigned long * m = ((unsigned long *) addr) + (nr >> 6); - - __asm__ __volatile__(" -1: ldx [%1], %%g7 - xor %%g7, %0, %%g5 - casx [%1], %%g7, %%g5 - cmp %%g7, %%g5 - bne,pn %%xcc, 1b - nop -" : /* no outputs */ - : "HIr" (1UL << (nr & 63)), "r" (m) - : "g5", "g7", "cc", "memory"); -} +#define test_and_set_bit(nr,addr) (__test_and_set_bit(nr,addr)!=0) +#define test_and_clear_bit(nr,addr) (__test_and_clear_bit(nr,addr)!=0) +#define test_and_change_bit(nr,addr) (__test_and_change_bit(nr,addr)!=0) +#define set_bit(nr,addr) ((void)__test_and_set_bit(nr,addr)) +#define clear_bit(nr,addr) ((void)__test_and_clear_bit(nr,addr)) +#define change_bit(nr,addr) ((void)__test_and_change_bit(nr,addr)) extern __inline__ int test_bit(int nr, __const__ void *addr) { @@ -280,50 +165,13 @@ found_middle: #define find_first_zero_bit(addr, size) \ find_next_zero_bit((addr), (size), 0) -/* Now for the ext2 filesystem bit operations and helper routines. - * Note the usage of the little endian ASI's, werd, V9 is supreme. - */ -extern __inline__ int set_le_bit(int nr,void * addr) -{ - unsigned int * m = ((unsigned int *) addr) + (nr >> 5); - unsigned long oldbit; - - __asm__ __volatile__(" -1: lduwa [%2] %3, %%g7 - andcc %%g7, %1, %0 - bne,pn %%icc, 2f - xor %%g7, %1, %%g5 - casa [%2] %3, %%g7, %%g5 - cmp %%g7, %%g5 - bne,pn %%icc, 1b - nop -2: -" : "=&r" (oldbit) - : "HIr" (1UL << (nr & 31)), "r" (m), "i" (ASI_PL) - : "g5", "g7", "cc", "memory"); - return oldbit != 0; -} - -extern __inline__ int clear_le_bit(int nr, void * addr) -{ - unsigned int * m = ((unsigned int *) addr) + (nr >> 5); - unsigned long oldbit; +extern long __test_and_set_le_bit(int nr, void *addr); +extern long __test_and_clear_le_bit(int nr, void *addr); - __asm__ __volatile__(" -1: lduwa [%2] %3, %%g7 - andcc %%g7, %1, %0 - be,pn %%icc, 2f - xor %%g7, %1, %%g5 - casa [%2] %3, %%g7, %%g5 - cmp %%g7, %%g5 - bne,pn %%icc, 1b - nop -2: -" : "=&r" (oldbit) - : "HIr" (1UL << (nr & 31)), "r" (m), "i" (ASI_PL) - : "g5", "g7", "cc", "memory"); - return oldbit != 0; -} +#define test_and_set_le_bit(nr,addr) (__test_and_set_le_bit(nr,addr)!=0) +#define test_and_clear_le_bit(nr,addr) (__test_and_clear_le_bit(nr,addr)!=0) +#define set_le_bit(nr,addr) ((void)__test_and_set_le_bit(nr,addr)) +#define clear_le_bit(nr,addr) ((void)__test_and_clear_le_bit(nr,addr)) extern __inline__ int test_le_bit(int nr, __const__ void * addr) { @@ -375,8 +223,8 @@ found_middle: #ifdef __KERNEL__ -#define ext2_set_bit set_le_bit -#define ext2_clear_bit clear_le_bit +#define ext2_set_bit test_and_set_le_bit +#define ext2_clear_bit test_and_clear_le_bit #define ext2_test_bit test_le_bit #define ext2_find_first_zero_bit find_first_zero_le_bit #define ext2_find_next_zero_bit find_next_zero_le_bit diff --git a/include/asm-sparc64/io.h b/include/asm-sparc64/io.h index f8bdaa8265ed..2ca3b4693eb1 100644 --- a/include/asm-sparc64/io.h +++ b/include/asm-sparc64/io.h @@ -1,4 +1,4 @@ -/* $Id: io.h,v 1.33 2000/02/25 05:47:38 davem Exp $ */ +/* $Id: io.h,v 1.34 2000/03/30 01:40:54 davem Exp $ */ #ifndef __SPARC64_IO_H #define __SPARC64_IO_H @@ -156,6 +156,68 @@ extern __inline__ void _writel(unsigned int l, unsigned long addr) #define writew(__w, __addr) (_writew((__w), (unsigned long)(__addr))) #define writel(__l, __addr) (_writel((__l), (unsigned long)(__addr))) +/* Now versions without byte-swapping. */ +extern __inline__ unsigned int _raw_readb(unsigned long addr) +{ + unsigned int ret; + + __asm__ __volatile__("lduba\t[%1] %2, %0\t/* pci_raw_readb */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +extern __inline__ unsigned int _raw_readw(unsigned long addr) +{ + unsigned int ret; + + __asm__ __volatile__("lduha\t[%1] %2, %0\t/* pci_raw_readw */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +extern __inline__ unsigned int _raw_readl(unsigned long addr) +{ + unsigned int ret; + + __asm__ __volatile__("lduwa\t[%1] %2, %0\t/* pci_raw_readl */" + : "=r" (ret) + : "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); + + return ret; +} + +extern __inline__ void _raw_writeb(unsigned char b, unsigned long addr) +{ + __asm__ __volatile__("stba\t%r0, [%1] %2\t/* pci_raw_writeb */" + : /* no outputs */ + : "Jr" (b), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +extern __inline__ void _raw_writew(unsigned short w, unsigned long addr) +{ + __asm__ __volatile__("stha\t%r0, [%1] %2\t/* pci_raw_writew */" + : /* no outputs */ + : "Jr" (w), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +extern __inline__ void _raw_writel(unsigned int l, unsigned long addr) +{ + __asm__ __volatile__("stwa\t%r0, [%1] %2\t/* pci_raw_writel */" + : /* no outputs */ + : "Jr" (l), "r" (addr), "i" (ASI_PHYS_BYPASS_EC_E)); +} + +#define __raw_readb(__addr) (_raw_readb((unsigned long)(__addr))) +#define __raw_readw(__addr) (_raw_readw((unsigned long)(__addr))) +#define __raw_readl(__addr) (_raw_readl((unsigned long)(__addr))) +#define __raw_writeb(__b, __addr) (_raw_writeb((__b), (unsigned long)(__addr))) +#define __raw_writew(__w, __addr) (_raw_writew((__w), (unsigned long)(__addr))) +#define __raw_writel(__l, __addr) (_raw_writel((__l), (unsigned long)(__addr))) + /* Valid I/O Space regions are anywhere, because each PCI bus supported * can live in an arbitrary area of the physical address range. */ diff --git a/include/asm-sparc64/pgalloc.h b/include/asm-sparc64/pgalloc.h index fe4d9e1faacc..697dc6fbcfed 100644 --- a/include/asm-sparc64/pgalloc.h +++ b/include/asm-sparc64/pgalloc.h @@ -70,27 +70,11 @@ extern void smp_flush_tlb_page(struct mm_struct *mm, unsigned long page); #define flush_cache_all() smp_flush_cache_all() #define flush_tlb_all() smp_flush_tlb_all() - -extern __inline__ void flush_tlb_mm(struct mm_struct *mm) -{ - if (CTX_VALID(mm->context)) - smp_flush_tlb_mm(mm); -} - -extern __inline__ void flush_tlb_range(struct mm_struct *mm, unsigned long start, - unsigned long end) -{ - if (CTX_VALID(mm->context)) - smp_flush_tlb_range(mm, start, end); -} - -extern __inline__ void flush_tlb_page(struct vm_area_struct *vma, unsigned long page) -{ - struct mm_struct *mm = vma->vm_mm; - - if (CTX_VALID(mm->context)) - smp_flush_tlb_page(mm, page); -} +#define flush_tlb_mm(mm) smp_flush_tlb_mm(mm) +#define flush_tlb_range(mm, start, end) \ + smp_flush_tlb_range(mm, start, end) +#define flush_tlb_page(vma, page) \ + smp_flush_tlb_page((vma)->vm_mm, page) #endif /* ! __SMP__ */ diff --git a/include/asm-sparc64/pgtable.h b/include/asm-sparc64/pgtable.h index 46a1e024806a..0d49e700ec8d 100644 --- a/include/asm-sparc64/pgtable.h +++ b/include/asm-sparc64/pgtable.h @@ -1,4 +1,4 @@ -/* $Id: pgtable.h,v 1.123 2000/03/26 09:13:53 davem Exp $ +/* $Id: pgtable.h,v 1.124 2000/03/27 10:38:56 davem Exp $ * pgtable.h: SpitFire page table operations. * * Copyright 1996,1997 David S. Miller (davem@caip.rutgers.edu) @@ -214,26 +214,9 @@ extern inline pte_t pte_modify(pte_t orig_pte, pgprot_t new_prot) #define pte_page(x) (mem_map+pte_pagenr(x)) /* Be very careful when you change these three, they are delicate. */ -static __inline__ pte_t pte_mkyoung(pte_t _pte) -{ if(pte_val(_pte) & _PAGE_READ) - return __pte(pte_val(_pte)|(_PAGE_ACCESSED|_PAGE_R)); - else - return __pte(pte_val(_pte)|(_PAGE_ACCESSED)); -} - -static __inline__ pte_t pte_mkwrite(pte_t _pte) -{ if(pte_val(_pte) & _PAGE_MODIFIED) - return __pte(pte_val(_pte)|(_PAGE_WRITE|_PAGE_W)); - else - return __pte(pte_val(_pte)|(_PAGE_WRITE)); -} - -static __inline__ pte_t pte_mkdirty(pte_t _pte) -{ if(pte_val(_pte) & _PAGE_WRITE) - return __pte(pte_val(_pte)|(_PAGE_MODIFIED|_PAGE_W)); - else - return __pte(pte_val(_pte)|(_PAGE_MODIFIED)); -} +#define pte_mkyoung(pte) (__pte(pte_val(pte) | _PAGE_ACCESSED | _PAGE_R)) +#define pte_mkwrite(pte) (__pte(pte_val(pte) | _PAGE_WRITE)) +#define pte_mkdirty(pte) (__pte(pte_val(pte) | _PAGE_MODIFIED | _PAGE_W)) /* to find an entry in a page-table-directory. */ #define pgd_index(address) (((address) >> PGDIR_SHIFT) & (PTRS_PER_PGD)) @@ -256,51 +239,7 @@ extern pgd_t swapper_pg_dir[1]; #define mmu_lockarea(vaddr, len) (vaddr) #define mmu_unlockarea(vaddr, len) do { } while(0) -/* There used to be some funny code here which tried to guess which - * TLB wanted the mapping, that wasn't accurate enough to justify it's - * existance. Instead we now have each TLB miss handler record a - * distinct code in the thread struct. - * - * What we do need to handle here is prevent I-cache corruption. The - * deal is that the I-cache snoops stores from other CPUs and all DMA - * activity, however stores from the local processor are not snooped. - * The dynamic linker and our signal handler mechanism take care of - * the cases where they write into instruction space, but when a page - * is copied in the kernel and then executed in user-space is not handled - * right. This leads to corruptions if things are "just right", consider - * the following scenerio: - * 1) Process 1 frees up a page that was used for the PLT of libc in - * it's address space. - * 2) Process 2 writes into a page in the PLT of libc for the first - * time. do_wp_page() copies the page locally, the local I-cache of - * the processor does not notice the writes during the page copy. - * The new page used just so happens to be the one just freed in #1. - * 3) After the PLT write, later the cpu calls into an unresolved PLT - * entry, the CPU executes old instructions from process 1's PLT - * table. - * 4) Splat. - */ -extern void __flush_icache_page(unsigned long phys_page); -extern void __prefill_dtlb(unsigned long vaddr, unsigned long pteval); -extern void __prefill_itlb(unsigned long vaddr, unsigned long pteval); -#define update_mmu_cache(__vma, __address, _pte) \ -do { \ - unsigned short __flags = ((__vma)->vm_flags); \ - unsigned long pteval = pte_val(_pte); \ - if ((__flags & VM_EXEC) != 0 && ((__vma)->vm_file != NULL) && \ - ((pteval & (_PAGE_PRESENT | _PAGE_WRITE | _PAGE_MODIFIED)) == \ - (_PAGE_PRESENT | _PAGE_WRITE | _PAGE_MODIFIED))) \ - __flush_icache_page(pte_pagenr(_pte) << PAGE_SHIFT); \ - if ((__vma)->vm_mm == current->mm && \ - (__flags = current->thread.fault_code) != 0) { \ - unsigned long tag = (__address & PAGE_MASK); \ - tag |= CTX_HWBITS(current->mm->context); \ - if (__flags & FAULT_CODE_DTLB) \ - __prefill_dtlb(tag, pteval); \ - else \ - __prefill_itlb(tag, pteval); \ - } \ -} while(0) +extern void update_mmu_cache(struct vm_area_struct *vma, unsigned long address, pte_t pte); #define flush_icache_page(vma, pg) do { } while(0) diff --git a/include/asm-sparc64/processor.h b/include/asm-sparc64/processor.h index 8ba0559dad3b..7237736fe1c1 100644 --- a/include/asm-sparc64/processor.h +++ b/include/asm-sparc64/processor.h @@ -1,4 +1,4 @@ -/* $Id: processor.h,v 1.62 2000/03/26 09:13:53 davem Exp $ +/* $Id: processor.h,v 1.63 2000/03/27 10:38:57 davem Exp $ * include/asm-sparc64/processor.h * * Copyright (C) 1996 David S. Miller (davem@caip.rutgers.edu) @@ -51,7 +51,7 @@ struct thread_struct { unsigned long ksp __attribute__ ((aligned(16))); unsigned char wstate, cwp, flags; mm_segment_t current_ds; - unsigned char w_saved, fpdepth, fault_code, __pad1; + unsigned char w_saved, fpdepth, fault_code, use_blkcommit; unsigned long fault_address; unsigned char fpsaved[7]; unsigned char __pad2; @@ -91,7 +91,7 @@ struct thread_struct { #define INIT_THREAD { \ /* ksp, wstate, cwp, flags, current_ds, */ \ 0, 0, 0, 0, KERNEL_DS, \ -/* w_saved, fpdepth, fault_code, __pad1, */ \ +/* w_saved, fpdepth, fault_code, use_blkcommit, */ \ 0, 0, 0, 0, \ /* fault_address, fpsaved, __pad2, kregs, */ \ 0, { 0 }, 0, 0, \ diff --git a/include/asm-sparc64/system.h b/include/asm-sparc64/system.h index 87379139bb40..1429e7772e10 100644 --- a/include/asm-sparc64/system.h +++ b/include/asm-sparc64/system.h @@ -1,4 +1,4 @@ -/* $Id: system.h,v 1.56 2000/03/06 22:33:45 davem Exp $ */ +/* $Id: system.h,v 1.57 2000/03/27 10:38:57 davem Exp $ */ #ifndef __SPARC64_SYSTEM_H #define __SPARC64_SYSTEM_H @@ -131,16 +131,8 @@ extern void __global_restore_flags(unsigned long flags); extern void synchronize_user_stack(void); -extern __inline__ void flushw_user(void) -{ - __asm__ __volatile__(" - rdpr %%otherwin, %%g1 - brz,pt %%g1, 1f - mov %%o7, %%g3 - call __flushw_user - clr %%g2 -1:" : : : "g1", "g2", "g3"); -} +extern void __flushw_user(void); +#define flushw_user() __flushw_user() #define flush_user_windows flushw_user #define flush_register_windows flushw_all diff --git a/include/linux/input.h b/include/linux/input.h index 4cc82fbf41e2..07d16988bd49 100644 --- a/include/linux/input.h +++ b/include/linux/input.h @@ -383,6 +383,7 @@ struct input_event { */ #include +#include #define NBITS(x) ((((x)-1)/BITS_PER_LONG)+1) #define BIT(x) (1<<((x)%BITS_PER_LONG)) @@ -433,8 +434,10 @@ struct input_handler { int (*connect)(struct input_handler *handler, struct input_dev *dev); void (*disconnect)(struct input_handle *handle); - struct input_handle *handle; + struct file_operations *fops; + int minor; + struct input_handle *handle; struct input_handler *next; }; @@ -458,6 +461,9 @@ void input_unregister_handler(struct input_handler *); void input_open_device(struct input_handle *); void input_close_device(struct input_handle *); +devfs_handle_t input_register_minor(char *name, int minor, int minor_base); +void input_unregister_minor(devfs_handle_t handle); + void input_event(struct input_dev *dev, unsigned int type, unsigned int code, int value); #define input_report_key(a,b,c) input_event(a, EV_KEY, b, c) diff --git a/include/linux/mm.h b/include/linux/mm.h index 4456ed716b18..36e035f7b6e2 100644 --- a/include/linux/mm.h +++ b/include/linux/mm.h @@ -163,7 +163,7 @@ typedef struct page { #define PG_error 1 #define PG_referenced 2 #define PG_uptodate 3 -#define PG__unused_00 4 +#define PG_dirty 4 #define PG_decr_after 5 #define PG_unused_01 6 #define PG__unused_02 7 @@ -180,6 +180,8 @@ typedef struct page { #define Page_Uptodate(page) test_bit(PG_uptodate, &(page)->flags) #define SetPageUptodate(page) set_bit(PG_uptodate, &(page)->flags) #define ClearPageUptodate(page) clear_bit(PG_uptodate, &(page)->flags) +#define Page_Dirty(page) test_bit(PG_dirty, &(page)->flags) +#define SetPageDirty(page) set_bit(PG_dirty, &(page)->flags) #define PageLocked(page) test_bit(PG_locked, &(page)->flags) #define LockPage(page) set_bit(PG_locked, &(page)->flags) #define TryLockPage(page) test_and_set_bit(PG_locked, &(page)->flags) @@ -188,7 +190,7 @@ typedef struct page { wake_up(&page->wait); \ } while (0) #define PageError(page) test_bit(PG_error, &(page)->flags) -#define SetPageError(page) test_and_set_bit(PG_error, &(page)->flags) +#define SetPageError(page) set_bit(PG_error, &(page)->flags) #define ClearPageError(page) clear_bit(PG_error, &(page)->flags) #define PageReferenced(page) test_bit(PG_referenced, &(page)->flags) #define PageDecrAfter(page) test_bit(PG_decr_after, &(page)->flags) diff --git a/include/linux/netfilter_ipv4/ip_queue.h b/include/linux/netfilter_ipv4/ip_queue.h index 8bbd6230fe85..a78776235775 100644 --- a/include/linux/netfilter_ipv4/ip_queue.h +++ b/include/linux/netfilter_ipv4/ip_queue.h @@ -2,7 +2,7 @@ * This is a module which is used for queueing IPv4 packets and * communicating with userspace via netlink. * - * (C) 2000 James Morris + * (C) 2000 James Morris, this code is GPL. */ #ifndef _IP_QUEUE_H #define _IP_QUEUE_H @@ -27,7 +27,7 @@ typedef struct ipq_packet_msg { char indev_name[IFNAMSIZ]; /* Name of incoming interface */ char outdev_name[IFNAMSIZ]; /* Name of outgoing interface */ size_t data_len; /* Length of packet data */ - /* Optional packet data follows */ + unsigned char payload[0]; /* Optional packet data */ } ipq_packet_msg_t; /* Messages sent from userspace */ @@ -40,7 +40,7 @@ typedef struct ipq_verdict_msg { unsigned int value; /* Verdict to hand to netfilter */ unsigned long id; /* Packet ID for this verdict */ size_t data_len; /* Length of replacement data */ - /* Optional replacement data follows */ + unsigned char payload[0]; /* Optional replacement packet */ } ipq_verdict_msg_t; typedef struct ipq_peer_msg { @@ -50,37 +50,19 @@ typedef struct ipq_peer_msg { } msg; } ipq_peer_msg_t; -/* Each queued packet has one of these states */ +/* Packet delivery modes */ enum { - IPQ_PS_NEW, /* Newly arrived packet */ - IPQ_PS_WAITING, /* User has been notified of packet, - we're waiting for a verdict */ - IPQ_PS_VERDICT /* Packet has been assigned verdict, - waiting to be reinjected */ -}; -#define IPQ_PS_MAX IPQ_PS_VERDICT - -/* The queue operates in one of these states */ -enum { - IPQ_QS_HOLD, /* Hold all packets in queue */ - IPQ_QS_COPY, /* Copy metadata and/or packets to user */ - IPQ_QS_FLUSH /* Flush and drop all queue entries */ -}; -#define IPQ_QS_MAX IPQ_QS_FLUSH - -/* Modes requested by peer */ -enum { - IPQ_COPY_NONE, /* Copy nothing */ + IPQ_COPY_NONE, /* Initial mode, packets are dropped */ IPQ_COPY_META, /* Copy metadata */ IPQ_COPY_PACKET /* Copy metadata + packet (range) */ -}; +}; #define IPQ_COPY_MAX IPQ_COPY_PACKET /* Types of messages */ #define IPQM_BASE 0x10 /* standard netlink messages below this */ -#define IPQM_MODE (IPQM_BASE + 1) /* Mode request from peer */ -#define IPQM_VERDICT (IPQM_BASE + 2) /* Verdict from peer */ -#define IPQM_PACKET (IPQM_BASE + 3) /* Packet from kernel */ +#define IPQM_MODE (IPQM_BASE + 1) /* Mode request from peer */ +#define IPQM_VERDICT (IPQM_BASE + 2) /* Verdict from peer */ +#define IPQM_PACKET (IPQM_BASE + 3) /* Packet from kernel */ #define IPQM_MAX (IPQM_BASE + 4) #endif /*_IP_QUEUE_H*/ diff --git a/include/linux/swap.h b/include/linux/swap.h index d79fd68ef5b6..e4e035db7e33 100644 --- a/include/linux/swap.h +++ b/include/linux/swap.h @@ -173,6 +173,8 @@ do { \ #define lru_cache_del(page) \ do { \ + if (!PageLocked(page)) \ + BUG(); \ spin_lock(&pagemap_lru_lock); \ list_del(&(page)->lru); \ nr_lru_pages--; \ diff --git a/include/net/sock.h b/include/net/sock.h index 32af02c2c31e..f9d986b81705 100644 --- a/include/net/sock.h +++ b/include/net/sock.h @@ -263,7 +263,7 @@ struct tcp_opt { __u16 mss_cache; /* Cached effective mss, not including SACKS */ __u16 mss_clamp; /* Maximal mss, negotiated at connection setup */ __u16 ext_header_len; /* Network protocol overhead (IP/IPv6 options) */ - __u8 dup_acks; /* Consequetive duplicate acks seen from other end */ + __u8 dup_acks; /* Consecutive duplicate acks seen from other end */ __u8 retransmits; __u8 __empty1; diff --git a/mm/filemap.c b/mm/filemap.c index bccdc9bd20e1..32003021cd72 100644 --- a/mm/filemap.c +++ b/mm/filemap.c @@ -250,6 +250,11 @@ int shrink_mmap(int priority, int gfp_mask, zone_t *zone) count--; dispose = &young; + + /* avoid unscalable SMP locking */ + if (!page->buffers && page_count(page) > 1) + goto dispose_continue; + if (TryLockPage(page)) goto dispose_continue; @@ -260,22 +265,11 @@ int shrink_mmap(int priority, int gfp_mask, zone_t *zone) page locked down ;). */ spin_unlock(&pagemap_lru_lock); - /* avoid unscalable SMP locking */ - if (!page->buffers && page_count(page) > 1) - goto unlock_noput_continue; - - /* Take the pagecache_lock spinlock held to avoid - other tasks to notice the page while we are looking at its - page count. If it's a pagecache-page we'll free it - in one atomic transaction after checking its page count. */ - spin_lock(&pagecache_lock); - /* avoid freeing the page while it's locked */ get_page(page); /* Is it a buffer page? */ if (page->buffers) { - spin_unlock(&pagecache_lock); if (!try_to_free_buffers(page)) goto unlock_continue; /* page was locked, inode can't go away under us */ @@ -283,9 +277,14 @@ int shrink_mmap(int priority, int gfp_mask, zone_t *zone) atomic_dec(&buffermem_pages); goto made_buffer_progress; } - spin_lock(&pagecache_lock); } + /* Take the pagecache_lock spinlock held to avoid + other tasks to notice the page while we are looking at its + page count. If it's a pagecache-page we'll free it + in one atomic transaction after checking its page count. */ + spin_lock(&pagecache_lock); + /* * We can't free pages unless there's just one user * (count == 2 because we added one ourselves above). @@ -293,12 +292,6 @@ int shrink_mmap(int priority, int gfp_mask, zone_t *zone) if (page_count(page) != 2) goto cache_unlock_continue; - /* - * We did the page aging part. - */ - if (nr_lru_pages < freepages.min * priority) - goto cache_unlock_continue; - /* * Is it a page swap page? If so, we want to * drop it if it is no longer used, even if it @@ -312,8 +305,7 @@ int shrink_mmap(int priority, int gfp_mask, zone_t *zone) /* is it a page-cache page? */ if (page->mapping) { - if (!pgcache_under_min()) - { + if (!Page_Dirty(page) && !pgcache_under_min()) { remove_page_from_inode_queue(page); remove_page_from_hash_queue(page); page->mapping = NULL; @@ -329,21 +321,12 @@ int shrink_mmap(int priority, int gfp_mask, zone_t *zone) cache_unlock_continue: spin_unlock(&pagecache_lock); unlock_continue: + spin_lock(&pagemap_lru_lock); UnlockPage(page); put_page(page); -dispose_relock_continue: - /* even if the dispose list is local, a truncate_inode_page() - may remove a page from its queue so always - synchronize with the lru lock while accesing the - page->lru field */ - spin_lock(&pagemap_lru_lock); list_add(page_lru, dispose); continue; -unlock_noput_continue: - UnlockPage(page); - goto dispose_relock_continue; - dispose_continue: list_add(page_lru, dispose); } @@ -1724,10 +1707,8 @@ static int msync_interval(struct vm_area_struct * vma, error = vma->vm_ops->sync(vma, start, end-start, flags); if (!error && (flags & MS_SYNC)) { struct file * file = vma->vm_file; - if (file) { - struct dentry * dentry = file->f_dentry; - error = file_fsync(file, dentry); - } + if (file) + error = file_fsync(file, file->f_dentry); } return error; } @@ -2237,9 +2218,9 @@ asmlinkage long sys_mincore(unsigned long start, size_t len, down(¤t->mm->mmap_sem); - if (start & ~PAGE_MASK) + if (start & ~PAGE_CACHE_MASK) goto out; - len = (len + ~PAGE_MASK) & PAGE_MASK; + len = (len + ~PAGE_CACHE_MASK) & PAGE_CACHE_MASK; end = start + len; if (end < start) goto out; @@ -2371,8 +2352,7 @@ static inline void remove_suid(struct inode *inode) } /* - * Write to a file through the page cache. This is mainly for the - * benefit of NFS and possibly other network-based file systems. + * Write to a file through the page cache. * * We currently put everything into the page cache prior to writing it. * This is not a problem when writing full pages. With partial pages, @@ -2389,8 +2369,7 @@ static inline void remove_suid(struct inode *inode) ssize_t generic_file_write(struct file *file,const char *buf,size_t count,loff_t *ppos) { - struct dentry *dentry = file->f_dentry; - struct inode *inode = dentry->d_inode; + struct inode *inode = file->f_dentry->d_inode; struct address_space *mapping = inode->i_mapping; unsigned long limit = current->rlim[RLIMIT_FSIZE].rlim_cur; loff_t pos; diff --git a/net/bridge/br_input.c b/net/bridge/br_input.c index fc549d76a899..2ca176f95058 100644 --- a/net/bridge/br_input.c +++ b/net/bridge/br_input.c @@ -5,7 +5,7 @@ * Authors: * Lennert Buytenhek * - * $Id: br_input.c,v 1.4 2000/03/21 21:08:47 davem Exp $ + * $Id: br_input.c,v 1.5 2000/03/30 01:22:23 davem Exp $ * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License @@ -94,6 +94,8 @@ static void __br_handle_frame(struct sk_buff *skb) br_flood(br, skb, 1); if (!passedup) br_pass_frame_up(br, skb); + else + kfree_skb(skb); return; } @@ -102,6 +104,8 @@ static void __br_handle_frame(struct sk_buff *skb) if (dst != NULL && dst->is_local) { if (!passedup) br_pass_frame_up(br, skb); + else + kfree_skb(skb); br_fdb_put(dst); return; } diff --git a/net/core/skbuff.c b/net/core/skbuff.c index 2143b327617c..54230a2737d8 100644 --- a/net/core/skbuff.c +++ b/net/core/skbuff.c @@ -4,7 +4,7 @@ * Authors: Alan Cox * Florian La Roche * - * Version: $Id: skbuff.c,v 1.70 2000/03/17 14:41:39 davem Exp $ + * Version: $Id: skbuff.c,v 1.71 2000/03/29 11:58:33 davem Exp $ * * Fixes: * Alan Cox : Fixed the worst of the load balancer bugs. diff --git a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c index 1d1256be530a..cbbc1ab8c682 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_icmp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_icmp.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff --git a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c index 0dc2703332ca..893248943958 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_tcp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_tcp.c @@ -4,6 +4,7 @@ #include #include #include +#include #include #include #include diff --git a/net/ipv4/netfilter/ip_conntrack_proto_udp.c b/net/ipv4/netfilter/ip_conntrack_proto_udp.c index 688ae10fb845..79ec821513da 100644 --- a/net/ipv4/netfilter/ip_conntrack_proto_udp.c +++ b/net/ipv4/netfilter/ip_conntrack_proto_udp.c @@ -2,6 +2,7 @@ #include #include #include +#include #include #include diff --git a/net/ipv4/netfilter/ip_fw_compat_masq.c b/net/ipv4/netfilter/ip_fw_compat_masq.c index e0074c1e2cff..96bdc9d8d675 100644 --- a/net/ipv4/netfilter/ip_fw_compat_masq.c +++ b/net/ipv4/netfilter/ip_fw_compat_masq.c @@ -5,6 +5,7 @@ DO IT. */ #include +#include #include #include #include diff --git a/net/ipv4/netfilter/ip_queue.c b/net/ipv4/netfilter/ip_queue.c index 70cd7a498349..80e43d977605 100644 --- a/net/ipv4/netfilter/ip_queue.c +++ b/net/ipv4/netfilter/ip_queue.c @@ -2,7 +2,7 @@ * This is a module which is used for queueing IPv4 packets and * communicating with userspace via netlink. * - * Copyright (C) 2000 James Morris + * (C) 2000 James Morris, this code is GPL. */ #include #include @@ -13,7 +13,6 @@ #include #include #include -#include #include #include #include @@ -21,18 +20,13 @@ #include -#define IPQ_THR_NAME "kipq" -#define IPQ_NAME "ip_queue" #define IPQ_QMAX_DEFAULT 1024 - #define IPQ_PROC_FS_NAME "ip_queue" - #define NET_IPQ_QMAX 2088 #define NET_IPQ_QMAX_NAME "ip_queue_maxlen" typedef struct ipq_queue_element { struct list_head list; /* Links element into queue */ - unsigned char state; /* State of this element */ int verdict; /* Current verdict */ struct nf_info *info; /* Extra info from netfilter */ struct sk_buff *skb; /* Packet inside */ @@ -48,178 +42,70 @@ typedef struct ipq_peer { ipq_send_cb_t send; /* Callback for sending data to peer */ } ipq_peer_t; -typedef struct ipq_thread { - pid_t pid; /* PID of kernel thread */ - unsigned char terminate; /* Termination flag */ - unsigned char running; /* Running flag */ - wait_queue_head_t wq; /* I/O wait queue */ - void (*process)(void *data); /* Queue processing function */ -} ipq_thread_t; - typedef struct ipq_queue { int len; /* Current queue len */ int *maxlen; /* Maximum queue len, via sysctl */ - unsigned char state; /* Current queue state */ + unsigned char flushing; /* If queue is being flushed */ + unsigned char terminate; /* If the queue is being terminated */ struct list_head list; /* Head of packet queue */ spinlock_t lock; /* Queue spinlock */ ipq_peer_t peer; /* Userland peer */ - ipq_thread_t thread; /* Thread context */ } ipq_queue_t; -/**************************************************************************** -* -* Kernel thread -* -****************************************************************************/ - -static void ipq_thread_init(char *thread_name) -{ - lock_kernel(); - exit_files(current); - daemonize(); - strcpy(current->comm, thread_name); - unlock_kernel(); - spin_lock_irq(¤t->sigmask_lock); - flush_signals(current); - sigfillset(¤t->blocked); - recalc_sigpending(current); - spin_unlock_irq(¤t->sigmask_lock); -} - -static int ipq_thread_start(void *data) -{ - ipq_queue_t *q = (ipq_queue_t *)data; - - q->thread.running = 1; - ipq_thread_init(IPQ_THR_NAME); - q->thread.pid = current->pid; - while (!q->thread.terminate) { - interruptible_sleep_on(&q->thread.wq); - q->thread.process(q); - } - q->thread.running = 0; - return 0; -} - -static void ipq_thread_stop(ipq_queue_t *q) -{ - if (!(q->thread.pid || q->thread.running)) - return; - q->state = IPQ_QS_FLUSH; - q->thread.terminate = 1; - wake_up_interruptible(&q->thread.wq); - current->state = TASK_INTERRUPTIBLE; - while (q->thread.running) { - schedule_timeout(HZ/10); - current->state = TASK_RUNNING; - } -} - -static int ipq_thread_create(ipq_queue_t *q) -{ - int status = kernel_thread(ipq_thread_start, q, 0); - return (status < 0) ? status : 0; -} - - /**************************************************************************** * * Packet queue * ****************************************************************************/ -/* Must be called under spinlock */ -static __inline__ void -ipq_dequeue(ipq_queue_t *q, - ipq_queue_element_t *e) -{ - list_del(&e->list); - nf_reinject(e->skb, e->info, e->verdict); - kfree(e); - q->len--; -} - -/* Must be called under spinlock */ -static __inline__ void -ipq_queue_drop(ipq_queue_t *q, - ipq_queue_element_t *e) +/* Dequeue with element packet ID, or from end of queue if ID is zero. */ +static ipq_queue_element_t *ipq_dequeue(ipq_queue_t *q, unsigned long id) { - e->verdict = NF_DROP; - ipq_dequeue(q, e); -} - -static int -ipq_notify_peer(ipq_queue_t *q, - ipq_queue_element_t *e) -{ - int status = q->peer.send(e); + struct list_head *i; + ipq_queue_element_t *e = NULL; - if (status >= 0) { - e->state = IPQ_PS_WAITING; - return status; + spin_lock_bh(&q->lock); + if (q->len == 0) + goto out_unlock; + i = q->list.prev; + if (id > 0) { + while (i != &q->list) { + if (id == (unsigned long )i) + goto out_unlink; + i = i->prev; + } + goto out_unlock; } - if (status == -ERESTARTSYS || status == -EAGAIN) - return 0; - printk(KERN_INFO "%s: error notifying peer %d, resetting " - "state and flushing queue\n", IPQ_NAME, q->peer.pid); - q->state = IPQ_QS_FLUSH; - q->peer.died = 1; - q->peer.pid = 0; - q->peer.copy_mode = IPQ_COPY_META; - q->peer.copy_range = 0; - return status; +out_unlink: + e = (ipq_queue_element_t *)i; + list_del(&e->list); + q->len--; +out_unlock: + spin_unlock_bh(&q->lock); + return e; } -static void -ipq_queue_process(void *data) +static void ipq_flush(ipq_queue_t *q) { - struct list_head *i; - ipq_queue_t *q = (ipq_queue_t *)data; - -restart: - if (q->state == IPQ_QS_HOLD) - return; + ipq_queue_element_t *e; + spin_lock_bh(&q->lock); - for (i = q->list.prev; i != &q->list; i = i->prev) { - ipq_queue_element_t *e = (ipq_queue_element_t *)i; - - if (q->state == IPQ_QS_FLUSH) { - QDEBUG("flushing packet %p\n", e); - ipq_queue_drop(q, e); - continue; - } - switch (e->state) { - case IPQ_PS_NEW: { - int status = ipq_notify_peer(q, e); - if (status < 0) { - spin_unlock_bh(&q->lock); - goto restart; - } - break; - } - case IPQ_PS_VERDICT: - ipq_dequeue(q, e); - break; - case IPQ_PS_WAITING: - break; - default: - printk(KERN_INFO "%s: dropping stuck packet %p " - "with ps=%d qs=%d\n", IPQ_NAME, - e, e->state, q->state); - ipq_queue_drop(q, e); - } + q->flushing = 1; + spin_unlock_bh(&q->lock); + while ((e = ipq_dequeue(q, 0))) { + e->verdict = NF_DROP; + nf_reinject(e->skb, e->info, e->verdict); + kfree(e); } + spin_lock_bh(&q->lock); + q->flushing = 0; spin_unlock_bh(&q->lock); - if (q->state == IPQ_QS_FLUSH) - q->state = IPQ_QS_HOLD; } -static ipq_queue_t * -ipq_queue_create(nf_queue_outfn_t outfn, - ipq_send_cb_t send_cb, - int *errp, - int *sysctl_qmax) +static ipq_queue_t *ipq_create_queue(nf_queue_outfn_t outfn, + ipq_send_cb_t send_cb, + int *errp, int *sysctl_qmax) { int status; ipq_queue_t *q; @@ -230,18 +116,15 @@ ipq_queue_create(nf_queue_outfn_t outfn, *errp = -ENOMEM; return NULL; } - q->thread.terminate = 0; - q->thread.running = 0; - q->thread.process = ipq_queue_process; - init_waitqueue_head(&q->thread.wq); q->peer.pid = 0; q->peer.died = 0; - q->peer.copy_mode = IPQ_COPY_META; + q->peer.copy_mode = IPQ_COPY_NONE; q->peer.copy_range = 0; q->peer.send = send_cb; q->len = 0; q->maxlen = sysctl_qmax; - q->state = IPQ_QS_HOLD; + q->flushing = 0; + q->terminate = 0; INIT_LIST_HEAD(&q->list); spin_lock_init(&q->lock); status = nf_register_queue_handler(PF_INET, outfn, q); @@ -250,91 +133,92 @@ ipq_queue_create(nf_queue_outfn_t outfn, kfree(q); return NULL; } - status = ipq_thread_create(q); - if (status < 0) { - nf_unregister_queue_handler(PF_INET); - *errp = status; - kfree(q); - return NULL; - } return q; } -static int -ipq_enqueue(ipq_queue_t *q, - struct sk_buff *skb, - struct nf_info *info) +static int ipq_enqueue(ipq_queue_t *q, + struct sk_buff *skb, struct nf_info *info) { - ipq_queue_element_t *e = NULL; - + ipq_queue_element_t *e; + int status; + e = kmalloc(sizeof(*e), GFP_ATOMIC); if (e == NULL) { - printk(KERN_ERR "%s: out of memory in %s\n", - IPQ_NAME, __FUNCTION__); - return -ENOMEM; + printk(KERN_ERR "ip_queue: OOM in enqueue\n"); + return -ENOMEM; } - e->state = IPQ_PS_NEW; e->verdict = NF_DROP; e->info = info; e->skb = skb; spin_lock_bh(&q->lock); if (q->len >= *q->maxlen) { spin_unlock_bh(&q->lock); - printk(KERN_WARNING "%s: queue full at %d entries, " - "dropping packet.\n", IPQ_NAME, q->len); - kfree(e); - nf_reinject(skb, info, NF_DROP); - return 0; + if (net_ratelimit()) + printk(KERN_WARNING "ip_queue: full at %d entries, " + "dropping packet(s).\n", q->len); + goto free_drop; + } + if (q->flushing || q->peer.copy_mode == IPQ_COPY_NONE + || q->peer.pid == 0 || q->peer.died || q->terminate) { + spin_unlock_bh(&q->lock); + goto free_drop; + } + status = q->peer.send(e); + if (status > 0) { + list_add(&e->list, &q->list); + q->len++; + spin_unlock_bh(&q->lock); + return status; } - list_add(&e->list, &q->list); - q->len++; spin_unlock_bh(&q->lock); - wake_up_interruptible(&q->thread.wq); - return 0; + if (status == -ECONNREFUSED) { + printk(KERN_INFO "ip_queue: peer %d died, " + "resetting state and flushing queue\n", q->peer.pid); + q->peer.died = 1; + q->peer.pid = 0; + q->peer.copy_mode = IPQ_COPY_NONE; + q->peer.copy_range = 0; + ipq_flush(q); + } +free_drop: + kfree(e); + return -EBUSY; } -/* FIXME: need to find a way to notify user during module unload */ -static void -ipq_queue_destroy(ipq_queue_t *q) +static void ipq_destroy_queue(ipq_queue_t *q) { - ipq_thread_stop(q); nf_unregister_queue_handler(PF_INET); + spin_lock_bh(&q->lock); + q->terminate = 1; + spin_unlock_bh(&q->lock); + ipq_flush(q); kfree(q); } -static int -ipq_queue_mangle_ipv4(unsigned char *buf, - ipq_verdict_msg_t *v, - ipq_queue_element_t *e) +static int ipq_mangle_ipv4(ipq_verdict_msg_t *v, ipq_queue_element_t *e) { - struct iphdr *user_iph = (struct iphdr *)buf; + struct iphdr *user_iph = (struct iphdr *)v->payload; if (v->data_len < sizeof(*user_iph)) return 0; - if (e->skb->nh.iph->check != user_iph->check) { int diff = v->data_len - e->skb->len; if (diff < 0) skb_trim(e->skb, v->data_len); else if (diff > 0) { - if (v->data_len > 0xFFFF) { - e->verdict = NF_DROP; + if (v->data_len > 0xFFFF) return -EINVAL; - } if (diff > skb_tailroom(e->skb)) { struct sk_buff *newskb; - /* Ack, we waste a memcpy() of data here */ newskb = skb_copy_expand(e->skb, skb_headroom(e->skb), diff, GFP_ATOMIC); if (newskb == NULL) { - printk(KERN_WARNING "%s: OOM in %s, " - "dropping packet\n", - IPQ_THR_NAME, __FUNCTION__); - e->verdict = NF_DROP; + printk(KERN_WARNING "ip_queue: OOM " + "in mangle, dropping packet\n"); return -ENOMEM; } kfree_skb(e->skb); @@ -342,101 +226,76 @@ ipq_queue_mangle_ipv4(unsigned char *buf, } skb_put(e->skb, diff); } - memcpy(e->skb->data, buf, v->data_len); + memcpy(e->skb->data, v->payload, v->data_len); e->skb->nfcache |= NFC_ALTERED; } return 0; } -static int -ipq_queue_set_verdict(ipq_queue_t *q, - ipq_verdict_msg_t *v, - unsigned char *buf, - unsigned int len) +static int ipq_set_verdict(ipq_queue_t *q, + ipq_verdict_msg_t *v, unsigned int len) { - struct list_head *i; + ipq_queue_element_t *e; if (v->value < 0 || v->value > NF_MAX_VERDICT) return -EINVAL; - spin_lock_bh(&q->lock); - for (i = q->list.next; i != &q->list; i = i->next) { - ipq_queue_element_t *e = (ipq_queue_element_t *)i; - - if (v->id == (unsigned long )e) { - int status = 0; - e->state = IPQ_PS_VERDICT; - e->verdict = v->value; - - if (buf && v->data_len == len) - status = ipq_queue_mangle_ipv4(buf, v, e); - spin_unlock_bh(&q->lock); - return status; - } + e = ipq_dequeue(q, v->id); + if (e == NULL) + return -ENOENT; + else { + e->verdict = v->value; + if (v->data_len && v->data_len == len) + if (ipq_mangle_ipv4(v, e) < 0) + e->verdict = NF_DROP; + nf_reinject(e->skb, e->info, e->verdict); + kfree(e); + return 0; } - spin_unlock_bh(&q->lock); - return -ENOENT; } -static int -ipq_receive_peer(ipq_queue_t *q, - ipq_peer_msg_t *m, - unsigned char type, - unsigned int len) +static int ipq_receive_peer(ipq_queue_t *q, ipq_peer_msg_t *m, + unsigned char type, unsigned int len) { - if (q->state == IPQ_QS_FLUSH) - return -EBUSY; + int status = 0; + + spin_lock_bh(&q->lock); + if (q->terminate || q->flushing) + return -EBUSY; + spin_unlock_bh(&q->lock); if (len < sizeof(ipq_peer_msg_t)) return -EINVAL; - switch (type) { case IPQM_MODE: switch (m->msg.mode.value) { - case IPQ_COPY_NONE: - q->peer.copy_mode = IPQ_COPY_NONE; - q->peer.copy_range = 0; - q->state = IPQ_QS_FLUSH; - break; case IPQ_COPY_META: - if (q->state == IPQ_QS_FLUSH) - return -EAGAIN; q->peer.copy_mode = IPQ_COPY_META; q->peer.copy_range = 0; - q->state = IPQ_QS_COPY; break; case IPQ_COPY_PACKET: - if (q->state == IPQ_QS_FLUSH) - return -EAGAIN; q->peer.copy_mode = IPQ_COPY_PACKET; q->peer.copy_range = m->msg.mode.range; - q->state = IPQ_QS_COPY; + if (q->peer.copy_range > 0xFFFF) + q->peer.copy_range = 0xFFFF; break; default: - return -EINVAL; + status = -EINVAL; } break; - case IPQM_VERDICT: { - int status; - unsigned char *data = NULL; - + case IPQM_VERDICT: if (m->msg.verdict.value > NF_MAX_VERDICT) - return -EINVAL; - if (m->msg.verdict.data_len) - data = (unsigned char *)m + sizeof(*m); - status = ipq_queue_set_verdict(q, &m->msg.verdict, - data, len - sizeof(*m)); - if (status < 0) - return status; + status = -EINVAL; + else + status = ipq_set_verdict(q, + &m->msg.verdict, + len - sizeof(*m)); break; - } default: - return -EINVAL; + status = -EINVAL; } - wake_up_interruptible(&q->thread.wq); - return 0; + return status; } - /**************************************************************************** * * Netfilter interface @@ -447,16 +306,10 @@ ipq_receive_peer(ipq_queue_t *q, * Packets arrive here from netfilter for queuing to userspace. * All of them must be fed back via nf_reinject() or Alexey will kill Rusty. */ -static int -receive_netfilter(struct sk_buff *skb, - struct nf_info *info, - void *data) +static int netfilter_receive(struct sk_buff *skb, + struct nf_info *info, void *data) { - ipq_queue_t *q = (ipq_queue_t *)data; - - if (q->state == IPQ_QS_FLUSH) - return -EBUSY; - return ipq_enqueue(q, skb, info); + return ipq_enqueue((ipq_queue_t *)data, skb, info); } /**************************************************************************** @@ -465,36 +318,10 @@ receive_netfilter(struct sk_buff *skb, * ****************************************************************************/ -static struct sk_buff * -netlink_build_message(ipq_queue_element_t *e, - int *errp); - -extern __inline__ void -receive_user_skb(struct sk_buff *skb); - -static int -netlink_send_peer(ipq_queue_element_t *e); - static struct sock *nfnl = NULL; ipq_queue_t *nlq = NULL; -static int -netlink_send_peer(ipq_queue_element_t *e) -{ - int status = 0; - struct sk_buff *skb; - - if (!nlq->peer.pid) - return -EINVAL; - skb = netlink_build_message(e, &status); - if (skb == NULL) - return status; - return netlink_unicast(nfnl, skb, nlq->peer.pid, MSG_DONTWAIT); -} - -static struct sk_buff * -netlink_build_message(ipq_queue_element_t *e, - int *errp) +static struct sk_buff *netlink_build_message(ipq_queue_element_t *e, int *errp) { unsigned char *old_tail; size_t size = 0; @@ -517,6 +344,7 @@ netlink_build_message(ipq_queue_element_t *e, else data_len = copy_range; size = NLMSG_SPACE(sizeof(*pm) + data_len); + break; case IPQ_COPY_NONE: default: @@ -540,7 +368,7 @@ netlink_build_message(ipq_queue_element_t *e, if (e->info->outdev) strcpy(pm->outdev_name, e->info->outdev->name); else pm->outdev_name[0] = '\0'; if (data_len) - memcpy(++pm, e->skb->data, data_len); + memcpy(pm->payload, e->skb->data, data_len); nlh->nlmsg_len = skb->tail - old_tail; NETLINK_CB(skb).dst_groups = 0; return skb; @@ -548,16 +376,24 @@ nlmsg_failure: if (skb) kfree(skb); *errp = 0; - printk(KERN_ERR "%s: error creating netlink message\n", IPQ_NAME); + printk(KERN_ERR "ip_queue: error creating netlink message\n"); return NULL; } +static int netlink_send_peer(ipq_queue_element_t *e) +{ + int status = 0; + struct sk_buff *skb; + + skb = netlink_build_message(e, &status); + if (skb == NULL) + return status; + return netlink_unicast(nfnl, skb, nlq->peer.pid, MSG_DONTWAIT); +} + #define RCV_SKB_FAIL(err) do { netlink_ack(skb, nlh, (err)); return; } while (0); -/* - * FIXME: ping old peer if we detect a new peer then resend. - */ -extern __inline__ void -receive_user_skb(struct sk_buff *skb) + +extern __inline__ void netlink_receive_user_skb(struct sk_buff *skb) { int status, type; struct nlmsghdr *nlh; @@ -579,9 +415,11 @@ receive_user_skb(struct sk_buff *skb) if(!cap_raised(NETLINK_CB(skb).eff_cap, CAP_NET_ADMIN)) RCV_SKB_FAIL(-EPERM); if (nlq->peer.pid && !nlq->peer.died - && (nlq->peer.pid != nlh->nlmsg_pid)) - printk(KERN_WARNING "%s: peer pid changed from %d to %d\n", - IPQ_NAME, nlq->peer.pid, nlh->nlmsg_pid); + && (nlq->peer.pid != nlh->nlmsg_pid)) { + printk(KERN_WARNING "ip_queue: peer pid changed from %d to " + "%d, flushing queue\n", nlq->peer.pid, nlh->nlmsg_pid); + ipq_flush(nlq); + } nlq->peer.pid = nlh->nlmsg_pid; nlq->peer.died = 0; status = ipq_receive_peer(nlq, NLMSG_DATA(nlh), @@ -594,9 +432,7 @@ receive_user_skb(struct sk_buff *skb) } /* Note: we are only dealing with single part messages at the moment. */ -static void -receive_user_sk(struct sock *sk, - int len) +static void netlink_receive_user_sk(struct sock *sk, int len) { do { struct sk_buff *skb; @@ -604,28 +440,25 @@ receive_user_sk(struct sock *sk, if (rtnl_shlock_nowait()) return; while ((skb = skb_dequeue(&sk->receive_queue)) != NULL) { - receive_user_skb(skb); + netlink_receive_user_skb(skb); kfree_skb(skb); } up(&rtnl_sem); } while (nfnl && nfnl->receive_queue.qlen); } - /**************************************************************************** * * System events * ****************************************************************************/ -static int -receive_event(struct notifier_block *this, - unsigned long event, - void *ptr) +static int receive_event(struct notifier_block *this, + unsigned long event, void *ptr) { if (event == NETDEV_UNREGISTER) if (nlq) - ipq_thread_stop(nlq); + ipq_destroy_queue(nlq); return NOTIFY_DONE; } @@ -635,7 +468,6 @@ struct notifier_block ipq_dev_notifier = { 0 }; - /**************************************************************************** * * Sysctl - queue tuning. @@ -668,33 +500,28 @@ static ctl_table ipq_root_table[] = { * ****************************************************************************/ -static int -ipq_get_info(char *buffer, char **start, off_t offset, int length) +static int ipq_get_info(char *buffer, char **start, off_t offset, int length) { int len; spin_lock_bh(&nlq->lock); len = sprintf(buffer, - "Thread pid : %d\n" - "Thread terminate : %d\n" - "Thread running : %d\n" - "Peer pid : %d\n" - "Peer died : %d\n" - "Peer copy mode : %d\n" - "Peer copy range : %d\n" - "Queue length : %d\n" - "Queue max. length : %d\n" - "Queue state : %d\n", - nlq->thread.pid, - nlq->thread.terminate, - nlq->thread.running, + "Peer pid : %d\n" + "Peer died : %d\n" + "Peer copy mode : %d\n" + "Peer copy range : %d\n" + "Queue length : %d\n" + "Queue max. length : %d\n" + "Queue flushing : %d\n" + "Queue terminate : %d\n", nlq->peer.pid, nlq->peer.died, nlq->peer.copy_mode, nlq->peer.copy_range, nlq->len, *nlq->maxlen, - nlq->state); + nlq->flushing, + nlq->terminate); spin_unlock_bh(&nlq->lock); *start = buffer + offset; len -= offset; @@ -714,18 +541,18 @@ ipq_get_info(char *buffer, char **start, off_t offset, int length) static int __init init(void) { int status = 0; - - nfnl = netlink_kernel_create(NETLINK_FIREWALL, receive_user_sk); + + nfnl = netlink_kernel_create(NETLINK_FIREWALL, netlink_receive_user_sk); if (nfnl == NULL) { - printk(KERN_ERR "%s: initialisation failed: unable to " - "create kernel netlink socket\n", IPQ_NAME); + printk(KERN_ERR "ip_queue: initialisation failed: unable to " + "create kernel netlink socket\n"); return -ENOMEM; } - nlq = ipq_queue_create(receive_netfilter, + nlq = ipq_create_queue(netfilter_receive, netlink_send_peer, &status, &sysctl_maxlen); if (nlq == NULL) { - printk(KERN_ERR "%s: initialisation failed: unable to " - "initialise queue\n", IPQ_NAME); + printk(KERN_ERR "ip_queue: initialisation failed: unable to " + "create queue\n"); sock_release(nfnl->socket); return status; } @@ -740,7 +567,7 @@ static void __exit fini(void) unregister_sysctl_table(ipq_sysctl_header); proc_net_remove(IPQ_PROC_FS_NAME); unregister_netdevice_notifier(&ipq_dev_notifier); - ipq_queue_destroy(nlq); + ipq_destroy_queue(nlq); sock_release(nfnl->socket); } @@ -748,3 +575,4 @@ MODULE_DESCRIPTION("IPv4 packet queue handler"); module_init(init); module_exit(fini); + diff --git a/net/ipx/af_spx.c b/net/ipx/af_spx.c index 9f52dfe4e020..1eb7a725c967 100644 --- a/net/ipx/af_spx.c +++ b/net/ipx/af_spx.c @@ -89,7 +89,7 @@ static unsigned int spx_datagram_poll(struct file * file, struct socket *sock, p if (sock_writeable(sk)) mask |= POLLOUT | POLLWRNORM | POLLWRBAND; else - sk->socket->flags |= SO_NOSPACE; + set_bit(SOCK_ASYNC_NOSPACE,&sk->socket->flags); return mask; } @@ -231,7 +231,7 @@ static int spx_listen(struct socket *sock, int backlog) sk->ack_backlog = 0; sk->state = TCP_LISTEN; } - sk->socket->flags |= SO_ACCEPTCON; + sk->socket->flags |= __SO_ACCEPTCON; return (0); } @@ -248,7 +248,7 @@ static int spx_accept(struct socket *sock, struct socket *newsock, int flags) return (-EINVAL); sk = sock->sk; - if((sock->state != SS_UNCONNECTED) || !(sock->flags & SO_ACCEPTCON)) + if((sock->state != SS_UNCONNECTED) || !(sock->flags & __SO_ACCEPTCON)) return (-EINVAL); if(sock->type != SOCK_SEQPACKET) return (-EOPNOTSUPP); -- 2.39.5