From f44f1554b2b9f8ea8738b29235d4dbf737449312 Mon Sep 17 00:00:00 2001 From: Linus Torvalds Date: Fri, 23 Nov 2007 15:11:10 -0500 Subject: [PATCH] Import 2.0.4 --- Documentation/Changes | 18 +- Documentation/cdrom/ide-cd | 6 +- Documentation/ide.txt | 19 +- Makefile | 2 +- arch/alpha/defconfig | 1 + arch/ppc/Makefile | 111 ++--- arch/ppc/boot/Makefile | 54 +-- arch/ppc/boot/compressed/Makefile | 2 +- arch/ppc/boot/cortstrip.c | 2 +- arch/ppc/kernel/Makefile | 30 +- arch/ppc/kernel/cortstrip.c | 62 --- arch/ppc/kernel/head.S | 21 +- arch/ppc/kernel/irq.c | 1 - arch/ppc/kernel/misc.S | 7 +- arch/ppc/kernel/mk_defs.c | 2 +- arch/ppc/kernel/mk_ramdisk.c | 65 --- arch/ppc/kernel/mkboot.c | 269 ---------- arch/ppc/kernel/mmu.h | 160 ------ arch/ppc/kernel/newppcdefs.h | 114 ----- arch/ppc/kernel/no_ramdisk.S | 6 - arch/ppc/kernel/ppc_asm.tmpl | 2 +- .../ppc/kernel/ppc_machine.h.isin.processor.h | 48 -- arch/ppc/kernel/process.c | 8 +- arch/ppc/kernel/ramdisk_drvr.c | 84 ---- arch/ppc/kernel/setup.c | 55 ++- arch/ppc/kernel/signal.c | 3 +- arch/ppc/kernel/stubs.c | 6 +- arch/ppc/kernel/test.S | 100 ---- arch/ppc/kernel/test1.c | 145 ------ arch/ppc/kernel/traps.c | 22 +- arch/ppc/mm/fault.c | 334 ++++++------- arch/ppc/mm/init.c | 129 +---- arch/ppc/mm/mmu.h | 160 ------ drivers/block/ide-cd.c | 65 ++- drivers/char/baycom.c | 52 +- drivers/net/3c59x.c | 459 +++++++++++------- drivers/net/arcnet.c | 20 +- drivers/pci/pci.c | 6 +- drivers/scsi/BusLogic.c | 36 +- drivers/scsi/Config.in | 8 +- drivers/scsi/README.BusLogic | 21 +- drivers/scsi/README.FlashPoint | 55 ++- drivers/scsi/ncr53c8xx.c | 6 + drivers/scsi/scsi.c | 2 + drivers/scsi/sd.c | 3 +- drivers/scsi/st.c | 11 +- drivers/sound/dev_table.h | 2 +- drivers/sound/lowlevel/aci.readme | 40 -- drivers/sound/pas2_pcm.c | 6 + drivers/sound/sb.h | 2 +- drivers/sound/sb_common.c | 24 + drivers/sound/sscape.c | 6 +- fs/ext2/super.c | 1 + fs/namei.c | 12 +- fs/open.c | 3 +- fs/pipe.c | 15 +- fs/ufs/ufs_super.c | 6 + include/asm-ppc/posix_types.h | 6 +- .../kernel => include/asm-ppc}/ppc_machine.h | 0 include/asm-ppc/unaligned.h | 16 + include/asm-ppc/unistd.h | 288 ++++++----- include/asm-ppc/unistd.h.cort | 376 ++++++++++++++ include/linux/baycom.h | 1 + include/linux/pci.h | 8 +- include/scsi/scsi.h | 3 +- kernel/ksyms.c | 1 + net/Config.in | 6 +- net/bridge/br.c | 20 +- net/ipv4/af_inet.c | 1 - net/ipv4/arp.c | 14 +- 70 files changed, 1462 insertions(+), 2187 deletions(-) delete mode 100644 arch/ppc/kernel/cortstrip.c delete mode 100644 arch/ppc/kernel/mk_ramdisk.c delete mode 100644 arch/ppc/kernel/mkboot.c delete mode 100644 arch/ppc/kernel/mmu.h delete mode 100644 arch/ppc/kernel/newppcdefs.h delete mode 100644 arch/ppc/kernel/no_ramdisk.S delete mode 100644 arch/ppc/kernel/ppc_machine.h.isin.processor.h delete mode 100644 arch/ppc/kernel/ramdisk_drvr.c delete mode 100644 arch/ppc/kernel/test.S delete mode 100644 arch/ppc/kernel/test1.c delete mode 100644 arch/ppc/mm/mmu.h delete mode 100644 drivers/sound/lowlevel/aci.readme rename {arch/ppc/kernel => include/asm-ppc}/ppc_machine.h (100%) create mode 100644 include/asm-ppc/unaligned.h create mode 100644 include/asm-ppc/unistd.h.cort diff --git a/Documentation/Changes b/Documentation/Changes index 6f1dccf1d28e..17e7587623df 100644 --- a/Documentation/Changes +++ b/Documentation/Changes @@ -40,6 +40,7 @@ Current Releases - Gpm 1.09 - SysVinit 2.64 - Util-linux 2.5 +- Net-tools 1.32-alpha Upgrade notes ************* @@ -263,7 +264,7 @@ direction (either incoming or outgoing). There also exists a possibility to match on device names and/or device addresses, so that only packets coming in/going out via that device (network interface) match with a rule. You'll need to get -ipfwadm from ftp://ftp.xos.nl/pub/linux/ipfwadm/ipfwadm-2.1.tar.gz to +ipfwadm from ftp://ftp.xos.nl/pub/linux/ipfwadm/ipfwadm-2.2.tar.gz to use this. IP Firewalls @@ -285,13 +286,13 @@ IP Masquerading always need to load separate modules (ip_masq_ftp.o and/or ip_masq_irc.o) if you are going to use FTP or IRC in combination with masquerading. You'll need to get -ftp://ftp.xos.nl/pub/linux/ipfwadm/ipfwadm-2.1.tar.gz to use this. +ftp://ftp.xos.nl/pub/linux/ipfwadm/ipfwadm-2.2.tar.gz to use this. ISDN support ============ The new kernels support ISDN. You'll need ISDN utils available from -ftp://ftp.franken.de/pub/isdn4linux/isdn4k-utils-1.3.97.tar.gz to try +ftp://ftp.franken.de/pub/isdn4linux/isdn4k-utils-2.0.0.tar.gz to try this. Networking @@ -299,10 +300,13 @@ Networking Some of the /proc/net entries have changed. You'll need to upgrade to the latest net-tools in -ftp://ftp.inka.de/pub/comp/Linux/networking/net-tools. The last -official release there is net-tools-1.2.0.tar.gz, and the latest -release is net-tools-1.32-alpha.tar.gz. If you need the upgrade, you -probably need the latest beta release. +ftp://ftp.inka.de/pub/comp/Linux/networking/NetTools/, where the latest +is currently net-tools-1.32-alpha.tar.gz. See +http://www.inka.de/sites/lina/linux/NetTools/index_en.html for more +information. Note that there is currently no ipfw (which is part of +net-tools) which works with 2.0.x kernels. If you need its functions, +learn how to use ipfwadm or patch ipfw to get it to work (ipfw's current +maintainer does not currently have time to fix it). Xntpd ===== diff --git a/Documentation/cdrom/ide-cd b/Documentation/cdrom/ide-cd index 632940cfea6a..4ce303e166d6 100644 --- a/Documentation/cdrom/ide-cd +++ b/Documentation/cdrom/ide-cd @@ -36,9 +36,9 @@ This driver provides the following features: with the ATAPI 2.6 draft standard (such as the NEC CDR-251). This merely adds a function to switch between the slots of the changer under control of an external program. A sample such program is - appended to the end of this file. I've heard that the Sanyo 3-disc - changer does not conform to this standard, so the changer functions - will probably not work with that drive. + appended to the end of this file. The Sanyo 3-disc changer + (which does not conform to the standard) is also now supported. + Please note the driver refers to the first CD as slot # 0. 2. Installation diff --git a/Documentation/ide.txt b/Documentation/ide.txt index efd175bad649..f4e6e2d9931a 100644 --- a/Documentation/ide.txt +++ b/Documentation/ide.txt @@ -90,8 +90,8 @@ There can be up to two drives per interface, as per the ATA-2 spec. Primary: ide0, port 0x1f0; major=3; hda is minor=0; hdb is minor=64 Secondary: ide1, port 0x170; major=22; hdc is minor=0; hdd is minor=64 -Tertiary: ide2, port 0x???; major=33; hde is minor=0; hdf is minor=64 -Quaternary: ide3, port 0x???; major=34; hdg is minor=0; hdh is minor=64 +Tertiary: ide2, port 0x1e8; major=33; hde is minor=0; hdf is minor=64 +Quaternary: ide3, port 0x168; major=34; hdg is minor=0; hdh is minor=64 To access devices on the 2nd/3rd/4th interfaces, device entries must first be created in /dev for them. To create such entries, simply run the included @@ -107,11 +107,22 @@ IRQ numbers being used by the interfaces (normally IRQ14 & IRQ15). Interfaces beyond the first two are not normally probed for, but may be specified using kernel "command line" options. For example, - ide3=0x1e8,0x3f0,11 /* ioports 0x1e8-0x1ef,0x3f0, irq 11 */ + ide3=0x168,0x36e,10 /* ioports 0x1e8-0x1ef,0x3f0, irq 11 */ Normally the irq number need not be specified, as ide.c will probe for it: - ide3=0x1e8,0x3f0 /* ioports 0x1e8-0x1ef,0x3f0 */ + ide3=0x168,0x36e /* ioports 0x168-0x16f,0x36e */ + +The standard port, and irq values are these: + + ide0=0x1f0,0x3f6,14 + ide1=0x170,0x376,15 + ide2=0x1e8,0x3ee,11 + ide3=0x168,0x36e,10 + +In all probability the device uses these ports and irqs if it is attached +to the appropriate ide channel. Pass the parameter for the correct ide +channel to the kernel, as explained above. Any number of interfaces may share a single IRQ if necessary, at a slight performance penalty, whether on separate cards or a single VLB card. diff --git a/Makefile b/Makefile index 84b6546e136a..72e306793c5b 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 0 -SUBLEVEL = 3 +SUBLEVEL = 4 ARCH = i386 diff --git a/arch/alpha/defconfig b/arch/alpha/defconfig index 2feff67b4739..1fd94a4f13d3 100644 --- a/arch/alpha/defconfig +++ b/arch/alpha/defconfig @@ -128,6 +128,7 @@ CONFIG_SCSI_CONSTANTS=y # CONFIG_SCSI_GENERIC_NCR5380 is not set # CONFIG_SCSI_NCR53C406A is not set # CONFIG_SCSI_NCR53C7xx is not set +# CONFIG_SCSI_NCR53C8XX is not set # CONFIG_SCSI_PPA is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_QLOGIC_FAS is not set diff --git a/arch/ppc/Makefile b/arch/ppc/Makefile index 3f75e23a6ae7..02c0525103d8 100644 --- a/arch/ppc/Makefile +++ b/arch/ppc/Makefile @@ -15,58 +15,54 @@ # # PowerPC (cross) tools -AS = as.ppc -ASFLAGS = -LD = ld.ppc -#LINKFLAGS = -T arch/ppc/ld.script -Ttext 0x90000000 -Map vmlinux.map -LINKFLAGS = -T arch/ppc/ld.script -Ttext 0x90000000 +SUFFIX =.ppc +#AS = /u/cort/ppc/gcc/ppc-linux-elf/bin/as +AS = as$(SUFFIX) +ASFLAGS = +#LD = /u/cort/ppc/gcc/ppc-linux-elf/bin/ld +LD = ld$(SUFFIX) +LINKFLAGS = -T arch/ppc/ld.script -Ttext 0x90000000 HOSTCC = gcc -CC = cc.ppc -CFLAGS = -D__KERNEL__ -I$(TOPDIR)/include \ - -Wall -Wstrict-prototypes \ - -msoft-float \ +#CC = /u/cort/ppc/gcc/bin/gcc +CC = gcc$(SUFFIX) +#CC = /u/cort/ppc/gcc/bin/gcc.ppc +CFLAGS = -D__KERNEL__ -I$(TOPDIR)/include -D__powerpc__ \ + -Wstrict-prototypes \ -fomit-frame-pointer \ -fno-builtin \ -finhibit-size-directive \ - -fsigned-char \ - -O2 + -O2 -fsigned-char CPP = $(CC) -E $(CFLAGS) -AR = ar.ppc -RANLIB = ranlib.ppc -STRIP = strip.ppc -NM = nm.ppc +#AR = /u/cort/ppc/gcc/ppc-linux-elf/bin/ar +AR = ar$(SUFFIX) +#RANLIB = /u/cort/ppc/gcc/ppc-linux-elf/bin/ranlib +RANLIB = ar$(SUFFIX) +#STRIP = /u/cort/ppc/gcc/ppc-linux-elf/bin/strip +STRIP = strip$(SUFFIX) +#NM = /u/cort/ppc/gcc/ppc-linux-elf/bin/nm +NM = nm$(SUFFIX) # -# Set these to indicate how to link it.. +# NFS_ROOT_NAME specifies the default name of the directory to mount +# as root via NFS, if the kernel does not get the "root=" option from +# the boot loader. The "%s" will be replaced by the IP-number of the +# local system. # -# -zmagic: -# -# ZLINKFLAGS = -Ttext 0x1000 -# LINKFLAGS = -Ttext 0x100000 -# -# -qmagic (we need to remove the 32 byte header for bootup purposes) -# -## ZLINKFLAGS =-qmagic -Ttext 0xfe0 -## LINKFLAGS =-qmagic -Ttext 0xfffe0 -## CFLAGS := $(CFLAGS) -pipe - -## ifdef CONFIG_M486 -## CFLAGS := $(CFLAGS) -m486 -## else -## ifdef CONFIG_M586 -## CFLAGS := $(CFLAGS) -mpentium -## else -## CFLAGS := $(CFLAGS) -m386 -## endif -## endif +NFS_ROOT = -DNFS_ROOT="\"/joplin/ppc/root/\"" HEAD := arch/ppc/kernel/head.o ARCH_SUBDIRS = arch/ppc/kernel arch/ppc/mm arch/ppc/lib SUBDIRS := $(SUBDIRS) $(ARCH_SUBDIRS) ARCHIVES := arch/ppc/kernel/kernel.o arch/ppc/mm/mm.o arch/ppc/lib/lib.o $(ARCHIVES) -NO_RD_ARCHIVES := arch/ppc/kernel/no_ramdisk.o $(ARCHIVES) -ARCHIVES := arch/ppc/kernel/ramdisk.o $(ARCHIVES) + + +MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot + +tImage: vmlinux + @$(MAKEBOOT) tImage + + arch/ppc/kernel: dummy $(MAKE) linuxsubdirs SUBDIRS=arch/ppc/kernel @@ -77,41 +73,12 @@ arch/ppc/mm: dummy arch/ppc/lib: dummy $(MAKE) linuxsubdirs SUBDIRS=arch/ppc/lib -MAKEBOOT = $(MAKE) -C arch/$(ARCH)/boot - -vmlinux.no_ramdisk: $(CONFIGURATION) init/main.o init/version.o linuxsubdirs - $(LD) $(LINKFLAGS) $(HEAD) init/main.o init/version.o \ - $(NO_RD_ARCHIVES) \ - $(FILESYSTEMS) \ - $(DRIVERS) \ - $(LIBS) -o vmlinux.no_ramdisk - -## -zImage: vmlinux - @$(MAKEBOOT) zImage - -tImage: vmlinux - @$(MAKEBOOT) tImage - -bImage: vmlinux.no_ramdisk - @$(MAKEBOOT) bImage - -bdisk: vmlinux.no_ramdisk - @$(MAKEBOOT) bdisk - -## compressed: zImage -## -## zlilo: vmlinux -## @$(MAKEBOOT) zlilo -## -zdisk: vmlinux - @$(MAKEBOOT) zdisk - -## install: vmlinux -## @$(MAKEBOOT) install archclean: - @$(MAKEBOOT) clean + /bin/rm -f arch/ppc/*/*.o #arch/ppc/kernel/mk_defs arch/ppc/kernel/ppc_defs.h + /bin/rm -f arch/ppc/*~ arch/ppc/*/*~ include/asm-ppc/*~ arch/ppc/boot/mkboot archdep: -# @$(MAKEBOOT) dep + +corttags : + etags arch/ppc/*/*.c include/asm-ppc/* drivers/*/*.c net/*.c */*.c diff --git a/arch/ppc/boot/Makefile b/arch/ppc/boot/Makefile index 2d1177579af6..1b5056bea3ed 100644 --- a/arch/ppc/boot/Makefile +++ b/arch/ppc/boot/Makefile @@ -22,50 +22,28 @@ OBJECTS = head.o main.o -all: linux.boot +all: linux.boot mkboot -#zImage: $(CONFIGURE) bootsect setup compressed/vmlinux tools/build -zImage: compressed/vmlinux mk_type41 - mkboot compressed/vmlinux vmlinux 0 - mk_type41 vmlinux zImage - cp compressed/vmlinux zBoot - rm -f vmlinux compressed/vmlinux +linux.boot: $(TOPDIR)/vmlinux mkboot + rsh charon /bin/rm -f /usr/tftpboot/vmlinux + /bin/rm -f /usr/tftpboot/vmlinux + ./mkboot $(TOPDIR)/vmlinux /usr/tftpboot/vmlinux + rcp /usr/tftpboot/vmlinux charon:/usr/tftpboot/vmlinux + sync -zdisk: zImage - dd if=zImage of=/dev/fd0 bs=36b - -compressed/vmlinux: $(TOPDIR)/vmlinux - @$(MAKE) -C compressed vmlinux - -tImage: mk_type41 $(TOPDIR)/vmlinux - mkboot $(TOPDIR)/vmlinux vmlinux 0 +tImage: mk_type41 $(TOPDIR)/vmlinux mkboot + ./mkboot $(TOPDIR)/vmlinux vmlinux mk_type41 vmlinux tImage - rm -f vmlinux - -bImage: mk_type41 $(TOPDIR)/vmlinux.no_ramdisk - mkboot $(TOPDIR)/vmlinux.no_ramdisk vmlinux 0 - mk_type41 vmlinux bImage - rm -f vmlinux + rm vmlinux -xImage: compressed/vmlinux.no_ramdisk - mkboot compressed/vmlinux.no_ramdisk vmlinux 0 - mk_type41 vmlinux xImage - rm -f vmlinux compressed/vmlinux.no_ramdisk - -compressed/vmlinux.no_ramdisk: $(TOPDIR)/vmlinux.no_ramdisk - @$(MAKE) -C compressed vmlinux.no_ramdisk - -bdisk: xImage - dd if=xImage of=/dev/fd0 bs=36b - -linux.boot: $(TOPDIR)/vmlinux - mkboot $(TOPDIR)/vmlinux $@ 0 +mkboot : cortstrip.c + $(HOSTCC) -o mkboot cortstrip.c mk_type41: mk_type41.c - cc -o mk_type41 mk_type41.c - + gcc -o mk_type41 mk_type41.c + clean: - rm -f linux.boot + rsh charon /bin/rm -f /usr/tftpboot/vmlinux + /bin/rm -f /usr/tftpboot/vmlinux dep: -fastdep: diff --git a/arch/ppc/boot/compressed/Makefile b/arch/ppc/boot/compressed/Makefile index 665fddcc328b..4cd4d1caf094 100644 --- a/arch/ppc/boot/compressed/Makefile +++ b/arch/ppc/boot/compressed/Makefile @@ -1,5 +1,5 @@ # -# linux/arch/i386/boot/compressed/Makefile +# linux/arch/ppc/boot/compressed/Makefile # # create a compressed vmlinux image from the original vmlinux # diff --git a/arch/ppc/boot/cortstrip.c b/arch/ppc/boot/cortstrip.c index df0ceab9aee7..c671ca34915b 100644 --- a/arch/ppc/boot/cortstrip.c +++ b/arch/ppc/boot/cortstrip.c @@ -35,7 +35,7 @@ int main(int argc, char **argv ) exit(-1); } - fdo = open(argv[2], O_WRONLY|O_CREAT); + fdo = open(argv[2], O_WRONLY|O_CREAT|O_TRUNC,0755); if ( fdo == -1 ) { fprintf(stderr,"Couldn't open %s\n", argv[2]); diff --git a/arch/ppc/kernel/Makefile b/arch/ppc/kernel/Makefile index 7bcf3664507a..8a3a845f1081 100644 --- a/arch/ppc/kernel/Makefile +++ b/arch/ppc/kernel/Makefile @@ -25,10 +25,10 @@ HOST_CC = gcc OBJS = misc.o setup.o port_io.o irq.o pci.o traps.o stubs.o process.o \ - signal.o raw_printf.o ksyms.o time.o ramdisk_drvr.o syscalls.o \ - support.o ptrace.o + signal.o ksyms.o time.o syscalls.o \ + support.o ptrace.o # ramdisk_drvr.o -all: head.o kernel.o no_ramdisk.o ramdisk.o +all: head.o kernel.o #no_ramdisk.o ramdisk.o head.o: head.s head.s: head.S $(TOPDIR)/include/linux/tasks.h ppc_defs.h @@ -37,31 +37,31 @@ ppc_defs.h: mk_defs # simppc mk_defs -- $@ mk_defs $@ -no_ramdisk.o: no_ramdisk.S +#no_ramdisk.o: no_ramdisk.S -ramdisk.o: ramdisk.image mk_ramdisk - mk_ramdisk ramdisk.image $*.s - $(AS) -o $@ $*.s - rm $*.s +#ramdisk.o: ramdisk.image mk_ramdisk +# mk_ramdisk ramdisk.image $*.s +# $(AS) -o $@ $*.s +# rm $*.s + +#mk_ramdisk: mk_ramdisk.c +# ${HOST_CC} -o mk_ramdisk mk_ramdisk.c -mk_ramdisk: mk_ramdisk.c - ${HOST_CC} -o mk_ramdisk mk_ramdisk.c - mk_defs: mk_defs.c $(TOPDIR)/include/asm/mmu.h $(TOPDIR)/include/asm/processor.h $(TOPDIR)/include/asm/pgtable.h $(TOPDIR)/include/asm/ptrace.h # cc.ppc ${CFLAGS} -o mk_defs -T ld.script-user -Ttext 0x1000 mk_defs.c - cc.ppc ${CFLAGS} -o mk_defs mk_defs.c + gcc.ppc ${CFLAGS} -o mk_defs mk_defs.c kernel.o: $(OBJS) $(LD) -r -o kernel.o $(OBJS) sync -mkboot: mkboot.c - ${HOST_CC} -o $@ -Iinclude mkboot.c +#mkboot: mkboot.c +# ${HOST_CC} -o $@ -Iinclude mkboot.c dep: $(CPP) -M *.c > .depend - + fastdep: modules: diff --git a/arch/ppc/kernel/cortstrip.c b/arch/ppc/kernel/cortstrip.c deleted file mode 100644 index c38dd30fe456..000000000000 --- a/arch/ppc/kernel/cortstrip.c +++ /dev/null @@ -1,62 +0,0 @@ -#include -#include -#include -#include - -/* amount to skip */ -/*#define PLACE 0x10000*/ - -/* size of read buffer */ -#define SIZE 0x10000 - -void main(int argc, char **argv ) -{ - int fd, fdo; - unsigned char data[SIZE]; - int i, n, skip; - - if ( argc != 4 ) - { - fprintf(stderr,"%s infile outfile skip\n", argv[0]); - exit(-1); - } - - - fd = open(argv[1], O_RDONLY); - if ( fd == -1 ) - { - fprintf(stderr,"Couldn't open %s\n", argv[1]); - perror("open()"); - exit(-1); - } - - fdo = open(argv[2], O_WRONLY|O_CREAT, 755); - if ( fdo == -1 ) - { - fprintf(stderr,"Couldn't open %s\n", argv[2]); - perror("open()"); - exit(-1); - } - - skip = atoi(argv[3]); - i = lseek(fd, skip, SEEK_SET); - printf("lseek'd %d bytes\n", i); - if ( i == -1 ) - { - perror("lseek()"); - } - - while ( (n = read(fd, data, SIZE)) > 0 ) - { - printf("Read %d bytes\n", n); - i = write(fdo, data, n); - printf("Wrote %d bytes\n", i); - } - - - close(fdo); - close(fd); - return(0); -} - - diff --git a/arch/ppc/kernel/head.S b/arch/ppc/kernel/head.S index 838eb8a0a8fc..bd6819c34b71 100644 --- a/arch/ppc/kernel/head.S +++ b/arch/ppc/kernel/head.S @@ -1,14 +1,14 @@ #include "ppc_asm.tmpl" #include "ppc_defs.h" #include - +#define NEWMM #define SYNC() \ isync; \ sync -/* #define TLB_STATS /* Trace TLB exceptions */ +/* #define TLB_STATS */ -/* Keep track of low-level exceptions - rather crude, but informative */ +/* Keep track of low-level exceptions - rather crude, but informative */ #define STATS /* @@ -50,9 +50,9 @@ /* gather some data without disturbing anything - Heisenberg are you watching? */ /* CAUTION! Don't turn on more than one of these at once! */ -/* #define DO_TRAP_TRACE /* */ -/* #define DO_TLB_TRACE /* */ -/* #define DO_RFI_TRACE /* */ +/* #define DO_TRAP_TRACE */ +/* #define DO_TLB_TRACE */ +/* #define DO_RFI_TRACE */ #ifdef DO_RFI_TRACE #define DO_RFI_TRACE_UNMAPPED(mark) \ @@ -801,8 +801,14 @@ Reset: lwz r0,4(r3) mtspr IBAT1L,r0 mtspr DBAT1L,r0 +/* this BAT mapping will cover all of kernel space */ +#ifdef NEWMM + lis r3,BAT2@h + ori r3,r3,BAT2@l +#else lis r3,TMP_BAT2@h ori r3,r3,TMP_BAT2@l +#endif andc r3,r3,r7 /* make unmapped address */ lwz r0,0(r3) mtspr IBAT2U,r0 @@ -847,7 +853,8 @@ DO_RFI_TRACE_MAPPED(0xDEAD0100) DO_RFI_TRACE_MAPPED(0xDEAD0200) SYNC rfi -20: +20: + DO_RFI_TRACE_UNMAPPED(0xDEAD0400) 20: lis r3,BAT2@h ori r3,r3,BAT2@l diff --git a/arch/ppc/kernel/irq.c b/arch/ppc/kernel/irq.c index 4bf3a992e958..27d14647956a 100644 --- a/arch/ppc/kernel/irq.c +++ b/arch/ppc/kernel/irq.c @@ -264,7 +264,6 @@ int request_irq(unsigned int irq, void (*handler)(int, void *, struct pt_regs *) #if 0 _printk("Request IRQ #%d, Handler: %x\n", irq, handler); -cnpause(); #endif if (irq > 15) { diff --git a/arch/ppc/kernel/misc.S b/arch/ppc/kernel/misc.S index 7d4f5859630b..7d84bdc89bfc 100644 --- a/arch/ppc/kernel/misc.S +++ b/arch/ppc/kernel/misc.S @@ -474,6 +474,7 @@ _GLOBAL(_get_PVR) * Create a kernel thread * __kernel_thread(flags, fn, arg) */ +#if 0 #define SYS_CLONE 120 _GLOBAL(__kernel_thread) __kernel_thread: @@ -484,7 +485,7 @@ __kernel_thread: mtlr r4 mr r3,r5 blr - +#endif /* Why isn't this a) automatic, b) written in 'C'? */ .data .align 4 @@ -652,5 +653,7 @@ sys_call_table: .long sys_sched_get_priority_max .long sys_sched_get_priority_min /* 160 */ .long sys_sched_rr_get_interval - .space (NR_syscalls-162)*4 + .long sys_nanosleep + .long sys_mremap + .space (NR_syscalls-163)*4 diff --git a/arch/ppc/kernel/mk_defs.c b/arch/ppc/kernel/mk_defs.c index e64361440392..e63e5c04a516 100644 --- a/arch/ppc/kernel/mk_defs.c +++ b/arch/ppc/kernel/mk_defs.c @@ -2,7 +2,7 @@ * This program is used to generate definitions needed by * assembly language modules. */ - +#define MK_DEFS #include #include diff --git a/arch/ppc/kernel/mk_ramdisk.c b/arch/ppc/kernel/mk_ramdisk.c deleted file mode 100644 index e46ec9b1d879..000000000000 --- a/arch/ppc/kernel/mk_ramdisk.c +++ /dev/null @@ -1,65 +0,0 @@ -#include - -extern long ce_exec_config[]; - -main(int argc, char *argv[]) -{ - FILE *out, *in; - int i, cnt, pos; - unsigned char *lp; - unsigned char buf[4096]; - if (argc != 3) - { - fprintf(stderr, "usage: %s \n", argv[0]); - exit(1); - } - if ((out = fopen(argv[2], "w")) == (FILE *)0) - { - fprintf(stderr, "Can't create '%s'\n", argv[2]); - exit(1); - } - if ((in = fopen(argv[1], "r")) == (FILE *)0) - { - fprintf(stderr, "Can't open '%s'\n", argv[1]); - exit(1); - } - fprintf(out, "#\n"); - fprintf(out, "# Miscellaneous data structures:\n"); - fprintf(out, "# WARNING - this file is automatically generated!\n"); - fprintf(out, "#\n"); - fprintf(out, "\n"); - fprintf(out, "\t.data\n"); - fprintf(out, "\t.globl builtin_ramdisk_image\n"); - fprintf(out, "builtin_ramdisk_image:\n"); - pos = 0; - while (fread(buf, sizeof(buf), 1, in) == 1) - { - cnt = 0; - lp = (unsigned char *)buf; - for (i = 0; i < sizeof(buf); i += 4) - { - if (cnt == 0) - { - fprintf(out, "\t.long\t"); - } - fprintf(out, "0x%02X%02X%02X%02X", lp[0], lp[1], lp[2], lp[3]); - lp += 4; - if (++cnt == 4) - { - cnt = 0; - fprintf(out, " # %x \n", pos+i-12); - fflush(out); - } else - { - fprintf(out, ","); - } - } - pos += sizeof(buf); - } - fprintf(out, "\t.globl builtin_ramdisk_size\n"); - fprintf(out, "builtin_ramdisk_size:\t.long\t0x%x\n", pos); - fflush(out); - fclose(out); - exit(0); -} - diff --git a/arch/ppc/kernel/mkboot.c b/arch/ppc/kernel/mkboot.c deleted file mode 100644 index 535e342577c5..000000000000 --- a/arch/ppc/kernel/mkboot.c +++ /dev/null @@ -1,269 +0,0 @@ -/* - * mkboot - Make a 'boot' image from a PowerPC (ELF) binary - * - * usage: mkboot - * - */ - -#include -#include -#include -#include -#include - -#define MAX_SECTIONS 64 -int fd; -Elf32_External_Ehdr hdr; -Elf32_External_Shdr sections[MAX_SECTIONS]; -char *symtab; - -/* Boolean type definitions */ - -#define FALSE 0 -#define TRUE 1 -#define bool short - -extern char *strerror(); -extern int errno; - -#define ADDR unsigned long - -/* Definitions that control the shape of the output */ -#define MAX_ITEMS 32 /* Max # bytes per line */ - -FILE *in_file; /* Input (binary image) file */ -FILE *out_file; /* Output (boot image) file */ - -int org = -1; - -#ifdef linux -long -_LONG(unsigned long *p) -{ - unsigned char *xp = (unsigned char *)p; - return ((xp[0]<<24) | (xp[1]<<16) | (xp[2]<<8) | xp[3]); -} - -unsigned short -_USHORT(unsigned short *p) -{ - unsigned char *xp = (unsigned char *)p; - return ((xp[0]<<8) | xp[1]); -} -#else -#define _LONG * -#define _USHORT * -#endif - -Elf32_External_Shdr * -find_section(char *section_name) -{ - Elf32_External_Shdr *shdr = sections; - int i; - for (i = 0; i < MAX_SECTIONS; i++, shdr++) - { - if (strcmp(section_name, &symtab[_LONG((int *)shdr->sh_name)]) == 0) - { - return (shdr); - } - } - return ((Elf32_External_Shdr *)0); -} - -main (argc, argv) - int argc; - char *argv[]; -{ - if ((argc == 3) || (argc == 4)) - { - if (argc == 4) - { - org = strtol(argv[3], NULL, 0); - } - if (init(argc, argv)) - { - process(argv[2]); - } - else exit(255); - } else - { /* Illegal command line */ - fprintf(stderr, "Syntax: mkboot \n"); - exit(255); - } - exit(0); -} - -init(argc, argv) - int argc; - char *argv[]; -{ - int sizeof_sections, size; - char *fn = argv[1]; - Elf32_External_Shdr *shdr; - if ((out_file = fopen(argv[2], "w")) == (FILE *)NULL) - { - io_err("creating output file"); - return (FALSE); - } - if ((in_file = fopen(fn, "r")) == (FILE *)NULL) - { - fprintf(stderr, "Can't open '%s': %s\n", fn, strerror(errno)); - return (FALSE); - } - if (fread(&hdr, sizeof(hdr), 1, in_file) != 1) - { - fprintf(stderr, "Can't read ELF header: %s\n", strerror(errno)); - return (FALSE); - } - /* Make sure this is a file we like */ - if ((hdr.e_ident[EI_MAG0] != ELFMAG0) || (hdr.e_ident[EI_MAG1] != ELFMAG1) || - (hdr.e_ident[EI_MAG2] != ELFMAG2) || (hdr.e_ident[EI_MAG3] != ELFMAG3)) - { - fprintf(stderr, "Invalid binary file (not ELF)\n"); - return (FALSE); - } - if (hdr.e_ident[EI_CLASS] != ELFCLASS32) - { - fprintf(stderr, "Invalid binary file (not ELF32)\n"); - return (FALSE); - } - if ((_USHORT((unsigned short *)hdr.e_machine) != EM_CYGNUS_POWERPC) && - (_USHORT((unsigned short *)hdr.e_machine) != EM_PPC)) - { - fprintf(stderr, "Invalid binary file (not PowerPC)\n"); - return (FALSE); - } - if (_USHORT((unsigned short *)hdr.e_shnum) > MAX_SECTIONS) - { - fprintf(stderr, "Invalid binary file (too many sections)\n"); - return (FALSE); - } - fseek(in_file, _LONG((int *)hdr.e_shoff), 0); - sizeof_sections = _USHORT((unsigned short *)hdr.e_shnum) * sizeof(sections[0]); - if (fread(sections, sizeof_sections, 1, in_file) != 1) - { - fprintf(stderr, "Can't read sections: %s\n", strerror(errno)); - return (FALSE); - } - /* Read in symbol table */ - shdr = §ions[_USHORT((unsigned short *)hdr.e_shstrndx)]; - size = _LONG((int *)shdr->sh_size); - if (!(symtab = malloc(256))) - { - fprintf(stderr, "Can't allocate memory for symbol table.\n"); - return (FALSE); - } - fseek(in_file, _LONG((int *)shdr->sh_offset), 0); - if (fread(symtab, size, 1, in_file) != 1) - { - fprintf(stderr, "Can't read symbol table: %s\n", strerror(errno)); - return (FALSE); - } - return (TRUE); -} - -process(out_name) - char *out_name; -{ - Elf32_External_Shdr *shdr_text, *shdr_data; - long relocated_text_base, text_base, text_offset, text_size; - long relocated_data_base, data_base, data_offset, data_size; - shdr_text = find_section(".text"); - shdr_data = find_section(".data"); - text_base = relocated_text_base = _LONG((int *)shdr_text->sh_addr); - text_size = _LONG((int *)shdr_text->sh_size); - text_offset = _LONG((int *)shdr_text->sh_offset); - data_base = relocated_data_base = _LONG((int *)shdr_data->sh_addr); - data_size = _LONG((int *)shdr_data->sh_size); - data_offset = _LONG((int *)shdr_data->sh_offset); - if (org >= 0) - { - relocated_text_base = org; - relocated_data_base = data_base - text_base + org; - } -fprintf(stderr, "TEXT %x bytes at %x[%x]\n", text_size, text_base, relocated_text_base); -fprintf(stderr, "DATA %x bytes at %x[%x]\n", data_size, data_base, relocated_data_base); - if (dump_segment(text_offset, relocated_text_base, text_size) && - dump_segment(data_offset, relocated_data_base, data_size)) - { - } else - { - unlink(out_name); - } -} - -dump_segment(off, base, size) - long off; - ADDR base; - long size; -{ - char buf[4096]; - int len; - bool ok = TRUE; -fprintf(stderr, "Reading %x bytes at %x.%x\n", size, off, base); - fseek(in_file, 0, 0); - fseek(in_file, off, 0); -#if 0 - if (org >= 0) - { - fseek(out_file, base+org, 0); - } else - { - fseek(out_file, base, 0); - } -#else - fseek(out_file, base, 0); -#endif - while (size && ok) - { - len = size; - if (len > sizeof(buf)) - { - len = sizeof(buf); - } - if (fread(buf, sizeof(char), len, in_file) == len) - { - fwrite(buf, sizeof(char), len, out_file); - } else - { - fprintf(stderr,"Premature EOF encountered.\n"); - ok = FALSE; - } - size -= len; - } - return (ok); -} - -io_err(what) - char *what; -{ - fprintf(stderr, "Error %s: %s\n", what, strerror(errno)); -} - - - -#ifdef sun -extern int sys_nerr; -extern char *sys_errlist[]; - -char * -strerror(int errno) -{ - static char msg[32]; - if (errno <= sys_nerr) - { - return (sys_errlist[errno]); - } else - { - sprintf(msg, "<>", errno); - return (msg); - } -} - -strtoul(char *str, char **radix, int base) -{ - return(strtol(str, radix, base)); -} -#endif - - diff --git a/arch/ppc/kernel/mmu.h b/arch/ppc/kernel/mmu.h deleted file mode 100644 index b63ea0e6a1f5..000000000000 --- a/arch/ppc/kernel/mmu.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * PowerPC memory management structures - */ - -#ifndef _PPC_MMU_H_ -#define _PPC_MMU_H_ - -/* Hardware Page Table Entry */ - -typedef struct _PTE - { - unsigned long v:1; /* Entry is valid */ - unsigned long vsid:24; /* Virtual segment identifier */ - unsigned long h:1; /* Hash algorithm indicator */ - unsigned long api:6; /* Abbreviated page index */ - unsigned long rpn:20; /* Real (physical) page number */ - unsigned long :3; /* Unused */ - unsigned long r:1; /* Referenced */ - unsigned long c:1; /* Changed */ - unsigned long w:1; /* Write-thru cache mode */ - unsigned long i:1; /* Cache inhibited */ - unsigned long m:1; /* Memory coherence */ - unsigned long g:1; /* Guarded */ - unsigned long :1; /* Unused */ - unsigned long pp:2; /* Page protection */ - } PTE; - -/* Values for PP (assumes Ks=0, Kp=1) */ -#define PP_RWXX 0 /* Supervisor read/write, User none */ -#define PP_RWRX 1 /* Supervisor read/write, User read */ -#define PP_RWRW 2 /* Supervisor read/write, User read/write */ -#define PP_RXRX 3 /* Supervisor read, User read */ - -/* Segment Register */ - -typedef struct _SEGREG - { - unsigned long t:1; /* Normal or I/O type */ - unsigned long ks:1; /* Supervisor 'key' (normally 0) */ - unsigned long kp:1; /* User 'key' (normally 1) */ - unsigned long n:1; /* No-execute */ - unsigned long :4; /* Unused */ - unsigned long vsid:24; /* Virtual Segment Identifier */ - } SEGREG; - -/* Block Address Translation (BAT) Registers */ - -typedef struct _BATU /* Upper part of BAT */ - { - unsigned long bepi:15; /* Effective page index (virtual address) */ - unsigned long :4; /* Unused */ - unsigned long bl:11; /* Block size mask */ - unsigned long vs:1; /* Supervisor valid */ - unsigned long vp:1; /* User valid */ - } BATU; - -typedef struct _BATL /* Lower part of BAT */ - { - unsigned long brpn:15; /* Real page index (physical address) */ - unsigned long :10; /* Unused */ - unsigned long w:1; /* Write-thru cache */ - unsigned long i:1; /* Cache inhibit */ - unsigned long m:1; /* Memory coherence */ - unsigned long g:1; /* Guarded (MBZ) */ - unsigned long :1; /* Unused */ - unsigned long pp:2; /* Page access protections */ - } BATL; - -typedef struct _BAT - { - BATU batu; /* Upper register */ - BATL batl; /* Lower register */ - } BAT; - -/* Block size masks */ -#define BL_128K 0x000 -#define BL_256K 0x001 -#define BL_512K 0x003 -#define BL_1M 0x007 -#define BL_2M 0x00F -#define BL_4M 0x01F -#define BL_8M 0x03F -#define BL_16M 0x07F -#define BL_32M 0x0FF -#define BL_64M 0x1FF -#define BL_128M 0x3FF -#define BL_256M 0x7FF - -/* BAT Access Protection */ -#define BPP_XX 0x00 /* No access */ -#define BPP_RX 0x01 /* Read only */ -#define BPP_RW 0x02 /* Read/write */ - -/* - * Simulated two-level MMU. This structure is used by the kernel - * to keep track of MMU mappings and is used to update/maintain - * the hardware HASH table which is really a cache of mappings. - * - * The simulated structures mimic the hardware available on other - * platforms, notably the 80x86 and 680x0. - */ - -typedef struct _pte - { - unsigned long page_num:20; - unsigned long unused:6; - unsigned long acc:3; /* Read/write/execute permissions */ - unsigned long r:1; /* Page has been referenced */ - unsigned long m:1; /* Page has been modified */ - unsigned long v:1; /* Entry is valid */ - } pte; - -#define ACC_Rxx 0x04 -#define ACC_xWx 0x02 -#define ACC_xxX 0x01 -#define ACC_RWX (ACC_Rxx|ACC_xWx|ACC_xxX) - -#define PD_SHIFT (10+12) /* Page directory */ -#define PD_MASK 0x02FF -#define PT_SHIFT (12) /* Page Table */ -#define PT_MASK 0x02FF -#define PG_SHIFT (12) /* Page Entry */ - - -/* MMU context */ - -typedef struct _MMU_context - { - SEGREG segs[16]; /* Segment registers */ - pte **pmap; /* Two-level page-map structure */ - } MMU_context; - -#if 0 -BAT ibat[4]; /* Instruction BAT images */ -BAT dbat[4]; /* Data BAT images */ -PTE *hash_table; /* Hardware hashed page table */ -int hash_table_size; -int hash_table_mask; -unsigned long sdr; /* Hardware image of SDR */ -#endif - -/* Used to set up SDR register */ -#define HASH_TABLE_SIZE_64K 0x00010000 -#define HASH_TABLE_SIZE_128K 0x00020000 -#define HASH_TABLE_SIZE_256K 0x00040000 -#define HASH_TABLE_SIZE_512K 0x00080000 -#define HASH_TABLE_SIZE_1M 0x00100000 -#define HASH_TABLE_SIZE_2M 0x00200000 -#define HASH_TABLE_SIZE_4M 0x00400000 -#define HASH_TABLE_MASK_64K 0x000 -#define HASH_TABLE_MASK_128K 0x001 -#define HASH_TABLE_MASK_256K 0x003 -#define HASH_TABLE_MASK_512K 0x007 -#define HASH_TABLE_MASK_1M 0x00F -#define HASH_TABLE_MASK_2M 0x01F -#define HASH_TABLE_MASK_4M 0x03F - -#define MMU_PAGE_SIZE 4096 - -#endif diff --git a/arch/ppc/kernel/newppcdefs.h b/arch/ppc/kernel/newppcdefs.h deleted file mode 100644 index 92aecca9dca7..000000000000 --- a/arch/ppc/kernel/newppcdefs.h +++ /dev/null @@ -1,114 +0,0 @@ -/* - * WARNING! This file is automatically generated - DO NOT EDIT! - */ -#define STATE 0 -#define COUNTER 4 -#define BLOCKED 16 -#define SIGNAL 12 -#define KERNEL_STACK_PAGE 88 -#define TSS 504 -#define KSP 0 -#define MMU_SEG0 8 -#define MMU_SEG1 12 -#define MMU_SEG2 16 -#define MMU_SEG3 20 -#define MMU_SEG4 24 -#define MMU_SEG5 28 -#define MMU_SEG6 32 -#define MMU_SEG7 36 -#define MMU_SEG8 40 -#define MMU_SEG9 44 -#define MMU_SEG10 48 -#define MMU_SEG11 52 -#define MMU_SEG12 56 -#define MMU_SEG13 60 -#define MMU_SEG14 64 -#define MMU_SEG15 68 -#define TSS_FPR0 72 -#define TSS_FPR1 80 -#define TSS_FPR2 88 -#define TSS_FPR3 96 -#define TSS_FPR4 104 -#define TSS_FPR5 112 -#define TSS_FPR6 120 -#define TSS_FPR7 128 -#define TSS_FPR8 136 -#define TSS_FPR9 144 -#define TSS_FPR10 152 -#define TSS_FPR11 160 -#define TSS_FPR12 168 -#define TSS_FPR13 176 -#define TSS_FPR14 184 -#define TSS_FPR15 192 -#define TSS_FPR16 200 -#define TSS_FPR17 208 -#define TSS_FPR18 216 -#define TSS_FPR19 224 -#define TSS_FPR20 232 -#define TSS_FPR21 240 -#define TSS_FPR22 248 -#define TSS_FPR23 256 -#define TSS_FPR24 264 -#define TSS_FPR25 272 -#define TSS_FPR26 280 -#define TSS_FPR27 288 -#define TSS_FPR28 296 -#define TSS_FPR29 304 -#define TSS_FPR30 312 -#define TSS_FPR31 320 -#define INT_FRAME_SIZE 384 -#define GPR0 56 -#define GPR1 60 -#define GPR2 64 -#define GPR3 68 -#define GPR4 72 -#define GPR5 76 -#define GPR6 80 -#define GPR7 84 -#define GPR8 88 -#define GPR9 92 -#define GPR10 96 -#define GPR11 100 -#define GPR12 104 -#define GPR13 108 -#define GPR14 112 -#define GPR15 116 -#define GPR16 120 -#define GPR17 124 -#define GPR18 128 -#define GPR19 132 -#define GPR20 136 -#define GPR21 140 -#define GPR22 144 -#define GPR23 148 -#define GPR24 152 -#define GPR25 156 -#define GPR26 160 -#define GPR27 164 -#define GPR28 168 -#define GPR29 172 -#define GPR30 176 -#define GPR31 180 -#define FPR0 256 -#define FPR1 264 -#define FPR2 272 -#define FPR3 280 -#define FPCSR 288 -#define _NIP 184 -#define _MSR 188 -#define _CTR 192 -#define _LINK 196 -#define _CCR 200 -#define _XER 208 -#define _DAR 212 -#define _DSISR 216 -#define _HASH1 220 -#define _HASH2 224 -#define _IMISS 228 -#define _DMISS 232 -#define _ICMP 236 -#define _DCMP 240 -#define ORIG_GPR3 244 -#define RESULT 248 -#define TRAP 296 -#define MARKER 300 diff --git a/arch/ppc/kernel/no_ramdisk.S b/arch/ppc/kernel/no_ramdisk.S deleted file mode 100644 index 849ac14c4277..000000000000 --- a/arch/ppc/kernel/no_ramdisk.S +++ /dev/null @@ -1,6 +0,0 @@ - .data - .globl builtin_ramdisk_image -builtin_ramdisk_image: - .globl builtin_ramdisk_size -builtin_ramdisk_size: .long 0 - diff --git a/arch/ppc/kernel/ppc_asm.tmpl b/arch/ppc/kernel/ppc_asm.tmpl index aece3d5f8c35..b6fa91a3c9b3 100644 --- a/arch/ppc/kernel/ppc_asm.tmpl +++ b/arch/ppc/kernel/ppc_asm.tmpl @@ -165,4 +165,4 @@ n: /* Missing instructions */ #define bdne bc 0,2, -#include "ppc_machine.h" +#include "asm/ppc_machine.h" diff --git a/arch/ppc/kernel/ppc_machine.h.isin.processor.h b/arch/ppc/kernel/ppc_machine.h.isin.processor.h deleted file mode 100644 index 60b1c63549a0..000000000000 --- a/arch/ppc/kernel/ppc_machine.h.isin.processor.h +++ /dev/null @@ -1,48 +0,0 @@ -/* - * PowerPC machine specifics - */ - -#ifndef _PPC_MACHINE_H_ -#define _PPC_MACHINE_H_ - -/* Bit encodings for Machine State Register (MSR) */ -#define MSR_POW (1<<18) /* Enable Power Management */ -#define MSR_TGPR (1<<17) /* TLB Update registers in use */ -#define MSR_ILE (1<<16) /* Interrupt Little-Endian enable */ -#define MSR_EE (1<<15) /* External Interrupt enable */ -#define MSR_PR (1<<14) /* Supervisor/User privilege */ -#define MSR_FP (1<<13) /* Floating Point enable */ -#define MSR_ME (1<<12) /* Machine Check enable */ -#define MSR_FE0 (1<<11) /* Floating Exception mode 0 */ -#define MSR_SE (1<<10) /* Single Step */ -#define MSR_BE (1<<9) /* Branch Trace */ -#define MSR_FE1 (1<<8) /* Floating Exception mode 1 */ -#define MSR_IP (1<<6) /* Exception prefix 0x000/0xFFF */ -#define MSR_IR (1<<5) /* Instruction MMU enable */ -#define MSR_DR (1<<4) /* Data MMU enable */ -#define MSR_RI (1<<1) /* Recoverable Exception */ -#define MSR_LE (1<<0) /* Little-Endian enable */ - -#define MSR_ MSR_FP|MSR_FE0|MSR_FE1|MSR_ME -#define MSR_USER MSR_|MSR_PR|MSR_EE|MSR_IR|MSR_DR - -/* Bit encodings for Hardware Implementation Register (HID0) */ -#define HID0_EMCP (1<<31) /* Enable Machine Check pin */ -#define HID0_EBA (1<<29) /* Enable Bus Address Parity */ -#define HID0_EBD (1<<28) /* Enable Bus Data Parity */ -#define HID0_SBCLK (1<<27) -#define HID0_EICE (1<<26) -#define HID0_ECLK (1<<25) -#define HID0_PAR (1<<24) -#define HID0_DOZE (1<<23) -#define HID0_NAP (1<<22) -#define HID0_SLEEP (1<<21) -#define HID0_DPM (1<<20) -#define HID0_ICE (1<<15) /* Instruction Cache Enable */ -#define HID0_DCE (1<<14) /* Data Cache Enable */ -#define HID0_ILOCK (1<<13) /* Instruction Cache Lock */ -#define HID0_DLOCK (1<<12) /* Data Cache Lock */ -#define HID0_ICFI (1<<11) /* Instruction Cache Flash Invalidate */ -#define HID0_DCI (1<<10) /* Data Cache Invalidate */ - -#endif diff --git a/arch/ppc/kernel/process.c b/arch/ppc/kernel/process.c index 0b85d43577df..11ddb7678c59 100644 --- a/arch/ppc/kernel/process.c +++ b/arch/ppc/kernel/process.c @@ -26,7 +26,7 @@ #include #include -#include "ppc_machine.h" +#include int dump_fpu() @@ -44,7 +44,6 @@ switch_to(struct task_struct *prev, struct task_struct *new) #if 0 printk("Task %x(%d) -> %x(%d)", current, current->pid, new, new->pid); printk(" - IP: %x, SR: %x, SP: %x\n", regs->nip, regs->msr, regs); - cnpause(); #endif new_tss = &new->tss; old_tss = ¤t->tss; @@ -105,7 +104,6 @@ void copy_thread(int nr, unsigned long clone_flags, unsigned long usp, struct pt_regs * childregs; #if 0 printk("copy thread - NR: %d, Flags: %x, USP: %x, Task: %x, Regs: %x\n", nr, clone_flags, usp, p, regs); -cnpause(); #endif /* Construct segment registers */ segs = p->tss.segs; @@ -120,7 +118,6 @@ cnpause(); p->mm->context = (nr<<4); #if 0 printk("Setting MM[%x] Context = %x Task = %x Current = %x/%x\n", p->mm, p->mm->context, p, current, current->mm); -cnpause(); #endif } /* Last 8 are shared with kernel & everybody else... */ @@ -172,7 +169,6 @@ void start_thread(struct pt_regs * regs, unsigned long eip, unsigned long esp) printk("Start thread [%x] at PC: %x, SR: %x, SP: %x\n", regs, eip, regs->msr, esp); dump_buf(esp, len); dump_buf(eip, 0x80); - cnpause(); } #endif } @@ -243,7 +239,7 @@ print_backtrace(unsigned long *sp) { printk("\n"); } - if (cnt > 16) break; + if (cnt > 32) break; } printk("\n"); } diff --git a/arch/ppc/kernel/ramdisk_drvr.c b/arch/ppc/kernel/ramdisk_drvr.c deleted file mode 100644 index 6eaa5d9f3b86..000000000000 --- a/arch/ppc/kernel/ramdisk_drvr.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * linux/kernel/blk_drv/ramdisk.c - * - * Written by Theodore Ts'o, 12/2/91 - * - * Modifications by Fred N. van Kempen to allow for bootable root - * disks (which are used in LINUX/Pro). Also some cleanups. 03/03/93 - */ - - -#include -#include -#include -#include -#include -#include -#include - -#include -#include - -#define MAJOR_NR MEM_MAJOR -#include - -#define RAMDISK_MINOR 1 - -char *rd_start; -int rd_length = 0; -static int rd_blocksizes[2] = {0, 0}; - -static void rd_request(void) -{ - int len; - char *addr; - -repeat: - INIT_REQUEST; - addr = rd_start + (CURRENT->sector << 9); - len = CURRENT->current_nr_sectors << 9; - - if (CURRENT-> cmd == WRITE) { - (void ) memcpy(addr, - CURRENT->buffer, - len); - } else if (CURRENT->cmd == READ) { - (void) memcpy(CURRENT->buffer, - addr, - len); - } else - panic("RAMDISK: unknown RAM disk command !\n"); - end_request(1); - goto repeat; -} - -static struct file_operations rd_fops = { - NULL, /* lseek - default */ - block_read, /* read - general block-dev read */ - block_write, /* write - general block-dev write */ - NULL, /* readdir - bad */ - NULL, /* select */ - NULL, /* ioctl */ - NULL, /* mmap */ - NULL, /* no special open code */ - NULL, /* no special release code */ - block_fsync /* fsync */ -}; - -void -rd_preloaded_init(char *start, int length) -{ - int i; - - if (register_blkdev(MEM_MAJOR,"rd",&rd_fops)) { - printk("RAMDISK: Unable to get major %d.\n", MEM_MAJOR); - return 0; - } - blk_dev[MEM_MAJOR].request_fn = DEVICE_REQUEST; - rd_start = start; - rd_length = length; - for(i=0;i<2;i++) rd_blocksizes[i] = 1024; - blksize_size[MAJOR_NR] = rd_blocksizes; - /* We loaded the file system image. Prepare for mounting it. */ - ROOT_DEV = to_kdev_t((MEM_MAJOR << 8) | RAMDISK_MINOR); -} diff --git a/arch/ppc/kernel/setup.c b/arch/ppc/kernel/setup.c index 579c6f808282..6f330b052974 100644 --- a/arch/ppc/kernel/setup.c +++ b/arch/ppc/kernel/setup.c @@ -21,6 +21,7 @@ #include #include #include +#include #define SIO_CONFIG_RA 0x398 #define SIO_CONFIG_RD 0x399 @@ -35,26 +36,33 @@ char sda_root[] = "root=/dev/sda1"; extern int root_mountflags; unsigned char aux_device_present; +#ifdef CONFIG_BLK_DEV_RAM +extern int rd_doload; /* 1 = load ramdisk, 0 = don't load */ +extern int rd_prompt; /* 1 = prompt for ramdisk, 0 = don't prompt */ +extern int rd_image_start; /* starting block # of image */ +#endif /* * The format of "screen_info" is strange, and due to early * i386-setup code. This is just enough to make the console * code think we're on a EGA+ colour display. */ + /* this is changed only in minor ways from the original + -- Cort + */ struct screen_info screen_info = { - 0, 0, /* orig-x, orig-y */ - 0, 0, /* unused */ + 0, 25, /* orig-x, orig-y */ + { 0, 0 }, /* unused */ 0, /* orig-video-page */ 0, /* orig-video-mode */ 80, /* orig-video-cols */ - 0, /* unused [short] */ - 0, /* ega_bx */ - 0, /* unused [short] */ + 0,0,0, /* ega_ax, ega_bx, ega_cx */ 25, /* orig-video-lines */ - 0, /* isVGA */ - 16 /* video points */ + 1, /* orig-video-isVGA */ + 16 /* orig-video-points */ }; + unsigned long bios32_init(unsigned long memory_start, unsigned long memory_end) { return memory_start; @@ -64,8 +72,9 @@ unsigned long find_end_of_memory(void) { unsigned char dram_size = inb(0x0804); unsigned long total; -_printk("DRAM Size = %x\n", dram_size); -_printk("Config registers = %x/%x/%x/%x\n", inb(0x0800), inb(0x0801), inb(0x0802), inb(0x0803)); + extern BAT BAT2; +printk("DRAM Size = %x\n", dram_size); +printk("Config registers = %x/%x/%x/%x\n", inb(0x0800), inb(0x0801), inb(0x0802), inb(0x0803)); switch (dram_size & 0x07) { case 0: @@ -132,6 +141,16 @@ _printk("Config registers = %x/%x/%x/%x\n", inb(0x0800), inb(0x0801), inb(0x0802 Hash_size = HASH_TABLE_SIZE_128K; Hash_mask = HASH_TABLE_MASK_128K; } + switch(total) + { + case 0x01000000: +/* BAT2[0][1] = BL_16M;*/ + break; + default: + printk("WARNING: setup.c: find_end_of_memory() unknown total ram size %x\n", total); + break; + } + Hash = (PTE *)((total-Hash_size)+KERNELBASE); bzero(Hash, Hash_size); return ((unsigned long)Hash); @@ -156,18 +175,32 @@ void setup_arch(char **cmdline_p, outb(reg, SIO_CONFIG_RD); outb(reg, SIO_CONFIG_RD); /* Have to write twice to change! */ ROOT_DEV = to_kdev_t(DEFAULT_ROOT_DEVICE); + /*ROOT_DEV = MKDEV(UNNAMED_MAJOR, 255);*/ /* nfs */ aux_device_present = 0xaa; + /*nfsaddrs=myip:serverip:gateip:netmaskip:clientname*/ + strcpy(cmd_line, + "nfsaddrs=129.138.6.13:129.138.6.90:129.138.6.1:255.255.255.0:pandora"); + /* strcpy(cmd_line,"root=/dev/sda1");*/ *cmdline_p = cmd_line; *memory_start_p = (unsigned long) &_end; *memory_end_p = (unsigned long *)end_of_DRAM; size_memory = *memory_end_p - KERNELBASE; /* Relative size of memory */ + +#ifdef CONFIG_BLK_DEV_RAM + rd_image_start = RAMDISK_FLAGS & RAMDISK_IMAGE_START_MASK; + rd_prompt = ((RAMDISK_FLAGS & RAMDISK_PROMPT_FLAG) != 0); + rd_doload = ((RAMDISK_FLAGS & RAMDISK_LOAD_FLAG) != 0); + rd_prompt = 0; + rd_doload = 0; + rd_image_start = 0; +#endif } asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int on) { return -EIO; } - +#if 0 extern char builtin_ramdisk_image; extern long builtin_ramdisk_size; @@ -182,7 +215,7 @@ builtin_ramdisk_init(void) root_mountflags |= MS_RDONLY; } } - +#endif #define MAJOR(n) (((n)&0xFF00)>>8) #define MINOR(n) ((n)&0x00FF) diff --git a/arch/ppc/kernel/signal.c b/arch/ppc/kernel/signal.c index 0869208d499a..18a0a10d98e7 100644 --- a/arch/ppc/kernel/signal.c +++ b/arch/ppc/kernel/signal.c @@ -30,7 +30,7 @@ asmlinkage int sys_sigsuspend(unsigned long set, int p2, int p3, int p4, int p6, mask = current->blocked; current->blocked = set & _BLOCKABLE; regs->gpr[3] = -EINTR; -#if 0 +#if 0 printk("Task: %x[%d] - SIGSUSPEND at %x, Mask: %x\n", current, current->pid, regs->nip, set); #endif while (1) { @@ -107,7 +107,6 @@ asmlinkage int do_signal(unsigned long oldmask, struct pt_regs * regs) struct sigcontext_struct *sc; struct sigaction * sa; int s = _disable_interrupts(); - while ((signr = current->signal & mask)) { #if 0 signr = ffz(~signr); /* Compute bit # */ diff --git a/arch/ppc/kernel/stubs.c b/arch/ppc/kernel/stubs.c index acdd87e2eb6d..b7af6dd44ef1 100644 --- a/arch/ppc/kernel/stubs.c +++ b/arch/ppc/kernel/stubs.c @@ -9,20 +9,20 @@ void sys_newselect(void) {_panic("sys_newselect"); } halt() { - _printk("\n...Halt!\n"); + printk("\n...Halt!\n"); abort(); } _panic(char *msg) { - _printk("Panic: %s\n", msg); + printk("Panic: %s\n", msg); printk("Panic: %s\n", msg); abort(); } _warn(char *msg) { - _printk("*** Warning: %s UNIMPLEMENTED!\n", msg); + printk("*** Warning: %s UNIMPLEMENTED!\n", msg); } diff --git a/arch/ppc/kernel/test.S b/arch/ppc/kernel/test.S deleted file mode 100644 index ea7f31a83646..000000000000 --- a/arch/ppc/kernel/test.S +++ /dev/null @@ -1,100 +0,0 @@ -#include "ppc_asm.tmpl" -#include "ppc_defs.h" - -#define SYNC() \ - isync; \ - sync - -#define BEEF ori r0,r0,0; ori r0,r0,0 ;.word 0 ; .word 0xBEEF -_BEG: - lis r7,0xF000 /* To mask upper 4 bits */ - - -/* Initialize BAT registers */ - lis r3,OFF_BAT@h - ori r3,r3,OFF_BAT@l - andc r3,r3,r7 /* make unmapped address */ - lwz r0,0(r3) - - mtspr IBAT0U,r0 - mtspr DBAT0U,r0 - lwz r0,4(r3) - mtspr IBAT0L,r0 - mtspr DBAT0L,r0 - - lis r3,OFF_BAT@h - ori r3,r3,OFF_BAT@l - andc r3,r3,r7 /* make unmapped address */ - lwz r0,0(r3) - mtspr IBAT1U,r0 - mtspr DBAT1U,r0 - lwz r0,4(r3) - mtspr IBAT1L,r0 - mtspr DBAT1L,r0 - - lis r3,ZERO_BAT@h - ori r3,r3,ZERO_BAT@l - andc r3,r3,r7 /* make unmapped address */ - lwz r0,0(r3) - mtspr IBAT2U,r0 - mtspr DBAT2U,r0 - lwz r0,4(r3) - mtspr IBAT2L,r0 - mtspr DBAT2L,r0 - - - lis r3,TMP_BAT2@h - ori r3,r3,TMP_BAT2@l - andc r3,r3,r7 /* make unmapped address */ - lwz r0,0(r3) - mtspr IBAT3U,r0 - mtspr DBAT3U,r0 - lwz r0,4(r3) - mtspr IBAT3L,r0 - mtspr DBAT3L,r0 - - -/* Now we can turn on the MMU */ -/* set srr1 for rfi */ - mfmsr r3 - ori r3,r3,MSR_DR|MSR_IR|MSR_ - - mtspr SRR1,r3 - -/* set srr0 for rfi */ - subf r2, r2, r2 -/* lis r2,10f@h*/ - lis r2,0 - ori r2,r2,10f@l - mtspr SRR0,r2 - - SYNC() - rfi - - ori r0, r0, 0 - ori r0, r0, 0 -10: ori r0, r0, 0 - ori r0, r0, 0 - BEEF - -#if 0 -/* check bptr to see if it actually has the correct values */ - - subf r2,r2,r2 - lis r2,bptr@h - ori r2,r2,bptr@l - lwz r0,0(r2) - -/* rfi to the beef */ - mtspr SRR1,r3 - mtspr SRR0,r2 - - SYNC() - rfi - -bptr: ori r0, r0, 0 - BEEF - BEEF - BEEF -#endif -_END: diff --git a/arch/ppc/kernel/test1.c b/arch/ppc/kernel/test1.c deleted file mode 100644 index 00bd753e0828..000000000000 --- a/arch/ppc/kernel/test1.c +++ /dev/null @@ -1,145 +0,0 @@ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include - -/*pgd_t *swapper_pg_dir;*/ - - - -BAT BAT0 = - { - { - 0x80000000>>17, /* bepi */ - BL_256M, /* bl */ - 1, /* vs */ - 1, /* vp */ - }, - { - 0x80000000>>17, /* brpn */ - 1, /* w */ - 1, /* i (cache disabled) */ - 0, /* m */ - 0, /* g */ - BPP_RW /* pp */ - } - }; -BAT BAT1 = - { - { - 0xC0000000>>17, /* bepi */ - BL_256M, /* bl */ - 1, /* vs */ - 1, /* vp */ - }, - { - 0xC0000000>>17, /* brpn */ - 1, /* w */ - 1, /* i (cache disabled) */ - 0, /* m */ - 0, /* g */ - BPP_RW /* pp */ - } - }; -BAT BAT2 = - { - { - 0x00000000>>17, /* bepi */ - BL_256M, /* bl */ - 0, /* vs */ - 0, /* vp */ - }, - { - 0x00000000>>17, /* brpn */ - 1, /* w */ - 1, /* i (cache disabled) */ - 0, /* m */ - 0, /* g */ - BPP_RW /* pp */ - } - }; -BAT BAT3 = - { - { - 0x00000000>>17, /* bepi */ - BL_256M, /* bl */ - 0, /* vs */ - 0, /* vp */ - }, - { - 0x00000000>>17, /* brpn */ - 1, /* w */ - 1, /* i (cache disabled) */ - 0, /* m */ - 0, /* g */ - BPP_RW /* pp */ - } - }; - - -BAT TMP_BAT2 = - { /* 0x9XXXXXXX -> 0x0XXXXXXX */ - { - 0x90000000>>17, /* bepi */ - BL_256M, /* bl */ - 1, /* vs */ - 1, /* vp */ - }, - { - 0x00000000>>17, /* brpn */ - 1, /* w */ - 0, /* i (cache enabled) */ - 0, /* m */ - 0, /* g */ - BPP_RW /* pp */ - } - }; - - - -BAT ZERO_BAT = - { /* 0x0XXXXXXX -> 0x0XXXXXXX */ - { - 0x00000000>>17, /* bepi */ - BL_256M, /* bl */ - 1, /* vs */ - 1, /* vp */ - }, - { - 0x00000000>>17, /* brpn */ - 1, /* w */ - 0, /* i (cache enabled) */ - 0, /* m */ - 0, /* g */ - BPP_RW /* pp */ - } - }; - - -BAT OFF_BAT = - { /* 0x0XXXXXXX -> 0x0XXXXXXX */ - { - 0x00000000>>17, /* bepi */ - BL_256M, /* bl */ - 0, /* vs */ - 0, /* vp */ - }, - { - 0x00000000>>17, /* brpn */ - 1, /* w */ - 0, /* i (cache enabled) */ - 0, /* m */ - 0, /* g */ - BPP_RW /* pp */ - } - }; diff --git a/arch/ppc/kernel/traps.c b/arch/ppc/kernel/traps.c index c602301348e1..e9f5e8e5b2be 100644 --- a/arch/ppc/kernel/traps.c +++ b/arch/ppc/kernel/traps.c @@ -26,7 +26,7 @@ #include #include -#include "ppc_machine.h" +#include /* * Trap & Exception support @@ -40,7 +40,7 @@ trap_init(void) void _exception(int signr, struct pt_regs *regs) { - dump_regs(regs); +/* dump_regs(regs);*/ force_sig(signr, current); if (!user_mode(regs)) { @@ -51,13 +51,13 @@ _exception(int signr, struct pt_regs *regs) MachineCheckException(struct pt_regs *regs) { - printk("Machine check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr); +/* printk("Machine check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/ _exception(SIGSEGV, regs); } ProgramCheckException(struct pt_regs *regs) { - printk("Program check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr); +/* printk("Program check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/ if (current->flags & PF_PTRACED) { _exception(SIGTRAP, regs); @@ -69,30 +69,29 @@ ProgramCheckException(struct pt_regs *regs) SingleStepException(struct pt_regs *regs) { - printk("Single step at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr); +/* printk("Single step at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/ regs->msr &= ~MSR_SE; /* Turn off 'trace' bit */ _exception(SIGTRAP, regs); } FloatingPointCheckException(struct pt_regs *regs) { - printk("Floating point check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr); +/* printk("Floating point check at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/ _exception(SIGFPE, regs); } AlignmentException(struct pt_regs *regs) { - printk("Alignment error at PC: %x, SR: %x\n", regs->nip, regs->msr); +/* printk("Alignment error at PC: %x, SR: %x\n", regs->nip, regs->msr); dump_regs(regs); - cnpause(); - printk("Alignment error at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr); + printk("Alignment error at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr);*/ _exception(SIGBUS, regs); } bad_stack(struct pt_regs *regs) { - printk("Kernel stack overflow at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr); - dump_regs(regs); +/* printk("Kernel stack overflow at PC: %x[%x], SR: %x\n", regs->nip, va_to_phys(regs->nip), regs->msr); + dump_regs(regs);*/ while (1) ; } @@ -130,7 +129,6 @@ trace_syscall(struct pt_regs *regs) if (++count == 20) { count = 0; - cnpause(); } } diff --git a/arch/ppc/mm/fault.c b/arch/ppc/mm/fault.c index b8216ea8504a..ff7e0b9a8ed2 100644 --- a/arch/ppc/mm/fault.c +++ b/arch/ppc/mm/fault.c @@ -23,107 +23,123 @@ extern void die_if_kernel(char *, struct pt_regs *, long); extern void do_page_fault(struct pt_regs *, unsigned long, unsigned long); -#define SHOW_FAULTS -#undef SHOW_FAULTS -#define PAUSE_AFTER_FAULT -#undef PAUSE_AFTER_FAULT +#undef SHOW_FAULTS +#undef NOISY_INSTRFAULT +#undef NOISY_DATAFAULT + +#define NEWMM 1 void DataAccessException(struct pt_regs *regs) { - pgd_t *dir; - pmd_t *pmd; - pte_t *pte; - int tries, mode = 0; - if (user_mode(regs)) mode |= 0x04; - if (regs->dsisr & 0x02000000) mode |= 0x02; /* Load/store */ - if (regs->dsisr & 0x08000000) mode |= 0x01; /* Protection violation */ -#ifdef SHOW_FAULTS - printk("Data Access Fault - Loc: %x, DSISR: %x, PC: %x\n", regs->dar, regs->dsisr, regs->nip); -#ifdef PAUSE_AFTER_FAULT -cnpause(); -#endif + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + int tries, mode = 0; + +#ifdef NOISY_DATAFAULT + printk("Data fault on %x\n",regs->dar); #endif - if (mode & 0x01) - { -#ifdef SHOW_FAULTS -printk("Write Protect Fault - Loc: %x, DSISR: %x, PC: %x\n", regs->dar, regs->dsisr, regs->nip); + + if (user_mode(regs)) mode |= 0x04; + if (regs->dsisr & 0x02000000) mode |= 0x02; /* Load/store */ + if (regs->dsisr & 0x08000000) mode |= 0x01; /* Protection violation */ + if (mode & 0x01) + { +#ifdef NOISY_DATAFAULT + printk("Write Protect fault\n "); #endif - do_page_fault(regs, regs->dar, mode); - return; - } - for (tries = 0; tries < 1; tries++) + do_page_fault(regs, regs->dar, mode); +#ifdef NOISY_DATAFAULT + printk("Write Protect fault handled\n"); +#endif + return; + } + + + for (tries = 0; tries < 1; tries++) + { + dir = pgd_offset(current->mm, regs->dar & PAGE_MASK); + if (dir) + { + pmd = pmd_offset(dir, regs->dar & PAGE_MASK); + if (pmd && pmd_present(*pmd)) + { + pte = pte_offset(pmd, regs->dar & PAGE_MASK); + if (pte && pte_present(*pte)) { - dir = pgd_offset(current->mm, regs->dar & PAGE_MASK); - if (dir) - { - pmd = pmd_offset(dir, regs->dar & PAGE_MASK); - if (pmd && pmd_present(*pmd)) - { - pte = pte_offset(pmd, regs->dar & PAGE_MASK); - if (pte && pte_present(*pte)) - { -#ifdef SHOW_FAULTS - printk("Page mapped - PTE: %x[%x], Context: %x\n", pte, *(long *)pte, current->mm->context); -#endif - MMU_hash_page(¤t->tss, regs->dar & PAGE_MASK, pte); - return; - } - } - } else - { - printk("No PGD\n"); - } - do_page_fault(regs, regs->dar, mode); +#if NOISY_DATAFAULT + printk("Page mapped - PTE: %x[%x]\n", pte, *(long *)pte); +#endif + MMU_hash_page(¤t->tss, regs->dar & PAGE_MASK, pte); + /*MMU_hash_page2(current->mm, regs->dar & PAGE_MASK, pte);*/ + return; } + } + } else + { +#if NOISY_DATAFAULT + printk("No PGD\n"); +#endif + } + do_page_fault(regs, regs->dar, mode); + } } void InstructionAccessException(struct pt_regs *regs) { - pgd_t *dir; - pmd_t *pmd; - pte_t *pte; - int tries, mode = 0; - unsigned long addr = regs->nip; - if (user_mode(regs)) mode |= 0x04; -#ifdef SHOW_FAULTS - printk("Instruction Access Fault - Loc: %x, DSISR: %x, PC: %x\n", regs->dar, regs->dsisr, regs->nip); -#ifdef PAUSE_AFTER_FAULT -cnpause(); + pgd_t *dir; + pmd_t *pmd; + pte_t *pte; + int tries, mode = 0; + +#if NOISY_INSTRFAULT + printk("Instr fault on %x\n",regs->dar); #endif -#endif - if (mode & 0x01) - { - do_page_fault(regs, addr, mode); - return; - } - for (tries = 0; tries < 1; tries++) - { - dir = pgd_offset(current->mm, addr & PAGE_MASK); - if (dir) - { - pmd = pmd_offset(dir, addr & PAGE_MASK); - if (pmd && pmd_present(*pmd)) - { - pte = pte_offset(pmd, addr & PAGE_MASK); - if (pte && pte_present(*pte)) - { -#ifdef SHOW_FAULTS - printk("Page mapped - PTE: %x[%x], Context: %x\n", pte, *(long *)pte, current->mm->context); -#endif - MMU_hash_page(¤t->tss, addr & PAGE_MASK, pte); - return; - } - } - } else - { - printk("No PGD\n"); - } - do_page_fault(regs, addr, mode); - } + +#ifdef NEWMM + if (!user_mode(regs)) + { + + panic("InstructionAcessException in kernel mode. PC %x addr %x", + regs->nip, regs->dar); + } +#endif + if (user_mode(regs)) mode |= 0x04; + if (regs->dsisr & 0x02000000) mode |= 0x02; /* Load/store */ + if (regs->dsisr & 0x08000000) mode |= 0x01; /* Protection violation */ + + if (mode & 0x01) + { + do_page_fault(regs, regs->dar, mode); + return; + } + for (tries = 0; tries < 1; tries++) + { + dir = pgd_offset(current->mm, regs->dar & PAGE_MASK); + if (dir) + { + pmd = pmd_offset(dir, regs->dar & PAGE_MASK); + if (pmd && pmd_present(*pmd)) + { + pte = pte_offset(pmd, regs->dar & PAGE_MASK); + if (pte && pte_present(*pte)) + { + + MMU_hash_page(¤t->tss, regs->dar & PAGE_MASK, pte); + /* MMU_hash_page2(current->mm, regs->dar & PAGE_MASK, pte);*/ + return; + } + } + } else + { + } + do_page_fault(regs, regs->dar, mode); + } } + /* * This routine handles page faults. It determines the address, * and the problem, and then passes it off to one of the appropriate @@ -137,103 +153,66 @@ cnpause(); */ void do_page_fault(struct pt_regs *regs, unsigned long address, unsigned long error_code) { - struct vm_area_struct * vma; - unsigned long page; + struct vm_area_struct * vma; + unsigned long page; - for (vma = current->mm->mmap ; ; vma = vma->vm_next) - { -#ifdef SHOW_FAULTS -printk("VMA(%x) - Start: %x, End: %x, Flags: %x\n", vma, vma->vm_start, vma->vm_end, vma->vm_flags); -#endif - if (!vma) - goto bad_area; - if (vma->vm_end > address) - break; - } - if (vma->vm_start <= address) - goto good_area; - if (!(vma->vm_flags & VM_GROWSDOWN)) - goto bad_area; - if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur) - goto bad_area; - vma->vm_offset -= vma->vm_start - (address & PAGE_MASK); - vma->vm_start = (address & PAGE_MASK); -/* - * Ok, we have a good vm_area for this memory access, so - * we can handle it.. - */ -good_area: - /* - * was it a write? - */ - if (error_code & 2) { - if (!(vma->vm_flags & VM_WRITE)) - goto bad_area; - } else { - /* read with protection fault? */ - if (error_code & 1) - goto bad_area; - if (!(vma->vm_flags & (VM_READ | VM_EXEC))) - goto bad_area; - } - handle_mm_fault(vma, address, error_code & 2); - flush_page(address); /* Flush & Invalidate cache - note: address is OK now */ - return; + vma = find_vma(current, address); + if (!vma) + { + goto bad_area; + } -/* - * Something tried to access memory that isn't in our memory map.. - * Fix it, but check if it's kernel or user first.. - */ + if (vma->vm_start <= address){ + goto good_area; + } + if (!(vma->vm_flags & VM_GROWSDOWN)) + { + goto bad_area; + } + if (vma->vm_end - address > current->rlim[RLIMIT_STACK].rlim_cur) + { + goto bad_area; + } + vma->vm_offset -= vma->vm_start - (address & PAGE_MASK); + + vma->vm_start = (address & PAGE_MASK); + +good_area: + /* a write */ + if (error_code & 2) { + if (!(vma->vm_flags & VM_WRITE)) + { + goto bad_area; + } + /* a read */ + } else { + /* protection fault */ + if (error_code & 1) + { + goto bad_area; + } + if (!(vma->vm_flags & (VM_READ | VM_EXEC))) + { + goto bad_area; + } + } + handle_mm_fault(vma, address, error_code & 2); + flush_page(address); /* Flush & Invalidate cache - note: address is OK now */ + return; + bad_area: -printk("Task: %x, PC: %x/%x, bad area! - Addr: %x\n", current, regs->nip, current->tss.last_pc, address); -print_user_backtrace(current->tss.user_stack); -print_kernel_backtrace(); -#if 0 -cnpause(); -if (!user_mode(regs)) -{ - print_backtrace(regs->gpr[1]); -} -#endif -dump_regs(regs); - if (user_mode(regs)) { -#if 0 - current->tss.cp0_badvaddr = address; - current->tss.error_code = error_code; - current->tss.trap_no = 14; -#endif - force_sig(SIGSEGV, current); - return; - } -printk("KERNEL! Task: %x, PC: %x, bad area! - Addr: %x, PGDIR: %x\n", current, regs->nip, address, current->tss.pg_tables); -dump_regs(regs); -while (1) ; -#if 0 - /* - * Oops. The kernel tried to access some bad page. We'll have to - * terminate things with extreme prejudice. - */ - if ((unsigned long) (address-TASK_SIZE) < PAGE_SIZE) { - printk(KERN_ALERT "Unable to handle kernel NULL pointer dereference"); - pg0[0] = pte_val(mk_pte(0, PAGE_SHARED)); - } else - printk(KERN_ALERT "Unable to handle kernel paging request"); - printk(" at virtual address %08lx\n",address); - page = current->tss.pg_dir; - printk(KERN_ALERT "current->tss.pg_dir = %08lx\n", page); - page = ((unsigned long *) page)[address >> PGDIR_SHIFT]; - printk(KERN_ALERT "*pde = %08lx\n", page); - if (page & 1) { - page &= PAGE_MASK; - address &= 0x003ff000; - page = ((unsigned long *) page)[address >> PAGE_SHIFT]; - printk(KERN_ALERT "*pte = %08lx\n", page); - } - die_if_kernel("Oops", regs, error_code); -#endif - do_exit(SIGKILL); + if (user_mode(regs)) + { +/* printk("Bad User Area: Addr %x PC %x Task %x pid %d %s\n", + address,regs->nip, current,current->pid,current->comm);*/ + send_sig(SIGSEGV, current, 1); + return; + } + panic("KERNEL access of bad area PC %x address %x vm_flags %x\n", + regs->nip,address,vma->vm_flags); } + va_to_phys(unsigned long address) { pgd_t *dir; @@ -261,6 +240,7 @@ va_to_phys(unsigned long address) return (0); } + /* * See if an address should be valid in the current context. */ diff --git a/arch/ppc/mm/init.c b/arch/ppc/mm/init.c index bafb0f28851f..81b8ab947cd2 100644 --- a/arch/ppc/mm/init.c +++ b/arch/ppc/mm/init.c @@ -47,50 +47,11 @@ extern void show_net_buffers(void); pte_t * __bad_pagetable(void) { panic("__bad_pagetable"); -#if 0 - extern char empty_bad_page_table[PAGE_SIZE]; - unsigned long dummy; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - "1:\tsw\t%2,(%0)\n\t" - "subu\t%1,%1,1\n\t" - "bne\t$0,%1,1b\n\t" - "addiu\t%0,%0,1\n\t" - ".set\treorder" - :"=r" (dummy), - "=r" (dummy) - :"r" (pte_val(BAD_PAGE)), - "0" ((long) empty_bad_page_table), - "1" (PTRS_PER_PAGE)); - - return (pte_t *) empty_bad_page_table; -#endif } - pte_t __bad_page(void) { panic("__bad_page"); -#if 0 - extern char empty_bad_page[PAGE_SIZE]; - unsigned long dummy; - - __asm__ __volatile__( - ".set\tnoreorder\n\t" - "1:\tsw\t$0,(%0)\n\t" - "subu\t%1,%1,1\n\t" - "bne\t$0,%1,1b\n\t" - "addiu\t%0,%0,1\n\t" - ".set\treorder" - :"=r" (dummy), - "=r" (dummy) - :"0" ((long) empty_bad_page), - "1" (PTRS_PER_PAGE)); - - return pte_mkdirty(mk_pte((unsigned long) empty_bad_page, PAGE_SHARED)); -#endif } - unsigned long __zero_page(void) { extern char empty_zero_page[PAGE_SIZE]; @@ -106,7 +67,8 @@ void show_mem(void) printk("Mem-info:\n"); show_free_areas(); printk("Free swap: %6dkB\n",nr_swap_pages<<(PAGE_SHIFT-10)); - i = high_memory >> PAGE_SHIFT; + /*i = high_memory >> PAGE_SHIFT;*/ + i = MAP_NR(high_memory); while (i-- > 0) { total++; if (PageReserved(mem_map+i)) @@ -137,39 +99,6 @@ extern unsigned long free_area_init(unsigned long, unsigned long); */ unsigned long paging_init(unsigned long start_mem, unsigned long end_mem) { -#if 0 - pgd_t * pg_dir; - pte_t * pg_table; - unsigned long tmp; - unsigned long address; - - start_mem = PAGE_ALIGN(start_mem); - address = 0; - pg_dir = swapper_pg_dir; - while (address < end_mem) { - if (pgd_none(pg_dir[0])) { - pgd_set(pg_dir, (pte_t *) start_mem); - start_mem += PAGE_SIZE; - } - /* - * also map it in at 0x00000000 for init - */ - pg_table = (pte_t *) pgd_page(pg_dir[0]); - pgd_set(pg_dir, pg_table); - pg_dir++; - for (tmp = 0 ; tmp < PTRS_PER_PAGE ; tmp++,pg_table++) { - if (address < end_mem) - *pg_table = mk_pte(address, PAGE_SHARED); - else - pte_clear(pg_table); - address += PAGE_SIZE; - } - } -#if KERNELBASE == KSEG0 - cacheflush(); -#endif - invalidate(); -#endif return free_area_init(start_mem, end_mem); } @@ -186,9 +115,6 @@ void mem_init(unsigned long start_mem, unsigned long end_mem) /* mark usable pages in the mem_map[] */ start_mem = PAGE_ALIGN(start_mem); -#if 0 -_printk("Mem init - Start: %x, End: %x\n", start_mem, high_memory); -#endif for (tmp = KERNELBASE ; tmp < high_memory ; tmp += PAGE_SIZE) { if (tmp < start_mem) @@ -239,28 +165,21 @@ void si_meminfo(struct sysinfo *val) return; } -/* Kernel MMU setup & lowest level hardware support */ - -/* Hardwired MMU segments */ - -/* Segment 0x8XXXXXXX, 0xCXXXXXXX always mapped (for I/O) */ -/* Segment 0x9XXXXXXX mapped during init */ - BAT BAT0 = { { 0x80000000>>17, /* bepi */ BL_256M, /* bl */ - 1, /* vs */ - 1, /* vp */ + 1, /* vs -- supervisor mode valid */ + 1, /* vp -- user mode valid */ }, { 0x80000000>>17, /* brpn */ - 1, /* w */ - 1, /* i (cache disabled) */ - 0, /* m */ - 1, /* g */ - BPP_RW /* pp */ + 1, /* write-through */ + 1, /* cache-inhibited */ + 0, /* memory coherence */ + 1, /* guarded */ + BPP_RW /* protection */ } }; BAT BAT1 = @@ -283,15 +202,15 @@ BAT BAT1 = BAT BAT2 = { { - 0x00000000>>17, /* bepi */ - BL_256M, /* bl */ - 0, /* vs */ + 0x90000000>>17, /* bepi */ + BL_16M, /* this should be set to amount of phys ram */ + 1, /* vs */ 0, /* vp */ }, { 0x00000000>>17, /* brpn */ - 1, /* w */ - 1, /* i (cache disabled) */ + 0, /* w */ + 0, /* i */ 0, /* m */ 0, /* g */ BPP_RW /* pp */ @@ -318,13 +237,13 @@ BAT TMP_BAT2 = { /* 0x9XXXXXXX -> 0x0XXXXXXX */ { 0x90000000>>17, /* bepi */ - BL_16M, /* bl */ + BL_256M, /* bl */ 1, /* vs */ 1, /* vp */ }, { 0x00000000>>17, /* brpn */ - 0, /* w */ + 1, /* w */ 0, /* i (cache enabled) */ 0, /* m */ 0, /* g */ @@ -406,9 +325,9 @@ MMU_init() { int i, p; SEGREG *segs; - _printk("MMU init - started\n"); + printk("MMU init - started\n"); find_end_of_memory(); - _printk(" Start at 0x%08X, End at 0x%08X, Hash at 0x%08X\n", _start, _end, Hash); + printk(" Start at 0x%08X, End at 0x%08X, Hash at 0x%08X\n", _start, _end, Hash); _SDR1 = ((unsigned long)Hash & 0x00FFFFFF) | Hash_mask; p = (int)mmu_pages; p = (p + (MMU_PAGE_SIZE-1)) & ~(MMU_PAGE_SIZE-1); @@ -459,7 +378,7 @@ MMU_init() /* Clear all DRAM not explicitly used by kernel */ bzero(_end, (unsigned long)end_of_DRAM-(unsigned long)_end); #endif - _printk("MMU init - done!\n"); + printk("MMU init - done!\n"); } pte * @@ -470,7 +389,7 @@ MMU_get_page() { bzero((char *)pg, MMU_PAGE_SIZE); } - _printk("MMU Allocate Page at %08X\n", pg); + printk("MMU Allocate Page at %08X\n", pg); return(pg); } @@ -587,7 +506,6 @@ for (i = 0; i < 8; i++, _pte++) { printk(" V: %d, VSID: %05x, H: %d, RPN: %04x, R: %d, C: %d, PP: %x\n", _pte->v, _pte->vsid, _pte->h, _pte->rpn, _pte->r, _pte->c, _pte->pp); } -cnpause(); printk("Last mappings:\n"); for (i = 0; i < NUM_MAPPINGS; i++) { @@ -597,14 +515,13 @@ for (i = 0; i < NUM_MAPPINGS; i++) last_mappings[next_mapping].task); if (++next_mapping == NUM_MAPPINGS) next_mapping = 0; } -cnpause(); _panic("Hash table full!\n"); } slot = empty; } found_it: #if 0 -_printk("Map VA: %08X, Slot: %08X[%08X/%08X], H: %d\n", va, slot, slot0, slot1, h); +printk("Map VA: %08X, Slot: %08X[%08X/%08X], H: %d\n", va, slot, slot0, slot1, h); #endif _tlbie(va); /* Clear TLB */ if (pg) @@ -1007,7 +924,7 @@ _verify_addr(long va) hash &= 0x3FF | (Hash_mask << 10); hash *= 8; /* Eight entries / hash bucket */ _pte = &Hash[hash]; - dump_buf(_pte, 64); +/* dump_buf(_pte, 64);*/ for (i = 0; i < 8; i++, _pte++) { if (_pte->v && _pte->vsid == vsid && _pte->h == _h && _pte->api == api) @@ -1025,7 +942,6 @@ _verify_addr(long va) } } found_it: - cnpause(); } flush_cache_all() @@ -1039,3 +955,4 @@ flush_tlb_mm() {} flush_tlb_page() {} flush_tlb_range() {} flush_page_to_ram() {} + diff --git a/arch/ppc/mm/mmu.h b/arch/ppc/mm/mmu.h deleted file mode 100644 index b63ea0e6a1f5..000000000000 --- a/arch/ppc/mm/mmu.h +++ /dev/null @@ -1,160 +0,0 @@ -/* - * PowerPC memory management structures - */ - -#ifndef _PPC_MMU_H_ -#define _PPC_MMU_H_ - -/* Hardware Page Table Entry */ - -typedef struct _PTE - { - unsigned long v:1; /* Entry is valid */ - unsigned long vsid:24; /* Virtual segment identifier */ - unsigned long h:1; /* Hash algorithm indicator */ - unsigned long api:6; /* Abbreviated page index */ - unsigned long rpn:20; /* Real (physical) page number */ - unsigned long :3; /* Unused */ - unsigned long r:1; /* Referenced */ - unsigned long c:1; /* Changed */ - unsigned long w:1; /* Write-thru cache mode */ - unsigned long i:1; /* Cache inhibited */ - unsigned long m:1; /* Memory coherence */ - unsigned long g:1; /* Guarded */ - unsigned long :1; /* Unused */ - unsigned long pp:2; /* Page protection */ - } PTE; - -/* Values for PP (assumes Ks=0, Kp=1) */ -#define PP_RWXX 0 /* Supervisor read/write, User none */ -#define PP_RWRX 1 /* Supervisor read/write, User read */ -#define PP_RWRW 2 /* Supervisor read/write, User read/write */ -#define PP_RXRX 3 /* Supervisor read, User read */ - -/* Segment Register */ - -typedef struct _SEGREG - { - unsigned long t:1; /* Normal or I/O type */ - unsigned long ks:1; /* Supervisor 'key' (normally 0) */ - unsigned long kp:1; /* User 'key' (normally 1) */ - unsigned long n:1; /* No-execute */ - unsigned long :4; /* Unused */ - unsigned long vsid:24; /* Virtual Segment Identifier */ - } SEGREG; - -/* Block Address Translation (BAT) Registers */ - -typedef struct _BATU /* Upper part of BAT */ - { - unsigned long bepi:15; /* Effective page index (virtual address) */ - unsigned long :4; /* Unused */ - unsigned long bl:11; /* Block size mask */ - unsigned long vs:1; /* Supervisor valid */ - unsigned long vp:1; /* User valid */ - } BATU; - -typedef struct _BATL /* Lower part of BAT */ - { - unsigned long brpn:15; /* Real page index (physical address) */ - unsigned long :10; /* Unused */ - unsigned long w:1; /* Write-thru cache */ - unsigned long i:1; /* Cache inhibit */ - unsigned long m:1; /* Memory coherence */ - unsigned long g:1; /* Guarded (MBZ) */ - unsigned long :1; /* Unused */ - unsigned long pp:2; /* Page access protections */ - } BATL; - -typedef struct _BAT - { - BATU batu; /* Upper register */ - BATL batl; /* Lower register */ - } BAT; - -/* Block size masks */ -#define BL_128K 0x000 -#define BL_256K 0x001 -#define BL_512K 0x003 -#define BL_1M 0x007 -#define BL_2M 0x00F -#define BL_4M 0x01F -#define BL_8M 0x03F -#define BL_16M 0x07F -#define BL_32M 0x0FF -#define BL_64M 0x1FF -#define BL_128M 0x3FF -#define BL_256M 0x7FF - -/* BAT Access Protection */ -#define BPP_XX 0x00 /* No access */ -#define BPP_RX 0x01 /* Read only */ -#define BPP_RW 0x02 /* Read/write */ - -/* - * Simulated two-level MMU. This structure is used by the kernel - * to keep track of MMU mappings and is used to update/maintain - * the hardware HASH table which is really a cache of mappings. - * - * The simulated structures mimic the hardware available on other - * platforms, notably the 80x86 and 680x0. - */ - -typedef struct _pte - { - unsigned long page_num:20; - unsigned long unused:6; - unsigned long acc:3; /* Read/write/execute permissions */ - unsigned long r:1; /* Page has been referenced */ - unsigned long m:1; /* Page has been modified */ - unsigned long v:1; /* Entry is valid */ - } pte; - -#define ACC_Rxx 0x04 -#define ACC_xWx 0x02 -#define ACC_xxX 0x01 -#define ACC_RWX (ACC_Rxx|ACC_xWx|ACC_xxX) - -#define PD_SHIFT (10+12) /* Page directory */ -#define PD_MASK 0x02FF -#define PT_SHIFT (12) /* Page Table */ -#define PT_MASK 0x02FF -#define PG_SHIFT (12) /* Page Entry */ - - -/* MMU context */ - -typedef struct _MMU_context - { - SEGREG segs[16]; /* Segment registers */ - pte **pmap; /* Two-level page-map structure */ - } MMU_context; - -#if 0 -BAT ibat[4]; /* Instruction BAT images */ -BAT dbat[4]; /* Data BAT images */ -PTE *hash_table; /* Hardware hashed page table */ -int hash_table_size; -int hash_table_mask; -unsigned long sdr; /* Hardware image of SDR */ -#endif - -/* Used to set up SDR register */ -#define HASH_TABLE_SIZE_64K 0x00010000 -#define HASH_TABLE_SIZE_128K 0x00020000 -#define HASH_TABLE_SIZE_256K 0x00040000 -#define HASH_TABLE_SIZE_512K 0x00080000 -#define HASH_TABLE_SIZE_1M 0x00100000 -#define HASH_TABLE_SIZE_2M 0x00200000 -#define HASH_TABLE_SIZE_4M 0x00400000 -#define HASH_TABLE_MASK_64K 0x000 -#define HASH_TABLE_MASK_128K 0x001 -#define HASH_TABLE_MASK_256K 0x003 -#define HASH_TABLE_MASK_512K 0x007 -#define HASH_TABLE_MASK_1M 0x00F -#define HASH_TABLE_MASK_2M 0x01F -#define HASH_TABLE_MASK_4M 0x03F - -#define MMU_PAGE_SIZE 4096 - -#endif diff --git a/drivers/block/ide-cd.c b/drivers/block/ide-cd.c index c4972f3248ed..a3c528ea9b99 100644 --- a/drivers/block/ide-cd.c +++ b/drivers/block/ide-cd.c @@ -100,14 +100,14 @@ * 3.13 May 19, 1996 -- Fixes for changer code. * 3.14 May 29, 1996 -- Add work-around for Vertos 600. * (From Hennus Bergman .) + * 3.15 July 2, 1996 -- Added support for Sanyo 3 CD changers + * from Ben Galliart with + * special help from Jeff Lightfoot + * * * NOTE: Direct audio reads will only work on some types of drive. * So far, i've received reports of success for Sony and Toshiba drives. * - * NOTE: The changer functions were tested with the NEC CDR-251 drive. - * They may not work with the Sanyo 3-cd changer, which i understand - * uses a different protocol. - * * ATAPI cd-rom driver. To be used with ide.c. * See Documentation/cdrom/ide-cd for usage information. * @@ -237,7 +237,8 @@ struct ide_cd_state_flags { __u8 toc_valid : 1; /* Saved TOC information is current. */ __u8 door_locked : 1; /* We think that the drive door is locked. */ __u8 eject_on_close: 1; /* Drive should eject when device is closed. */ - __u8 reserved : 4; + __u8 sanyo_slot : 2; /* Sanyo 3 CD changer support */ + __u8 reserved : 2; }; #define CDROM_STATE_FLAGS(drive) ((struct ide_cd_state_flags *)&((drive)->bios_head)) @@ -1503,6 +1504,11 @@ cdrom_check_status (ide_drive_t *drive, pc.sense_data = reqbuf; pc.c[0] = TEST_UNIT_READY; + /* the Sanyo 3 CD changer uses byte 7 of TEST_UNIT_READY to + switch CDs instead of supporting the LOAD_UNLOAD opcode */ + + pc.c[7] = CDROM_STATE_FLAGS (drive)->sanyo_slot % 3; + return cdrom_queue_packet_command (drive, &pc); } @@ -1965,15 +1971,38 @@ static int cdrom_load_unload (ide_drive_t *drive, int slot, struct atapi_request_sense *reqbuf) { - struct packet_command pc; + /* if the drive is a Sanyo 3 CD changer then TEST_UNIT_READY + (used in the cdrom_check_status function) is used to + switch CDs instead of LOAD_UNLOAD */ - memset (&pc, 0, sizeof (pc)); - pc.sense_data = reqbuf; + if (CDROM_STATE_FLAGS (drive)->sanyo_slot > 0) { - pc.c[0] = LOAD_UNLOAD; - pc.c[4] = 2 + (slot >= 0); - pc.c[8] = slot; - return cdrom_queue_packet_command (drive, &pc); + if ((slot == 1) || (slot == 2)) { + CDROM_STATE_FLAGS (drive)->sanyo_slot = slot; + } else if (slot >= 0) { + CDROM_STATE_FLAGS (drive)->sanyo_slot = 3; + } else { + return 0; + } + + return cdrom_check_status (drive, NULL); + + } else { + + /* ATAPI Rev. 2.2+ standard for requesting switching of + CDs in a multiplatter device */ + + struct packet_command pc; + + memset (&pc, 0, sizeof (pc)); + pc.sense_data = reqbuf; + + pc.c[0] = LOAD_UNLOAD; + pc.c[4] = 2 + (slot >= 0); + pc.c[8] = slot; + return cdrom_queue_packet_command (drive, &pc); + + } } @@ -2574,6 +2603,10 @@ void ide_cdrom_setup (ide_drive_t *drive) CDROM_CONFIG_FLAGS (drive)->no_doorlock = 0; #endif + /* by default Sanyo 3 CD changer support is turned off and + ATAPI Rev 2.2+ standard support for CD changers is used */ + CDROM_STATE_FLAGS (drive)->sanyo_slot = 0; + if (drive->id != NULL) CDROM_CONFIG_FLAGS (drive)->drq_interrupt = ((drive->id->config & 0x0060) == 0x20); @@ -2621,6 +2654,14 @@ void ide_cdrom_setup (ide_drive_t *drive) CDROM_CONFIG_FLAGS (drive)->playmsf_as_bcd = 1; CDROM_CONFIG_FLAGS (drive)->subchan_as_bcd = 1; } + + /* Sanyo 3 CD changer uses a non-standard command + for CD changing */ + else if (strcmp (drive->id->model, "CD-ROM CDR-C3 G") == 0) { + /* uses CD in slot 0 when value is set to 3 */ + CDROM_STATE_FLAGS (drive)->sanyo_slot = 3; + } + } #endif /* not STANDARD_ATAPI */ diff --git a/drivers/char/baycom.c b/drivers/char/baycom.c index 0c1dfefdf199..5aa478068dd5 100644 --- a/drivers/char/baycom.c +++ b/drivers/char/baycom.c @@ -565,14 +565,14 @@ static inline void add_bitbuffer_word(struct bit_buffer * buf, /* ---------------------------------------------------------------------- */ -static inline unsigned int tenms_to_flags(struct baycom_state *bc, +static inline unsigned int tenms_to_2flags(struct baycom_state *bc, unsigned int tenms) { switch (bc->modem_type) { case BAYCOM_MODEM_SER12: - return tenms * 12 / 8; + return tenms * 3 / 4; case BAYCOM_MODEM_PAR96: - return tenms * 12; + return tenms * 6; default: return 0; } @@ -697,7 +697,7 @@ static unsigned int hdlc_tx_word(struct baycom_state *bc) &bc->hdlc_tx.len); if (!bc->hdlc_tx.bp || !bc->hdlc_tx.len) { bc->hdlc_tx.tx_state = 1; - bc->hdlc_tx.numflags = tenms_to_flags + bc->hdlc_tx.numflags = tenms_to_2flags (bc, bc->ch_params.tx_tail); break; } @@ -777,9 +777,10 @@ static inline void tx_arbitrate(struct baycom_state *bc) if ((random_num() % 256) > bc->ch_params.ppersist) return; } - bc->hdlc_tx.ptt = 1; bc->hdlc_tx.tx_state = 0; - bc->hdlc_tx.numflags = tenms_to_flags(bc, bc->ch_params.tx_delay); + bc->hdlc_tx.numflags = tenms_to_2flags(bc, bc->ch_params.tx_delay); + bc->hdlc_tx.numbits = bc->hdlc_tx.bitbuf = bc->hdlc_tx.bitstream = 0; + bc->hdlc_tx.ptt = 1; bc->stat.ptt_keyed++; } @@ -1160,7 +1161,7 @@ static int ser12_on_open(struct baycom_state *bc) ser12_set_divisor(bc, (bc->options & BAYCOM_OPTIONS_SOFTDCD) ? 4 : 6); outb(0x0d, MCR(bc->iobase)); outb(0, IER(bc->iobase)); - if (request_irq(bc->irq, baycom_ser12_interrupt, 0, + if (request_irq(bc->irq, baycom_ser12_interrupt, SA_INTERRUPT, "baycom_ser12", bc)) return -EBUSY; /* @@ -1210,7 +1211,7 @@ static void baycom_par96_interrupt(int irq, void *dev_id, struct pt_regs *regs) { register struct baycom_state *bc = (struct baycom_state *)dev_id; int i; - unsigned int data, mask, mask2; + unsigned int data, descx, mask, mask2; if (!bc || bc->magic != BAYCOM_MAGIC) return; @@ -1269,7 +1270,6 @@ static void baycom_par96_interrupt(int irq, void *dev_id, struct pt_regs *regs) * do receiver; differential decode and descramble on the fly */ for(data = i = 0; i < PAR96_BURSTBITS; i++) { - unsigned int descx; bc->modem.par96.descram = (bc->modem.par96.descram << 1); if (inb(LPT_STATUS(bc->iobase)) & PAR96_RXBIT) bc->modem.par96.descram |= 1; @@ -1307,16 +1307,16 @@ static void baycom_par96_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* check for abort/noise sequences */ for(mask = 0x1fe00, mask2 = 0x1fe00, i = 0; i < PAR96_BURSTBITS; i++, mask <<= 1, mask2 <<= 1) - if ((bc->modem.par96.dcd_shreg & mask) == mask2) - if (bc->modem.par96.dcd_count >= 0) - bc->modem.par96.dcd_count -= - BAYCOM_MAXFLEN-10; + if (((bc->modem.par96.dcd_shreg & mask) == mask2) && + (bc->modem.par96.dcd_count >= 0)) + bc->modem.par96.dcd_count -= BAYCOM_MAXFLEN-10; /* decrement and set the dcd variable */ if (bc->modem.par96.dcd_count >= 0) bc->modem.par96.dcd_count -= 2; bc->modem.dcd = bc->modem.par96.dcd_count > 0; } else { - bc->modem.dcd = !!(inb(LPT_STATUS(bc->iobase)) & PAR96_DCD); + bc->modem.dcd = !!(inb(LPT_STATUS(bc->iobase)) + & PAR96_DCD); } if (--bc->modem.arb_divider <= 0) { #ifdef BAYCOM_USE_BH @@ -1400,7 +1400,7 @@ static int par96_on_open(struct baycom_state *bc) outb(0, LPT_CONTROL(bc->iobase)); /* disable interrupt */ /* switch off PTT */ outb(PAR96_PTT | PAR97_POWER, LPT_DATA(bc->iobase)); - if (request_irq(bc->irq, baycom_par96_interrupt, 0, + if (request_irq(bc->irq, baycom_par96_interrupt, SA_INTERRUPT, "baycom_par96", bc)) return -EBUSY; outb(LPT_IRQ_ENABLE, LPT_CONTROL(bc->iobase)); /* enable interrupt */ @@ -1586,6 +1586,10 @@ static void baycom_put_char(struct tty_struct *tty, unsigned char ch) } if (!bc->kiss_decode.dec_state) return; + if (ch == KISS_FESC) { + bc->kiss_decode.escaped = 1; + return; + } if (bc->kiss_decode.wr >= sizeof(bc->kiss_decode.pkt_buf)) { bc->kiss_decode.wr = 0; bc->kiss_decode.dec_state = 0; @@ -2269,6 +2273,7 @@ void cleanup_module(void) printk(KERN_INFO "baycom: cleanup_module called\n"); + disable_bh(BAYCOM_BH); if (tty_unregister_driver(&baycom_driver)) printk(KERN_WARNING "baycom: failed to unregister tty " "driver\n"); @@ -2320,20 +2325,3 @@ void baycom_setup(char *str, int *ints) #endif /* MODULE */ /* --------------------------------------------------------------------- */ - -/* - * Overrides for Emacs so that we follow Linus's tabbing style. - * Emacs will notice this stuff at the end of the file and automatically - * adjust the settings for this buffer only. This must remain at the end - * of the file. - * --------------------------------------------------------------------------- - * Local variables: - * c-indent-level: 8 - * c-brace-imaginary-offset: 0 - * c-brace-offset: -8 - * c-argdecl-indent: 8 - * c-label-offset: -8 - * c-continued-statement-offset: 8 - * c-continued-brace-offset: 0 - * End: - */ diff --git a/drivers/net/3c59x.c b/drivers/net/3c59x.c index b3fd2922802c..e7dfd6eb6920 100644 --- a/drivers/net/3c59x.c +++ b/drivers/net/3c59x.c @@ -7,24 +7,24 @@ This driver is for the 3Com "Vortex" series ethercards. Members of the series include the 3c590 PCI EtherLink III and 3c595-Tx PCI Fast - EtherLink. It also works with the 10Mbs-only 3c590 PCI EtherLink III. + EtherLink. The author may be reached as becker@CESDIS.gsfc.nasa.gov, or C/O Center of Excellence in Space Data and Information Sciences Code 930.5, Goddard Space Flight Center, Greenbelt MD 20771 */ -static char *version = "3c59x.c:v0.13 2/13/96 becker@cesdis.gsfc.nasa.gov\n"; +static char *version = "3c59x.c:v0.25 5/17/96 becker@cesdis.gsfc.nasa.gov\n"; /* "Knobs" that turn on special features. */ +/* Enable the experimental automatic media selection code. */ +#define AUTOMEDIA 1 + /* Allow the use of bus master transfers instead of programmed-I/O for the Tx process. Bus master transfers are always disabled by default, but iff this is set they may be turned on using 'options'. */ #define VORTEX_BUS_MASTER -/* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */ -#define VORTEX_DEBUG 1 - #include #include @@ -46,10 +46,23 @@ static char *version = "3c59x.c:v0.13 2/13/96 becker@cesdis.gsfc.nasa.gov\n"; #include #include -#ifdef HAVE_SHARED_IRQ -#define USE_SHARED_IRQ -#include -#endif +#define RUN_AT(x) (jiffies + (x)) +#define DEV_ALLOC_SKB(len) dev_alloc_skb(len + 2) + +#define FREE_IRQ(irqnum, dev) free_irq(irqnum, dev) +#define REQUEST_IRQ(i,h,f,n, instance) request_irq(i,h,f,n, instance) +#define IRQ(irq, dev_id, pt_regs) (irq, dev_id, pt_regs) + +/* "Knobs" for adjusting internal parameters. */ +/* Put out somewhat more debugging messages. (0 - no msg, 1 minimal msgs). */ +#define VORTEX_DEBUG 2 + +/* Number of times to check to see if the Tx FIFO has space, used in some + limited cases. */ +#define WAIT_TX_AVAIL 200 + +/* Operational parameter that usually are not changed. */ +#define TX_TIMEOUT 40 /* Time in jiffies before concluding Tx hung */ /* The total size is twice that of the original EtherLinkIII series: the runtime register window, window 1, is now always mapped in. */ @@ -117,8 +130,8 @@ IV. Notes Thanks to Cameron Spitzer and Terry Murphy of 3Com for providing both 3c590 and 3c595 boards. The name "Vortex" is the internal 3Com project name for the PCI ASIC, and -the not-yet-released (3/95) EISA version is called "Demon". According to -Terry these names come from rides at the local amusement park. +the EISA version is called "Demon". According to Terry these names come +from rides at the local amusement park. The new chips support both ethernet (1.5K) and FDDI (4.5K) packet sizes! This driver only supports ethernet packets because of the skbuff allocation @@ -176,6 +189,7 @@ enum Window1 { }; enum Window0 { Wn0EepromCmd = 10, /* Window 0: EEPROM command register. */ + Wn0EepromData = 12, /* Window 0: EEPROM results register. */ }; enum Win0_EEPROM_bits { EEPROM_Read = 0x80, EEPROM_WRITE = 0x40, EEPROM_ERASE = 0xC0, @@ -206,7 +220,10 @@ enum Window4 { Wn4_Media = 0x0A, /* Window 4: Various transcvr/media bits. */ }; enum Win4_Media_bits { - Media_TP = 0x00C0, /* Enable link beat and jabber for 10baseT. */ + Media_SQE = 0x0008, /* Enable SQE error counting for AUI. */ + Media_10TP = 0x00C0, /* Enable link beat and jabber for 10baseT. */ + Media_Lnk = 0x0080, /* Enable just link beat for 100TX/100FX. */ + Media_LnkBeat = 0x0800, }; enum Window7 { /* Window 7: Bus Master control. */ Wn7_MasterAddr = 0, Wn7_MasterLen = 6, Wn7_MasterStatus = 12, @@ -217,17 +234,36 @@ struct vortex_private { const char *product_name; struct device *next_module; struct enet_statistics stats; -#ifdef VORTEX_BUS_MASTER struct sk_buff *tx_skb; /* Packet being eaten by bus master ctrl. */ -#endif struct timer_list timer; /* Media selection timer. */ - int options; /* User-settable driver options (none yet). */ - unsigned int media_override:3, full_duplex:1, bus_master:1, autoselect:1; + int options; /* User-settable misc. driver options. */ + int last_rx_packets; /* For media autoselection. */ + unsigned int available_media:8, /* From Wn3_Options */ + media_override:3, /* Passed-in media type. */ + default_media:3, /* Read from the EEPROM. */ + full_duplex:1, bus_master:1, autoselect:1; }; -static char *if_names[] = { - "10baseT", "10Mbs AUI", "undefined", "10base2", - "100baseTX", "100baseFX", "MII", "undefined"}; +/* The action to take with a media selection timer tick. + Note that we deviate from the 3Com order by checking 10base2 before AUI. + */ +static struct media_table { + char *name; + unsigned int media_bits:16, /* Bits to set in Wn4_Media register. */ + mask:8, /* The transceiver-present bit in Wn3_Config.*/ + next:8; /* The media type to try next. */ + short wait; /* Time before we check media status. */ +} media_tbl[] = { + { "10baseT", Media_10TP,0x08, 3 /* 10baseT->10base2 */, (14*HZ)/10}, + { "10Mbs AUI", Media_SQE, 0x20, 8 /* AUI->default */, (1*HZ)/10}, + { "undefined", 0, 0x80, 0 /* Undefined */, 0}, + { "10base2", 0, 0x10, 1 /* 10base2->AUI. */, (1*HZ)/10}, + { "100baseTX", Media_Lnk, 0x02, 5 /* 100baseTX->100baseFX */, (14*HZ)/10}, + { "100baseFX", Media_Lnk, 0x04, 6 /* 100baseFX->MII */, (14*HZ)/10}, + { "MII", 0, 0x40, 0 /* MII->10baseT */, (14*HZ)/10}, + { "undefined", 0, 0x01, 0 /* Undefined/100baseT4 */, 0}, + { "Default", 0, 0xFF, 0 /* Use default */, 0}, +}; static int vortex_scan(struct device *dev); static int vortex_found_device(struct device *dev, int ioaddr, int irq, @@ -237,11 +273,11 @@ static int vortex_open(struct device *dev); static void vortex_timer(unsigned long arg); static int vortex_start_xmit(struct sk_buff *skb, struct device *dev); static int vortex_rx(struct device *dev); -static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs); +static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs); static int vortex_close(struct device *dev); static void update_stats(int addr, struct device *dev); static struct enet_statistics *vortex_get_stats(struct device *dev); -static void set_multicast_list(struct device *dev); +static void set_rx_mode(struct device *dev); /* Unlike the other PCI cards the 59x cards don't need a large contiguous @@ -260,7 +296,7 @@ static void set_multicast_list(struct device *dev); */ /* This driver uses 'options' to pass the media type, full-duplex flag, etc. */ /* Note: this is the only limit on the number of cards supported!! */ -int options[8] = { -1, -1, -1, -1, -1, -1, -1, -1,}; +static int options[8] = { -1, -1, -1, -1, -1, -1, -1, -1,}; #ifdef MODULE static int debug = -1; @@ -283,7 +319,7 @@ init_module(void) } #else -unsigned long tc59x_probe(struct device *dev) +int tc59x_probe(struct device *dev) { int cards_found = 0; @@ -302,55 +338,54 @@ static int vortex_scan(struct device *dev) if (pcibios_present()) { static int pci_index = 0; - for (; pci_index < 8; pci_index++) { - unsigned char pci_bus, pci_device_fn, pci_irq_line, pci_latency; - unsigned int pci_ioaddr; - unsigned short pci_command; - int index; - - for (index = 0; product_ids[index]; index++) { - if ( ! pcibios_find_device(TCOM_VENDOR_ID, product_ids[index], - pci_index, &pci_bus, - &pci_device_fn)) + static int board_index = 0; + for (; product_ids[board_index]; board_index++, pci_index = 0) { + for (; pci_index < 16; pci_index++) { + unsigned char pci_bus, pci_device_fn, pci_irq_line; + unsigned char pci_latency; + unsigned int pci_ioaddr; + unsigned short pci_command; + + if (pcibios_find_device(TCOM_VENDOR_ID, + product_ids[board_index], pci_index, + &pci_bus, &pci_device_fn)) break; - } - if ( ! product_ids[index]) - break; - - pcibios_read_config_byte(pci_bus, pci_device_fn, - PCI_INTERRUPT_LINE, &pci_irq_line); - pcibios_read_config_dword(pci_bus, pci_device_fn, - PCI_BASE_ADDRESS_0, &pci_ioaddr); - /* Remove I/O space marker in bit 0. */ - pci_ioaddr &= ~3; + pcibios_read_config_byte(pci_bus, pci_device_fn, + PCI_INTERRUPT_LINE, &pci_irq_line); + pcibios_read_config_dword(pci_bus, pci_device_fn, + PCI_BASE_ADDRESS_0, &pci_ioaddr); + /* Remove I/O space marker in bit 0. */ + pci_ioaddr &= ~3; #ifdef VORTEX_BUS_MASTER - /* Get and check the bus-master and latency values. - Some PCI BIOSes fail to set the master-enable bit, and - the latency timer must be set to the maximum value to avoid - data corruption that occurs when the timer expires during - a transfer. Yes, it's a bug. */ - pcibios_read_config_word(pci_bus, pci_device_fn, - PCI_COMMAND, &pci_command); - if ( ! (pci_command & PCI_COMMAND_MASTER)) { - printk(" PCI Master Bit has not been set! Setting...\n"); - pci_command |= PCI_COMMAND_MASTER; - pcibios_write_config_word(pci_bus, pci_device_fn, - PCI_COMMAND, pci_command); - } - pcibios_read_config_byte(pci_bus, pci_device_fn, + /* Get and check the bus-master and latency values. + Some PCI BIOSes fail to set the master-enable bit, and + the latency timer must be set to the maximum value to avoid + data corruption that occurs when the timer expires during + a transfer. Yes, it's a bug. */ + pcibios_read_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, &pci_command); + if ( ! (pci_command & PCI_COMMAND_MASTER)) { + printk(" PCI Master Bit has not been set! Setting...\n"); + pci_command |= PCI_COMMAND_MASTER; + pcibios_write_config_word(pci_bus, pci_device_fn, + PCI_COMMAND, pci_command); + } + pcibios_read_config_byte(pci_bus, pci_device_fn, PCI_LATENCY_TIMER, &pci_latency); - if (pci_latency != 255) { - printk(" Overriding PCI latency timer (CFLT) setting of %d, new value is 255.\n", pci_latency); - pcibios_write_config_byte(pci_bus, pci_device_fn, - PCI_LATENCY_TIMER, 255); - } + if (pci_latency != 255) { + printk(" Overriding PCI latency timer (CFLT) setting of" + " %d, new value is 255.\n", pci_latency); + pcibios_write_config_byte(pci_bus, pci_device_fn, + PCI_LATENCY_TIMER, 255); + } #endif /* VORTEX_BUS_MASTER */ - vortex_found_device(dev, pci_ioaddr, pci_irq_line, index, - dev && dev->mem_start ? dev->mem_start - : options[cards_found]); - dev = 0; - cards_found++; + vortex_found_device(dev, pci_ioaddr, pci_irq_line, board_index, + dev && dev->mem_start ? dev->mem_start + : options[cards_found]); + dev = 0; + cards_found++; + } } } @@ -361,9 +396,9 @@ static int vortex_scan(struct device *dev) /* Check the standard EISA ID register for an encoded '3Com'. */ if (inw(ioaddr + 0xC80) != 0x6d50) continue; - /* Check for a product that we support. */ - if ((inw(ioaddr + 0xC82) & 0xFFF0) != 0x5970 - && (inw(ioaddr + 0xC82) & 0xFFF0) != 0x5920) + /* Check for a product that we support, 3c59{2,7} any rev. */ + if ((inw(ioaddr + 0xC82) & 0xF0FF) != 0x7059 /* 597 */ + && (inw(ioaddr + 0xC82) & 0xF0FF) != 0x2059) /* 592 */ continue; vortex_found_device(dev, ioaddr, inw(ioaddr + 0xC88) >> 12, DEMON_INDEX, dev && dev->mem_start @@ -452,12 +487,12 @@ static int vortex_probe1(struct device *dev) int timer; outw(EEPROM_Read + PhysAddr01 + i, ioaddr + Wn0EepromCmd); /* Pause for at least 162 us. for the read to take place. */ - for (timer = 0; timer < 162*4 + 400; timer++) { + for (timer = 162*4 + 400; timer >= 0; timer--) { SLOW_DOWN_IO; if ((inw(ioaddr + Wn0EepromCmd) & 0x8000) == 0) break; } - phys_addr[i] = htons(inw(ioaddr + 12)); + phys_addr[i] = htons(inw(ioaddr + Wn0EepromData)); } for (i = 0; i < 6; i++) printk("%c%2.2x", i ? ':' : ' ', dev->dev_addr[i]); @@ -470,6 +505,7 @@ static int vortex_probe1(struct device *dev) char *ram_split[] = {"5:3", "3:1", "1:1", "invalid"}; union wn3_config config; EL3WINDOW(3); + vp->available_media = inw(ioaddr + Wn3_Options); config.i = inl(ioaddr + Wn3_Config); if (vortex_debug > 1) printk(" Internal config register is %4.4x, transceivers %#x.\n", @@ -479,8 +515,9 @@ static int vortex_probe1(struct device *dev) config.u.ram_width ? "word" : "byte", ram_split[config.u.ram_split], config.u.autoselect ? "autoselect/" : "", - if_names[config.u.xcvr]); + media_tbl[config.u.xcvr].name); dev->if_port = config.u.xcvr; + vp->default_media = config.u.xcvr; vp->autoselect = config.u.autoselect; } @@ -492,10 +529,7 @@ static int vortex_probe1(struct device *dev) dev->hard_start_xmit = &vortex_start_xmit; dev->stop = &vortex_close; dev->get_stats = &vortex_get_stats; - dev->set_multicast_list = &set_multicast_list; -#if defined (HAVE_SET_MAC_ADDR) && 0 - dev->set_mac_address = &set_mac_address; -#endif + dev->set_multicast_list = &set_rx_mode; return 0; } @@ -518,11 +552,29 @@ vortex_open(struct device *dev) if (vp->media_override != 7) { if (vortex_debug > 1) printk("%s: Media override to transceiver %d (%s).\n", - dev->name, vp->media_override, if_names[vp->media_override]); - config.u.xcvr = vp->media_override; + dev->name, vp->media_override, + media_tbl[vp->media_override].name); dev->if_port = vp->media_override; - outl(config.i, ioaddr + Wn3_Config); - } + } else if (vp->autoselect) { + /* Find first available media type, starting with 100baseTx. */ + dev->if_port = 4; + while (! (vp->available_media & media_tbl[dev->if_port].mask)) + dev->if_port = media_tbl[dev->if_port].next; + + if (vortex_debug > 1) + printk("%s: Initial media type %s.\n", + dev->name, media_tbl[dev->if_port].name); + + init_timer(&vp->timer); + vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait); + vp->timer.data = (unsigned long)dev; + vp->timer.function = &vortex_timer; /* timer handler */ + add_timer(&vp->timer); + } else + dev->if_port = vp->default_media; + + config.u.xcvr = dev->if_port; + outl(config.i, ioaddr + Wn3_Config); if (vortex_debug > 1) { printk("%s: vortex_open() InternalConfig %8.8x.\n", @@ -542,19 +594,11 @@ vortex_open(struct device *dev) outw(SetStatusEnb | 0x00, ioaddr + EL3_CMD); -#ifdef USE_SHARED_IRQ - i = request_shared_irq(dev->irq, &vortex_interrupt, dev, vp->product_name); - if (i) /* Error */ - return i; -#else - if (dev->irq == 0 || irq2dev_map[dev->irq] != NULL) - return -EAGAIN; - irq2dev_map[dev->irq] = dev; - if (request_irq(dev->irq, &vortex_interrupt, 0, vp->product_name, NULL)) { - irq2dev_map[dev->irq] = NULL; + /* Use the now-standard shared IRQ implementation. */ + if (request_irq(dev->irq, &vortex_interrupt, SA_SHIRQ, + vp->product_name, dev)) { return -EAGAIN; } -#endif if (vortex_debug > 1) { EL3WINDOW(4); @@ -572,11 +616,9 @@ vortex_open(struct device *dev) if (dev->if_port == 3) /* Start the thinnet transceiver. We should really wait 50ms...*/ outw(StartCoax, ioaddr + EL3_CMD); - else if (dev->if_port == 0) { - /* 10baseT interface, enabled link beat and jabber check. */ - EL3WINDOW(4); - outw(inw(ioaddr + Wn4_Media) | Media_TP, ioaddr + Wn4_Media); - } + EL3WINDOW(4); + outw((inw(ioaddr + Wn4_Media) & ~(Media_10TP|Media_SQE)) | + media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media); /* Switch to the stats window, and clear all stats by reading. */ outw(StatsDisable, ioaddr + EL3_CMD); @@ -592,8 +634,8 @@ vortex_open(struct device *dev) /* Switch to register set 7 for normal use. */ EL3WINDOW(7); - /* Accept b-case and phys addr only. */ - outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); + /* Set reciever mode: presumably accept b-case and phys addr only. */ + set_rx_mode(dev); outw(StatsEnable, ioaddr + EL3_CMD); /* Turn on statistics. */ dev->tbusy = 0; @@ -610,26 +652,83 @@ vortex_open(struct device *dev) outw(SetIntrEnb | IntLatch | TxAvailable | RxComplete | StatsFull | DMADone, ioaddr + EL3_CMD); -#ifdef MODULE MOD_INC_USE_COUNT; -#endif - if (vp->autoselect) { - init_timer(&vp->timer); - vp->timer.expires = (14*HZ)/10; /* 1.4 sec. */ - vp->timer.data = (unsigned long)dev; - vp->timer.function = &vortex_timer; /* timer handler */ - add_timer(&vp->timer); - } return 0; } static void vortex_timer(unsigned long data) { +#ifdef AUTOMEDIA struct device *dev = (struct device *)data; - if (vortex_debug > 2) - printk("%s: Media selection timer tick happened.\n", dev->name); - /* ToDo: active media selection here! */ + struct vortex_private *vp = (struct vortex_private *)dev->priv; + int ioaddr = dev->base_addr; + unsigned long flags; + int ok = 0; + + if (vortex_debug > 1) + printk("%s: Media selection timer tick happened, %s.\n", + dev->name, media_tbl[dev->if_port].name); + + save_flags(flags); cli(); { + int old_window = inw(ioaddr + EL3_CMD) >> 13; + int media_status; + EL3WINDOW(4); + media_status = inw(ioaddr + Wn4_Media); + switch (dev->if_port) { + case 0: case 4: case 5: /* 10baseT, 100baseTX, 100baseFX */ + if (media_status & Media_LnkBeat) { + ok = 1; + if (vortex_debug > 1) + printk("%s: Media %s has link beat, %x.\n", + dev->name, media_tbl[dev->if_port].name, media_status); + } else if (vortex_debug > 1) + printk("%s: Media %s is has no link beat, %x.\n", + dev->name, media_tbl[dev->if_port].name, media_status); + + break; + default: /* Other media types handled by Tx timeouts. */ + if (vortex_debug > 1) + printk("%s: Media %s is has no indication, %x.\n", + dev->name, media_tbl[dev->if_port].name, media_status); + ok = 1; + } + if ( ! ok) { + union wn3_config config; + + do { + dev->if_port = media_tbl[dev->if_port].next; + } while ( ! (vp->available_media & media_tbl[dev->if_port].mask)); + if (dev->if_port == 8) { /* Go back to default. */ + dev->if_port = vp->default_media; + if (vortex_debug > 1) + printk("%s: Media selection failing, using default %s port.\n", + dev->name, media_tbl[dev->if_port].name); + } else { + if (vortex_debug > 1) + printk("%s: Media selection failed, now trying %s port.\n", + dev->name, media_tbl[dev->if_port].name); + vp->timer.expires = RUN_AT(media_tbl[dev->if_port].wait); + add_timer(&vp->timer); + } + outw((media_status & ~(Media_10TP|Media_SQE)) | + media_tbl[dev->if_port].media_bits, ioaddr + Wn4_Media); + + EL3WINDOW(3); + config.i = inl(ioaddr + Wn3_Config); + config.u.xcvr = dev->if_port; + outl(config.i, ioaddr + Wn3_Config); + + outw(dev->if_port == 3 ? StartCoax : StopCoax, ioaddr + EL3_CMD); + } + EL3WINDOW(old_window); + } restore_flags(flags); + if (vortex_debug > 1) + printk("%s: Media selection timer finished, %s.\n", + dev->name, media_tbl[dev->if_port].name); + +#endif /* AUTOMEDIA*/ + return; } static int @@ -638,33 +737,49 @@ vortex_start_xmit(struct sk_buff *skb, struct device *dev) struct vortex_private *vp = (struct vortex_private *)dev->priv; int ioaddr = dev->base_addr; - /* Transmitter timeout, serious problems. */ - if (dev->tbusy) { + /* Part of the following code is inspired by code from Giuseppe Ciaccio, + ciaccio@disi.unige.it. + It works around a ?bug? in the 8K Vortex that only occurs on some + systems: the TxAvailable interrupt seems to be lost. + The ugly work-around is to busy-wait for room available in the Tx + buffer before deciding the transmitter is actually hung. + This busy-wait should never really occur, since the problem is that + there actually *is* room in the Tx FIFO. + + This pointed out an optimization -- we can ignore dev->tbusy if + we actually have room for this packet. + */ + + if (inw(ioaddr + TxFree) > skb->len) /* We actually have free room. */ + dev->tbusy = 0; /* Fake out the check below. */ + else if (dev->tbusy) { + /* Transmitter timeout, serious problems. */ int tickssofar = jiffies - dev->trans_start; - if (tickssofar < 40) + int i; + + if (tickssofar < 2) /* We probably aren't empty. */ return 1; - printk("%s: transmit timed out, tx_status %2.2x status %4.4x.\n", - dev->name, inb(ioaddr + TxStatus), inw(ioaddr + EL3_STATUS)); - vp->stats.tx_errors++; - /* Issue TX_RESET and TX_START commands. */ - outw(TxReset, ioaddr + EL3_CMD); - { - int i; + /* Wait a while to see if there really is room. */ + for (i = WAIT_TX_AVAIL; i >= 0; i--) + if (inw(ioaddr + TxFree) > skb->len) + break; + if ( i < 0) { + if (tickssofar < TX_TIMEOUT) + return 1; + printk("%s: transmit timed out, tx_status %2.2x status %4.4x.\n", + dev->name, inb(ioaddr + TxStatus), inw(ioaddr + EL3_STATUS)); + /* Issue TX_RESET and TX_START commands. */ + outw(TxReset, ioaddr + EL3_CMD); for (i = 20; i >= 0 ; i--) - if ( ! inw(ioaddr + EL3_STATUS) & CmdInProgress) - break; + if ( ! inw(ioaddr + EL3_STATUS) & CmdInProgress) break; + outw(TxEnable, ioaddr + EL3_CMD); + dev->trans_start = jiffies; + dev->tbusy = 0; + vp->stats.tx_errors++; + vp->stats.tx_dropped++; + return 0; /* Yes, silently *drop* the packet! */ } - outw(TxEnable, ioaddr + EL3_CMD); - dev->trans_start = jiffies; dev->tbusy = 0; - return 0; - } - - if (skb == NULL || skb->len <= 0) { - printk("%s: Obsolete driver layer request made: skbuff==NULL.\n", - dev->name); - dev_tint(dev); - return 0; } /* Block a timer-based transmit from overlapping. This could better be @@ -684,6 +799,7 @@ vortex_start_xmit(struct sk_buff *skb, struct device *dev) outw((skb->len + 3) & ~3, ioaddr + Wn7_MasterLen); vp->tx_skb = skb; outw(StartDMADown, ioaddr + EL3_CMD); + /* dev->tbusy will be cleared at the DMADone interrupt. */ } else { /* ... and the packet rounded to a doubleword. */ outsl(ioaddr + TX_FIFO, skb->data, (skb->len + 3) >> 2); @@ -736,23 +852,15 @@ vortex_start_xmit(struct sk_buff *skb, struct device *dev) /* The interrupt handler does all of the Rx thread work and cleans up after the Tx thread. */ -static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) +static void vortex_interrupt IRQ(int irq, void *dev_id, struct pt_regs *regs) { -#ifdef USE_SHARED_IRQ - struct device *dev = (struct device *)(irq == 0 ? regs : irq2dev_map[irq]); -#else - struct device *dev = (struct device *)(irq2dev_map[irq]); -#endif + /* Use the now-standard shared IRQ implementation. */ + struct device *dev = dev_id; struct vortex_private *lp; int ioaddr, status; int latency; int i = 0; - if (dev == NULL) { - printk ("vortex_interrupt(): irq %d for unknown device.\n", irq); - return; - } - if (dev->interrupt) printk("%s: Re-entering the interrupt handler.\n", dev->name); dev->interrupt = 1; @@ -774,7 +882,7 @@ static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) if (donedidthis++ > 1) { printk("%s: Bogus interrupt, bailing. Status %4.4x, start=%d.\n", dev->name, status, dev->start); - free_irq(dev->irq, NULL); + FREE_IRQ(dev->irq, dev); } } @@ -833,10 +941,7 @@ static void vortex_interrupt(int irq, void *dev_id, struct pt_regs *regs) /* Adapter failure requires Rx reset and reinit. */ outw(RxReset, ioaddr + EL3_CMD); /* Set the Rx filter to the current state. */ - outw(SetRxFilter | RxStation | RxBroadcast - | (dev->flags & IFF_ALLMULTI ? RxMulticast : 0) - | (dev->flags & IFF_PROMISC ? RxProm : 0), - ioaddr + EL3_CMD); + set_rx_mode(dev); outw(RxEnable, ioaddr + EL3_CMD); /* Re-enable the receiver. */ outw(AckIntr | AdapterFailure, ioaddr + EL3_CMD); } @@ -890,7 +995,7 @@ vortex_rx(struct device *dev) short pkt_len = rx_status & 0x1fff; struct sk_buff *skb; - skb = dev_alloc_skb(pkt_len + 5); + skb = DEV_ALLOC_SKB(pkt_len + 5); if (vortex_debug > 4) printk("Receiving packet size %d status %4.4x.\n", pkt_len, rx_status); @@ -927,6 +1032,7 @@ vortex_rx(struct device *dev) static int vortex_close(struct device *dev) { + struct vortex_private *vp = (struct vortex_private *)dev->priv; int ioaddr = dev->base_addr; dev->start = 0; @@ -936,6 +1042,8 @@ vortex_close(struct device *dev) printk("%s: vortex_close() status %4.4x, Tx status %2.2x.\n", dev->name, inw(ioaddr + EL3_STATUS), inb(ioaddr + TxStatus)); + del_timer(&vp->timer); + /* Turn off statistics ASAP. We update lp->stats below. */ outw(StatsDisable, ioaddr + EL3_CMD); @@ -946,24 +1054,11 @@ vortex_close(struct device *dev) if (dev->if_port == 3) /* Turn off thinnet power. Green! */ outw(StopCoax, ioaddr + EL3_CMD); - else if (dev->if_port == 0) { - /* Disable link beat and jabber, if_port may change ere next open(). */ - EL3WINDOW(4); - outw(inw(ioaddr + Wn4_Media) & ~Media_TP, ioaddr + Wn4_Media); - } -#ifdef USE_SHARED_IRQ - free_shared_irq(dev->irq, dev); -#else - free_irq(dev->irq, NULL); - /* Mmmm, we should disable all interrupt sources here. */ - irq2dev_map[dev->irq] = 0; -#endif + FREE_IRQ(dev->irq, dev); update_stats(ioaddr, dev); -#ifdef MODULE MOD_DEC_USE_COUNT; -#endif return 0; } @@ -1019,26 +1114,27 @@ static void update_stats(int ioaddr, struct device *dev) return; } -/* There are two version of set_multicast_list() to support both v1.2 and - v1.4 kernels. */ +/* This new version of set_rx_mode() supports v1.4 kernels. + The Vortex chip has no documented multicast filter, so the only + multicast setting is to receive all multicast frames. At least + the chip has a very clean way to set the mode, unlike many others. */ static void -set_multicast_list(struct device *dev) +set_rx_mode(struct device *dev) { short ioaddr = dev->base_addr; - - if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) { - outw(SetRxFilter|RxStation|RxMulticast|RxBroadcast, ioaddr + EL3_CMD); - if (vortex_debug > 3) { - printk("%s: Setting Rx multicast mode, %d addresses.\n", - dev->name, dev->mc_count); - } - } else if (dev->flags & IFF_PROMISC) { - outw(SetRxFilter | RxStation | RxMulticast | RxBroadcast | RxProm, - ioaddr + EL3_CMD); - } else - outw(SetRxFilter | RxStation | RxBroadcast, ioaddr + EL3_CMD); + short new_mode; + + if (dev->flags & IFF_PROMISC) { + if (vortex_debug > 3) + printk("%s: Setting promiscuous mode.\n", dev->name); + new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast|RxProm; + } else if ((dev->mc_list) || (dev->flags & IFF_ALLMULTI)) { + new_mode = SetRxFilter|RxStation|RxMulticast|RxBroadcast; + } else + new_mode = SetRxFilter | RxStation | RxBroadcast; + + outw(new_mode, ioaddr + EL3_CMD); } - #ifdef MODULE void @@ -1050,6 +1146,7 @@ cleanup_module(void) while (root_vortex_dev) { next_dev = ((struct vortex_private *)root_vortex_dev->priv)->next_module; unregister_netdev(root_vortex_dev); + outw(TotalReset, root_vortex_dev->base_addr + EL3_CMD); release_region(root_vortex_dev->base_addr, VORTEX_TOTAL_SIZE); kfree(root_vortex_dev); root_vortex_dev = next_dev; @@ -1059,7 +1156,7 @@ cleanup_module(void) /* * Local variables: - * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c 3c59x.c -o 3c59x.o" + * compile-command: "gcc -DMODULE -D__KERNEL__ -I/usr/src/linux/net/inet -Wall -Wstrict-prototypes -O6 -m486 -c 3c59x.c -o ../../modules/3c59x.o" * c-indent-level: 4 * tab-width: 4 * End: diff --git a/drivers/net/arcnet.c b/drivers/net/arcnet.c index cab55df3b0ca..9db0a04e569f 100644 --- a/drivers/net/arcnet.c +++ b/drivers/net/arcnet.c @@ -17,6 +17,14 @@ ********************** + v2.54 (96/07/05) + - Under some situations, Stage 5 autoprobe was a little bit too + picky about the TXACK flag. + - D_EXTRA removed from default debugging flags. Hey, it's stable, + right? + - Removed redundant "unknown protocol ID" messages and made remaining + ones D_EXTRA. + v2.53 (96/06/06) - arc0e and arc0s wouldn't initialize in newer kernels, which don't like dev->open==NULL or dev->stop==NULL. @@ -184,7 +192,7 @@ */ static const char *version = - "arcnet.c: v2.53 96/06/06 Avery Pennarun \n"; + "arcnet.c: v2.54 96/07/05 Avery Pennarun \n"; @@ -341,7 +349,7 @@ static const char *version = #endif #ifndef ARCNET_DEBUG -#define ARCNET_DEBUG (D_NORMAL|D_EXTRA) +#define ARCNET_DEBUG (D_NORMAL) #endif int arcnet_debug = ARCNET_DEBUG; @@ -976,7 +984,7 @@ int arcnet_probe(struct device *dev) ioaddr=*port; status=inb(STATUS); - if ((status & 0x9F) + if ((status & 0x9D) != (NORXflag|RECONflag|TXFREEflag|RESETflag)) { BUGMSG2(D_INIT_REASONS,"(status=%Xh)\n",status); @@ -2240,7 +2248,7 @@ arcnet_rx(struct device *dev,int recbuf) #endif case ARC_P_LANSOFT: /* don't understand. fall through. */ default: - BUGMSG(D_NORMAL,"received unknown protocol %d (%Xh) from station %d.\n", + BUGMSG(D_EXTRA,"received unknown protocol %d (%Xh) from station %d.\n", arcsoft[0],arcsoft[0],saddr); lp->stats.rx_errors++; lp->stats.rx_crc_errors++; @@ -2733,8 +2741,6 @@ unsigned short arcnetA_type_trans(struct sk_buff *skb,struct device *dev) case ARC_P_NOVELL_EC: return htons(ETH_P_802_3); default: - BUGMSG(D_NORMAL,"received packet of unknown protocol id %d (%Xh)\n", - head->protocol_id,head->protocol_id); lp->stats.rx_errors++; lp->stats.rx_crc_errors++; return 0; @@ -3196,8 +3202,6 @@ unsigned short arcnetS_type_trans(struct sk_buff *skb,struct device *dev) case ARC_P_ARP_RFC1051: return htons(ETH_P_ARP); case ARC_P_ATALK: return htons(ETH_P_ATALK); /* untested appletalk */ default: - BUGMSG(D_NORMAL,"received packet of unknown protocol id %d (%Xh)\n", - head->protocol_id,head->protocol_id); lp->stats.rx_errors++; lp->stats.rx_crc_errors++; return 0; diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c index a1a2f82ad49c..7bee9ac07b82 100644 --- a/drivers/pci/pci.c +++ b/drivers/pci/pci.c @@ -111,9 +111,9 @@ struct pci_dev_info dev_info[] = { DEVICE( OPTI, OPTI_82C822, "82C822"), DEVICE( SGS, SGS_2000, "STG 2000X"), DEVICE( SGS, SGS_1764, "STG 1764X"), - DEVICE( BUSLOGIC, BUSLOGIC_946C_2,"BT-946C"), - DEVICE( BUSLOGIC, BUSLOGIC_946C, "BT-946C"), - DEVICE( BUSLOGIC, BUSLOGIC_930, "BT-930"), + DEVICE( BUSLOGIC, BUSLOGIC_MULTIMASTER_NC, "MultiMaster NC"), + DEVICE( BUSLOGIC, BUSLOGIC_MULTIMASTER, "MultiMaster"), + DEVICE( BUSLOGIC, BUSLOGIC_FLASHPOINT, "FlashPoint"), DEVICE( OAK, OAK_OTI107, "OTI107"), DEVICE( PROMISE, PROMISE_5300, "DC5030"), DEVICE( N9, N9_I128, "Imagine 128"), diff --git a/drivers/scsi/BusLogic.c b/drivers/scsi/BusLogic.c index ce408e7081ee..8830d7dde57e 100644 --- a/drivers/scsi/BusLogic.c +++ b/drivers/scsi/BusLogic.c @@ -24,8 +24,8 @@ */ -#define BusLogic_DriverVersion "2.0.4" -#define BusLogic_DriverDate "5 June 1996" +#define BusLogic_DriverVersion "2.0.5" +#define BusLogic_DriverDate "7 July 1996" #include @@ -601,8 +601,8 @@ static void BusLogic_InitializeAddressProbeList(void) VendorID == PCI_VENDOR_ID_BUSLOGIC && pcibios_read_config_word(Bus, DeviceFunction, PCI_DEVICE_ID, &DeviceID) == 0 && - (DeviceID == PCI_DEVICE_ID_BUSLOGIC_946C || - DeviceID == PCI_DEVICE_ID_BUSLOGIC_946C_2) && + (DeviceID == PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER || + DeviceID == PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC) && pcibios_read_config_dword(Bus, DeviceFunction, PCI_BASE_ADDRESS_0, &BaseAddress0) == 0 && (BaseAddress0 & PCI_BASE_ADDRESS_SPACE) == @@ -936,8 +936,15 @@ static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T /* Issue the Inquire Board Model Number command. */ - if (!(BoardID.FirmwareVersion1stDigit == '2' && - ExtendedSetupInformation.BusType == 'A')) + if (ExtendedSetupInformation.BusType == 'A' && + BoardID.FirmwareVersion1stDigit == '2') + /* BusLogic BT-542B ISA 2.xx */ + strcpy(BoardModelNumber, "542B"); + else if (ExtendedSetupInformation.BusType == 'E' && + BoardID.FirmwareVersion1stDigit == '0') + /* AMI FastDisk EISA Series 441 0.x */ + strcpy(BoardModelNumber, "747A"); + else { RequestedReplyLength = sizeof(BoardModelNumber); if (BusLogic_Command(HostAdapter, BusLogic_InquireBoardModelNumber, @@ -946,15 +953,16 @@ static boolean BusLogic_ReadHostAdapterConfiguration(BusLogic_HostAdapter_T != sizeof(BoardModelNumber)) return BusLogic_Failure(HostAdapter, "INQUIRE BOARD MODEL NUMBER"); } - else strcpy(BoardModelNumber, "542B"); /* Issue the Inquire Firmware Version 3rd Digit command. */ - if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit, - NULL, 0, &FirmwareVersion3rdDigit, - sizeof(FirmwareVersion3rdDigit)) - != sizeof(FirmwareVersion3rdDigit)) - return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT"); + FirmwareVersion3rdDigit = '\0'; + if (BoardID.FirmwareVersion1stDigit > '0') + if (BusLogic_Command(HostAdapter, BusLogic_InquireFirmwareVersion3rdDigit, + NULL, 0, &FirmwareVersion3rdDigit, + sizeof(FirmwareVersion3rdDigit)) + != sizeof(FirmwareVersion3rdDigit)) + return BusLogic_Failure(HostAdapter, "INQUIRE FIRMWARE 3RD DIGIT"); /* BusLogic Host Adapters can be identified by their model number and the major version number of their firmware as follows: @@ -2520,13 +2528,13 @@ int BusLogic_QueueCommand(SCSI_Command_T *Command, the Host Adapter and Target Device can establish Synchronous and Wide Transfer before Queue Tag messages can interfere with the Synchronous and Wide Negotiation message. By waiting to enable Tagged Queuing until after - the first BusLogic_PreferredQueueDepth commands have been sent, it is + the first 2*BusLogic_PreferredQueueDepth commands have been sent, it is assured that after a Reset any pending commands are resent before Tagged Queuing is enabled and that the Tagged Queuing message will not occur while the partition table is being printed. */ if (HostAdapter->TotalCommandCount[TargetID]++ == - BusLogic_PreferredTaggedQueueDepth && + 2*BusLogic_PreferredTaggedQueueDepth && (HostAdapter->TaggedQueuingPermitted & (1 << TargetID)) && Command->device->tagged_supported) { diff --git a/drivers/scsi/Config.in b/drivers/scsi/Config.in index d9ada0d9bc2b..db3894adb74f 100644 --- a/drivers/scsi/Config.in +++ b/drivers/scsi/Config.in @@ -45,11 +45,7 @@ if [ "$CONFIG_PCI" = "y" ]; then fi fi if [ "$CONFIG_PCI" = "y" -a "$CONFIG_SCSI_NCR53C7xx" != "y" ]; then - if [ "$CONFIG_SCSI" != "n" -a "$CONFIG_SCSI_NCR53C7xx" = "m" ]; then - dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX m - else - dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI - fi + dep_tristate 'NCR53C8XX SCSI support' CONFIG_SCSI_NCR53C8XX $CONFIG_SCSI if [ "$CONFIG_SCSI_NCR53C8XX" != "n" ]; then bool ' enable tagged command queueing' CONFIG_SCSI_NCR53C8XX_TAGGED_QUEUE bool ' force normal IO' CONFIG_SCSI_NCR53C8XX_IOMAPPED @@ -57,7 +53,7 @@ if [ "$CONFIG_PCI" = "y" -a "$CONFIG_SCSI_NCR53C7xx" != "y" ]; then bool ' force asynchronous transfer mode' CONFIG_SCSI_NCR53C8XX_FORCE_ASYNCHRONOUS bool ' force synchronous negotiation' CONFIG_SCSI_NCR53C8XX_FORCE_SYNC_NEGO fi - if [ "$CONFIG_SCSI_NCR53C8XX" != "n" -a $CONFIG_EXPERIMENTAL = 'y' ]; then + if [ "$CONFIG_SCSI_NCR53C8XX" != "n" -a "$CONFIG_EXPERIMENTAL" = "y" ]; then bool ' disable master parity checking' CONFIG_SCSI_NCR53C8XX_DISABLE_MPARITY_CHECK bool ' disable scsi parity checking' CONFIG_SCSI_NCR53C8XX_DISABLE_PARITY_CHECK fi diff --git a/drivers/scsi/README.BusLogic b/drivers/scsi/README.BusLogic index e363b1476c69..fe70d521b9fb 100644 --- a/drivers/scsi/README.BusLogic +++ b/drivers/scsi/README.BusLogic @@ -1,9 +1,9 @@ BusLogic MultiMaster SCSI Driver for Linux - Version 1.2.4 for Linux 1.2.13 - Version 2.0.4 for Linux 2.0.0 + Version 1.2.5 for Linux 1.2.13 + Version 2.0.5 for Linux 2.0.4 - 5 June 1996 + 7 July 1996 Leonard N. Zubkoff Dandelion Digital @@ -31,10 +31,11 @@ the major performance and error recovery features can be configured from the Linux kernel command line, allowing individual installations to tune driver performance and error recovery to their particular needs. -The most recent versions of this driver will always be available by anonymous -FTP from ftp.dandelion.com. While directory listings are not permitted, the -introductory banner displayed on anonymous FTP login will provide a list of the -driver versions and any other files that are available for retrieval. +The most recent versions of this driver will always be available from my Linux +Home Page at URL "http://www.dandelion.com/Linux/" and by anonymous FTP from +ftp.dandelion.com. While only limited FTP directory listings are permitted, +the introductory banner displayed on anonymous FTP login will provide a list of +the driver versions and any other files that are available for retrieval. Bug reports should be sent via electronic mail to "lnz@dandelion.com". Please include with the bug report the complete configuration messages reported by the @@ -322,10 +323,10 @@ Note that limiting the tagged queue depth or disabling tagged queuing can substantially impact performance. - INSTALLATION + INSTALLATION This distribution was prepared for Linux kernel version 1.2.13 -(BusLogic-1.2.4.tar.gz) or Linux kernel version 2.0.0 (BusLogic-2.0.4.tar.gz). +(BusLogic-1.2.5.tar.gz) or Linux kernel version 2.0.4 (BusLogic-2.0.5.tar.gz). Installation in later versions will probably be successful as well, though BusLogic.patch may not be required. Installation in earlier versions is not recommended. @@ -335,7 +336,7 @@ replacing "/usr/src" with wherever you keep your Linux kernel source tree (substitute "1.2" or "2.0" for "x.y" in the tar command as appropriate): cd /usr/src - tar -xvzf BusLogic-x.y.4.tar.gz + tar -xvzf BusLogic-x.y.5.tar.gz mv README.* BusLogic.[ch] linux/drivers/scsi patch -p < BusLogic.patch (on Linux 1.2.13 only) patch -p < BusLogic.elf_patch (on Linux 1.2.13 ELF systems only) diff --git a/drivers/scsi/README.FlashPoint b/drivers/scsi/README.FlashPoint index c3472d65a166..174d897fb38d 100644 --- a/drivers/scsi/README.FlashPoint +++ b/drivers/scsi/README.FlashPoint @@ -1,7 +1,11 @@ - ANNOUNCEMENT - BusLogic FlashPoint/BT-948 Upgrade Program - 1 February 1996 + ANNOUNCEMENT + BusLogic FlashPoint LT/BT-948 Upgrade Program + 1 February 1996 + + ADDITIONAL ANNOUNCEMENT + BusLogic FlashPoint LW/BT-958 Upgrade Program + 14 June 1996 Ever since its introduction last October, the BusLogic FlashPoint LT has been problematic for members of the Linux community, in that no Linux @@ -58,32 +62,39 @@ SCSI Host Adapter. The BT-948 is the Ultra SCSI successor to the BT-946C and has all the best features of both the BT-946C and FlashPoint LT, including smart termination and a flash PROM for easy firmware updates, and is of course compatible with the present Linux driver. The price for this -upgrade has been set at US $45, and the upgrade program will be -administered through BusLogic Technical Support, which can be reached by -electronic mail at techsup@buslogic.com, by Voice at +1 408 654-0760, or by -FAX at +1 408 492-1542. +upgrade has been set at US $45 plus shipping and handling, and the upgrade +program will be administered through BusLogic Technical Support, which can +be reached by electronic mail at techsup@buslogic.com, by Voice at +1 408 +654-0760, or by FAX at +1 408 492-1542. + +As of 14 June 1996, the original BusLogic FlashPoint LT to BT-948 upgrade +program has now been extended to encompass the FlashPoint LW Wide Ultra +SCSI Host Adapter. Any Linux user worldwide may trade in their FlashPoint +LW (BT-950) for a BT-958 MultiMaster PCI Ultra SCSI Host Adapter. The +price for this upgrade has been set at US $65 plus shipping and handling. -I was a beta test site for the BT-948 and versions 1.2.1 and 1.3.1 of my -BusLogic driver already include latent support for the BT-948. Additional -cosmetic support for the Ultra SCSI MultiMaster cards will be added in a -subsequent release. As a result of this cooperative testing process, -several firmware bugs were found and corrected (make sure you have firmware -version 5.05R or later). My heavily loaded Linux test system provided an -ideal environment for testing error recovery processes that are much more -rarely exercised in production systems, but are crucial to overall system -stability. It was especially convenient being able to work directly with -their firmware engineer in demonstrating the problems under control of the -firmware debugging environment; things sure have come a long way since the -last time I worked on firmware for an embedded system. I am presently -working on some performance testing and expect to have some data to report -in the not too distant future. +I was a beta test site for the BT-948/958, and versions 1.2.1 and 1.3.1 of +my BusLogic driver already included latent support for the BT-948/958. +Additional cosmetic support for the Ultra SCSI MultiMaster cards was added +subsequent releases. As a result of this cooperative testing process, +several firmware bugs were found and corrected. My heavily loaded Linux +test system provided an ideal environment for testing error recovery +processes that are much more rarely exercised in production systems, but +are crucial to overall system stability. It was especially convenient +being able to work directly with their firmware engineer in demonstrating +the problems under control of the firmware debugging environment; things +sure have come a long way since the last time I worked on firmware for an +embedded system. I am presently working on some performance testing and +expect to have some data to report in the not too distant future. BusLogic asked me to send this announcement since a large percentage of the questions regarding support for the FlashPoint have either been sent to me directly via email, or have appeared in the Linux newsgroups in which I participate. To summarize, BusLogic is offering Linux users an upgrade from the unsupported FlashPoint LT (BT-930) to the supported BT-948 for US -$45. Contact BusLogic Technical Support at techsup@buslogic.com or +1 408 +$45 plus shipping and handling, or from the unsupported FlashPoint LW +(BT-950) to the supported BT-958 for $65 plus shipping and handling. +Contact BusLogic Technical Support at techsup@buslogic.com or +1 408 654-0760 to take advantage of their offer. Leonard N. Zubkoff diff --git a/drivers/scsi/ncr53c8xx.c b/drivers/scsi/ncr53c8xx.c index 19baf073b6b2..ee08fa11e7bb 100644 --- a/drivers/scsi/ncr53c8xx.c +++ b/drivers/scsi/ncr53c8xx.c @@ -8023,6 +8023,12 @@ printf("ncr_user_command: data=%ld\n", uc->data); break; } + /* + ** Not allow to disable tagged queue + */ + if (uc->cmd == UC_SETTAGS && uc->data < 1) + return -EINVAL; + if (len) return -EINVAL; #ifdef SCSI_NCR_USER_COMMAND diff --git a/drivers/scsi/scsi.c b/drivers/scsi/scsi.c index e47f62bda168..62f35cbace32 100644 --- a/drivers/scsi/scsi.c +++ b/drivers/scsi/scsi.c @@ -1621,6 +1621,7 @@ static void scsi_done (Scsi_Cmnd * SCpnt) break; case CHECK_CONDITION: + case COMMAND_TERMINATED: switch (check_sense(SCpnt)) { case 0: @@ -1652,6 +1653,7 @@ static void scsi_done (Scsi_Cmnd * SCpnt) break; case BUSY: + case QUEUE_FULL: update_timeout(SCpnt, oldto); status = REDO; break; diff --git a/drivers/scsi/sd.c b/drivers/scsi/sd.c index e6660e8631c7..c3eed8117d20 100644 --- a/drivers/scsi/sd.c +++ b/drivers/scsi/sd.c @@ -1388,7 +1388,8 @@ static void sd_finish() static int sd_detect(Scsi_Device * SDp){ if(SDp->type != TYPE_DISK && SDp->type != TYPE_MOD) return 0; - printk("Detected scsi disk sd%c at scsi%d, channel %d, id %d, lun %d\n", + printk("Detected scsi %sdisk sd%c at scsi%d, channel %d, id %d, lun %d\n", + SDp->removable ? "removable " : "", 'a'+ (sd_template.dev_noticed++), SDp->host->host_no, SDp->channel, SDp->id, SDp->lun); diff --git a/drivers/scsi/st.c b/drivers/scsi/st.c index a6f0f6b7d50b..06bddf75f389 100644 --- a/drivers/scsi/st.c +++ b/drivers/scsi/st.c @@ -11,7 +11,7 @@ Copyright 1992 - 1996 Kai Makisara email Kai.Makisara@metla.fi - Last modified: Sun Jun 30 15:26:23 1996 by root@kai.makisara.fi + Last modified: Sun Jul 7 10:08:46 1996 by root@kai.makisara.fi Some small formal changes - aeb, 950809 */ @@ -1414,6 +1414,7 @@ st_read(struct inode * inode, struct file * filp, char * buf, int count) SCpnt->request.rq_status = RQ_INACTIVE; /* Mark as not busy */ if (total == 0 && STp->eof == ST_FM) { STp->eof = ST_NOEOF; + STp->eof_hit = 0; STp->drv_block = 0; if (STps->moves_after_eof > 1) STps->moves_after_eof = 0; @@ -2038,7 +2039,9 @@ st_int_ioctl(struct inode * inode, if (cmd_in == MTFSF) STps->moves_after_eof = 0; - else if (cmd_in != MTLOAD) + else if (cmd_in != MTLOAD && cmd_in != MTLOCK && cmd_in != MTUNLOCK && + cmd_in != MTSETBLK && cmd_in != MTSETDENSITY && + cmd_in != MTSETDRVBUFFER) STps->moves_after_eof = 1; if (!ioctl_result) { /* SCSI command successful */ STp->drv_block = blkno; @@ -2537,12 +2540,12 @@ st_ioctl(struct inode * inode,struct file * file, if (!(STp->device)->was_reset) { if (STp->eof_hit) { - if (mtc.mt_op == MTFSF || mtc.mt_op == MTEOM) { + if (mtc.mt_op == MTFSF || mtc.mt_op == MTFSFM|| mtc.mt_op == MTEOM) { mtc.mt_count -= 1; if ((STp->mt_status)->mt_fileno >= 0) (STp->mt_status)->mt_fileno += 1; } - else if (mtc.mt_op == MTBSF) { + else if (mtc.mt_op == MTBSF || mtc.mt_op == MTBSFM) { mtc.mt_count += 1; if ((STp->mt_status)->mt_fileno >= 0) (STp->mt_status)->mt_fileno += 1; diff --git a/drivers/sound/dev_table.h b/drivers/sound/dev_table.h index 063ee916933d..1fbb9480501c 100644 --- a/drivers/sound/dev_table.h +++ b/drivers/sound/dev_table.h @@ -331,7 +331,7 @@ struct sound_timer_operations { #ifdef CONFIG_SB {"SBLAST", 0, SNDCARD_SB, "Sound Blaster", attach_sb_card, probe_sb, unload_sb}, #ifdef CONFIG_MIDI - {"UART401", 0, SNDCARD_UART401,"MPU-401 UART", attach_uart401, probe_uart401, unload_uart401}, + {"SBMPU", 0, SNDCARD_SB16MIDI,"SB MPU-401", attach_sbmpu, probe_sbmpu, unload_sbmpu}, #endif #endif #ifdef CONFIG_GUS16 diff --git a/drivers/sound/lowlevel/aci.readme b/drivers/sound/lowlevel/aci.readme deleted file mode 100644 index 960b9a69ad30..000000000000 --- a/drivers/sound/lowlevel/aci.readme +++ /dev/null @@ -1,40 +0,0 @@ - -ACI mixer driver extension (miroSOUND PCM12) for Linux ------------------------------------------------------- - -Markus Kuhn -- 1995-12-31 - - -This is the ACI mixer driver for the miroSOUND PCM12 soundcard. It -works probably also for other ACI miroSOUND boards like the PCM1 pro -or the PCM20, however this has not been tested. - -Just copy the file aci.c into the /usr/src/linux/drivers/sound/ -subdirectory, then change to the subdirectory /usr/src/linux/drivers/ -and apply with "patch -p0 - Germany -WWW Home: diff --git a/drivers/sound/pas2_pcm.c b/drivers/sound/pas2_pcm.c index b685f57cc993..973613c9e39e 100644 --- a/drivers/sound/pas2_pcm.c +++ b/drivers/sound/pas2_pcm.c @@ -41,6 +41,9 @@ pcm_set_speed (int arg) int foo, tmp; unsigned long flags; + if (arg == 0) + return pcm_speed; + if (arg > 44100) arg = 44100; if (arg < 5000) @@ -127,6 +130,9 @@ pcm_set_channels (int arg) int pcm_set_bits (int arg) { + if (arg == 0) + return pcm_bits; + if ((arg & pcm_bitsok) != arg) return pcm_bits; diff --git a/drivers/sound/sb.h b/drivers/sound/sb.h index 6dfeb072db16..40a415c14b37 100644 --- a/drivers/sound/sb.h +++ b/drivers/sound/sb.h @@ -83,7 +83,7 @@ typedef struct sb_devc { volatile int intr_active, irq_mode; /* Mixer fields */ - int levels[SOUND_MIXER_NRDEVICES]; + unsigned short levels[SOUND_MIXER_NRDEVICES]; mixer_tab *iomap; int mixer_caps, recmask, supported_devices; int supported_rec_devices; diff --git a/drivers/sound/sb_common.c b/drivers/sound/sb_common.c index 0ccd2dd94d41..9093d8cae1b9 100644 --- a/drivers/sound/sb_common.c +++ b/drivers/sound/sb_common.c @@ -261,6 +261,29 @@ sb16_set_dma_hw (sb_devc * devc) return 1; } +static void +sb16_set_mpu_port(sb_devc *devc, struct address_info *hw_config) +{ +/* + * This routine initializes new MIDI port setup register of SB Vibra. + */ + unsigned char bits = sb_getmixer(devc, 0x84) & ~0x06; + switch (hw_config->io_base) + { + case 0x300: + sb_setmixer (devc, 0x84, bits | 0x04); + break; + + case 0x330: + sb_setmixer (devc, 0x84, bits | 0x00); + break; + + default: + sb_setmixer (devc, 0x84, bits | 0x02); /* Disable MPU */ + printk("SB16: Invalid MIDI I/O port %x\n", hw_config->io_base); + } +} + static int sb16_set_irq_hw (sb_devc * devc, int level) { @@ -1150,6 +1173,7 @@ probe_sbmpu (struct address_info *hw_config) } hw_config->name = "Sound Blaster 16"; hw_config->irq = -devc->irq; + sb16_set_mpu_port(devc, hw_config) break; case MDL_ESS: diff --git a/drivers/sound/sscape.c b/drivers/sound/sscape.c index c3a679fe656d..f28ed5f996da 100644 --- a/drivers/sound/sscape.c +++ b/drivers/sound/sscape.c @@ -304,7 +304,7 @@ sscapeintr (int irq, void *dev_id, struct pt_regs *dummy) printk ("SSCAPE: Host interrupt, data=%02x\n", host_read (devc)); } -#if defined(CONFIG_MPU401) && defined(CONFIG_MIDI) +#if defined(CONFIG_MPU_EMU) && defined(CONFIG_MIDI) if (bits & 0x01) { mpuintr (irq, NULL, NULL); @@ -787,7 +787,7 @@ attach_sscape (struct address_info *hw_config) } #endif -#if defined(CONFIG_MIDI) && defined(CONFIG_MPU401) +#if defined(CONFIG_MIDI) && defined(CONFIG_MPU_EMU) if (probe_mpu401 (hw_config)) hw_config->always_detect = 1; { @@ -990,7 +990,7 @@ attach_ss_ms_sound (struct address_info *hw_config) void unload_sscape (struct address_info *hw_config) { -#if defined(CONFIG_MPU401) && defined(CONFIG_MIDI) +#if defined(CONFIG_MPU_EMU) && defined(CONFIG_MIDI) unload_mpu401 (hw_config); #endif snd_release_irq (hw_config->irq); diff --git a/fs/ext2/super.c b/fs/ext2/super.c index 9cf9fc1cbe5a..f2fbe6177025 100644 --- a/fs/ext2/super.c +++ b/fs/ext2/super.c @@ -375,6 +375,7 @@ struct super_block * ext2_read_super (struct super_block * sb, void * data, int db_count; int i, j; + sb->u.ext2_sb.s_mount_opt = 0; set_opt (sb->u.ext2_sb.s_mount_opt, CHECK_NORMAL); if (!parse_options ((char *) data, &sb_block, &resuid, &resgid, &sb->u.ext2_sb.s_mount_opt)) { diff --git a/fs/namei.c b/fs/namei.c index 4ba75622e3f2..302db71d2985 100644 --- a/fs/namei.c +++ b/fs/namei.c @@ -102,6 +102,9 @@ int permission(struct inode * inode,int mask) if (inode->i_op && inode->i_op->permission) return inode->i_op->permission(inode, mask); + else if ((mask & S_IWOTH) && IS_RDONLY(inode) && + (S_ISREG(mode) || S_ISDIR(mode) || S_ISLNK(mode))) + return -EROFS; /* Nobody gets write access to a read-only fs */ else if ((mask & S_IWOTH) && IS_IMMUTABLE(inode)) return -EACCES; /* Nobody gets write access to an immutable file */ else if (current->fsuid == inode->i_uid) @@ -363,12 +366,12 @@ int open_namei(const char * pathname, int flag, int mode, iput(inode); error = -EEXIST; } - } else if ((error = permission(dir,MAY_WRITE | MAY_EXEC)) != 0) - ; /* error is already set! */ + } else if (IS_RDONLY(dir)) + error = -EROFS; else if (!dir->i_op || !dir->i_op->create) error = -EACCES; - else if (IS_RDONLY(dir)) - error = -EROFS; + else if ((error = permission(dir,MAY_WRITE | MAY_EXEC)) != 0) + ; /* error is already set! */ else { dir->i_count++; /* create eats the dir */ if (dir->i_sb && dir->i_sb->dq_op) @@ -405,6 +408,7 @@ int open_namei(const char * pathname, int flag, int mode, * If there was something like IS_NODEV(inode) for * pipes and/or sockets I'd check it here. */ + flag &= ~O_TRUNC; } else if (S_ISBLK(inode->i_mode) || S_ISCHR(inode->i_mode)) { if (IS_NODEV(inode)) { diff --git a/fs/open.c b/fs/open.c index 4d908b08a60d..ccc69e1c51e0 100644 --- a/fs/open.c +++ b/fs/open.c @@ -184,7 +184,8 @@ asmlinkage int sys_utime(char * filename, struct utimbuf * times) newattrs.ia_mtime = get_user(×->modtime); newattrs.ia_valid |= ATTR_ATIME_SET | ATTR_MTIME_SET; } else { - if ((error = permission(inode,MAY_WRITE)) != 0) { + if (current->fsuid != inode->i_uid && + (error = permission(inode,MAY_WRITE)) != 0) { iput(inode); return error; } diff --git a/fs/pipe.c b/fs/pipe.c index 0d8277caf07e..64636c38bc8d 100644 --- a/fs/pipe.c +++ b/fs/pipe.c @@ -216,16 +216,8 @@ static int fifo_select(struct inode * inode, struct file * filp, int sel_type, s */ static int connect_read(struct inode * inode, struct file * filp, char * buf, int count) { - while (!PIPE_SIZE(*inode)) { - if (PIPE_WRITERS(*inode)) - break; - if (filp->f_flags & O_NONBLOCK) - return -EAGAIN; - wake_up_interruptible(& PIPE_WAIT(*inode)); - if (current->signal & ~current->blocked) - return -ERESTARTSYS; - interruptible_sleep_on(& PIPE_WAIT(*inode)); - } + if (PIPE_EMPTY(*inode) && !PIPE_WRITERS(*inode)) + return 0; filp->f_op = &read_fifo_fops; return pipe_read(inode,filp,buf,count); } @@ -238,6 +230,9 @@ static int connect_select(struct inode * inode, struct file * filp, int sel_type filp->f_op = &read_fifo_fops; return 1; } + if (PIPE_WRITERS(*inode)) { + filp->f_op = &read_fifo_fops; + } select_wait(&PIPE_WAIT(*inode), wait); return 0; case SEL_OUT: diff --git a/fs/ufs/ufs_super.c b/fs/ufs/ufs_super.c index c0b1e0094314..b8b8f22d2e02 100644 --- a/fs/ufs/ufs_super.c +++ b/fs/ufs/ufs_super.c @@ -129,7 +129,13 @@ ufs_read_super(struct super_block * sb, void * data, int silent) /* XXX - redo this so we can free it later... */ usb = (struct ufs_superblock *)__get_free_page(GFP_KERNEL); if (usb == NULL) { + sb->s_dev=0; + unlock_super(sb); + brelse(bh1); + brelse(bh2); printk ("ufs_read_super: get_free_page() failed\n"); + MOD_DEC_USE_COUNT; + return (NULL); } memcpy((char *)usb, bh1->b_data, BLOCK_SIZE); diff --git a/include/asm-ppc/posix_types.h b/include/asm-ppc/posix_types.h index 03cb50ce2003..0b180d79505c 100644 --- a/include/asm-ppc/posix_types.h +++ b/include/asm-ppc/posix_types.h @@ -77,15 +77,15 @@ static __inline__ void __FD_ZERO(__kernel_fd_set *p) unsigned int *tmp = p->fds_bits; int i; - if (__builtin_constant_p(__FDSET_INTS)) { - switch (__FDSET_INTS) { + if (__builtin_constant_p(__FDSET_LONGS)) { + switch (__FDSET_LONGS) { case 8: tmp[0] = 0; tmp[1] = 0; tmp[2] = 0; tmp[3] = 0; tmp[4] = 0; tmp[5] = 0; tmp[6] = 0; tmp[7] = 0; return; } } - i = __FDSET_INTS; + i = __FDSET_LONGS; while (i) { i--; *tmp = 0; diff --git a/arch/ppc/kernel/ppc_machine.h b/include/asm-ppc/ppc_machine.h similarity index 100% rename from arch/ppc/kernel/ppc_machine.h rename to include/asm-ppc/ppc_machine.h diff --git a/include/asm-ppc/unaligned.h b/include/asm-ppc/unaligned.h new file mode 100644 index 000000000000..90a54eae9bb5 --- /dev/null +++ b/include/asm-ppc/unaligned.h @@ -0,0 +1,16 @@ +#ifndef __PPC_UNALIGNED_H +#define __PPC_UNALIGNED_H + +/* + * The PowerPC can do unaligned accesses itself in big endian mode. + * + * The strange macros are there to make sure these can't + * be misused in a way that makes them not work on other + * architectures where unaligned accesses aren't as simple. + */ + +#define get_unaligned(ptr) (*(ptr)) + +#define put_unaligned(val, ptr) ((void)( *(ptr) = (val) )) + +#endif diff --git a/include/asm-ppc/unistd.h b/include/asm-ppc/unistd.h index 0e6ec2b73594..be4cee27e862 100644 --- a/include/asm-ppc/unistd.h +++ b/include/asm-ppc/unistd.h @@ -1,4 +1,3 @@ -/* * Last edited: Nov 17 16:28 1995 (cort) */ #ifndef _ASM_PPC_UNISTD_H_ #define _ASM_PPC_UNISTD_H_ @@ -154,97 +153,145 @@ #define __NR__newselect 142 #define __NR_flock 143 #define __NR_msync 144 -/*#define __NR_kclone 145*/ +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 + +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 -/* XXX - _foo needs to be __foo, while __NR_bar could be _NR_bar. */ #define _syscall0(type,name) \ type name(void) \ { \ - __asm__ (_lisc(__NR_##name)); \ - __asm__ ("sc"); \ - __asm__ ("mr 31,3"); \ - __asm__ ("bns 10f"); \ - __asm__ ("mr 0,3"); \ - __asm__ ("lis 3,errno@ha"); \ - __asm__ ("stw 0,errno@l(3)"); \ - __asm__ ("li 3,-1"); \ - __asm__ ("10:"); \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval);\ } #define _syscall1(type,name,type1,arg1) \ type name(type1 arg1) \ { \ - __asm__ (_lisc(__NR_##name)); \ - __asm__ ("sc"); \ - __asm__ ("mr 31,3"); \ - __asm__ ("bns 10f"); \ - __asm__ ("mr 0,3"); \ - __asm__ ("lis 3,errno@ha"); \ - __asm__ ("stw 0,errno@l(3)"); \ - __asm__ ("li 3,-1"); \ - __asm__ ("10:"); \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ } #define _syscall2(type,name,type1,arg1,type2,arg2) \ type name(type1 arg1,type2 arg2) \ { \ - __asm__ (_lisc(__NR_##name)); \ - __asm__ ("sc"); \ - __asm__ ("mr 31,3"); \ - __asm__ ("bns 10f"); \ - __asm__ ("mr 0,3"); \ - __asm__ ("lis 3,errno@ha"); \ - __asm__ ("stw 0,errno@l(3)"); \ - __asm__ ("li 3,-1"); \ - __asm__ ("10:"); \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ } + #define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ -type name(type1 arg1,type2 arg2,type3 arg3) \ +type name(type1 arg1,type2 arg2, type3 arg3) \ { \ - __asm__ (_lisc(__NR_##name)); \ - __asm__ ("sc"); \ - __asm__ ("mr 31,3"); \ - __asm__ ("bns 10f"); \ - __asm__ ("mr 0,3"); \ - __asm__ ("lis 3,errno@ha"); \ - __asm__ ("stw 0,errno@l(3)"); \ - __asm__ ("li 3,-1"); \ - __asm__ ("10:"); \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ } #define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ { \ - __asm__ (_lisc(__NR_##name)); \ - __asm__ ("sc"); \ - __asm__ ("mr 31,3"); \ - __asm__ ("bns 10f"); \ - __asm__ ("mr 0,3"); \ - __asm__ ("lis 3,errno@ha"); \ - __asm__ ("stw 0,errno@l(3)"); \ - __asm__ ("li 3,-1"); \ - __asm__ ("10:"); \ -} + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} #define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ type5,arg5) \ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ { \ - __asm__ (_lisc(__NR_##name)); \ - __asm__ ("sc"); \ - __asm__ ("mr 31,3"); \ - __asm__ ("bns 10f"); \ - __asm__ ("mr 0,3"); \ - __asm__ ("lis 3,errno@ha"); \ - __asm__ ("stw 0,errno@l(3)"); \ - __asm__ ("li 3,-1"); \ - __asm__ ("10:"); \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ } #ifdef __KERNEL_SYSCALLS__ - /* * we need this inline - forking from kernel space will result * in NO COPY ON WRITE (!!!), until an execve is executed. This @@ -258,83 +305,72 @@ type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ * some others too. */ -extern long __kernel_thread(unsigned long, int (*)(void *), void *); - -static inline long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) -{ - return __kernel_thread(flags | CLONE_VM, fn, arg); -} - /* some of these had problems getting the right arguments (namely sys_clone()) - when they were inline. + when they were inline so I made them non-inline until we get problems with gcc + worked out. I need to check with Linus to find out which he wants inline now + since the above comment was written a long time ago. + + Once I understand the macro language better this should go away. -- Cort */ -#define __NR__exit __NR_exit -static inline _syscall0(int,idle) /* made inline "just in case" -- Cort */ -static inline _syscall0(int,fork) /* needs to be inline */ -static inline _syscall0(int,pause) /* needs to be inline */ -static inline _syscall0(int,setup) /* called in init before execve */ -static inline _syscall0(int,sync) -static inline _syscall0(pid_t,setsid) -static /*inline*/ _syscall3(int,write,int,fd,const char *,buf,off_t,count) -static /*inline*/ _syscall1(int,dup,int,fd) -static /*inline*/ _syscall3(int,execve,const char *,file,char **,argv,char **,envp) -static /*inline*/ _syscall3(int,open,const char *,file,int,flag,int,mode) -static inline _syscall1(int,close,int,fd) -static /*inline*/ _syscall1(int,_exit,int,exitcode) -static inline _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) -/*static inline _syscall2(int,clone,unsigned long,flags,char *,esp)*/ -/* - syscalls from kernel mode is a little strange and I can't get used to - the idea -- this makes me feel better. -- Cort - */ -/*static inline int kclone (void) -{ - __asm__ (_lisc(__NR_kclone)); - __asm__ ("sc"); - __asm__ ("mr 31,3"); - __asm__ ("bns 10f"); - __asm__ ("mr 0,3"); - __asm__ ("lis 3,errno@ha"); - __asm__ ("stw 0,errno@l(3)"); - __asm__ ("li 3,-1"); - __asm__ ("10:"); -}*/ +#define __NR__exit __NR_exit +static /*__inline__*/ _syscall0(int,setup) +static __inline__ _syscall0(int,idle) +static /*__inline__*/ _syscall0(int,fork) +static __inline__ _syscall0(int,pause) +static __inline__ _syscall0(int,sync) +static __inline__ _syscall0(pid_t,setsid) +static __inline__ _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static /*__inline__*/ _syscall1(int,dup,int,fd) +static /*__inline__*/ _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +static __inline__ _syscall3(int,open,const char *,file,int,flag,int,mode) +static /*__inline__*/ _syscall1(int,close,int,fd) +static /*__inline__*/ _syscall1(int,_exit,int,exitcode) +static __inline__ _syscall2(int,clone,unsigned long,flags,char *,esp) +static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) -static inline int clone (unsigned long flags,char *esp) +static __inline__ pid_t wait(int * wait_stat) { -/* printk("unistd.h: clone(): flags = %x, esp = %x\n", flags, esp);*/ - __asm__ (_lisc(__NR_clone)); - __asm__ ("sc"); - __asm__ ("mr 31,3"); - -/* this is a hack to get the damned thing to return something even though inlined - -- Cort - */ - __asm__ ("mr 0,3"); - __asm__ ("lis 3,errno@ha"); - __asm__ ("stw 0,errno@l(3)"); - - __asm__ ("bns 10f"); - __asm__ ("mr 0,3"); - __asm__ ("lis 3,errno@ha"); - __asm__ ("stw 0,errno@l(3)"); - __asm__ ("li 3,-1"); - __asm__ ("10:"); - return errno; + return waitpid(-1,wait_stat,0); } - -/* called from init before execve -- need to be inline? -- Cort */ -static inline pid_t wait(int * wait_stat) +/* + This is the mechanism for creating a new kernel thread. + For the time being it only behaves the same as clone(). + It should be changed very soon to work properly and cleanly. This + gets us going for now, though. + -- Cort + */ +static __inline__ long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) { - return waitpid(-1,wait_stat,0); + long retval; + __asm__ ( + "li 0, 120 \n\t" /* __NR_clone */ + "li 3, %5 \n\t" /* load flags as arg to clone */ + /*"mr 1,7 \n\t"*/ /* save kernel stack */ + "sc \n\t" /* syscall */ + /*"cmp 0,1,7 \n\t"*/ /* if kernel stack changes -- child */ + "cmpi 0,3,0 \n\t" + "bne 1f \n\t" /* return if parent */ + /* this is in child */ + "li 3, %3 \n\t" /* child -- load args and call fn */ + "mtlr %4 \n\t" + "blrl \n\t" + "li 0, %2 \n\t" /* exit after child exits */ + "li 3, 0 \n\t" + "sc \n\t" + /* parent */ + "1: \n\t" + :"=3" (retval) + :"i" (__NR_clone), "i" (__NR_exit), + "r" (arg), "r" (fn), "g" (CLONE_VM|flags) + :"cc", "1", "0", "3", "7", "31", "memory" ); + return retval; } -#endif - -#endif /* _ASM_PPC_UNISTD_H_ */ +#endif /* __KERNEL_SYSCALLS__ */ +#endif /* _ASM_PPC_UNISTD_H_ */ diff --git a/include/asm-ppc/unistd.h.cort b/include/asm-ppc/unistd.h.cort new file mode 100644 index 000000000000..be4cee27e862 --- /dev/null +++ b/include/asm-ppc/unistd.h.cort @@ -0,0 +1,376 @@ +#ifndef _ASM_PPC_UNISTD_H_ +#define _ASM_PPC_UNISTD_H_ + +#define _NR(n) #n +#define _lisc(n) "li 0," _NR(n) + +/* + * This file contains the system call numbers. + */ + +#define __NR_setup 0 /* used only by init, to get system going */ +#define __NR_exit 1 +#define __NR_fork 2 +#define __NR_read 3 +#define __NR_write 4 +#define __NR_open 5 +#define __NR_close 6 +#define __NR_waitpid 7 +#define __NR_creat 8 +#define __NR_link 9 +#define __NR_unlink 10 +#define __NR_execve 11 +#define __NR_chdir 12 +#define __NR_time 13 +#define __NR_mknod 14 +#define __NR_chmod 15 +#define __NR_chown 16 +#define __NR_break 17 +#define __NR_oldstat 18 +#define __NR_lseek 19 +#define __NR_getpid 20 +#define __NR_mount 21 +#define __NR_umount 22 +#define __NR_setuid 23 +#define __NR_getuid 24 +#define __NR_stime 25 +#define __NR_ptrace 26 +#define __NR_alarm 27 +#define __NR_oldfstat 28 +#define __NR_pause 29 +#define __NR_utime 30 +#define __NR_stty 31 +#define __NR_gtty 32 +#define __NR_access 33 +#define __NR_nice 34 +#define __NR_ftime 35 +#define __NR_sync 36 +#define __NR_kill 37 +#define __NR_rename 38 +#define __NR_mkdir 39 +#define __NR_rmdir 40 +#define __NR_dup 41 +#define __NR_pipe 42 +#define __NR_times 43 +#define __NR_prof 44 +#define __NR_brk 45 +#define __NR_setgid 46 +#define __NR_getgid 47 +#define __NR_signal 48 +#define __NR_geteuid 49 +#define __NR_getegid 50 +#define __NR_acct 51 +#define __NR_phys 52 +#define __NR_lock 53 +#define __NR_ioctl 54 +#define __NR_fcntl 55 +#define __NR_mpx 56 +#define __NR_setpgid 57 +#define __NR_ulimit 58 +#define __NR_oldolduname 59 +#define __NR_umask 60 +#define __NR_chroot 61 +#define __NR_ustat 62 +#define __NR_dup2 63 +#define __NR_getppid 64 +#define __NR_getpgrp 65 +#define __NR_setsid 66 +#define __NR_sigaction 67 +#define __NR_sgetmask 68 +#define __NR_ssetmask 69 +#define __NR_setreuid 70 +#define __NR_setregid 71 +#define __NR_sigsuspend 72 +#define __NR_sigpending 73 +#define __NR_sethostname 74 +#define __NR_setrlimit 75 +#define __NR_getrlimit 76 +#define __NR_getrusage 77 +#define __NR_gettimeofday 78 +#define __NR_settimeofday 79 +#define __NR_getgroups 80 +#define __NR_setgroups 81 +#define __NR_select 82 +#define __NR_symlink 83 +#define __NR_oldlstat 84 +#define __NR_readlink 85 +#define __NR_uselib 86 +#define __NR_swapon 87 +#define __NR_reboot 88 +#define __NR_readdir 89 +#define __NR_mmap 90 +#define __NR_munmap 91 +#define __NR_truncate 92 +#define __NR_ftruncate 93 +#define __NR_fchmod 94 +#define __NR_fchown 95 +#define __NR_getpriority 96 +#define __NR_setpriority 97 +#define __NR_profil 98 +#define __NR_statfs 99 +#define __NR_fstatfs 100 +#define __NR_ioperm 101 +#define __NR_socketcall 102 +#define __NR_syslog 103 +#define __NR_setitimer 104 +#define __NR_getitimer 105 +#define __NR_stat 106 +#define __NR_lstat 107 +#define __NR_fstat 108 +#define __NR_olduname 109 +#define __NR_iopl 110 +#define __NR_vhangup 111 +#define __NR_idle 112 +#define __NR_vm86 113 +#define __NR_wait4 114 +#define __NR_swapoff 115 +#define __NR_sysinfo 116 +#define __NR_ipc 117 +#define __NR_fsync 118 +#define __NR_sigreturn 119 +#define __NR_clone 120 +#define __NR_setdomainname 121 +#define __NR_uname 122 +#define __NR_modify_ldt 123 +#define __NR_adjtimex 124 +#define __NR_mprotect 125 +#define __NR_sigprocmask 126 +#define __NR_create_module 127 +#define __NR_init_module 128 +#define __NR_delete_module 129 +#define __NR_get_kernel_syms 130 +#define __NR_quotactl 131 +#define __NR_getpgid 132 +#define __NR_fchdir 133 +#define __NR_bdflush 134 +#define __NR_sysfs 135 +#define __NR_personality 136 +#define __NR_afs_syscall 137 /* Syscall for Andrew File System */ +#define __NR_setfsuid 138 +#define __NR_setfsgid 139 +#define __NR__llseek 140 +#define __NR_getdents 141 +#define __NR__newselect 142 +#define __NR_flock 143 +#define __NR_msync 144 +#define __NR_readv 145 +#define __NR_writev 146 +#define __NR_getsid 147 + +#define __NR_mlock 150 +#define __NR_munlock 151 +#define __NR_mlockall 152 +#define __NR_munlockall 153 + + +#define _syscall0(type,name) \ +type name(void) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval);\ +} + +#define _syscall1(type,name,type1,arg1) \ +type name(type1 arg1) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#define _syscall2(type,name,type1,arg1,type2,arg2) \ +type name(type1 arg1,type2 arg2) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + + +#define _syscall3(type,name,type1,arg1,type2,arg2,type3,arg3) \ +type name(type1 arg1,type2 arg2, type3 arg3) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#define _syscall4(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4) \ +type name (type1 arg1, type2 arg2, type3 arg3, type4 arg4) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#define _syscall5(type,name,type1,arg1,type2,arg2,type3,arg3,type4,arg4, \ + type5,arg5) \ +type name (type1 arg1,type2 arg2,type3 arg3,type4 arg4,type5 arg5) \ +{ \ + long retval; \ + __asm__ ( \ + "li 0, %0 \n\t" \ + "sc \n\t" \ + "mr 31,3 \n\t" \ + "bns 10f \n\t" \ + "mr 0,3 \n\t" \ + "lis 3,errno@ha \n\t" \ + "stw 0,errno@l(3) \n\t" \ + "li 3,-1 \n\t" \ + "10: \n\t" \ + : \ + : "i" (__NR_##name) \ + : "0", "31", "3", "cc", "memory" \ + ); \ + return(retval); \ +} + +#ifdef __KERNEL_SYSCALLS__ +/* + * we need this inline - forking from kernel space will result + * in NO COPY ON WRITE (!!!), until an execve is executed. This + * is no problem, but for the stack. This is handled by not letting + * main() use the stack at all after fork(). Thus, no function + * calls - which means inline code for fork too, as otherwise we + * would use the stack upon exit from 'fork()'. + * + * Actually only pause and fork are needed inline, so that there + * won't be any messing with the stack from main(), but we define + * some others too. + */ + +/* + some of these had problems getting the right arguments (namely sys_clone()) + when they were inline so I made them non-inline until we get problems with gcc + worked out. I need to check with Linus to find out which he wants inline now + since the above comment was written a long time ago. + + Once I understand the macro language better this should go away. + -- Cort + */ + +#define __NR__exit __NR_exit +static /*__inline__*/ _syscall0(int,setup) +static __inline__ _syscall0(int,idle) +static /*__inline__*/ _syscall0(int,fork) +static __inline__ _syscall0(int,pause) +static __inline__ _syscall0(int,sync) +static __inline__ _syscall0(pid_t,setsid) +static __inline__ _syscall3(int,write,int,fd,const char *,buf,off_t,count) +static /*__inline__*/ _syscall1(int,dup,int,fd) +static /*__inline__*/ _syscall3(int,execve,const char *,file,char **,argv,char **,envp) +static __inline__ _syscall3(int,open,const char *,file,int,flag,int,mode) +static /*__inline__*/ _syscall1(int,close,int,fd) +static /*__inline__*/ _syscall1(int,_exit,int,exitcode) +static __inline__ _syscall2(int,clone,unsigned long,flags,char *,esp) +static __inline__ _syscall3(pid_t,waitpid,pid_t,pid,int *,wait_stat,int,options) + +static __inline__ pid_t wait(int * wait_stat) +{ + return waitpid(-1,wait_stat,0); +} + +/* + This is the mechanism for creating a new kernel thread. + For the time being it only behaves the same as clone(). + It should be changed very soon to work properly and cleanly. This + gets us going for now, though. + -- Cort + */ +static __inline__ long kernel_thread(int (*fn)(void *), void * arg, unsigned long flags) +{ + long retval; + __asm__ ( + "li 0, 120 \n\t" /* __NR_clone */ + "li 3, %5 \n\t" /* load flags as arg to clone */ + /*"mr 1,7 \n\t"*/ /* save kernel stack */ + "sc \n\t" /* syscall */ + /*"cmp 0,1,7 \n\t"*/ /* if kernel stack changes -- child */ + "cmpi 0,3,0 \n\t" + "bne 1f \n\t" /* return if parent */ + /* this is in child */ + "li 3, %3 \n\t" /* child -- load args and call fn */ + "mtlr %4 \n\t" + "blrl \n\t" + "li 0, %2 \n\t" /* exit after child exits */ + "li 3, 0 \n\t" + "sc \n\t" + /* parent */ + "1: \n\t" + :"=3" (retval) + :"i" (__NR_clone), "i" (__NR_exit), + "r" (arg), "r" (fn), "g" (CLONE_VM|flags) + :"cc", "1", "0", "3", "7", "31", "memory" ); + return retval; +} + + +#endif /* __KERNEL_SYSCALLS__ */ + +#endif /* _ASM_PPC_UNISTD_H_ */ diff --git a/include/linux/baycom.h b/include/linux/baycom.h index fb656acfd813..4a727e144d40 100644 --- a/include/linux/baycom.h +++ b/include/linux/baycom.h @@ -8,6 +8,7 @@ #define _BAYCOM_H #include +#undef BAYCOM_DEBUG /* -------------------------------------------------------------------- */ diff --git a/include/linux/pci.h b/include/linux/pci.h index 516c93dbeee4..21464d1e321d 100644 --- a/include/linux/pci.h +++ b/include/linux/pci.h @@ -339,10 +339,10 @@ #define PCI_DEVICE_ID_SGS_2000 0x0008 #define PCI_DEVICE_ID_SGS_1764 0x0009 -#define PCI_VENDOR_ID_BUSLOGIC 0x104B -#define PCI_DEVICE_ID_BUSLOGIC_946C_2 0x0140 -#define PCI_DEVICE_ID_BUSLOGIC_946C 0x1040 -#define PCI_DEVICE_ID_BUSLOGIC_930 0x8130 +#define PCI_VENDOR_ID_BUSLOGIC 0x104B +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER_NC 0x0140 +#define PCI_DEVICE_ID_BUSLOGIC_MULTIMASTER 0x1040 +#define PCI_DEVICE_ID_BUSLOGIC_FLASHPOINT 0x8130 #define PCI_VENDOR_ID_OAK 0x104e #define PCI_DEVICE_ID_OAK_OTI107 0x0107 diff --git a/include/scsi/scsi.h b/include/scsi/scsi.h index 6907e5e36ea3..8328210e856c 100644 --- a/include/scsi/scsi.h +++ b/include/scsi/scsi.h @@ -94,7 +94,8 @@ #define INTERMEDIATE_GOOD 0x08 #define INTERMEDIATE_C_GOOD 0x0a #define RESERVATION_CONFLICT 0x0c -#define QUEUE_FULL 0x1a +#define COMMAND_TERMINATED 0x11 +#define QUEUE_FULL 0x14 #define STATUS_MASK 0x3e diff --git a/kernel/ksyms.c b/kernel/ksyms.c index acbd730bd963..2d0476a6089b 100644 --- a/kernel/ksyms.c +++ b/kernel/ksyms.c @@ -333,6 +333,7 @@ struct symbol_table symbol_table = { X(insert_inode_hash), X(event), X(__down), + X(securelevel), /* all busmice */ X(add_mouse_randomness), X(fasync_helper), diff --git a/net/Config.in b/net/Config.in index 8f8705f70bcf..bc6e936e2010 100644 --- a/net/Config.in +++ b/net/Config.in @@ -20,9 +20,9 @@ if [ "$CONFIG_AX25" = "y" ]; then bool 'AX.25 over Ethernet' CONFIG_BPQETHER bool 'Amateur Radio NET/ROM' CONFIG_NETROM fi -#if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then -# bool 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE -#fi +if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'Bridging (EXPERIMENTAL)' CONFIG_BRIDGE +fi bool 'Kernel/User network link driver' CONFIG_NETLINK if [ "$CONFIG_NETLINK" = "y" ]; then bool 'Routing messages' CONFIG_RTNETLINK diff --git a/net/bridge/br.c b/net/bridge/br.c index ad35365cff0c..bcd69bed8405 100644 --- a/net/bridge/br.c +++ b/net/bridge/br.c @@ -1052,6 +1052,7 @@ static int br_device_event(struct notifier_block *unused, unsigned long event, v int br_receive_frame(struct sk_buff *skb) /* 3.5 */ { int port; + int i; if (br_stats.flags & BR_DEBUG) printk("br_receive_frame: "); @@ -1130,6 +1131,8 @@ int br_receive_frame(struct sk_buff *skb) /* 3.5 */ port_info[port].dev->dev_addr, ETH_ALEN) == 0) { + /* Packet is for us */ + skb->pkt_type = PACKET_HOST; return(0); /* pass frame up our stack (this will */ /* happen in net_bh() in dev.c) */ } @@ -1159,6 +1162,13 @@ int br_tx_frame(struct sk_buff *skb) /* 3.5 */ printk(KERN_CRIT "br_tx_frame: no skb!\n"); return(0); } + + if (!skb->dev) + { + printk(KERN_CRIT "br_tx_frame: no dev!\n"); + return(0); + } + /* check for loopback */ if (skb->dev->flags & IFF_LOOPBACK) return(0); @@ -1289,7 +1299,7 @@ int br_forward(struct sk_buff *skb, int port) /* 3.7 */ /* * Send flood and drop. */ - if (!f | !(f->flags & FDB_ENT_VALID)) { + if (!f || !(f->flags & FDB_ENT_VALID)) { /* not found; flood all ports */ br_flood(skb, port); return(br_dev_drop(skb)); @@ -1354,9 +1364,15 @@ int br_flood(struct sk_buff *skb, int port) if (port_info[i].state == Forwarding) { nskb = skb_clone(skb, GFP_ATOMIC); + if(nskb==NULL) + continue; /* mark that's we've been here... */ nskb->pkt_bridged = IS_BRIDGED; - nskb->arp = skb->arp; + /* Send to each port in turn */ + nskb->dev= port_info[i].dev; + /* To get here we must have done ARP already, + or have a received valid MAC header */ + nskb->arp = 1; /* printk("Flood to port %d\n",i);*/ nskb->h.raw = nskb->data + ETH_HLEN; diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c index 430839878d07..f2d9fd1da127 100644 --- a/net/ipv4/af_inet.c +++ b/net/ipv4/af_inet.c @@ -692,7 +692,6 @@ static int inet_create(struct socket *sock, int protocol) sk->timer.function = &net_timer; skb_queue_head_init(&sk->back_log); sock->data =(void *) sk; - sk->dummy_th.doff = sizeof(sk->dummy_th)/4; sk->ip_ttl=ip_statistics.IpDefaultTTL; if(sk->type==SOCK_RAW && protocol==IPPROTO_RAW) sk->ip_hdrincl=1; diff --git a/net/ipv4/arp.c b/net/ipv4/arp.c index f83034bfa914..c78082e19cbe 100644 --- a/net/ipv4/arp.c +++ b/net/ipv4/arp.c @@ -58,6 +58,8 @@ * Jonathan Layes : Added arpd support through kerneld * message queue (960314) * Mike Shaver : /proc/sys/net/ipv4/arp_* support + * Stuart Cheshire : Metricom and grat arp fixes + * *** FOR 2.1 clean this up *** */ /* RFC1122 Status: @@ -1931,18 +1933,10 @@ int arp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *pt) else arp_send(ARPOP_REPLY,ETH_P_ARP,sip,dev,tip,sha,dev->dev_addr,sha); -/* - * Handle gratuitous arp. - */ - arp_fast_lock(); - arp_update(sip, sha, dev, 0, NULL, 1); - arp_unlock(); - kfree_skb(skb, FREE_READ); - return 0; } arp_fast_lock(); - arp_update(sip, sha, dev, 0, NULL, ip_chk_addr(tip) != IS_MYADDR); + arp_update(sip, sha, dev, 0, NULL, ip_chk_addr(tip) != IS_MYADDR && dev->type != ARPHRD_METRICOM); arp_unlock(); kfree_skb(skb, FREE_READ); return 0; @@ -1994,7 +1988,7 @@ static int arp_req_set(struct arpreq *r, struct device * dev) } else { - if (ip_chk_addr(ip)) + if (ip_chk_addr(ip) && dev->type != ARPHRD_METRICOM) return -EINVAL; if (!dev) { -- 2.39.5