diff -u --recursive --new-file v2.1.120/linux/COPYING linux/COPYING --- v2.1.120/linux/COPYING Sun Jun 7 11:16:25 1998 +++ linux/COPYING Sun Sep 6 09:53:05 1998 @@ -14,7 +14,7 @@ Version 2, June 1991 Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA + 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. @@ -291,7 +291,7 @@ END OF TERMS AND CONDITIONS - Appendix: How to Apply These Terms to Your New Programs + How to Apply These Terms to Your New Programs If you develop a new program, and you want it to be of the greatest possible use to the public, the best way to achieve this is to make it @@ -317,7 +317,8 @@ You should have received a copy of the GNU General Public License along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. + Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + Also add information on how to contact you by electronic and paper mail. diff -u --recursive --new-file v2.1.120/linux/CREDITS linux/CREDITS --- v2.1.120/linux/CREDITS Sat Sep 5 16:46:40 1998 +++ linux/CREDITS Tue Sep 8 16:24:40 1998 @@ -61,7 +61,7 @@ S: USA N: Andrea Arcangeli -E: arcangeli@mbox.queen.it +E: andrea@e-mind.com W: http://e-mind.com/~andrea/ P: 1024/CB4660B9 CC A0 71 81 F4 A0 63 AC C0 4B 81 1D 8C 15 C8 E5 D: Parport hacker @@ -129,6 +129,12 @@ S: Provo, Utah 84606 S: USA +N: Paul Barton-Davis +E: pbd@op.net +D: Driver for WaveFront soundcards (Turtle Beach Maui, Tropez, Tropez+) +D: Various bugfixes and changes to sound drivers +S: USA + M: Krzysztof G. Baranowski E: kgb@manjak.knm.org.pl P: 1024/FA6F16D1 96 D1 1A CF 5F CA 69 EC F9 4F 36 1F 6D 60 7B DA @@ -158,7 +164,7 @@ N: Donald Becker E: becker@cesdis.gsfc.nasa.gov D: General low-level networking hacker -D: Most of the Ethernet drivers +D: Most of the ethercard drivers D: Original author of the NFS server S: USRA Center of Excellence in Space Data and Information Sciences S: Code 930.5, Goddard Space Flight Center @@ -248,6 +254,15 @@ S: Pittsburgh, Pennsylvania 15213 S: USA +N: Derrick J. Brashear +E: shadow@dementia.org +W: http://www.dementia.org/~shadow +P: 512/71EC9367 C5 29 0F BC 83 51 B9 F0 BC 05 89 A0 4F 1F 30 05 +D: Author of Sparc CS4231 audio driver, random Sparc work +S: 403 Gilmore Avenue +S: Trafford, Pennsylvania 15085 +S: USA + N: Andries Brouwer E: aeb@cwi.nl D: random Linux hacker @@ -711,8 +726,8 @@ E: rth@cygnus.com E: richard@gnu.org D: Alpha/ELF, gcc, binutils, and glibc -S: 5450 Mayme #25 -S: San Jose, California 95129 +S: 50 E. Middlefield #10 +S: Mountain View, California 94043 S: USA N: Sebastian Hetze @@ -1073,9 +1088,10 @@ N: Jamie Lokier E: jamie@imbolc.ucc.ie D: Reboot-through-BIOS for broken 486 motherboards -S: 26 Oatlands Road +S: 11 Goodson Walk +S: Marston S: Oxford -S: OX2 0ET +S: OX3 0HX S: United Kingdom N: Warner Losh @@ -1711,6 +1727,13 @@ S: 1050 Woodduck Avenue S: Santa Clara, California 95051 S: USA + +N: Stefan Traby +E: stefan@quant-x.com +D: Minor Alpha kernel hacks +S: Mitterlasznitzstr. 13 +S: 8302 Nestelbach +S: Austria N: Jeff Tranter E: Jeff_Tranter@Mitel.COM diff -u --recursive --new-file v2.1.120/linux/Documentation/Changes linux/Documentation/Changes --- v2.1.120/linux/Documentation/Changes Thu Aug 27 19:56:28 1998 +++ linux/Documentation/Changes Sat Sep 5 17:14:54 1998 @@ -33,8 +33,8 @@ Also, don't forget http://www.linuxhq.com/ for all your Linux kernel needs. -Last updated: May 31, 1998 -Current Author: Chris Ricker (kaboom@gatech.edu). +Last updated: September 3, 1998 +Current Author: Chris Ricker (kaboom@gatech.edu or chris.ricker@m.cc.utah.edu). Current Minimal Requirements **************************** @@ -43,14 +43,15 @@ encountered a bug! If you're unsure what version you're currently running, the suggested command should tell you. -- Kernel modules modutils-2.1.85 ; insmod -V +- Kernel modules 2.1.85 ; insmod -V - Gnu C 2.7.2.3 ; gcc --version - Binutils 2.8.1.0.23 ; ld -v -- Linux C Library 5.4.44 ; ls -l /lib/libc.so.* +- Linux C Library 5.4.46 ; ls -l /lib/libc.so.* - Dynamic Linker (ld.so) 1.9.9 ; ldd --version or ldd -v - Linux C++ Library 2.7.2.8 ; ls -l /usr/lib/libg++.so.* -- Procps 1.2.7 ; ps --version +- Procps 1.2.8 ; ps --version - Procinfo 14 ; procinfo -v +- Psmisc 17 ; pstree -V - Mount 2.7l ; mount --version - Net-tools 1.45 ; hostname -V - Loadlin 1.6a @@ -59,7 +60,7 @@ - NFS 0.4.21 ; showmount --version - Bash 1.14.7 ; bash -version - Ncpfs 2.2.0 ; ncpmount -v -- Pcmcia-cs 3.0.1 +- Pcmcia-cs 3.0.5 ; cardmgr -V - PPP 2.3.5 ; pppd -v Upgrade notes @@ -83,6 +84,36 @@ compiled under 2.0 or earlier kernels should be replaced with ones compiled under 2.1, for example. + As of 2.1.115, Unix98 pty support was added as an option, and +support for the deprecated major 4 /dev/ttyp* devices was removed. If +necessary (eg, you get "out of pty" error messages when you obviously +are not out of pty's), create major 3 /dev/tty* and major 2 /dev/pty* +devices (see Documentation/devices.txt for more information). If you +want to use the Unix98 ptys, you should be running at least +glibc-2.0.9x, and you must switch completely to Unix98 pty's. The +general procedure for configuring Unix98 pty support is: + +- Compile your kernel with CONFIG_UNIX98_PTYS and CONFIG_DEVPTS_FS. +- mknod /dev/ptmx c 5 2 + chmod 666 /dev/ptmx + mkdir /dev/pts +- Add to /etc/fstab: + + none /dev/pts devpts gid=5,mode=620 0 0 + + (Note: gid=5 is applicable for RedHat systems for which group "tty" has + gid 5. Adjust according to your distribution. Use mode=600 if you want + "mesg n" to be default.) +- Mount /dev/pts + + Frame buffer consoles ("fbcon") are now in the kernel for all +platforms, not just those non-Intel ones for which VGA text mode is +impossible. VGAcon is still available for those who want it, but fbcon +has the advantage of providing a uniform graphical subsystem across all +Linux ports, and it displays a spiffy penguin logo on boot-up ;-). For +more information, see the files in Documentation/fb/ ; you may also +need to download the fbset utilities. + Libc ==== @@ -95,12 +126,12 @@ For modules to work, you need to be running libc-5.4.x or greater. Since updates to libc fix other problems as well (security flaws, for example) and since 5.4.7 is missing a few needed symbols, try to get -the latest 5.4.x you can. Currently, libc-5.4.44 is the latest public +the latest 5.4.x you can. Currently, libc-5.4.46 is the latest public release. If you upgrade to libc-5.4.x, you also have to upgrade your dynamic -linker (ld.so) to at least 1.9.5, or all sorts of weirdness will -happen. Actually, ld.so-1.8.2 and later will work, but 1.9.5 is widely +linker (ld.so) to at least 1.9.9, or all sorts of weirdness will +happen. Actually, ld.so-1.8.2 and later will work, but 1.9.9 is widely available, so if you need to upgrade, use it. If you get a release later than 1.8.5, avoid 1.8.10 as it introduces a few bugs that are fixed in later releases. Please make sure you don't install ld.so-2.x @@ -109,7 +140,7 @@ If you upgrade to libc-5.4.x, you may also need to upgrade ypbind if you're using NIS. - If you upgrade to libc-5.4.44, please read and pay attention to its + If you upgrade to libc-5.4.46, please read and pay attention to its accompanying release notes. The section about it breaking make is not a joke. @@ -135,8 +166,8 @@ The last public release of the binutils 2.8.x series was 2.8.1.0.23. Binutils 2.8.1.0.25 to 2.9.1.0.2 are beta releases, and are known to be very buggy. Binutils 2.9.1 (note the absence of a suffix) from the FSF -should work, and binutils 2.9.1.0.3 and later releases are also good. -Either use binutils-2.8.1.0.23 or binutils-2.9.1.0.4 or later. Glibc2 +should work, and binutils 2.9.1.0.7 and later releases are also good. +Either use binutils-2.8.1.0.23 or binutils-2.9.1.0.7 or later. Glibc2 users should especially try to use the 2.9.1.0.x releases, as they resolve known issues with glibc2 and binutils-2.8.x releases. @@ -185,15 +216,15 @@ something appears broken, check the /proc/sys/net/ipv4/ directory. "1" generally denotes enabled, while "0" generally denotes disabled. - For support for new features like IPv6, upgrade to the latest -net-tools. This will also fix other problems. For example, the format -of /proc/net/dev changed; as a result, an older ifconfig will -incorrectly report errors. - - The IP firewalling code has been replaced: ipfwadm will no longer -work. You need to obtain `ipchains', available from -http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html -which includes an ipfwadm wrapper. + If you're experiencing reports of lots of network errors, chances +are you need to upgrade to a more recent net-tools that understands the +new /proc/net/dev format. This will also provide support for new +features like IPv6. + + As of 2.1.102, the IP firewalling code has been replaced; ipfwadm +will no longer work. You need to optain "ipchains," available from +http://www.adelaide.net.au/~rustcorp/ipfwchains/ipfwchains.html, and use +that instead of ipfwadm. Memory ====== @@ -209,7 +240,8 @@ much-improved performance. As a result, you'll need to upgrade mount to a recent 2.6 release. Also, amd is being phased out in favor of the much better autofs. You'll also have to get the appropriate utils to -use autofs as well as the new NFS utils. +use autofs as well as the new NFS utils. In addition, you have the +choice of user-land NFS or kernel-level NFS (knfs). RPM === @@ -267,6 +299,13 @@ To mount NetWare shares, you'll need to upgrade to a more recent version of the ncpfs utils. +SMBfs +===== + + To mount SMB (Samba / Windows) shares, you'll need to use the +smbmount utility included with recent Samba releases. +Documentation/filesystems/smbfs.txt has more information about this. + Pcmcia-cs ========= @@ -279,6 +318,23 @@ Due to changes in the routing code, those of you using PPP networking will need to upgrade your pppd. +iBCS +==== + + A new version of iBCS is necessary for 2.1 kernels. + +AppleTalk +========= + + Use the Asun version of netatalk for AppleTalk support, as Umich's +version is not compatible with 2.1 kernels. + +Psmisc +====== + + fuser, which comes with psmisc, reads /proc/*/fd/* to do its job. +Upgrade psmisc if 2.1 changes to /proc broke the version you're using. + Where to get the files ********************** @@ -292,16 +348,16 @@ ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.8.1.0.23 ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.8.1.0.23 -The 2.9.1.0.4 release: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.4-glibc.x86.tar.gz -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.4-libc5.x86.tar.gz -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.4.tar.gz -ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.4-glibc.x86.tar.gz -ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.4-libc5.x86.tar.gz -ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.4.tar.gz +The 2.9.1.0.7 release: +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.7-glibc.x86.tar.gz +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.7-libc5.x86.tar.gz +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/binutils-2.9.1.0.7.tar.gz +ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.7-glibc.x86.tar.gz +ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.7-libc5.x86.tar.gz +ftp://sunsite.unc.edu/pub/Linux/GCC/binutils-2.9.1.0.7.tar.gz Installation notes: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.9.1.0.4 -ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.9.1.0.4 +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.binutils-2.9.1.0.7 +ftp://sunsite.unc.edu/pub/Linux/GCC/release.binutils-2.9.1.0.7 Gnu C ===== @@ -329,12 +385,12 @@ Linux C Library =============== -The 5.4.44 release: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/libc-5.4.44.bin.tar.gz -ftp://sunsite.unc.edu/pub/Linux/GCC/libc-5.4.44.bin.tar.gz -Installation notes for 5.4.44: -ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.libc-5.4.44 -ftp://sunsite.unc.edu/pub/Linux/GCC/release.libc-5.4.44 +The 5.4.46 release: +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/libc-5.4.46.bin.tar.gz +ftp://sunsite.unc.edu/pub/Linux/GCC/libc-5.4.46.bin.tar.gz +Installation notes for 5.4.46: +ftp://tsx-11.mit.edu/pub/linux/packages/GCC/release.libc-5.4.46 +ftp://sunsite.unc.edu/pub/Linux/GCC/release.libc-5.4.46 Linux C++ Library ================= @@ -363,8 +419,8 @@ ================ The 1.2 release: -ftp://tsx-11.mit.edu/pub/linux/sources/usr.bin/procps-1.2.7.tar.gz -ftp://sunsite.unc.edu/pub/Linux/system/status/ps/procps-1.2.7.tgz +ftp://tsx-11.mit.edu/pub/linux/sources/usr.bin/procps-1.2.8.tar.gz +ftp://sunsite.unc.edu/pub/Linux/system/status/ps/procps-1.2.8.tgz Procinfo utilities ================== @@ -372,6 +428,13 @@ The 14 release: ftp://ftp.cistron.nl/pub/people/svm/procinfo-14.tar.gz +Psmisc utilities +================ + +The 17 release: +ftp://lrcftp.epfl.ch/pub/linux/local/psmisc/psmisc-17.tar.gz +ftp://sunsite.unc.edu/pub/Linux/system/status/ps/psmisc-17.tar.gz + RPM utilities ============= @@ -414,16 +477,19 @@ Autofs ====== -The 0.3.11 release: -ftp://ftp.kernel.org/pub/linux/daemons/autofs/autofs-0.3.11.tar.gz +The 3.1.1 release: +ftp://ftp.kernel.org/pub/linux/daemons/autofs/autofs-3.1.1.tar.gz NFS === -The 0.4.21 release: +The user-land 0.4.21 release: ftp://ftp.mathematik.th-darmstadt.de/pub/linux/okir/linux-nfs-0.4.21.tar.gz ftp://linux.nrao.edu/mirrors/fb0429.mathematik.th-darmstadt.de/pub/linux/okir/linux-nfs-0.4.21.tar.gz +The kernel-level 8/30/98 release: +ftp://ftp.yggdrasil.com/private/hjl/knfsd-980830.tar.gz + Net-tools ========= @@ -449,11 +515,17 @@ The 2.2.0 release: ftp://ftp.gwdg.de/pub/linux/misc/ncpfs/ncpfs-2.2.0.tgz +SMBfs +===== + +The 1.9.18p10 release of Samba: +ftp://samba.anu.edu.au/pub/samba/samba-1.9.18p10.tar.gz + Pcmcia-cs ========= -The 3.0.1 release: -ftp://hyper.stanford.edu/pub/pcmcia/pcmcia-cs.3.0.1.tar.gz +The 3.0.5 release: +ftp://hyper.stanford.edu/pub/pcmcia/pcmcia-cs.3.0.5.tar.gz PPP === @@ -468,6 +540,24 @@ http://www.adelaide.net.au/~rustcorp/ipfwchains/ipchains-source-1.3.3.tar.gz http://www.adelaide.net.au/~rustcorp/ipfwchains/ipchains-source-1.3.3.tar.bz2 +iBCS +==== + +The 8/30/98 release: +ftp://tsx-11.mit.edu/pub/linux/BETA/ibcs2/ibcs-2.1-980830-ALPHA.tar.gz + +Asun netatalk +============= + +The 2.0a18.2 release: +ftp://ftp.u.washington.edu/pub/user-supported/asun/netatalk-1.4b2+asun2.0a18.2.tar.gz + +Fbset +===== + +The 7/13/98 release: +http://www.cs.kuleuven.ac.be/~geert/bin/fbset-2.0-pre-19980713.tar.gz + Other Info ========== @@ -497,5 +587,5 @@ Please send info about any other packages that 2.1.x "broke" or about any new features of 2.1.x that require extra or new packages for use to -Chris Ricker (kaboom@gatech.edu). +Chris Ricker (kaboom@gatech.edu or chris.ricker@m.cc.utah.edu). diff -u --recursive --new-file v2.1.120/linux/MAINTAINERS linux/MAINTAINERS --- v2.1.120/linux/MAINTAINERS Sat Sep 5 16:46:40 1998 +++ linux/MAINTAINERS Tue Sep 8 10:39:27 1998 @@ -471,7 +471,7 @@ P: David Campbell M: campbell@torque.net P: Andrea Arcangeli -M: arcangeli@mbox.queen.it +M: andrea@e-mind.com L: linux-parport@torque.net L: pnp-list@redhat.com W: http://www.cyberelk.demon.co.uk/parport.html diff -u --recursive --new-file v2.1.120/linux/Makefile linux/Makefile --- v2.1.120/linux/Makefile Sat Sep 5 16:46:40 1998 +++ linux/Makefile Sat Sep 5 17:17:27 1998 @@ -1,6 +1,6 @@ VERSION = 2 PATCHLEVEL = 1 -SUBLEVEL = 120 +SUBLEVEL = 121 ARCH := $(shell uname -m | sed -e s/i.86/i386/ -e s/sun4u/sparc64/ -e s/arm.*/arm/ -e s/sa110/arm/) diff -u --recursive --new-file v2.1.120/linux/arch/alpha/Makefile linux/arch/alpha/Makefile --- v2.1.120/linux/arch/alpha/Makefile Tue Aug 18 22:02:01 1998 +++ linux/arch/alpha/Makefile Sun Sep 6 10:34:33 1998 @@ -10,7 +10,7 @@ NM := nm -B -LINKFLAGS = -static -T arch/alpha/vmlinux.lds -N +LINKFLAGS = -static -T arch/alpha/vmlinux.lds #-N -relax CFLAGS := $(CFLAGS) -pipe -mno-fp-regs -ffixed-8 # Determine if we can use the BWX instructions with GAS. @@ -79,6 +79,7 @@ @$(MAKEBOOT) srmboot archclean: + @$(MAKE) -C arch/$(ARCH)/kernel clean @$(MAKEBOOT) clean archmrproper: diff -u --recursive --new-file v2.1.120/linux/arch/alpha/boot/Makefile linux/arch/alpha/boot/Makefile --- v2.1.120/linux/arch/alpha/boot/Makefile Mon Jan 12 14:51:14 1998 +++ linux/arch/alpha/boot/Makefile Sun Sep 6 10:34:33 1998 @@ -8,17 +8,7 @@ # Copyright (C) 1994 by Linus Torvalds # -ifdef CONFIG_CROSSCOMPILE -# enable this for linking under OSF/1: -LINKFLAGS = -non_shared -T 0x20000000 -N -else - elf=$(shell if $(LD) --help | grep elf64alpha >/dev/null; then echo yes; fi) - ifeq ($(elf),yes) - LINKFLAGS = -static -Ttext 0x20000000 -N - else - LINKFLAGS = -static -T bootloader.lds -N - endif -endif +LINKFLAGS = -static -T bootloader.lds #-N -relax .S.s: $(CC) -D__ASSEMBLY__ -traditional -E -o $*.o $< @@ -56,7 +46,7 @@ @test "$(BOOTDEV)" != "" || (echo You must specify BOOTDEV ; exit -1) vmlinux.gz: vmlinux - gzip -fv vmlinux + gzip -fv9 vmlinux # # A raw binary without header. Used by raw boot. @@ -69,18 +59,10 @@ echo "#define KERNEL_SIZE `$(OBJSTRIP) -p vmlinux.nh /dev/null`" > $@ vmlinux.nh: $(VMLINUX) $(OBJSTRIP) -ifeq ($(elf),yes) - cp $(VMLINUX) vmlinux.stripped - strip vmlinux.stripped # work around ELF binutils bug... - $(OBJSTRIP) -v vmlinux.stripped vmlinux.nh - rm -f vmlinux.stripped -else $(OBJSTRIP) -v $(VMLINUX) vmlinux.nh -endif vmlinux: $(TOPDIR)/vmlinux - cp $(TOPDIR)/vmlinux vmlinux - strip vmlinux + strip -o vmlinux $(VMLINUX) tools/lxboot: $(OBJSTRIP) bootloader $(OBJSTRIP) -p bootloader tools/lxboot @@ -98,21 +80,14 @@ $(HOSTCC) tools/mkbb.c -o tools/mkbb bootloader: $(OBJECTS) - $(LD) $(LINKFLAGS) \ - $(OBJECTS) \ - $(LIBS) \ - -o bootloader && strip bootloader || \ - (rm -f bootloader && exit 1) + $(LD) $(LINKFLAGS) $(OBJECTS) $(LIBS) -o bootloader bootpheader: $(BPOBJECTS) - $(LD) $(LINKFLAGS) \ - $(BPOBJECTS) \ - $(LIBS) \ - -o bootpheader && strip bootpheader || \ - (rm -f bootpheader && exit 1) + $(LD) $(LINKFLAGS) $(BPOBJECTS) $(LIBS) -o bootpheader clean: - rm -f $(TARGETS) bootloader bootimage vmlinux.nh \ - tools/mkbb tools/bootlx tools/lxboot ksize.h + rm -f $(TARGETS) bootloader bootimage bootpfile bootpheader + rm -f tools/mkbb tools/bootlx tools/lxboot tools/bootph + rm -f vmlinux.nh ksize.h dep: diff -u --recursive --new-file v2.1.120/linux/arch/alpha/boot/bootloader.lds linux/arch/alpha/boot/bootloader.lds --- v2.1.120/linux/arch/alpha/boot/bootloader.lds Tue Aug 29 00:15:48 1995 +++ linux/arch/alpha/boot/bootloader.lds Sun Sep 6 10:34:33 1998 @@ -1,50 +1,23 @@ -OUTPUT_FORMAT("ecoff-littlealpha") +OUTPUT_FORMAT("elf64-alpha") ENTRY(__start) SECTIONS { - .text 0x20000000: { - _ftext = . ; - __istart = . ; - eprol = .; - *(.text) - __fstart = . ; - _etext = .; - } - .rdata : { - *(.rdata) - } - .pdata : { - _fpdata = .; - *(.pdata) - } - .data : { - _fdata = .; - *(.data) - CONSTRUCTORS - } - .xdata : { - *(.xdata) - } - _gp = ALIGN (16) + 0x8000; - .lit8 : { - *(.lit8) - } - .lita : { - *(.lita) - } - .sdata : { - *(.sdata) - } - _EDATA = .; - _FBSS = .; - .sbss : { - *(.sbss) - *(.scommon) - . = ALIGN(16); - } - .bss : { - *(.bss) - *(COMMON) - } - _end = .; + . = 0x20000000; + .text : { *(.text) } + _etext = .; + PROVIDE (etext = .); + .rodata : { *(.rodata) } + .data : { *(.data) CONSTRUCTORS } + .got : { *(.got) } + .sdata : { *(.sdata) } + _edata = .; + PROVIDE (edata = .); + .sbss : { *(.sbss) *(.scommon) } + .bss : { *(.bss) *(COMMON) } + _end = . ; + PROVIDE (end = .); + + .mdebug 0 : { *(.mdebug) } + .note 0 : { *(.note) } + .comment 0 : { *(.comment) } } diff -u --recursive --new-file v2.1.120/linux/arch/alpha/boot/bootp.c linux/arch/alpha/boot/bootp.c --- v2.1.120/linux/arch/alpha/boot/bootp.c Wed Apr 8 19:36:24 1998 +++ linux/arch/alpha/boot/bootp.c Sun Sep 6 10:34:33 1998 @@ -27,12 +27,27 @@ struct pcb_struct * pcb_va, struct pcb_struct * pcb_pa, unsigned long vptb, unsigned long *kstk); +extern long dispatch(long code, ...); + +static void +puts(const char *str, int len) +{ + long written; + + while (len > 0) { + written = dispatch(CCB_PUTS, 0, str, len); + if (written < 0) + break; + len -= (unsigned int) written; + str += (unsigned int) written; + } +} + int printk(const char * fmt, ...) { va_list args; - int i, j, written, remaining, num_nl; + int i, j, remaining, num_nl; static char buf[1024]; - char * str; va_start(args, fmt); i = vsprintf(buf, fmt, args); @@ -54,12 +69,7 @@ } } - str = buf; - do { - written = puts(str, remaining); - remaining -= written; - str += written; - } while (remaining > 0); + puts(buf, remaining); return i; } diff -u --recursive --new-file v2.1.120/linux/arch/alpha/defconfig linux/arch/alpha/defconfig --- v2.1.120/linux/arch/alpha/defconfig Tue Aug 18 22:02:01 1998 +++ linux/arch/alpha/defconfig Sun Sep 6 10:34:33 1998 @@ -5,14 +5,14 @@ # # Code maturity level options # -# CONFIG_EXPERIMENTAL is not set +CONFIG_EXPERIMENTAL=y # # Loadable module support # CONFIG_MODULES=y -# CONFIG_MODVERSIONS is not set -# CONFIG_KMOD is not set +CONFIG_MODVERSIONS=y +CONFIG_KMOD=y # # General setup @@ -53,6 +53,7 @@ CONFIG_BINFMT_AOUT=y CONFIG_BINFMT_ELF=y # CONFIG_BINFMT_MISC is not set +# CONFIG_BINFMT_JAVA is not set CONFIG_BINFMT_EM86=y # CONFIG_PARPORT is not set @@ -65,20 +66,37 @@ # Block devices # CONFIG_BLK_DEV_FD=y -# CONFIG_BLK_DEV_IDE is not set +CONFIG_BLK_DEV_IDE=y # # Please see Documentation/ide.txt for help/info on IDE drives # -# CONFIG_BLK_DEV_HD_ONLY is not set +# CONFIG_BLK_DEV_HD_IDE is not set +CONFIG_BLK_DEV_IDEDISK=y +CONFIG_BLK_DEV_IDECD=y +# CONFIG_BLK_DEV_IDETAPE is not set +CONFIG_BLK_DEV_IDEFLOPPY=y +# CONFIG_BLK_DEV_IDESCSI is not set +CONFIG_BLK_DEV_CMD640=y +CONFIG_BLK_DEV_CMD640_ENHANCED=y +# CONFIG_BLK_DEV_RZ1000 is not set +CONFIG_BLK_DEV_IDEPCI=y +CONFIG_BLK_DEV_IDEDMA=y +CONFIG_IDEDMA_AUTO=y +CONFIG_BLK_DEV_OPTI621=y +CONFIG_BLK_DEV_TRM290=y +CONFIG_BLK_DEV_NS87415=y +CONFIG_BLK_DEV_CMD646=y +# CONFIG_IDE_CHIPSETS is not set # # Additional Block Devices # -# CONFIG_BLK_DEV_LOOP is not set +CONFIG_BLK_DEV_LOOP=y # CONFIG_BLK_DEV_NBD is not set # CONFIG_BLK_DEV_MD is not set -# CONFIG_BLK_DEV_RAM is not set +CONFIG_BLK_DEV_RAM=y +CONFIG_BLK_DEV_INITRD=y # CONFIG_BLK_DEV_XD is not set CONFIG_PARIDE_PARPORT=y # CONFIG_PARIDE is not set @@ -87,34 +105,61 @@ # # Networking options # -# CONFIG_PACKET is not set +CONFIG_PACKET=y # CONFIG_NETLINK is not set -# CONFIG_FIREWALL is not set -# CONFIG_NET_ALIAS is not set +CONFIG_FIREWALL=y +CONFIG_NET_ALIAS=y # CONFIG_FILTER is not set CONFIG_UNIX=y CONFIG_INET=y -# CONFIG_IP_MULTICAST is not set +CONFIG_IP_MULTICAST=y # CONFIG_IP_ADVANCED_ROUTER is not set # CONFIG_IP_PNP is not set +CONFIG_IP_FIREWALL=y +CONFIG_IP_TRANSPARENT_PROXY=y +CONFIG_IP_ALWAYS_DEFRAG=y +CONFIG_IP_MASQUERADE=y + +# +# Protocol-specific masquerading support will be built as modules. +# +CONFIG_IP_MASQUERADE_ICMP=y + +# +# Protocol-specific masquerading support will be built as modules. +# +# CONFIG_IP_MASQUERADE_IPAUTOFW is not set +# CONFIG_IP_MASQUERADE_IPPORTFW is not set # CONFIG_IP_ROUTER is not set # CONFIG_NET_IPIP is not set # CONFIG_NET_IPGRE is not set -# CONFIG_IP_ALIAS is not set -# CONFIG_SYN_COOKIES is not set +# CONFIG_IP_MROUTE is not set +CONFIG_IP_ALIAS=y +CONFIG_SYN_COOKIES=y # # (it is safe to leave these untouched) # -# CONFIG_INET_RARP is not set +CONFIG_INET_RARP=y CONFIG_IP_NOSR=y CONFIG_SKB_LARGE=y +# CONFIG_IPV6 is not set # # # # CONFIG_IPX is not set # CONFIG_ATALK is not set +# CONFIG_X25 is not set +# CONFIG_LAPB is not set +# CONFIG_BRIDGE is not set +# CONFIG_LLC is not set +# CONFIG_ECONET is not set +# CONFIG_WAN_ROUTER is not set +# CONFIG_NET_FASTROUTE is not set +# CONFIG_NET_HW_FLOWCONTROL is not set +# CONFIG_CPU_IS_SLOW is not set +# CONFIG_NET_SCHED is not set # # SCSI support @@ -125,9 +170,9 @@ # SCSI support type (disk, tape, CD-ROM) # CONFIG_BLK_DEV_SD=y -# CONFIG_CHR_DEV_ST is not set +CONFIG_CHR_DEV_ST=y CONFIG_BLK_DEV_SR=y -# CONFIG_BLK_DEV_SR_VENDOR is not set +CONFIG_BLK_DEV_SR_VENDOR=y # CONFIG_CHR_DEV_SG is not set # @@ -144,11 +189,15 @@ # CONFIG_SCSI_AHA152X is not set # CONFIG_SCSI_AHA1542 is not set # CONFIG_SCSI_AHA1740 is not set -# CONFIG_SCSI_AIC7XXX is not set +CONFIG_SCSI_AIC7XXX=y +# CONFIG_OVERRIDE_CMDS is not set +# CONFIG_AIC7XXX_PROC_STATS is not set +CONFIG_AIC7XXX_RESET_DELAY=5 # CONFIG_SCSI_ADVANSYS is not set # CONFIG_SCSI_IN2000 is not set # CONFIG_SCSI_AM53C974 is not set -# CONFIG_SCSI_BUSLOGIC is not set +CONFIG_SCSI_BUSLOGIC=y +# CONFIG_SCSI_OMIT_FLASHPOINT is not set # CONFIG_SCSI_DTC3280 is not set # CONFIG_SCSI_EATA_DMA is not set # CONFIG_SCSI_EATA_PIO is not set @@ -158,7 +207,13 @@ # 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_NCR53C8XX=y +CONFIG_SCSI_NCR53C8XX_DEFAULT_TAGS=8 +CONFIG_SCSI_NCR53C8XX_MAX_TAGS=32 +CONFIG_SCSI_NCR53C8XX_SYNC=20 +# CONFIG_SCSI_NCR53C8XX_PROFILE is not set +# CONFIG_SCSI_NCR53C8XX_IOMAPPED is not set +# CONFIG_SCSI_NCR53C8XX_SYMBIOS_COMPAT is not set # CONFIG_SCSI_PAS16 is not set # CONFIG_SCSI_PCI2000 is not set # CONFIG_SCSI_PCI2220I is not set @@ -170,40 +225,50 @@ # CONFIG_SCSI_T128 is not set # CONFIG_SCSI_U14_34F is not set # CONFIG_SCSI_ULTRASTOR is not set +# CONFIG_SCSI_DEBUG is not set # # Network device support # CONFIG_NETDEVICES=y # CONFIG_ARCNET is not set -CONFIG_DUMMY=m +# CONFIG_DUMMY is not set # CONFIG_EQUALIZER is not set CONFIG_NET_ETHERNET=y # CONFIG_NET_VENDOR_3COM is not set # CONFIG_LANCE is not set # CONFIG_NET_VENDOR_SMC is not set # CONFIG_NET_VENDOR_RACAL is not set +# CONFIG_RTL8139 is not set +# CONFIG_YELLOWFIN is not set # CONFIG_NET_ISA is not set CONFIG_NET_EISA=y # CONFIG_PCNET32 is not set +# CONFIG_AC3200 is not set # CONFIG_APRICOT is not set # CONFIG_CS89x0 is not set -CONFIG_DE4X5=y -# CONFIG_DEC_ELCP is not set +# CONFIG_DE4X5 is not set +CONFIG_DEC_ELCP=y # CONFIG_DGRS is not set # CONFIG_EEXPRESS_PRO100 is not set +# CONFIG_LNE390 is not set # CONFIG_NE2K_PCI is not set # CONFIG_TLAN is not set +# CONFIG_ES3210 is not set +CONFIG_EPIC100=y +# CONFIG_ZNET is not set # CONFIG_NET_POCKET is not set # CONFIG_FDDI is not set # CONFIG_DLCI is not set -# CONFIG_PPP is not set +CONFIG_PPP=y + +# +# CCP compressors for PPP are only built as modules. +# # CONFIG_SLIP is not set # CONFIG_NET_RADIO is not set # CONFIG_TR is not set -# CONFIG_WAN_DRIVERS is not set -# CONFIG_LAPBETHER is not set -# CONFIG_X25_ASY is not set +# CONFIG_SHAPER is not set # # Amateur Radio support @@ -226,7 +291,7 @@ CONFIG_VT=y CONFIG_VT_CONSOLE=y CONFIG_SERIAL=y -# CONFIG_SERIAL_CONSOLE is not set +CONFIG_SERIAL_CONSOLE=y # CONFIG_SERIAL_EXTENDED is not set # CONFIG_SERIAL_NONSTANDARD is not set CONFIG_UNIX98_PTYS=y @@ -259,14 +324,14 @@ # CONFIG_MINIX_FS is not set CONFIG_EXT2_FS=y CONFIG_ISO9660_FS=y -# CONFIG_JOLIET is not set -# CONFIG_FAT_FS is not set -# CONFIG_MSDOS_FS is not set +CONFIG_JOLIET=y +CONFIG_FAT_FS=y +CONFIG_MSDOS_FS=y # CONFIG_UMSDOS_FS is not set # CONFIG_VFAT_FS is not set CONFIG_PROC_FS=y CONFIG_NFS_FS=y -# CONFIG_NFSD is not set +CONFIG_NFSD=m CONFIG_SUNRPC=y CONFIG_LOCKD=y # CONFIG_CODA_FS is not set @@ -277,25 +342,100 @@ # CONFIG_AFFS_FS is not set # CONFIG_HFS_FS is not set # CONFIG_ROMFS_FS is not set -# CONFIG_AUTOFS_FS is not set +CONFIG_AUTOFS_FS=m # CONFIG_UFS_FS is not set CONFIG_DEVPTS_FS=y +# CONFIG_ADFS_FS is not set +# CONFIG_QNX4FS_FS is not set # CONFIG_MAC_PARTITION is not set -# CONFIG_NLS is not set +CONFIG_NLS=y + +# +# Native Language Support +# +CONFIG_NLS_CODEPAGE_437=y +# CONFIG_NLS_CODEPAGE_737 is not set +# CONFIG_NLS_CODEPAGE_775 is not set +# CONFIG_NLS_CODEPAGE_850 is not set +# CONFIG_NLS_CODEPAGE_852 is not set +# CONFIG_NLS_CODEPAGE_855 is not set +# CONFIG_NLS_CODEPAGE_857 is not set +# CONFIG_NLS_CODEPAGE_860 is not set +# CONFIG_NLS_CODEPAGE_861 is not set +# CONFIG_NLS_CODEPAGE_862 is not set +# CONFIG_NLS_CODEPAGE_863 is not set +# CONFIG_NLS_CODEPAGE_864 is not set +# CONFIG_NLS_CODEPAGE_865 is not set +# CONFIG_NLS_CODEPAGE_866 is not set +# CONFIG_NLS_CODEPAGE_869 is not set +# CONFIG_NLS_CODEPAGE_874 is not set +# CONFIG_NLS_ISO8859_1 is not set +# CONFIG_NLS_ISO8859_2 is not set +# CONFIG_NLS_ISO8859_3 is not set +# CONFIG_NLS_ISO8859_4 is not set +# CONFIG_NLS_ISO8859_5 is not set +# CONFIG_NLS_ISO8859_6 is not set +# CONFIG_NLS_ISO8859_7 is not set +# CONFIG_NLS_ISO8859_8 is not set +# CONFIG_NLS_ISO8859_9 is not set +# CONFIG_NLS_KOI8_R is not set # # Console drivers # CONFIG_VGA_CONSOLE=y -# CONFIG_FB is not set +CONFIG_FB=y +CONFIG_PCI_CONSOLE=y +CONFIG_DUMMY_CONSOLE=y +# CONFIG_FB_VGA is not set +CONFIG_FB_TGA=y +# CONFIG_FB_VIRTUAL is not set +# CONFIG_FBCON_ADVANCED is not set +CONFIG_FBCON_CFB8=y +CONFIG_FBCON_CFB32=y +# CONFIG_FBCON_FONTWIDTH8_ONLY is not set +# CONFIG_FBCON_FONTS is not set +CONFIG_FONT_8x8=y +CONFIG_FONT_8x16=y # # Sound # -# CONFIG_SOUND is not set +CONFIG_SOUND=m +# CONFIG_SOUND_ES1370 is not set +# CONFIG_SOUND_ES1371 is not set +# CONFIG_SOUND_SONICVIBES is not set +# CONFIG_SOUND_MSNDCLAS is not set +# CONFIG_SOUND_MSNDPIN is not set +CONFIG_SOUND_OSS=m +# CONFIG_SOUND_PAS is not set +CONFIG_SOUND_SB=m +# CONFIG_SOUND_ADLIB is not set +# CONFIG_SOUND_GUS is not set +# CONFIG_SOUND_MPU401 is not set +# CONFIG_SOUND_PSS is not set +CONFIG_SOUND_MSS=m +# CONFIG_SOUND_SSCAPE is not set +# CONFIG_SOUND_TRIX is not set +# CONFIG_SOUND_MAD16 is not set +# CONFIG_SOUND_WAVEFRONT is not set +# CONFIG_SOUND_CS4232 is not set +# CONFIG_SOUND_MAUI is not set +# CONFIG_SOUND_SGALAXY is not set +# CONFIG_SOUND_OPL3SA1 is not set +CONFIG_SOUND_SOFTOSS=m +CONFIG_SOUND_YM3812=m +# CONFIG_SOUND_VMIDI is not set +# CONFIG_SOUND_UART6850 is not set + +# +# Additional low level sound drivers +# +# CONFIG_LOWLEVEL_SOUND is not set # # Kernel hacking # +# CONFIG_EARLY_SERIAL_CONSOLE is not set CONFIG_MATHEMU=y -# CONFIG_MAGIC_SYSRQ is not set +CONFIG_MAGIC_SYSRQ=y diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/Makefile linux/arch/alpha/kernel/Makefile --- v2.1.120/linux/arch/alpha/kernel/Makefile Tue Aug 18 22:02:01 1998 +++ linux/arch/alpha/kernel/Makefile Sun Sep 6 10:34:33 1998 @@ -8,9 +8,9 @@ # Note 2! The CFLAGS definitions are now in the main makefile... .S.s: - $(CPP) -D__ASSEMBLY__ $(AFLAGS) -traditional $< -o $*.s + $(CC) -D__ASSEMBLY__ $(AFLAGS) -E -o $*.s $< .S.o: - $(CC) -D__ASSEMBLY__ $(AFLAGS) -traditional -c $< -o $*.o + $(CC) -D__ASSEMBLY__ $(AFLAGS) -c -o $*.o $< all: kernel.o head.o @@ -116,5 +116,14 @@ endif all: kernel.o head.o + +asm_offsets: check_asm + ./check_asm > $(TOPDIR)/include/asm-alpha/asm_offsets.h + +check_asm: check_asm.c + gcc -o $@ $< -I$(TOPDIR)/include -D__KERNEL__ -ffixed-8 + +clean:: + rm -f check_asm include $(TOPDIR)/Rules.make diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/bios32.c linux/arch/alpha/kernel/bios32.c --- v2.1.120/linux/arch/alpha/kernel/bios32.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/bios32.c Sun Sep 6 10:34:33 1998 @@ -23,6 +23,7 @@ * Manuals are $25 each or $50 for all three, plus $7 shipping * within the United States, $35 abroad. */ + #include #include #include @@ -38,6 +39,7 @@ #include "bios32.h" #define DEBUG_DEVS 0 +#define DEBUG_HOSE 0 #if DEBUG_DEVS # define DBG_DEVS(args) printk args @@ -45,6 +47,12 @@ # define DBG_DEVS(args) #endif +#if DEBUG_HOSE +# define DBG_HOSE(args) printk args +#else +# define DBG_HOSE(args) +#endif + #ifndef CONFIG_PCI asmlinkage int sys_pciconfig_read() { return -ENOSYS; } @@ -68,21 +76,28 @@ #define MAJOR_REV 0 #define MINOR_REV 4 /* minor revision 4, add multi-PCI handling */ +struct linux_hose_info *bus2hose[256]; +struct linux_hose_info *hose_head, **hose_tail = &hose_head; +int hose_count; +int pci_probe_enabled; + +static void layout_hoses(void); int pcibios_present(void) { - return alpha_mv.pci_read_config_byte != NULL; + return alpha_mv.hose_read_config_byte != NULL; } void __init pcibios_init(void) { - printk("Alpha PCI BIOS32 revision %x.%02x\n", MAJOR_REV, MINOR_REV); + if (!pcibios_present()) + return; + + printk("Alpha PCI BIOS32 revision %d.%02d\n", MAJOR_REV, MINOR_REV); if (alpha_use_srm_setup) printk(" NOT modifying existing (SRM) PCI configuration\n"); - - /* FIXME: Scan for multiple PCI busses here. */ } char * __init @@ -106,8 +121,11 @@ pcibios_read_config_byte (u8 bus, u8 dev, u8 where, u8 *value) { int r = PCIBIOS_FUNC_NOT_SUPPORTED; - if (alpha_mv.pci_read_config_byte) - r = alpha_mv.pci_read_config_byte(bus, dev, where, value); + *value = 0xff; + if (alpha_mv.hose_read_config_byte) { + r = (alpha_mv.hose_read_config_byte + (bus, dev, where, value, bus2hose[bus])); + } return r; } @@ -115,8 +133,13 @@ pcibios_read_config_word (u8 bus, u8 dev, u8 where, u16 *value) { int r = PCIBIOS_FUNC_NOT_SUPPORTED; - if (alpha_mv.pci_read_config_word) - r = alpha_mv.pci_read_config_word(bus, dev, where, value); + *value = 0xffff; + if (alpha_mv.hose_read_config_word) { + r = PCIBIOS_BAD_REGISTER_NUMBER; + if (!(where & 1)) + r = (alpha_mv.hose_read_config_word + (bus, dev, where, value, bus2hose[bus])); + } return r; } @@ -124,8 +147,13 @@ pcibios_read_config_dword (u8 bus, u8 dev, u8 where, u32 *value) { int r = PCIBIOS_FUNC_NOT_SUPPORTED; - if (alpha_mv.pci_read_config_dword) - r = alpha_mv.pci_read_config_dword(bus, dev, where, value); + *value = 0xffffffff; + if (alpha_mv.hose_read_config_dword) { + r = PCIBIOS_BAD_REGISTER_NUMBER; + if (!(where & 3)) + r = (alpha_mv.hose_read_config_dword + (bus, dev, where, value, bus2hose[bus])); + } return r; } @@ -133,8 +161,10 @@ pcibios_write_config_byte (u8 bus, u8 dev, u8 where, u8 value) { int r = PCIBIOS_FUNC_NOT_SUPPORTED; - if (alpha_mv.pci_write_config_byte) - r = alpha_mv.pci_write_config_byte(bus, dev, where, value); + if (alpha_mv.hose_write_config_byte) { + r = (alpha_mv.hose_write_config_byte + (bus, dev, where, value, bus2hose[bus])); + } return r; } @@ -142,8 +172,12 @@ pcibios_write_config_word (u8 bus, u8 dev, u8 where, u16 value) { int r = PCIBIOS_FUNC_NOT_SUPPORTED; - if (alpha_mv.pci_write_config_word) - r = alpha_mv.pci_write_config_word(bus, dev, where, value); + if (alpha_mv.hose_write_config_word) { + r = PCIBIOS_BAD_REGISTER_NUMBER; + if (!(where & 1)) + r = (alpha_mv.hose_write_config_word + (bus, dev, where, value, bus2hose[bus])); + } return r; } @@ -151,8 +185,12 @@ pcibios_write_config_dword (u8 bus, u8 dev, u8 where, u32 value) { int r = PCIBIOS_FUNC_NOT_SUPPORTED; - if (alpha_mv.pci_write_config_dword) - r = alpha_mv.pci_write_config_dword(bus, dev, where, value); + if (alpha_mv.hose_write_config_dword) { + r = PCIBIOS_BAD_REGISTER_NUMBER; + if (!(where & 3)) + r = (alpha_mv.hose_write_config_dword + (bus, dev, where, value, bus2hose[bus])); + } return r; } @@ -171,31 +209,23 @@ if (!pcibios_present()) return -ENOSYS; - lock_kernel(); switch (len) { case 1: err = pcibios_read_config_byte(bus, dfn, off, &ubyte); - if (err != PCIBIOS_SUCCESSFUL) - ubyte = 0xff; put_user(ubyte, buf); break; case 2: err = pcibios_read_config_word(bus, dfn, off, &ushort); - if (err != PCIBIOS_SUCCESSFUL) - ushort = 0xffff; put_user(ushort, (unsigned short *)buf); break; case 4: err = pcibios_read_config_dword(bus, dfn, off, &uint); - if (err != PCIBIOS_SUCCESSFUL) - uint = 0xffffffff; put_user(uint, (unsigned int *)buf); break; default: err = -EINVAL; break; } - unlock_kernel(); return err; } @@ -214,7 +244,6 @@ if (!pcibios_present()) return -ENOSYS; - lock_kernel(); switch (len) { case 1: err = get_user(ubyte, buf); @@ -247,7 +276,6 @@ err = -EINVAL; break; } - unlock_kernel(); return err; } @@ -256,8 +284,6 @@ * Gory details start here... */ -struct linux_hose_info *bus2hose[256]; - /* * Align VAL to ALIGN, which must be a power of two. */ @@ -715,18 +741,7 @@ { struct pci_bus *cur; -#if defined(CONFIG_ALPHA_GENERIC) - static struct linux_hose_info dummy_hose; - int i; - - /* - * HACK: Emulate a multi-bus machine to a limited extent - * by initializing bus2hose to point to something that - * has pci_hose_index & pci_first_busno zero. - */ - for (i = 0; i <= 0xff; i++) - bus2hose[i] = &dummy_hose; -#endif + layout_hoses(); /* * Scan the tree, allocating PCI memory and I/O space. @@ -869,6 +884,18 @@ continue; /* + * We don't have code that will init the CYPRESS bridge + * correctly so we do the next best thing, and depend on + * the previous console code to do the right thing, and + * ignore it here... :-\ + */ + if (dev->vendor == PCI_VENDOR_ID_CONTAQ && + dev->device == PCI_DEVICE_ID_CONTAQ_82C693) { + DBG_DEVS(("common_pci_fixup: ignoring CYPRESS bridge...\n")); + continue; + } + + /* * This device is not on the primary bus, we need * to figure out which interrupt pin it will come * in on. We know which slot it will come in on @@ -997,4 +1024,259 @@ /* The slot is the slot of the last bridge. */ return PCI_SLOT(dev->devfn); } + +/* + * On multiple bus machines, in order to cope with a somewhat deficient + * API, we must map the 8-bit bus identifier so that it is unique across + * multiple interfaces (hoses). At the same time we do this, chain the + * other hoses off of pci_root so that they will be found during normal + * PCI probing and layout. + */ + +#define PRIMARY(b) ((b)&0xff) +#define SECONDARY(b) (((b)>>8)&0xff) +#define SUBORDINATE(b) (((b)>>16)&0xff) + +static int __init +hose_scan_bridges(struct linux_hose_info *hose, unsigned char bus) +{ + unsigned int devfn, l, class; + unsigned char hdr_type = 0; + unsigned int found = 0; + + for (devfn = 0; devfn < 0xff; ++devfn) { + if (PCI_FUNC(devfn) == 0) { + alpha_mv.hose_read_config_byte(bus, devfn, + PCI_HEADER_TYPE, + &hdr_type, hose); + } else if (!(hdr_type & 0x80)) { + /* not a multi-function device */ + continue; + } + + /* Check if there is anything here. */ + alpha_mv.hose_read_config_dword(bus, devfn, PCI_VENDOR_ID, + &l, hose); + if (l == 0xffffffff || l == 0x00000000) { + hdr_type = 0; + continue; + } + + /* See if this is a bridge device. */ + alpha_mv.hose_read_config_dword(bus, devfn, PCI_CLASS_REVISION, + &class, hose); + + if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) { + unsigned int busses; + + found++; + + alpha_mv.hose_read_config_dword(bus, devfn, + PCI_PRIMARY_BUS, + &busses, hose); + + DBG_HOSE(("hose_scan_bridges: hose %d bus %d " + "slot %d busses 0x%x\n", + hose->pci_hose_index, bus, PCI_SLOT(devfn), + busses)); + + /* + * Do something with first_busno and last_busno + */ + if (hose->pci_first_busno > PRIMARY(busses)) { + hose->pci_first_busno = PRIMARY(busses); + DBG_HOSE(("hose_scan_bridges: hose %d bus %d " + "slot %d change first to %d\n", + hose->pci_hose_index, bus, + PCI_SLOT(devfn), PRIMARY(busses))); + } + if (hose->pci_last_busno < SUBORDINATE(busses)) { + hose->pci_last_busno = SUBORDINATE(busses); + DBG_HOSE(("hose_scan_bridges: hose %d bus %d " + "slot %d change last to %d\n", + hose->pci_hose_index, bus, + PCI_SLOT(devfn), + SUBORDINATE(busses))); + } + /* + * Now scan everything underneath the bridge. + */ + hose_scan_bridges(hose, SECONDARY(busses)); + } + } + return found; +} + +static void __init +hose_reconfigure_bridges(struct linux_hose_info *hose, unsigned char bus) +{ + unsigned int devfn, l, class; + unsigned char hdr_type = 0; + + for (devfn = 0; devfn < 0xff; ++devfn) { + if (PCI_FUNC(devfn) == 0) { + alpha_mv.hose_read_config_byte(bus, devfn, + PCI_HEADER_TYPE, + &hdr_type, hose); + } else if (!(hdr_type & 0x80)) { + /* not a multi-function device */ + continue; + } + + /* Check if there is anything here. */ + alpha_mv.hose_read_config_dword(bus, devfn, PCI_VENDOR_ID, + &l, hose); + if (l == 0xffffffff || l == 0x00000000) { + hdr_type = 0; + continue; + } + + /* See if this is a bridge device. */ + alpha_mv.hose_read_config_dword(bus, devfn, PCI_CLASS_REVISION, + &class, hose); + + if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) { + unsigned int busses; + + alpha_mv.hose_read_config_dword(bus, devfn, + PCI_PRIMARY_BUS, + &busses, hose); + + /* + * First reconfigure everything underneath the bridge. + */ + hose_reconfigure_bridges(hose, (busses >> 8) & 0xff); + + /* + * Unconfigure this bridges bus numbers, + * pci_scan_bus() will fix this up properly. + */ + busses &= 0xff000000; + alpha_mv.hose_write_config_dword(bus, devfn, + PCI_PRIMARY_BUS, + busses, hose); + } + } +} + +static void __init +hose_fixup_busno(struct linux_hose_info *hose, unsigned char bus) +{ + int nbus; + + /* + * First, scan for all bridge devices underneath this hose, + * to determine the first and last busnos. + */ + DBG_HOSE(("hose_fixup_busno: before hose_scan_bridges()\n")); + + if (!hose_scan_bridges(hose, 0)) { + /* none found, exit */ + hose->pci_first_busno = bus; + hose->pci_last_busno = bus; + } else { + /* + * Reconfigure all bridge devices underneath this hose. + */ + DBG_HOSE(("hose_fixup_busno: before hose_reconfigure_bridges\n")); + hose_reconfigure_bridges(hose, hose->pci_first_busno); + } + + /* + * Now reconfigure the hose to it's new bus number and set up + * our bus2hose mapping for this hose. + */ + nbus = hose->pci_last_busno - hose->pci_first_busno; + + hose->pci_first_busno = bus; + + DBG_HOSE(("hose_fixup_busno: hose %d startbus %d nbus %d\n", + hose->pci_hose_index, bus, nbus)); + + do { + bus2hose[bus++] = hose; + } while (nbus-- > 0); + DBG_HOSE(("hose_fixup_busno: returning...\n")); +} + +static void __init +layout_one_hose(struct linux_hose_info *hose) +{ + static struct pci_bus *pchain = NULL; + struct pci_bus *pbus = &hose->pci_bus; + static unsigned char busno = 0; + + DBG_HOSE(("layout_one_hose: entry\n")); + + /* + * Hoses include child PCI bridges in bus-range property, + * but we don't scan each of those ourselves, Linux generic PCI + * probing code will find child bridges and link them into this + * hose's root PCI device hierarchy. + */ + + pbus->number = pbus->secondary = busno; + pbus->sysdata = hose; + + DBG_HOSE(("layout_one_hose: before hose_fixup_busno()\n")); + + hose_fixup_busno(hose, busno); + + DBG_HOSE(("layout_one_hose: before pci_scan_bus()\n")); + + pbus->subordinate = pci_scan_bus(pbus); /* the original! */ + + /* + * Set the maximum subordinate bus of this hose. + */ + hose->pci_last_busno = pbus->subordinate; +#if 0 + alpha_mv.hose_write_config_byte(busno, 0, 0x41, hose->pci_last_busno, + hose); +#endif + busno = pbus->subordinate + 1; + + /* + * Fixup the chain of primary PCI busses. + */ + if (pchain) { + pchain->next = &hose->pci_bus; + pchain = pchain->next; + } else { + pchain = &pci_root; + memcpy(pchain, &hose->pci_bus, sizeof(pci_root)); + } + DBG_HOSE(("layout_one_hose: returning...\n")); +} + +static void __init +layout_hoses(void) +{ + struct linux_hose_info * hose; + int i; + + /* On multiple bus machines, we play games with pci_root in order + that all of the busses are probed as part of the normal PCI + setup. The existance of the busses was determined in init_arch. */ + + if (hose_head) { + /* Multi-bus machines did not yet wish to allow bus + accesses. We now do our own thing after the normal + pci_scan_bus is over. This mechanism is relatively + broken but will be fixed later. */ + pci_probe_enabled = 1; + + for (hose = hose_head; hose; hose = hose->next) + layout_one_hose(hose); + } else { + /* For the benefit of single-bus machines, emulate a + multi-bus machine to the (limited) extent necessary. + Init all bus2hose entries to point to a dummy. */ + hose = kmalloc(sizeof(*hose), GFP_KERNEL); + memset(hose, 0, sizeof(*hose)); + for (i = 0; i < 256; ++i) + bus2hose[i] = hose; + } +} + #endif /* CONFIG_PCI */ diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/bios32.h linux/arch/alpha/kernel/bios32.h --- v2.1.120/linux/arch/alpha/kernel/bios32.h Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/bios32.h Sun Sep 6 10:34:33 1998 @@ -153,3 +153,9 @@ if (slot >= min_idsel && slot <= max_idsel && pin < irqs_per_slot) \ _ctl_ = irq_tab[slot - min_idsel][pin]; \ _ctl_; }) + + +/* The hose list. */ +extern struct linux_hose_info *hose_head, **hose_tail; +extern int hose_count; +extern int pci_probe_enabled; diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/check_asm.c linux/arch/alpha/kernel/check_asm.c --- v2.1.120/linux/arch/alpha/kernel/check_asm.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/kernel/check_asm.c Sun Sep 6 10:34:33 1998 @@ -0,0 +1,33 @@ +#include +#include +#include +#include +#include + +int main() +{ + printf("#ifndef __ASM_OFFSETS_H__\n#define __ASM_OFFSETS_H__\n"); + + printf("#define TASK_STATE %ld\n", + (long)offsetof(struct task_struct, state)); + printf("#define TASK_FLAGS %ld\n", + (long)offsetof(struct task_struct, flags)); + printf("#define TASK_SIGPENDING %ld\n", + (long)offsetof(struct task_struct, sigpending)); + printf("#define TASK_ADDR_LIMIT %ld\n", + (long)offsetof(struct task_struct, addr_limit)); + printf("#define TASK_EXEC_DOMAIN %ld\n", + (long)offsetof(struct task_struct, exec_domain)); + printf("#define TASK_NEED_RESCHED %ld\n", + (long)offsetof(struct task_struct, need_resched)); + printf("#define TASK_SIZE %ld\n", sizeof(struct task_struct)); + printf("#define STACK_SIZE %ld\n", sizeof(union task_union)); + + printf("#define HAE_CACHE %ld\n", + (long)offsetof(struct alpha_machine_vector, hae_cache)); + printf("#define HAE_REG %ld\n", + (long)offsetof(struct alpha_machine_vector, hae_register)); + + printf("#endif /* __ASM_OFFSETS_H__ */\n"); + return 0; +} diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/core_apecs.c linux/arch/alpha/kernel/core_apecs.c --- v2.1.120/linux/arch/alpha/kernel/core_apecs.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/core_apecs.c Sun Sep 6 10:34:33 1998 @@ -130,8 +130,7 @@ unsigned int stat0, value; unsigned int haxr2 = 0; - save_flags(flags); /* avoid getting hit by machine check */ - cli(); + __save_and_cli(flags); /* avoid getting hit by machine check */ DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1)); @@ -201,7 +200,7 @@ *(vuip)APECS_IOC_HAXR2 = haxr2 & ~1; mb(); } - restore_flags(flags); + __restore_flags(flags); return value; } @@ -213,8 +212,8 @@ unsigned int stat0; unsigned int haxr2 = 0; - save_flags(flags); /* avoid getting hit by machine check */ - cli(); + __save_and_cli(flags); /* avoid getting hit by machine check */ + /* Reset status register to avoid losing errors. */ stat0 = *(vuip)APECS_IOC_DCSR; @@ -270,18 +269,17 @@ *(vuip)APECS_IOC_HAXR2 = haxr2 & ~1; mb(); } - restore_flags(flags); + __restore_flags(flags); } int -apecs_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value) +apecs_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value, + struct linux_hose_info *hose) { unsigned long addr = APECS_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xff; - if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -293,16 +291,13 @@ } int -apecs_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value) +apecs_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value, + struct linux_hose_info *hose) { unsigned long addr = APECS_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xffff; - - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -313,15 +308,13 @@ } int -apecs_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value) +apecs_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value, + struct linux_hose_info *hose) { unsigned long addr = APECS_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xffffffff; - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -331,7 +324,8 @@ } int -apecs_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value) +apecs_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value, + struct linux_hose_info *hose) { unsigned long addr = APECS_CONF; unsigned long pci_addr; @@ -346,7 +340,8 @@ } int -apecs_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value) +apecs_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value, + struct linux_hose_info *hose) { unsigned long addr = APECS_CONF; unsigned long pci_addr; @@ -361,7 +356,8 @@ } int -apecs_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value) +apecs_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value, + struct linux_hose_info *hose) { unsigned long addr = APECS_CONF; unsigned long pci_addr; diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/core_cia.c linux/arch/alpha/kernel/core_cia.c --- v2.1.120/linux/arch/alpha/kernel/core_cia.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/core_cia.c Sun Sep 6 10:34:33 1998 @@ -30,8 +30,6 @@ * handle the system transaction. Another involves timing. Ho hum. */ -extern asmlinkage void wrmces(unsigned long mces); - /* * Machine check reasons. Defined according to PALcode sources * (osf.h and platform.h). @@ -155,8 +153,7 @@ value = 0xffffffffU; mb(); - save_flags(flags); /* avoid getting hit by machine check */ - cli(); + __save_and_cli(flags); /* avoid getting hit by machine check */ DBGC(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1)); @@ -224,7 +221,7 @@ DBGC(("conf_read(): finished\n")); - restore_flags(flags); + __restore_flags(flags); return value; } @@ -235,8 +232,7 @@ unsigned int stat0; unsigned int cia_cfg = 0; - save_flags(flags); /* avoid getting hit by machine check */ - cli(); + __save_and_cli(flags); /* avoid getting hit by machine check */ /* Reset status register to avoid losing errors. */ stat0 = *(vuip)CIA_IOC_CIA_ERR; @@ -295,18 +291,17 @@ } DBGC(("conf_write(): finished\n")); - restore_flags(flags); + __restore_flags(flags); } int -cia_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value) +cia_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value, + struct linux_hose_info *hose) { unsigned long addr = CIA_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xff; - if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -316,16 +311,13 @@ } int -cia_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value) +cia_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value, + struct linux_hose_info *hose) { unsigned long addr = CIA_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xffff; - - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -335,15 +327,13 @@ } int -cia_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value) +cia_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value, + struct linux_hose_info *hose) { unsigned long addr = CIA_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xffffffff; - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -353,7 +343,8 @@ } int -cia_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value) +cia_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value, + struct linux_hose_info *hose) { unsigned long addr = CIA_CONF; unsigned long pci_addr; @@ -368,14 +359,13 @@ } int -cia_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value) +cia_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value, + struct linux_hose_info *hose) { unsigned long addr = CIA_CONF; unsigned long pci_addr; unsigned char type1; - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -385,14 +375,13 @@ } int -cia_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value) +cia_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value, + struct linux_hose_info *hose) { unsigned long addr = CIA_CONF; unsigned long pci_addr; unsigned char type1; - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/core_lca.c linux/arch/alpha/kernel/core_lca.c --- v2.1.120/linux/arch/alpha/kernel/core_lca.c Sat Sep 5 16:46:40 1998 +++ linux/arch/alpha/kernel/core_lca.c Sun Sep 6 10:34:33 1998 @@ -128,8 +128,7 @@ unsigned long flags, code, stat0; unsigned int value; - save_flags(flags); - cli(); + __save_and_cli(flags); /* Reset status register to avoid loosing errors. */ stat0 = *(vulp)LCA_IOC_STAT0; @@ -157,7 +156,7 @@ value = 0xffffffff; } - restore_flags(flags); + __restore_flags(flags); return value; } @@ -166,8 +165,7 @@ { unsigned long flags, code, stat0; - save_flags(flags); /* avoid getting hit by machine check */ - cli(); + __save_and_cli(flags); /* avoid getting hit by machine check */ /* Reset status register to avoid loosing errors. */ stat0 = *(vulp)LCA_IOC_STAT0; @@ -193,17 +191,16 @@ /* Reset machine check. */ wrmces(0x7); } - restore_flags(flags); + __restore_flags(flags); } int -lca_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value) +lca_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value, + struct linux_hose_info *hose) { unsigned long addr = LCA_CONF; unsigned long pci_addr; - *value = 0xff; - if (mk_conf_addr(bus, device_fn, where, &pci_addr)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -213,15 +210,12 @@ } int -lca_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value) +lca_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value, + struct linux_hose_info *hose) { unsigned long addr = LCA_CONF; unsigned long pci_addr; - *value = 0xffff; - - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -231,14 +225,12 @@ } int -lca_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value) +lca_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value, + struct linux_hose_info *hose) { unsigned long addr = LCA_CONF; unsigned long pci_addr; - *value = 0xffffffff; - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -248,7 +240,8 @@ } int -lca_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value) +lca_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value, + struct linux_hose_info *hose) { unsigned long addr = LCA_CONF; unsigned long pci_addr; @@ -262,13 +255,12 @@ } int -lca_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value) +lca_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value, + struct linux_hose_info *hose) { unsigned long addr = LCA_CONF; unsigned long pci_addr; - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -278,13 +270,12 @@ } int -lca_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value) +lca_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value, + struct linux_hose_info *hose) { unsigned long addr = LCA_CONF; unsigned long pci_addr; - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr)) return PCIBIOS_DEVICE_NOT_FOUND; diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/core_mcpcia.c linux/arch/alpha/kernel/core_mcpcia.c --- v2.1.120/linux/arch/alpha/kernel/core_mcpcia.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/core_mcpcia.c Sun Sep 6 10:34:33 1998 @@ -12,10 +12,13 @@ #include #include #include +#include #include #include #include +#include +#include #define __EXTERN_INLINE inline #include @@ -23,6 +26,7 @@ #undef __EXTERN_INLINE #include "proto.h" +#include "bios32.h" /* * NOTE: Herein lie back-to-back mb instructions. They are magic. @@ -30,8 +34,6 @@ * handle the system transaction. Another involves timing. Ho hum. */ -extern asmlinkage void wrmces(unsigned long mces); - /* * BIOS32-style PCI interface: */ @@ -44,42 +46,20 @@ # define DBG_CFG(args) #endif -#undef DEBUG_PCI - -#ifdef DEBUG_PCI -# define DBG_PCI(args) printk args -#else -# define DBG_PCI(args) -#endif #define DEBUG_MCHECK #ifdef DEBUG_MCHECK # define DBG_MCK(args) printk args -# define DEBUG_MCHECK_DUMP #else # define DBG_MCK(args) #endif -#define vuip volatile unsigned int * -#define vulp volatile unsigned long * - static volatile unsigned int MCPCIA_mcheck_expected[NR_CPUS]; static volatile unsigned int MCPCIA_mcheck_taken[NR_CPUS]; static unsigned int MCPCIA_jd[NR_CPUS]; #define MCPCIA_MAX_HOSES 2 -static int mcpcia_num_hoses = 0; - -static int pci_probe_enabled = 0; /* disable to start */ - -static struct linux_hose_info *mcpcia_root = NULL, *mcpcia_last_hose; - -static inline unsigned long long_align(unsigned long addr) -{ - return ((addr + (sizeof(unsigned long) - 1)) & - ~(sizeof(unsigned long) - 1)); -} /* @@ -134,7 +114,7 @@ cpu = smp_processor_id(); - save_and_cli(flags); + __save_and_cli(flags); DBG_CFG(("conf_read(addr=0x%lx, type1=%d, hose=%d)\n", addr, type1, hoseno)); @@ -166,7 +146,7 @@ DBG_CFG(("conf_read(): finished\n")); - restore_flags(flags); + __restore_flags(flags); return value; } @@ -180,7 +160,7 @@ cpu = smp_processor_id(); - save_and_cli(flags); /* avoid getting hit by machine check */ + __save_and_cli(flags); /* avoid getting hit by machine check */ /* Reset status register to avoid losing errors. */ stat0 = *(vuip)MCPCIA_CAP_ERR(hoseno); @@ -201,7 +181,7 @@ mb(); DBG_CFG(("conf_write(): finished\n")); - restore_flags(flags); + __restore_flags(flags); } static int @@ -211,7 +191,7 @@ { unsigned long addr; - if (!pci_probe_enabled) /* if doing standard pci_init(), ignore */ + if (!pci_probe_enabled) return -1; DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x," @@ -232,18 +212,13 @@ return 0; } -/* FIXME: At some point we should update these routines to use the new - PCI interface, which can jump through these hoops for us. */ - -static inline int -hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value, - struct linux_hose_info *hose) +int +mcpcia_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; - *value = 0xff; - if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -252,17 +227,13 @@ return PCIBIOS_SUCCESSFUL; } -static inline int -hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value, - struct linux_hose_info *hose) +int +mcpcia_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; - *value = 0xffff; - - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -271,17 +242,13 @@ return PCIBIOS_SUCCESSFUL; } -static inline int -hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value, - struct linux_hose_info *hose) +int +mcpcia_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; - *value = 0xffffffff; - - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(hose, bus, device_fn, where, &addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -290,9 +257,9 @@ return PCIBIOS_SUCCESSFUL; } -static inline int -hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value, - struct linux_hose_info *hose) +int +mcpcia_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; @@ -305,9 +272,9 @@ return PCIBIOS_SUCCESSFUL; } -static inline int -hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value, - struct linux_hose_info *hose) +int +mcpcia_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; @@ -320,9 +287,9 @@ return PCIBIOS_SUCCESSFUL; } -static inline int -hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value, - struct linux_hose_info *hose) +int +mcpcia_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; @@ -335,77 +302,64 @@ return PCIBIOS_SUCCESSFUL; } -int -mcpcia_pcibios_read_config_byte (u8 bus, u8 devfn, u8 where, u8 *value) -{ - return hose_read_config_byte(bus, devfn, where, value, bus2hose[bus]); -} - -int -mcpcia_pcibios_read_config_word (u8 bus, u8 devfn, u8 where, u16 *value) -{ - return hose_read_config_word(bus, devfn, where, value, bus2hose[bus]); -} - -int -mcpcia_pcibios_read_config_dword (u8 bus, u8 devfn, u8 where, u32 *value) -{ - return hose_read_config_dword(bus, devfn, where, value, bus2hose[bus]); -} - -int -mcpcia_pcibios_write_config_byte (u8 bus, u8 devfn, u8 where, u8 value) -{ - return hose_write_config_byte(bus, devfn, where, value, bus2hose[bus]); -} - -int -mcpcia_pcibios_write_config_word (u8 bus, u8 devfn, u8 where, u16 value) -{ - return hose_write_config_word(bus, devfn, where, value, bus2hose[bus]); -} - -int -mcpcia_pcibios_write_config_dword (u8 bus, u8 devfn, u8 where, u32 val) -{ - return hose_write_config_dword(bus, devfn, where, val, bus2hose[bus]); -} - void __init mcpcia_init_arch(unsigned long *mem_start, unsigned long *mem_end) { + extern asmlinkage void entInt(void); struct linux_hose_info *hose; unsigned int mcpcia_err; unsigned int pci_rev; - int h; + int h, cpu; - *mem_start = long_align(*mem_start); + /* Ho hum.. init_arch is called before init_IRQ, but we need to be + able to handle machine checks. So install the handler now. */ + wrent(entInt, 0); - for (h = 0; h < NR_CPUS; h++) { - MCPCIA_mcheck_expected[h] = 0; - MCPCIA_mcheck_taken[h] = 0; - } + /* Align memory to cache line; we'll be allocating from it. */ + *mem_start = (*mem_start | 31) + 1; + + cpu = smp_processor_id(); /* First, find how many hoses we have. */ for (h = 0; h < MCPCIA_MAX_HOSES; h++) { + + /* Gotta be REAL careful. If hose is absent, we get a + machine check. */ + + mb(); + mb(); + draina(); + MCPCIA_mcheck_expected[cpu] = 1; + MCPCIA_mcheck_taken[cpu] = 0; + mb(); + + /* Access the bus revision word. */ pci_rev = *(vuip)MCPCIA_REV(h); + + mb(); + mb(); /* magic */ + if (MCPCIA_mcheck_taken[cpu]) { + MCPCIA_mcheck_taken[cpu] = 0; + pci_rev = 0xffffffff; + mb(); + } + MCPCIA_mcheck_expected[cpu] = 0; + mb(); + #if 0 - printk("mcpcia_init: got 0x%x for PCI_REV for hose %d\n", + printk("mcpcia_init_arch: got 0x%x for PCI_REV for hose %d\n", pci_rev, h); #endif if ((pci_rev >> 16) == PCI_CLASS_BRIDGE_HOST) { - mcpcia_num_hoses++; + hose_count++; hose = (struct linux_hose_info *)*mem_start; - *mem_start = long_align(*mem_start + sizeof(*hose)); + *mem_start = (unsigned long)(hose + 1); memset(hose, 0, sizeof(*hose)); - if (mcpcia_root) - mcpcia_last_hose->next = hose; - else - mcpcia_root = hose; - mcpcia_last_hose = hose; + *hose_tail = hose; + hose_tail = &hose->next; hose->pci_io_space = MCPCIA_IO(h); hose->pci_mem_space = MCPCIA_DENSE(h); @@ -418,14 +372,14 @@ } #if 1 - printk("mcpcia_init: found %d hoses\n", mcpcia_num_hoses); + printk("mcpcia_init_arch: found %d hoses\n", hose_count); #endif /* Now do init for each hose. */ - for (hose = mcpcia_root; hose; hose = hose->next) { + for (hose = hose_head; hose; hose = hose->next) { h = hose->pci_hose_index; #if 0 - printk("mcpcia_init: -------- hose %d --------\n",h); + printk("mcpcia_init_arch: -------- hose %d --------\n",h); printk("MCPCIA_REV 0x%x\n", *(vuip)MCPCIA_REV(h)); printk("MCPCIA_WHOAMI 0x%x\n", *(vuip)MCPCIA_WHOAMI(h)); printk("MCPCIA_HAE_MEM 0x%x\n", *(vuip)MCPCIA_HAE_MEM(h)); @@ -470,8 +424,8 @@ MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W0_MASK(h) & 0xfff00000U; MCPCIA_DMA_WIN_SIZE += 0x00100000U; #if 1 - printk("mcpcia_init: using Window 0 settings\n"); - printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n", + printk("mcpcia_init_arch: using Window 0 settings\n"); + printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n", *(vuip)MCPCIA_W0_BASE(h), *(vuip)MCPCIA_W0_MASK(h), *(vuip)MCPCIA_T0_BASE(h)); @@ -487,8 +441,8 @@ MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W1_MASK(h) & 0xfff00000U; MCPCIA_DMA_WIN_SIZE += 0x00100000U; #if 1 - printk("mcpcia_init: using Window 1 settings\n"); - printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n", + printk("mcpcia_init_arch: using Window 1 settings\n"); + printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n", *(vuip)MCPCIA_W1_BASE(h), *(vuip)MCPCIA_W1_MASK(h), *(vuip)MCPCIA_T1_BASE(h)); @@ -504,8 +458,8 @@ MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W2_MASK(h) & 0xfff00000U; MCPCIA_DMA_WIN_SIZE += 0x00100000U; #if 1 - printk("mcpcia_init: using Window 2 settings\n"); - printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n", + printk("mcpcia_init_arch: using Window 2 settings\n"); + printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n", *(vuip)MCPCIA_W2_BASE(h), *(vuip)MCPCIA_W2_MASK(h), *(vuip)MCPCIA_T2_BASE(h)); @@ -521,8 +475,8 @@ MCPCIA_DMA_WIN_SIZE = *(vuip)MCPCIA_W3_MASK(h) & 0xfff00000U; MCPCIA_DMA_WIN_SIZE += 0x00100000U; #if 1 - printk("mcpcia_init: using Window 3 settings\n"); - printk("mcpcia_init: BASE 0x%x MASK 0x%x TRANS 0x%x\n", + printk("mcpcia_init_arch: using Window 3 settings\n"); + printk("mcpcia_init_arch: BASE 0x%x MASK 0x%x TRANS 0x%x\n", *(vuip)MCPCIA_W3_BASE(h), *(vuip)MCPCIA_W3_MASK(h), *(vuip)MCPCIA_T3_BASE(h)); @@ -541,7 +495,7 @@ * future, we may want to use them to do scatter/ * gather DMA. * - * Window 0 goes at 1 GB and is 1 GB large. + * Window 0 goes at 2 GB and is 2 GB large. */ *(vuip)MCPCIA_W0_BASE(h) = 1U | (MCPCIA_DMA_WIN_BASE_DEFAULT & 0xfff00000U); @@ -559,7 +513,7 @@ #if 0 { unsigned int mcpcia_int_ctl = *((vuip)MCPCIA_INT_CTL(h)); - printk("mcpcia_init: INT_CTL was 0x%x\n", mcpcia_int_ctl); + printk("mcpcia_init_arch: INT_CTL was 0x%x\n", mcpcia_int_ctl); *(vuip)MCPCIA_INT_CTL(h) = 1U; mb(); mcpcia_int_ctl = *(vuip)MCPCIA_INT_CTL(h); } @@ -750,221 +704,9 @@ else if (type == 0x630) printk("MCPCIA machine check: processor CORRECTABLE!\n"); else - mcpcia_print_uncorrectable(mchk_logout); #endif /* DEBUG_MCHECK_DUMP */ + mcpcia_print_uncorrectable(mchk_logout); } #endif #endif -} - -/*==========================================================================*/ - -#define PRIMARY(b) ((b)&0xff) -#define SECONDARY(b) (((b)>>8)&0xff) -#define SUBORDINATE(b) (((b)>>16)&0xff) - -static int __init -hose_scan_bridges(struct linux_hose_info *hose, unsigned char bus) -{ - unsigned int devfn, l, class; - unsigned char hdr_type = 0; - unsigned int found = 0; - - for (devfn = 0; devfn < 0xff; ++devfn) { - if (PCI_FUNC(devfn) == 0) { - hose_read_config_byte(bus, devfn, PCI_HEADER_TYPE, - &hdr_type, hose); - } else if (!(hdr_type & 0x80)) { - /* not a multi-function device */ - continue; - } - - /* Check if there is anything here. */ - hose_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l, hose); - if (l == 0xffffffff || l == 0x00000000) { - hdr_type = 0; - continue; - } - - /* See if this is a bridge device. */ - hose_read_config_dword(bus, devfn, PCI_CLASS_REVISION, - &class, hose); - - if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) { - unsigned int busses; - - found++; - - hose_read_config_dword(bus, devfn, PCI_PRIMARY_BUS, - &busses, hose); - - DBG_PCI(("hose_scan_bridges: hose %d bus %d " - "slot %d busses 0x%x\n", - hose->pci_hose_index, bus, PCI_SLOT(devfn), - busses)); - - /* - * Do something with first_busno and last_busno - */ - if (hose->pci_first_busno > PRIMARY(busses)) { - hose->pci_first_busno = PRIMARY(busses); - DBG_PCI(("hose_scan_bridges: hose %d bus %d " - "slot %d change first to %d\n", - hose->pci_hose_index, bus, - PCI_SLOT(devfn), PRIMARY(busses))); - } - if (hose->pci_last_busno < SUBORDINATE(busses)) { - hose->pci_last_busno = SUBORDINATE(busses); - DBG_PCI(("hose_scan_bridges: hose %d bus %d " - "slot %d change last to %d\n", - hose->pci_hose_index, bus, - PCI_SLOT(devfn), - SUBORDINATE(busses))); - } - /* - * Now scan everything underneath the bridge. - */ - hose_scan_bridges(hose, SECONDARY(busses)); - } - } - return found; -} - -static void __init -hose_reconfigure_bridges(struct linux_hose_info *hose, unsigned char bus) -{ - unsigned int devfn, l, class; - unsigned char hdr_type = 0; - - for (devfn = 0; devfn < 0xff; ++devfn) { - if (PCI_FUNC(devfn) == 0) { - hose_read_config_byte(bus, devfn, PCI_HEADER_TYPE, - &hdr_type, hose); - } else if (!(hdr_type & 0x80)) { - /* not a multi-function device */ - continue; - } - - /* Check if there is anything here. */ - hose_read_config_dword(bus, devfn, PCI_VENDOR_ID, &l, hose); - if (l == 0xffffffff || l == 0x00000000) { - hdr_type = 0; - continue; - } - - /* See if this is a bridge device. */ - hose_read_config_dword(bus, devfn, PCI_CLASS_REVISION, - &class, hose); - - if ((class >> 16) == PCI_CLASS_BRIDGE_PCI) { - unsigned int busses; - - hose_read_config_dword(bus, devfn, PCI_PRIMARY_BUS, - &busses, hose); - - /* - * First reconfigure everything underneath the bridge. - */ - hose_reconfigure_bridges(hose, (busses >> 8) & 0xff); - - /* - * Unconfigure this bridges bus numbers, - * pci_scan_bus() will fix this up properly. - */ - busses &= 0xff000000; - hose_write_config_dword(bus, devfn, PCI_PRIMARY_BUS, - busses, hose); - } - } -} - -static void __init -mcpcia_fixup_busno(struct linux_hose_info *hose, unsigned char bus) -{ - unsigned int nbus; - - /* - * First, scan for all bridge devices underneath this hose, - * to determine the first and last busnos. - */ - if (!hose_scan_bridges(hose, 0)) { - /* none found, exit */ - hose->pci_first_busno = bus; - hose->pci_last_busno = bus; - } else { - /* - * Reconfigure all bridge devices underneath this hose. - */ - hose_reconfigure_bridges(hose, hose->pci_first_busno); - } - - /* - * Now reconfigure the hose to it's new bus number and set up - * our bus2hose mapping for this hose. - */ - nbus = hose->pci_last_busno - hose->pci_first_busno; - - hose->pci_first_busno = bus; - - DBG_PCI(("mcpcia_fixup_busno: hose %d startbus %d nbus %d\n", - hose->pci_hose_index, bus, nbus)); - - do { - bus2hose[bus++] = hose; - } while (nbus-- > 0); -} - -static void __init -mcpcia_probe(struct linux_hose_info *hose) -{ - static struct pci_bus *pchain = NULL; - struct pci_bus *pbus = &hose->pci_bus; - static unsigned char busno = 0; - - /* - * Hoses include child PCI bridges in bus-range property, - * but we don't scan each of those ourselves, Linux generic PCI - * probing code will find child bridges and link them into this - * hose's root PCI device hierarchy. - */ - - pbus->number = pbus->secondary = busno; - pbus->sysdata = hose; - - mcpcia_fixup_busno(hose, busno); - - pbus->subordinate = pci_scan_bus(pbus); /* the original! */ - - /* - * Set the maximum subordinate bus of this hose. - */ - hose->pci_last_busno = pbus->subordinate; -#if 0 - hose_write_config_byte(busno, 0, 0x41, hose->pci_last_busno, hose); -#endif - busno = pbus->subordinate + 1; - - /* - * Fixup the chain of primary PCI busses. - */ - if (pchain) { - pchain->next = &hose->pci_bus; - pchain = pchain->next; - } else { - pchain = &pci_root; - memcpy(pchain, &hose->pci_bus, sizeof(pci_root)); - } -} - -void __init -mcpcia_pci_fixup(void) -{ - struct linux_hose_info *hose; - - /* Turn on Config space access finally! */ - pci_probe_enabled = 1; - - /* For each hose, probe and setup the devices on the hose. */ - for (hose = mcpcia_root; hose; hose = hose->next) - mcpcia_probe(hose); } diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/core_pyxis.c linux/arch/alpha/kernel/core_pyxis.c --- v2.1.120/linux/arch/alpha/kernel/core_pyxis.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/core_pyxis.c Sun Sep 6 10:34:33 1998 @@ -27,22 +27,22 @@ One plausible explanation is that the I/O controller does not properly handle the system transaction. Another involves timing. Ho hum. */ -extern asmlinkage void wrmces(unsigned long mces); - /* * BIOS32-style PCI interface: */ -#ifdef DEBUG -# define DBG(args) printk args +#define DEBUG_CONFIG 0 +#define DEBUG_MCHECK 0 + +#if DEBUG_CONFIG +# define DBG_CNF(args) printk args #else -# define DBG(args) +# define DBG_CNF(args) #endif -#define DEBUG_MCHECK -#ifdef DEBUG_MCHECK +#if DEBUG_MCHECK # define DBG_MCK(args) printk args -#define DEBUG_MCHECK_DUMP +# define DEBUG_MCHECK_DUMP #else # define DBG_MCK(args) #endif @@ -101,9 +101,9 @@ { unsigned long addr; - DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x," - " pci_addr=0x%p, type1=0x%p)\n", - bus, device_fn, where, pci_addr, type1)); + DBG_CNF(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x," + " pci_addr=0x%p, type1=0x%p)\n", + bus, device_fn, where, pci_addr, type1)); if (bus == 0) { int device; @@ -112,8 +112,8 @@ /* Type 0 configuration cycle. */ #if NOT_NOW if (device > 20) { - DBG(("mk_conf_addr: device (%d) > 20, returning -1\n", - device)); + DBG_CNF(("mk_conf_addr: device (%d) > 20, return -1\n", + device)); return -1; } #endif @@ -125,7 +125,7 @@ addr = (bus << 16) | (device_fn << 8) | (where); } *pci_addr = addr; - DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); + DBG_CNF(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); return 0; } @@ -136,22 +136,19 @@ unsigned int stat0, value, temp; unsigned int pyxis_cfg = 0; - save_and_cli(flags); /* avoid getting hit by machine check */ - - DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1)); + __save_and_cli(flags); /* avoid getting hit by machine check */ /* Reset status register to avoid losing errors. */ stat0 = *(vuip)PYXIS_ERR; *(vuip)PYXIS_ERR = stat0; mb(); temp = *(vuip)PYXIS_ERR; /* re-read to force write */ - DBG(("conf_read: PYXIS ERR was 0x%x\n", stat0)); + DBG_CNF(("conf_read: PYXIS ERR was 0x%x\n", stat0)); /* If Type1 access, must set PYXIS CFG. */ if (type1) { pyxis_cfg = *(vuip)PYXIS_CFG; *(vuip)PYXIS_CFG = pyxis_cfg | 1; mb(); temp = *(vuip)PYXIS_CFG; /* re-read to force write */ - DBG(("conf_read: TYPE1 access\n")); } mb(); @@ -179,9 +176,10 @@ temp = *(vuip)PYXIS_CFG; /* re-read to force write */ } - DBG(("conf_read(): finished\n")); + DBG_CNF(("conf_read(addr=0x%lx, type1=%d) = %#x\n", + addr, type1, value)); - restore_flags(flags); + __restore_flags(flags); return value; } @@ -192,24 +190,27 @@ unsigned int stat0, temp; unsigned int pyxis_cfg = 0; - save_and_cli(flags); /* avoid getting hit by machine check */ + DBG_CNF(("conf_write(addr=%#lx, value=%#x, type1=%d)\n", + addr, value, type1)); + + __save_and_cli(flags); /* avoid getting hit by machine check */ /* Reset status register to avoid losing errors. */ stat0 = *(vuip)PYXIS_ERR; *(vuip)PYXIS_ERR = stat0; mb(); temp = *(vuip)PYXIS_ERR; /* re-read to force write */ - DBG(("conf_write: PYXIS ERR was 0x%x\n", stat0)); /* If Type1 access, must set PYXIS CFG. */ if (type1) { pyxis_cfg = *(vuip)PYXIS_CFG; *(vuip)PYXIS_CFG = pyxis_cfg | 1; mb(); temp = *(vuip)PYXIS_CFG; /* re-read to force write */ - DBG(("conf_read: TYPE1 access\n")); } + mb(); draina(); PYXIS_mcheck_expected = 1; + PYXIS_mcheck_taken = 0; mb(); /* Access configuration space. */ @@ -226,18 +227,17 @@ temp = *(vuip)PYXIS_CFG; /* re-read to force write */ } - DBG(("conf_write(): finished\n")); - restore_flags(flags); + __restore_flags(flags); } int -pyxis_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value) +pyxis_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value, + struct linux_hose_info *hose) { unsigned long addr = PYXIS_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xff; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -247,15 +247,13 @@ } int -pyxis_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value) +pyxis_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value, + struct linux_hose_info *hose) { unsigned long addr = PYXIS_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xffff; - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -265,15 +263,13 @@ } int -pyxis_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value) +pyxis_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value, + struct linux_hose_info *hose) { unsigned long addr = PYXIS_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xffffffff; - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -283,7 +279,8 @@ } int -pyxis_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value) +pyxis_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value, + struct linux_hose_info *hose) { unsigned long addr = PYXIS_CONF; unsigned long pci_addr; @@ -298,14 +295,13 @@ } int -pyxis_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value) +pyxis_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value, + struct linux_hose_info *hose) { unsigned long addr = PYXIS_CONF; unsigned long pci_addr; unsigned char type1; - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -315,14 +311,13 @@ } int -pyxis_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value) +pyxis_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value, + struct linux_hose_info *hose) { unsigned long addr = PYXIS_CONF; unsigned long pci_addr; unsigned char type1; - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -555,7 +550,7 @@ pyxis_pci_clr_err(void) { PYXIS_jd = *(vuip)PYXIS_ERR; - DBG(("PYXIS_pci_clr_err: PYXIS ERR after read 0x%x\n", PYXIS_jd)); + DBG_MCK(("PYXIS_pci_clr_err: PYXIS ERR after read 0x%x\n", PYXIS_jd)); *(vuip)PYXIS_ERR = 0x0180; mb(); PYXIS_jd = *(vuip)PYXIS_ERR; /* re-read to force write */ return 0; @@ -583,17 +578,6 @@ PYXIS_mcheck_expected, mchk_sysdata->epic_dcsr, mchk_sysdata->epic_pear)); #endif -#ifdef DEBUG_MCHECK_DUMP - { - unsigned long *ptr; - int i; - - ptr = (unsigned long *)la_ptr; - for (i = 0; i < mchk_header->size / sizeof(long); i += 2) { - printk(" +%lx %lx %lx\n", i*sizeof(long), ptr[i], ptr[i+1]); - } - } -#endif /* DEBUG_MCHECK_DUMP */ /* * Check if machine check is due to a badaddr() and if so, @@ -602,7 +586,7 @@ mb(); mb(); /* magic */ if (PYXIS_mcheck_expected) { - DBG(("PYXIS machine check expected\n")); + DBG_MCK(("PYXIS machine check expected\n")); PYXIS_mcheck_expected = 0; PYXIS_mcheck_taken = 1; mb(); @@ -612,7 +596,6 @@ wrmces(0x7); mb(); } -#if 1 else { printk("PYXIS machine check NOT expected\n") ; DBG_MCK(("pyxis_machine_check: vector=0x%lx la_ptr=0x%lx\n", @@ -629,6 +612,17 @@ pyxis_pci_clr_err(); wrmces(0x7); mb(); - } + +#ifdef DEBUG_MCHECK_DUMP + { + unsigned long *ptr = (unsigned long *)la_ptr;; + long n = mchk_header->size / (2*sizeof(long)); + + do + printk(" +%lx %lx %lx\n", i*sizeof(long), + ptr[i], ptr[i+1]); + while (--i); + } #endif + } } diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/core_t2.c linux/arch/alpha/kernel/core_t2.c --- v2.1.120/linux/arch/alpha/kernel/core_t2.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/core_t2.c Sun Sep 6 10:34:33 1998 @@ -148,8 +148,7 @@ cpu = smp_processor_id(); - save_flags(flags); /* avoid getting hit by machine check */ - cli(); + __save_and_cli(flags); /* avoid getting hit by machine check */ DBG(("conf_read(addr=0x%lx, type1=%d)\n", addr, type1)); @@ -195,7 +194,7 @@ } DBG(("conf_read(): finished\n")); - restore_flags(flags); + __restore_flags(flags); return value; } @@ -208,8 +207,7 @@ cpu = smp_processor_id(); - save_flags(flags); /* avoid getting hit by machine check */ - cli(); + __save_and_cli(flags); /* avoid getting hit by machine check */ #if 0 /* Reset status register to avoid losing errors. */ @@ -246,18 +244,17 @@ mb(); } DBG(("conf_write(): finished\n")); - restore_flags(flags); + __restore_flags(flags); } - int -t2_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value) +t2_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value, + struct linux_hose_info *hose) { unsigned long addr = T2_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xff; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -267,15 +264,13 @@ } int -t2_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value) +t2_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value, + struct linux_hose_info *hose) { unsigned long addr = T2_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xffff; - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -285,15 +280,13 @@ } int -t2_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value) +t2_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value, + struct linux_hose_info *hose) { unsigned long addr = T2_CONF; unsigned long pci_addr; unsigned char type1; - *value = 0xffffffff; - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -303,7 +296,8 @@ } int -t2_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value) +t2_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value, + struct linux_hose_info *hose) { unsigned long addr = T2_CONF; unsigned long pci_addr; @@ -318,14 +312,13 @@ } int -t2_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value) +t2_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value, + struct linux_hose_info *hose) { unsigned long addr = T2_CONF; unsigned long pci_addr; unsigned char type1; - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; @@ -335,14 +328,13 @@ } int -t2_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value) +t2_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value, + struct linux_hose_info *hose) { unsigned long addr = T2_CONF; unsigned long pci_addr; unsigned char type1; - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; if (mk_conf_addr(bus, device_fn, where, &pci_addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/core_tsunami.c linux/arch/alpha/kernel/core_tsunami.c --- v2.1.120/linux/arch/alpha/kernel/core_tsunami.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/core_tsunami.c Sun Sep 6 10:34:33 1998 @@ -6,6 +6,8 @@ * Based on code written by David A. Rusling (david.rusling@reo.mts.dec.com). * */ + +#include #include #include #include @@ -15,6 +17,7 @@ #include #include +#include #define __EXTERN_INLINE inline #include @@ -22,6 +25,7 @@ #undef __EXTERN_INLINE #include "proto.h" +#include "bios32.h" /* * NOTE: Herein lie back-to-back mb instructions. They are magic. @@ -33,10 +37,10 @@ * BIOS32-style PCI interface: */ -#ifdef DEBUG -# define DBG(args) printk args +#ifdef DEBUG_CONFIG +# define DBG_CFG(args) printk args #else -# define DBG(args) +# define DBG_CFG(args) #endif #define DEBUG_MCHECK @@ -50,7 +54,7 @@ static volatile unsigned int TSUNAMI_mcheck_expected[NR_CPUS]; static volatile unsigned int TSUNAMI_mcheck_taken[NR_CPUS]; static unsigned int TSUNAMI_jd[NR_CPUS]; - +int TSUNAMI_bootcpu; /* * Given a bus, device, and function number, compute resulting @@ -87,249 +91,205 @@ */ static int -mk_conf_addr(u8 bus, u8 device_fn, u8 where, unsigned long *pci_addr, - unsigned char *type1) +mk_conf_addr(u8 bus, u8 device_fn, u8 where, struct linux_hose_info *hose, + unsigned long *pci_addr, unsigned char *type1) { unsigned long addr; - DBG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, " - "pci_addr=0x%p, type1=0x%p)\n", - bus, device_fn, where, pci_addr, type1)); - - if (bus == 0) { - *type1 = 0; - } else { - /* Type 1 configuration cycle. */ - *type1 = 1; - } - addr = (bus << 16) | (device_fn << 8) | (where); + if (!pci_probe_enabled) + return -1; + + DBG_CFG(("mk_conf_addr(bus=%d ,device_fn=0x%x, where=0x%x, " + "pci_addr=0x%p, type1=0x%p)\n", + bus, device_fn, where, pci_addr, type1)); + + *type1 = (bus != 0); + + if (hose->pci_first_busno == bus) + bus = 0; + + addr = (bus << 16) | (device_fn << 8) | where; + addr |= hose->pci_config_space; + *pci_addr = addr; - DBG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); + DBG_CFG(("mk_conf_addr: returning pci_addr 0x%lx\n", addr)); return 0; } int -tsunami_pcibios_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value) +tsunami_hose_read_config_byte (u8 bus, u8 device_fn, u8 where, u8 *value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; - *value = 0xff; - if (mk_conf_addr(bus, device_fn, where, &addr, &type1)) + if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; - *value = __kernel_ldbu(*(vucp)(addr+TSUNAMI_PCI0_CONF)); + *value = __kernel_ldbu(*(vucp)addr); return PCIBIOS_SUCCESSFUL; } int -tsunami_pcibios_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value) +tsunami_hose_read_config_word (u8 bus, u8 device_fn, u8 where, u16 *value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; - *value = 0xffff; - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (mk_conf_addr(bus, device_fn, where, &addr, &type1)) + if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; - *value = __kernel_ldwu(*(vusp)(addr+TSUNAMI_PCI0_CONF)); + *value = __kernel_ldwu(*(vusp)addr); return PCIBIOS_SUCCESSFUL; } int -tsunami_pcibios_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value) +tsunami_hose_read_config_dword (u8 bus, u8 device_fn, u8 where, u32 *value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; - *value = 0xffffffff; - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (mk_conf_addr(bus, device_fn, where, &addr, &type1)) + if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; - *value = *(vuip)(addr+TSUNAMI_PCI0_CONF); + *value = *(vuip)addr; return PCIBIOS_SUCCESSFUL; } int -tsunami_pcibios_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value) +tsunami_hose_write_config_byte (u8 bus, u8 device_fn, u8 where, u8 value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; - if (mk_conf_addr(bus, device_fn, where, &addr, &type1)) + if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; - __kernel_stb(value, *(vucp)(addr+TSUNAMI_PCI0_CONF)); + __kernel_stb(value, *(vucp)addr); return PCIBIOS_SUCCESSFUL; } int -tsunami_pcibios_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value) +tsunami_hose_write_config_word (u8 bus, u8 device_fn, u8 where, u16 value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; - if (where & 0x1) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (mk_conf_addr(bus, device_fn, where, &addr, &type1)) + if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; - __kernel_stw(value, *(vusp)(addr+TSUNAMI_PCI0_CONF)); + __kernel_stw(value, *(vusp)addr); return PCIBIOS_SUCCESSFUL; } int -tsunami_pcibios_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value) +tsunami_hose_write_config_dword (u8 bus, u8 device_fn, u8 where, u32 value, + struct linux_hose_info *hose) { unsigned long addr; unsigned char type1; - if (where & 0x3) - return PCIBIOS_BAD_REGISTER_NUMBER; - if (mk_conf_addr(bus, device_fn, where, &addr, &type1)) + if (mk_conf_addr(bus, device_fn, where, hose, &addr, &type1)) return PCIBIOS_DEVICE_NOT_FOUND; - *(vuip)(addr+TSUNAMI_PCI0_CONF) = value; + *(vuip)addr = value; return PCIBIOS_SUCCESSFUL; } -void __init -tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end) +#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI +static long +tsunami_probe_read(volatile unsigned long *vaddr) { - unsigned long tsunami_err; - unsigned int i; + long dont_care, probe_result; + int cpu = smp_processor_id(); + int s = swpipl(6); /* Block everything but machine checks. */ + + TSUNAMI_mcheck_taken[cpu] = 0; + TSUNAMI_mcheck_expected[cpu] = 1; + dont_care = *vaddr; + draina(); + TSUNAMI_mcheck_expected[cpu] = 0; + probe_result = !TSUNAMI_mcheck_taken[cpu]; + TSUNAMI_mcheck_taken[cpu] = 0; + setipl(s); -#if 0 - printk("tsunami_init: CChip registers:\n"); - printk("CSR_CSC 0x%lx\n", *(vulp)TSUNAMI_CSR_CSC); - printk("CSR_MTR 0x%lx\n", *(vulp)TSUNAMI_CSR_MTR); - printk("CSR_MISC 0x%lx\n", *(vulp)TSUNAMI_CSR_MISC); - printk("CSR_DIM0 0x%lx\n", *(vulp)TSUNAMI_CSR_DIM0); - printk("CSR_DIM1 0x%lx\n", *(vulp)TSUNAMI_CSR_DIM1); - printk("CSR_DIR0 0x%lx\n", *(vulp)TSUNAMI_CSR_DIR0); - printk("CSR_DIR1 0x%lx\n", *(vulp)TSUNAMI_CSR_DIR1); - printk("CSR_DRIR 0x%lx\n", *(vulp)TSUNAMI_CSR_DRIR); - - printk("tsunami_init: DChip registers:\n"); - printk("CSR_DSC 0x%lx\n", *(vulp)TSUNAMI_CSR_DSC); - printk("CSR_STR 0x%lx\n", *(vulp)TSUNAMI_CSR_STR); - printk("CSR_DREV 0x%lx\n", *(vulp)TSUNAMI_CSR_DREV); - - printk("tsunami_init: PChip registers:\n"); - printk("PCHIP0_WSBA0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA0); - printk("PCHIP0_WSBA1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA1); - printk("PCHIP0_WSBA2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA2); - printk("PCHIP0_WSBA3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSBA3); - printk("PCHIP0_WSM0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM0); - printk("PCHIP0_WSM1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM1); - printk("PCHIP0_WSM2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM2); - printk("PCHIP0_WSM3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_WSM3); - printk("PCHIP0_TBA0 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA0); - printk("PCHIP0_TBA1 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA1); - printk("PCHIP0_TBA2 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA2); - printk("PCHIP0_TBA3 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_TBA3); - printk("PCHIP0_PCTL 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PCTL); - printk("PCHIP0_PLAT 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PLAT); - printk("PCHIP0_PERROR 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PERROR); - printk("PCHIP0_PERRMASK 0x%lx\n", *(vulp)TSUNAMI_PCHIP0_PERRMASK); -#endif + printk("dont_care == 0x%lx\n", dont_care); + + return probe_result; +} - for (i = 0; i < NR_CPUS; i++) { - TSUNAMI_mcheck_expected[i] = 0; - TSUNAMI_mcheck_taken[i] = 0; +static long +tsunami_probe_write(volatile unsigned long *vaddr) +{ + long true_contents, probe_result = 1; + + TSUNAMI_cchip->misc.csr |= (1L << 28); /* clear NXM... */ + true_contents = *vaddr; + *vaddr = 0; + draina(); + if (TSUNAMI_cchip->misc.csr & (1L << 28)) { + int source = (TSUNAMI_cchip->misc.csr >> 29) & 7; + TSUNAMI_cchip->misc.csr |= (1L << 28); /* ...and unlock NXS. */ + probe_result = 0; + printk("tsunami_probe_write: unit %d at 0x%016lx\n", source, + (unsigned long)vaddr); } + if (probe_result) + *vaddr = true_contents; + return probe_result; +} +#else +#define tsunami_probe_read(ADDR) 1 +#endif /* NXM_MACHINE_CHECKS_ON_TSUNAMI */ -#ifdef NOT_YET - /* - * Set up error reporting. Make sure CPU_PE is OFF in the mask. - */ - tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERRMASK; - tsunami_err &= ~20; - *(vulp)TSUNAMI_PCHIP0_PERRMASK = tsunami_err; - mb(); - tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERRMASK; +#define FN __FUNCTION__ - tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERROR ; - tsunami_err |= 0x40; /* master/target abort */ - *(vulp)TSUNAMI_PCHIP0_PERROR = tsunami_err ; - mb() ; - tsunami_err = *(vulp)TSUNAMI_PCHIP0_PERROR ; -#endif /* NOT_YET */ +static void __init +tsunami_init_one_pchip(tsunami_pchip *pchip, int index, + unsigned long *mem_start) +{ + struct linux_hose_info *hose; + int i; + + if (tsunami_probe_read(&pchip->pctl.csr) == 0) + return; + + hose = (struct linux_hose_info *)*mem_start; + *mem_start = (unsigned long)(hose + 1); + memset(hose, 0, sizeof(*hose)); + + *hose_tail = hose; + hose_tail = &hose->next; + + hose->pci_io_space = TSUNAMI_IO(index); + hose->pci_mem_space = TSUNAMI_MEM(index); + hose->pci_config_space = TSUNAMI_CONF(index); + hose->pci_sparse_space = 0; + hose->pci_hose_index = index; switch (alpha_use_srm_setup) { default: #if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_SRM_SETUP) - /* Check window 0 for enabled and mapped to 0. */ - if (((*(vulp)TSUNAMI_PCHIP0_WSBA0 & 3) == 1) - && (*(vulp)TSUNAMI_PCHIP0_TBA0 == 0) - && ((*(vulp)TSUNAMI_PCHIP0_WSM0 & 0xfff00000U) > 0x0ff00000U)) { - TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA0 & 0xfff00000U; - TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM0 & 0xfff00000U; - TSUNAMI_DMA_WIN_SIZE += 0x00100000U; -#if 1 - printk("tsunami_init: using Window 0 settings\n"); - printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n", - *(vulp)TSUNAMI_PCHIP0_WSBA0, - *(vulp)TSUNAMI_PCHIP0_WSM0, - *(vulp)TSUNAMI_PCHIP0_TBA0); -#endif - break; - } - - /* Check window 1 for enabled and mapped to 0. */ - if (((*(vulp)TSUNAMI_PCHIP0_WSBA1 & 3) == 1) - && (*(vulp)TSUNAMI_PCHIP0_TBA1 == 0) - && ((*(vulp)TSUNAMI_PCHIP0_WSM1 & 0xfff00000U) > 0x0ff00000U)) { - TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA1 & 0xfff00000U; - TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM1 & 0xfff00000U; - TSUNAMI_DMA_WIN_SIZE += 0x00100000U; + for (i = 0; i < 4; ++i) { + if ((pchip->wsba[i].csr & 3) == 1 + && pchip->tba[i].csr == 0 + && (pchip->wsm[i].csr & 0xfff00000) > 0x0ff00000) { + TSUNAMI_DMA_WIN_BASE = pchip->wsba[i].csr & 0xfff00000; + TSUNAMI_DMA_WIN_SIZE = pchip->wsm[i].csr & 0xfff00000; + TSUNAMI_DMA_WIN_SIZE += 0x00100000; #if 1 - printk("tsunami_init: using Window 1 settings\n"); - printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n", - *(vulp)TSUNAMI_PCHIP0_WSBA1, - *(vulp)TSUNAMI_PCHIP0_WSM1, - *(vulp)TSUNAMI_PCHIP0_TBA1); + printk("%s: using Window %d settings\n", FN, i); + printk("%s: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n", + FN, pchip->wsba[i].csr, pchip->wsm[i].csr, + pchip->tba[i].csr); #endif - break; - } - - /* Check window 2 for enabled and mapped to 0. */ - if (((*(vulp)TSUNAMI_PCHIP0_WSBA2 & 3) == 1) - && (*(vulp)TSUNAMI_PCHIP0_TBA2 == 0) - && ((*(vulp)TSUNAMI_PCHIP0_WSM2 & 0xfff00000U) > 0x0ff00000U)) { - TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA2 & 0xfff00000U; - TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM2 & 0xfff00000U; - TSUNAMI_DMA_WIN_SIZE += 0x00100000U; -#if 1 - printk("tsunami_init: using Window 2 settings\n"); - printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n", - *(vulp)TSUNAMI_PCHIP0_WSBA2, - *(vulp)TSUNAMI_PCHIP0_WSM2, - *(vulp)TSUNAMI_PCHIP0_TBA2); -#endif - break; - } - - /* Check window 3 for enabled and mapped to 0. */ - if (((*(vulp)TSUNAMI_PCHIP0_WSBA3 & 3) == 1) - && (*(vulp)TSUNAMI_PCHIP0_TBA3 == 0) - && ((*(vulp)TSUNAMI_PCHIP0_WSM3 & 0xfff00000U) > 0x0ff00000U)) { - TSUNAMI_DMA_WIN_BASE = *(vulp)TSUNAMI_PCHIP0_WSBA3 & 0xfff00000U; - TSUNAMI_DMA_WIN_SIZE = *(vulp)TSUNAMI_PCHIP0_WSM3 & 0xfff00000U; - TSUNAMI_DMA_WIN_SIZE += 0x00100000U; -#if 1 - printk("tsunami_init: using Window 3 settings\n"); - printk("tsunami_init: BASE 0x%lx MASK 0x%lx TRANS 0x%lx\n", - *(vulp)TSUNAMI_PCHIP0_WSBA3, - *(vulp)TSUNAMI_PCHIP0_WSM3, - *(vulp)TSUNAMI_PCHIP0_TBA3); -#endif - break; + goto found; + } } /* Otherwise, we must use our defaults. */ @@ -345,28 +305,80 @@ * Window 0 goes at 1 GB and is 1 GB large. */ - *(vulp)TSUNAMI_PCHIP0_WSBA0 - = 1L | (TSUNAMI_DMA_WIN_BASE_DEFAULT & 0xfff00000U); - *(vulp)TSUNAMI_PCHIP0_WSM0 - = (TSUNAMI_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000UL; - *(vulp)TSUNAMI_PCHIP0_TBA0 = 0UL; - - *(vulp)TSUNAMI_PCHIP0_WSBA1 = 0UL; - *(vulp)TSUNAMI_PCHIP0_WSBA2 = 0UL; - *(vulp)TSUNAMI_PCHIP0_WSBA3 = 0UL; + pchip->wsba[0].csr = 1L | (TSUNAMI_DMA_WIN_BASE_DEFAULT & 0xfff00000U); + pchip->wsm[0].csr = (TSUNAMI_DMA_WIN_SIZE_DEFAULT - 1) & 0xfff00000UL; + pchip->tba[0].csr = 0; + + pchip->wsba[1].csr = 0; + pchip->wsba[2].csr = 0; + pchip->wsba[3].csr = 0; mb(); } +found:; +} + +void __init +tsunami_init_arch(unsigned long *mem_start, unsigned long *mem_end) +{ +#ifdef NXM_MACHINE_CHECKS_ON_TSUNAMI + extern asmlinkage void entInt(void); + unsigned long tmp; + + /* Ho hum.. init_arch is called before init_IRQ, but we need to be + able to handle machine checks. So install the handler now. */ + wrent(entInt, 0); + + /* NXMs just don't matter to Tsunami--unless they make it + choke completely. */ + tmp = (unsigned long)(TSUNAMI_cchip - 1); + printk("%s: probing bogus address: 0x%016lx\n", FN, bogus_addr); + printk("\tprobe %s\n", + tsunami_probe_write((unsigned long *)bogus_addr) + ? "succeeded" : "failed"); +#endif /* NXM_MACHINE_CHECKS_ON_TSUNAMI */ + +#if 0 + printk("%s: CChip registers:\n", FN); + printk("%s: CSR_CSC 0x%lx\n", FN, TSUNAMI_cchip->csc.csr); + printk("%s: CSR_MTR 0x%lx\n", FN, TSUNAMI_cchip.mtr.csr); + printk("%s: CSR_MISC 0x%lx\n", FN, TSUNAMI_cchip->misc.csr); + printk("%s: CSR_DIM0 0x%lx\n", FN, TSUNAMI_cchip->dim0.csr); + printk("%s: CSR_DIM1 0x%lx\n", FN, TSUNAMI_cchip->dim1.csr); + printk("%s: CSR_DIR0 0x%lx\n", FN, TSUNAMI_cchip->dir0.csr); + printk("%s: CSR_DIR1 0x%lx\n", FN, TSUNAMI_cchip->dir1.csr); + printk("%s: CSR_DRIR 0x%lx\n", FN, TSUNAMI_cchip->drir.csr); + + printk("%s: DChip registers:\n"); + printk("%s: CSR_DSC 0x%lx\n", FN, TSUNAMI_dchip->dsc.csr); + printk("%s: CSR_STR 0x%lx\n", FN, TSUNAMI_dchip->str.csr); + printk("%s: CSR_DREV 0x%lx\n", FN, TSUNAMI_dchip->drev.csr); +#endif + + /* Align memory to cache line; we'll be allocating from it. */ + *mem_start = (*mem_start | 31) + 1; + + /* Find how many hoses we have, and initialize them. */ + tsunami_init_one_pchip(TSUNAMI_pchip0, 0, mem_start); + tsunami_init_one_pchip(TSUNAMI_pchip1, 1, mem_start); +} + +static inline void +tsunami_pci_clr_err_1(tsunami_pchip *pchip, int cpu) +{ + TSUNAMI_jd[cpu] = pchip->perror.csr; + DBG_MCK(("TSUNAMI_pci_clr_err: PERROR after read 0x%x\n", + TSUNAMI_jd[cpu])); + pchip->perror.csr = 0x040; + mb(); + TSUNAMI_jd[cpu] = pchip->perror.csr; } static int tsunami_pci_clr_err(void) { - unsigned int cpu = smp_processor_id(); - - TSUNAMI_jd[cpu] = *((vulp)TSUNAMI_PCHIP0_PERROR); - DBG(("TSUNAMI_pci_clr_err: PERROR after read 0x%x\n",TSUNAMI_jd[cpu])); - *((vulp)TSUNAMI_PCHIP0_PERROR) = 0x040; mb(); - TSUNAMI_jd[cpu] = *((vulp)TSUNAMI_PCHIP0_PERROR); + int cpu = smp_processor_id(); + tsunami_pci_clr_err_1(TSUNAMI_pchip0, cpu); + tsunami_pci_clr_err_1(TSUNAMI_pchip1, cpu); return 0; } @@ -374,13 +386,14 @@ tsunami_machine_check(unsigned long vector, unsigned long la_ptr, struct pt_regs * regs) { -#if 1 +#if 0 printk("TSUNAMI machine check ignored\n") ; #else struct el_common *mchk_header; struct el_TSUNAMI_sysdata_mcheck *mchk_sysdata; unsigned int cpu = smp_processor_id(); + mb(); mchk_header = (struct el_common *)la_ptr; mchk_sysdata = (struct el_TSUNAMI_sysdata_mcheck *) @@ -414,7 +427,7 @@ mb(); mb(); /* magic */ if (TSUNAMI_mcheck_expected[cpu]) { - DBG(("TSUNAMI machine check expected\n")); + DBG_MCK(("TSUNAMI machine check expected\n")); TSUNAMI_mcheck_expected[cpu] = 0; TSUNAMI_mcheck_taken[cpu] = 1; mb(); diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/entry.S linux/arch/alpha/kernel/entry.S --- v2.1.120/linux/arch/alpha/kernel/entry.S Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/entry.S Sun Sep 6 10:34:33 1998 @@ -51,56 +51,7 @@ * JRP - Save regs 16-18 in a special area of the stack, so that * the palcode-provided values are available to the signal handler. */ -#if defined(CONFIG_ALPHA_TSUNAMI) -/* TSUNAMI has no HAE register to save/restore */ -#define SAVE_ALL \ - subq $30,184,$30; \ - stq $0,0($30); \ - stq $1,8($30); \ - stq $2,16($30); \ - stq $3,24($30); \ - stq $4,32($30); \ - stq $5,40($30); \ - stq $6,48($30); \ - stq $7,56($30); \ - stq $8,64($30); \ - stq $19,72($30); \ - stq $20,80($30); \ - stq $21,88($30); \ - stq $22,96($30); \ - stq $23,104($30); \ - stq $24,112($30); \ - stq $25,120($30); \ - stq $26,128($30); \ - stq $27,136($30); \ - stq $28,144($30); \ - stq $16,160($30); \ - stq $17,168($30); \ - stq $18,176($30) -#define RESTORE_ALL \ - ldq $0,0($30); \ - ldq $1,8($30); \ - ldq $2,16($30); \ - ldq $3,24($30); \ - ldq $4,32($30); \ - ldq $5,40($30); \ - ldq $6,48($30); \ - ldq $7,56($30); \ - ldq $8,64($30); \ - ldq $19,72($30); \ - ldq $20,80($30); \ - ldq $21,88($30); \ - ldq $22,96($30); \ - ldq $23,104($30); \ - ldq $24,112($30); \ - ldq $25,120($30); \ - ldq $26,128($30); \ - ldq $27,136($30); \ - ldq $28,144($30); \ - addq $30,184,$30 - -#else /* TSUNAMI */ #define SAVE_ALL \ subq $30,184,$30; \ stq $0,0($30); \ @@ -166,8 +117,6 @@ ldq $28,144($30); \ addq $30,184,$30 -#endif /* TSUNAMI */ - .text .set noat #if defined(__linux__) && !defined(__ELF__) @@ -181,8 +130,8 @@ SAVE_ALL lda $8,0x3fff bic $30,$8,$8 - jsr $26,do_entInt - br $31,ret_from_sys_call + lda $26,ret_from_sys_call + jsr $31,do_entInt .end entInt .align 3 @@ -224,11 +173,8 @@ SAVE_ALL lda $8,0x3fff bic $30,$8,$8 - /* How much of a win is this clockwise? We are, after all, messing - up the call/return prefetch stack. -- rth */ - lda $27,do_entArith lda $26,ret_from_sys_call - jsr $31,($27),do_entArith + jsr $31,do_entArith .end entArith .align 3 @@ -238,9 +184,8 @@ SAVE_ALL lda $8,0x3fff bic $30,$8,$8 - lda $27,do_entIF lda $26,ret_from_sys_call - jsr $31,($27),do_entIF + jsr $31,do_entIF .end entIF /* @@ -373,7 +318,7 @@ stt $f29,296($30) stt $f30,304($30) stt $f0,312($30) # save fpcr in slot of $f31 - ldt $f0,64($30) # don't let "do_switch_stack" change any fp state. + ldt $f0,64($30) # dont let "do_switch_stack" change fp state. ret $31,($1),1 .end do_switch_stack @@ -744,8 +689,8 @@ .ent ret_from_smpfork ret_from_smpfork: .set at + mb /* Make the changed data visible before the freed lock. */ stq $31,scheduler_lock - mb /* ?????????????????? */ br ret_from_sys_call .set noat .end ret_from_smpfork @@ -834,7 +779,7 @@ .quad sys_lseek .quad sys_getxpid /* 20 */ .quad osf_mount - .quad osf_umount + .quad sys_umount .quad sys_setuid .quad sys_getxuid .quad alpha_ni_syscall /* 25 */ diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/irq.c linux/arch/alpha/kernel/irq.c --- v2.1.120/linux/arch/alpha/kernel/irq.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/irq.c Sun Sep 6 10:34:33 1998 @@ -20,6 +20,7 @@ #include #include #include +#include #include #include @@ -35,7 +36,7 @@ unsigned int local_irq_count[NR_CPUS]; unsigned int local_bh_count[NR_CPUS]; - +unsigned long hardirq_no[NR_CPUS]; #define RTC_IRQ 8 #ifdef CONFIG_RTC @@ -100,7 +101,7 @@ #elif defined(CONFIG_ALPHA_PYXIS) # define IACK_SC PYXIS_IACK_SC #elif defined(CONFIG_ALPHA_TSUNAMI) -# define IACK_SC TSUNAMI_PCI0_IACK_SC +# define IACK_SC TSUNAMI_IACK_SC #else /* This is bogus but necessary to get it to compile on all platforms. */ # define IACK_SC 1L @@ -159,13 +160,9 @@ srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq, ack; - unsigned long flags; - __save_and_cli(flags); ack = irq = (vector - 0x800) >> 4; - handle_irq(irq, ack, regs); - __restore_flags(flags); } @@ -338,7 +335,7 @@ #ifdef __SMP__ /* Who has global_irq_lock. */ -unsigned char global_irq_holder = NO_PROC_ID; +int global_irq_holder = NO_PROC_ID; /* This protects IRQ's. */ spinlock_t global_irq_lock = SPIN_LOCK_UNLOCKED; @@ -350,74 +347,66 @@ atomic_t global_bh_lock = ATOMIC_INIT(0); atomic_t global_bh_count = ATOMIC_INIT(0); -static unsigned long previous_irqholder = NO_PROC_ID; +static void *previous_irqholder = NULL; -#undef INIT_STUCK -#define INIT_STUCK 100000000 +#define MAXCOUNT 100000000 -#undef STUCK -#define STUCK \ - if (!--stuck) { \ - printk("wait_on_irq CPU#%d stuck at %08lx, " \ - "waiting for %08lx (local=%d, global=%d)\n", \ - cpu, where, previous_irqholder, local_count, \ - atomic_read(&global_irq_count)); \ - stuck = INIT_STUCK; \ - } +static void show(char * str, void *where); static inline void -wait_on_irq(int cpu, unsigned long where) +wait_on_irq(int cpu, void *where) { - int stuck = INIT_STUCK; - int local_count = local_irq_count[cpu]; + int count = MAXCOUNT; + + for (;;) { - /* Are we the only one in an interrupt context? */ - while (local_count != atomic_read(&global_irq_count)) { /* - * No such luck. Now we need to release the lock, - * _and_ release our interrupt context, because - * otherwise we'd have dead-locks and live-locks - * and other fun things. + * Wait until all interrupts are gone. Wait + * for bottom half handlers unless we're + * already executing in one.. */ - atomic_sub(local_count, &global_irq_count); + if (!atomic_read(&global_irq_count)) { + if (local_bh_count[cpu] || + !atomic_read(&global_bh_count)) + break; + } + + /* Duh, we have to loop. Release the lock to avoid deadlocks */ spin_unlock(&global_irq_lock); + mb(); - /* - * Wait for everybody else to go away and release - * their things before trying to get the lock again. - */ for (;;) { - STUCK; + if (!--count) { + show("wait_on_irq", where); + count = MAXCOUNT; + } + __sti(); +#if 0 + SYNC_OTHER_CORES(cpu); +#else + udelay(cpu+1); +#endif + __cli(); + if (atomic_read(&global_irq_count)) continue; if (global_irq_lock.lock) continue; + if (!local_bh_count[cpu] && + atomic_read(&global_bh_count)) + continue; if (spin_trylock(&global_irq_lock)) break; } - atomic_add(local_count, &global_irq_count); } } -#undef INIT_STUCK -#define INIT_STUCK 10000000 - -#undef STUCK -#define STUCK \ - if (!--stuck) { \ - printk("get_irqlock stuck at %08lx, waiting for %08lx\n", \ - where, previous_irqholder); \ - stuck = INIT_STUCK; \ - } - static inline void -get_irqlock(int cpu, unsigned long where) +get_irqlock(int cpu, void* where) { - int stuck = INIT_STUCK; - if (!spin_trylock(&global_irq_lock)) { /* do we already hold the lock? */ - if ((unsigned char) cpu == global_irq_holder) { + if (cpu == global_irq_holder) { #if 0 printk("get_irqlock: already held at %08lx\n", previous_irqholder); @@ -425,12 +414,7 @@ return; } /* Uhhuh.. Somebody else got it. Wait.. */ - do { - do { - STUCK; - barrier(); - } while (global_irq_lock.lock); - } while (!spin_trylock(&global_irq_lock)); + spin_lock(&global_irq_lock); } /* * Ok, we got the lock bit. @@ -443,6 +427,8 @@ /* * Finally. */ + global_irq_lock.task = current; + global_irq_lock.previous = where; global_irq_holder = cpu; previous_irqholder = where; } @@ -450,14 +436,15 @@ void __global_cli(void) { - int cpu = smp_processor_id(); - unsigned long where; + int cpu; + void *where = __builtin_return_address(0); - __asm__("mov $26, %0" : "=r" (where)); - __cli(); - - if (!local_irq_count[cpu]) - get_irqlock(smp_processor_id(), where); + /* + * Maximize ipl. If ipl was previously 0 and if this thread + * is not in an irq, then take global_irq_lock. + */ + if ((swpipl(7) == 0) && !local_irq_count[cpu = smp_processor_id()]) + get_irqlock(cpu, where); } void @@ -465,38 +452,66 @@ { int cpu = smp_processor_id(); - if (!local_irq_count[cpu]) - release_irqlock(smp_processor_id()); - + if (!local_irq_count[cpu]) { + release_irqlock(cpu); + } __sti(); } -#if 0 +/* + * SMP flags value to restore to: + * 0 - global cli + * 1 - global sti + * 2 - local cli + * 3 - local sti + */ unsigned long __global_save_flags(void) { - return global_irq_holder == (unsigned char) smp_processor_id(); + int retval; + int local_enabled; + unsigned long flags; + int cpu = smp_processor_id(); + + __save_flags(flags); + local_enabled = (!(flags & 7)); + /* default to local */ + retval = 2 + local_enabled; + + /* Check for global flags if we're not in an interrupt. */ + if (!local_irq_count[cpu]) { + if (local_enabled) + retval = 1; + if (global_irq_holder == cpu) + retval = 0; + } + return retval; } -#endif void __global_restore_flags(unsigned long flags) { - if (flags & 1) { - __global_cli(); - } else { - /* release_irqlock() */ - if (global_irq_holder == smp_processor_id()) { - global_irq_holder = NO_PROC_ID; - spin_unlock(&global_irq_lock); - } - if (!(flags & 2)) - __sti(); - } + switch (flags) { + case 0: + __global_cli(); + break; + case 1: + __global_sti(); + break; + case 2: + __cli(); + break; + case 3: + __sti(); + break; + default: + printk("global_restore_flags: %08lx (%p)\n", + flags, __builtin_return_address(0)); + } } #undef INIT_STUCK -#define INIT_STUCK 200000000 +#define INIT_STUCK (1<<26) #undef STUCK #define STUCK \ @@ -516,10 +531,10 @@ #endif int stuck = INIT_STUCK; - hardirq_enter(cpu); + hardirq_enter(cpu, irq); barrier(); while (global_irq_lock.lock) { - if ((unsigned char) cpu == global_irq_holder) { + if (cpu == global_irq_holder) { int globl_locked = global_irq_lock.lock; int globl_icount = atomic_read(&global_irq_count); int local_count = local_irq_count[cpu]; @@ -529,11 +544,7 @@ printk() as printk() could end up changing them... */ -#if 0 - printk("CPU[%d]: BAD! Local IRQ's enabled," - " global disabled interrupt\n", cpu); -#endif - printk("CPU[%d]: where [%08lx] glocked[%d] gicnt[%d]" + printk("CPU[%d]: where [%p] glocked[%d] gicnt[%d]" " licnt[%d]\n", cpu, previous_irqholder, globl_locked, globl_icount, local_count); @@ -552,12 +563,12 @@ void irq_exit(int cpu, int irq) { - hardirq_exit(cpu); + hardirq_exit(cpu, irq); release_irqlock(cpu); } static void -show(char * str) +show(char * str, void *where) { #if 0 int i; @@ -565,10 +576,16 @@ #endif int cpu = smp_processor_id(); - printk("\n%s, CPU %d:\n", str, cpu); - printk("irq: %d [%d %d]\n", - atomic_read(&global_irq_count), local_irq_count[0], - local_irq_count[1]); + int global_count = atomic_read(&global_irq_count); + int local_count0 = local_irq_count[0]; + int local_count1 = local_irq_count[1]; + long hardirq_no0 = hardirq_no[0]; + long hardirq_no1 = hardirq_no[1]; + + printk("\n%s, CPU %d: %p\n", str, cpu, where); + printk("irq: %d [%d(0x%016lx) %d(0x%016lx)]\n", global_count, + local_count0, hardirq_no0, local_count1, hardirq_no1); + printk("bh: %d [%d %d]\n", atomic_read(&global_bh_count), local_bh_count[0], local_bh_count[1]); @@ -584,15 +601,13 @@ #endif } -#define MAXCOUNT 100000000 - static inline void wait_on_bh(void) { int count = MAXCOUNT; do { if (!--count) { - show("wait_on_bh"); + show("wait_on_bh", 0); count = ~0; } /* nothing .. wait for the other bh's to go away */ @@ -618,20 +633,36 @@ } } -/* There has to be a better way. */ +/* + * From its use, I infer that synchronize_irq() stalls a thread until + * the effects of a command to an external device are known to have + * taken hold. Typically, the command is to stop sending interrupts. + * The strategy here is wait until there is at most one processor + * (this one) in an irq. The memory barrier serializes the write to + * the device and the subsequent accesses of global_irq_count. + * --jmartin + */ +#define DEBUG_SYNCHRONIZE_IRQ 0 + void synchronize_irq(void) { int cpu = smp_processor_id(); - int local_count = local_irq_count[cpu]; - - if (local_count != atomic_read(&global_irq_count)) { - unsigned long flags; - - /* An infamously unpopular approach. */ - save_and_cli(flags); - restore_flags(flags); - } + int local_count; + int global_count; + int countdown = 1<<24; + void *where = __builtin_return_address(0); + + mb(); + do { + local_count = local_irq_count[cpu]; + global_count = atomic_read(&global_irq_count); + if (DEBUG_SYNCHRONIZE_IRQ && (--countdown == 0)) { + printk("%d:%d/%d\n", cpu, local_count, global_count); + show("synchronize_irq", where); + break; + } + } while (global_count != local_count); } #else /* !__SMP__ */ @@ -687,6 +718,26 @@ return; } +#if 0 + /* A useful bit of code to find out if an interrupt is going wild. */ + { + static unsigned int last_msg, last_cc; + static int last_irq, count; + unsigned int cc; + + __asm __volatile("rpcc %0" : "=r"(cc)); + ++count; + if (cc - last_msg > 150000000 || irq != last_irq) { + printk("handle_irq: irq %d count %d cc %u @ %p\n", + irq, count, cc-last_cc, regs->pc); + count = 0; + last_msg = cc; + last_irq = irq; + } + last_cc = cc; + } +#endif + irq_enter(cpu, irq); kstat.irqs[cpu][irq] += 1; action = irq_action[irq]; @@ -784,23 +835,31 @@ unsigned long a3, unsigned long a4, unsigned long a5, struct pt_regs regs) { + unsigned long flags; + switch (type) { case 0: #ifdef __SMP__ + __save_and_cli(flags); handle_ipi(®s); + __restore_flags(flags); return; #else printk("Interprocessor interrupt? You must be kidding\n"); #endif break; case 1: + __save_and_cli(flags); handle_irq(RTC_IRQ, -1, ®s); + __restore_flags(flags); return; case 2: alpha_mv.machine_check(vector, la_ptr, ®s); return; case 3: + __save_and_cli(flags); alpha_mv.device_interrupt(vector, ®s); + __restore_flags(flags); return; case 4: printk("Performance counter interrupt\n"); diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/irq.h linux/arch/alpha/kernel/irq.h --- v2.1.120/linux/arch/alpha/kernel/irq.h Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/irq.h Sun Sep 6 10:34:33 1998 @@ -8,15 +8,15 @@ * with the IRQ handling routines in irq.c. */ - -/* FIXME FIXME FIXME FIXME FIXME */ -/* We need to figure out why these fail on the DP264 & SX164. Otherwise - we'd just do this in init_IRQ(). */ #define STANDARD_INIT_IRQ_PROLOG \ outb(0, DMA1_RESET_REG); \ outb(0, DMA2_RESET_REG); \ + outb(0, DMA1_MASK_REG); \ + outb(0, DMA2_MASK_REG); \ outb(0, DMA1_CLR_MASK_REG); \ - outb(0, DMA2_CLR_MASK_REG) + outb(0, DMA2_CLR_MASK_REG); \ + outb(DMA_MODE_CASCADE, DMA2_MODE_REG) + extern unsigned long alpha_irq_mask; diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/machvec.h linux/arch/alpha/kernel/machvec.h --- v2.1.120/linux/arch/alpha/kernel/machvec.h Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/machvec.h Sun Sep 6 10:34:33 1998 @@ -28,7 +28,7 @@ #define CAT(x,y) CAT1(x,y) #define DO_DEFAULT_RTC \ - rtc_port: 0x70, rtc_addr: 0x80 + rtc_port: 0x70, rtc_addr: 0x80, rtc_bcd: 0 #define DO_EV4_MMU \ max_asn: EV4_MAX_ASN, \ @@ -47,7 +47,7 @@ mv_flush_tlb_current_page: ev5_flush_tlb_current_page #define DO_EV6_MMU \ - max_asn: EV5_MAX_ASN, \ + max_asn: EV6_MAX_ASN, \ mmu_context_mask: 0xfffffffffful, \ mv_get_mmu_context: ev5_get_mmu_context, \ mv_flush_tlb_current: ev5_flush_tlb_current, \ @@ -75,12 +75,12 @@ #define IO(UP,low1,low2) \ IO_LITE(UP,low1,low2), \ - pci_read_config_byte: CAT(low2,_pcibios_read_config_byte), \ - pci_read_config_word: CAT(low2,_pcibios_read_config_word), \ - pci_read_config_dword: CAT(low2,_pcibios_read_config_dword), \ - pci_write_config_byte: CAT(low2,_pcibios_write_config_byte), \ - pci_write_config_word: CAT(low2,_pcibios_write_config_word), \ - pci_write_config_dword: CAT(low2,_pcibios_write_config_dword), \ + hose_read_config_byte: CAT(low2,_hose_read_config_byte), \ + hose_read_config_word: CAT(low2,_hose_read_config_word), \ + hose_read_config_dword: CAT(low2,_hose_read_config_dword), \ + hose_write_config_byte: CAT(low2,_hose_write_config_byte), \ + hose_write_config_word: CAT(low2,_hose_write_config_word), \ + hose_write_config_dword: CAT(low2,_hose_write_config_dword), \ dma_win_base: CAT(UP,_DMA_WIN_BASE_DEFAULT), \ dma_win_size: CAT(UP,_DMA_WIN_SIZE_DEFAULT) diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/osf_sys.c linux/arch/alpha/kernel/osf_sys.c --- v2.1.120/linux/arch/alpha/kernel/osf_sys.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/osf_sys.c Sun Sep 6 10:34:33 1998 @@ -47,7 +47,6 @@ extern kdev_t get_unnamed_dev(void); extern void put_unnamed_dev(kdev_t); -extern asmlinkage int sys_umount(char *, int); extern asmlinkage int sys_swapon(const char *specialfile, int swap_flags); extern asmlinkage unsigned long sys_brk(unsigned long); @@ -535,16 +534,6 @@ } unlock_kernel(); return retval; -} - -asmlinkage int osf_umount(char *path, int flag) -{ - int ret; - - lock_kernel(); - ret = sys_umount(path,flag); - unlock_kernel(); - return ret; } asmlinkage int osf_utsname(char *name) diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/process.c linux/arch/alpha/kernel/process.c --- v2.1.120/linux/arch/alpha/kernel/process.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/process.c Sun Sep 6 10:34:33 1998 @@ -75,58 +75,34 @@ return 0; } -#ifdef __SMP__ -/* This is being executed in task 0 'user space'. */ -#define resched_needed() 1 -int -cpu_idle(void *unused) +static void __attribute__((noreturn)) +do_cpu_idle(void) { - extern volatile int smp_commenced; - - current->priority = -100; + /* An endless idle loop with no priority at all. */ + current->priority = 0; while (1) { + check_pgt_cache(); run_task_queue(&tq_scheduler); - /* endless idle loop with no priority at all */ - current->counter = -100; - if (!smp_commenced || resched_needed()) { - schedule(); - } + current->counter = 0; + schedule(); } } -asmlinkage int -sys_idle(void) +#ifdef __SMP__ +void +cpu_idle(void *unused) { - if(current->pid != 0) - return -EPERM; - - cpu_idle(NULL); - return 0; + do_cpu_idle(); } - -#else /* __SMP__ */ +#endif asmlinkage int sys_idle(void) { - int ret = -EPERM; - - lock_kernel(); - if (current->pid != 0) - goto out; - - /* endless idle loop with no priority at all */ - current->counter = -100; - for (;;) { - check_pgt_cache(); - schedule(); - } - ret = 0; -out: - unlock_kernel(); - return ret; + if (current->pid == 0) + do_cpu_idle(); + return -EPERM; } -#endif /* __SMP__ */ void generic_kill_arch (int mode, char *restart_cmd) @@ -154,7 +130,7 @@ cpup->ipc_buffer[0] = 0; } else { flags |= 0x00030000UL; /* "warm bootstrap" */ - strncpy(cpup->ipc_buffer, restart_cmd, + strncpy((char *)cpup->ipc_buffer, restart_cmd, sizeof(cpup->ipc_buffer)); } } diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/proto.h linux/arch/alpha/kernel/proto.h --- v2.1.120/linux/arch/alpha/kernel/proto.h Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/proto.h Sun Sep 6 10:34:33 1998 @@ -6,13 +6,21 @@ #define vuip volatile unsigned int * #define vulp volatile unsigned long * +struct linux_hose_info; + /* core_apecs.c */ -extern int apecs_pcibios_read_config_byte (u8, u8, u8, u8 *value); -extern int apecs_pcibios_read_config_word (u8, u8, u8, u16 *value); -extern int apecs_pcibios_read_config_dword (u8, u8, u8, u32 *value); -extern int apecs_pcibios_write_config_byte (u8, u8, u8, u8 value); -extern int apecs_pcibios_write_config_word (u8, u8, u8, u16 value); -extern int apecs_pcibios_write_config_dword (u8, u8, u8, u32 value); +extern int apecs_hose_read_config_byte (u8, u8, u8, u8 *value, + struct linux_hose_info *hose); +extern int apecs_hose_read_config_word (u8, u8, u8, u16 *value, + struct linux_hose_info *hose); +extern int apecs_hose_read_config_dword (u8, u8, u8, u32 *value, + struct linux_hose_info *hose); +extern int apecs_hose_write_config_byte (u8, u8, u8, u8 value, + struct linux_hose_info *hose); +extern int apecs_hose_write_config_word (u8, u8, u8, u16 value, + struct linux_hose_info *hose); +extern int apecs_hose_write_config_dword (u8, u8, u8, u32 value, + struct linux_hose_info *hose); extern void apecs_init_arch(unsigned long *, unsigned long *); extern volatile unsigned int apecs_mcheck_expected; @@ -21,43 +29,66 @@ extern void apecs_machine_check(u64, u64, struct pt_regs *); /* core_cia.c */ -extern int cia_pcibios_read_config_byte (u8, u8, u8, u8 *value); -extern int cia_pcibios_read_config_word (u8, u8, u8, u16 *value); -extern int cia_pcibios_read_config_dword (u8, u8, u8, u32 *value); -extern int cia_pcibios_write_config_byte (u8, u8, u8, u8 value); -extern int cia_pcibios_write_config_word (u8, u8, u8, u16 value); -extern int cia_pcibios_write_config_dword (u8, u8, u8, u32 value); +extern int cia_hose_read_config_byte (u8, u8, u8, u8 *value, + struct linux_hose_info *hose); +extern int cia_hose_read_config_word (u8, u8, u8, u16 *value, + struct linux_hose_info *hose); +extern int cia_hose_read_config_dword (u8, u8, u8, u32 *value, + struct linux_hose_info *hose); +extern int cia_hose_write_config_byte (u8, u8, u8, u8 value, + struct linux_hose_info *hose); +extern int cia_hose_write_config_word (u8, u8, u8, u16 value, + struct linux_hose_info *hose); +extern int cia_hose_write_config_dword (u8, u8, u8, u32 value, + struct linux_hose_info *hose); extern void cia_init_arch(unsigned long *, unsigned long *); extern void cia_machine_check(u64, u64, struct pt_regs *); /* core_lca.c */ -extern int lca_pcibios_read_config_byte (u8, u8, u8, u8 *value); -extern int lca_pcibios_read_config_word (u8, u8, u8, u16 *value); -extern int lca_pcibios_read_config_dword (u8, u8, u8, u32 *value); -extern int lca_pcibios_write_config_byte (u8, u8, u8, u8 value); -extern int lca_pcibios_write_config_word (u8, u8, u8, u16 value); -extern int lca_pcibios_write_config_dword (u8, u8, u8, u32 value); +extern int lca_hose_read_config_byte (u8, u8, u8, u8 *value, + struct linux_hose_info *hose); +extern int lca_hose_read_config_word (u8, u8, u8, u16 *value, + struct linux_hose_info *hose); +extern int lca_hose_read_config_dword (u8, u8, u8, u32 *value, + struct linux_hose_info *hose); +extern int lca_hose_write_config_byte (u8, u8, u8, u8 value, + struct linux_hose_info *hose); +extern int lca_hose_write_config_word (u8, u8, u8, u16 value, + struct linux_hose_info *hose); +extern int lca_hose_write_config_dword (u8, u8, u8, u32 value, + struct linux_hose_info *hose); extern void lca_init_arch(unsigned long *, unsigned long *); extern void lca_machine_check(u64, u64, struct pt_regs *); /* core_mcpcia.c */ -extern int mcpcia_pcibios_read_config_byte (u8, u8, u8, u8 *value); -extern int mcpcia_pcibios_read_config_word (u8, u8, u8, u16 *value); -extern int mcpcia_pcibios_read_config_dword (u8, u8, u8, u32 *value); -extern int mcpcia_pcibios_write_config_byte (u8, u8, u8, u8 value); -extern int mcpcia_pcibios_write_config_word (u8, u8, u8, u16 value); -extern int mcpcia_pcibios_write_config_dword (u8, u8, u8, u32 value); +extern int mcpcia_hose_read_config_byte (u8, u8, u8, u8 *value, + struct linux_hose_info *hose); +extern int mcpcia_hose_read_config_word (u8, u8, u8, u16 *value, + struct linux_hose_info *hose); +extern int mcpcia_hose_read_config_dword (u8, u8, u8, u32 *value, + struct linux_hose_info *hose); +extern int mcpcia_hose_write_config_byte (u8, u8, u8, u8 value, + struct linux_hose_info *hose); +extern int mcpcia_hose_write_config_word (u8, u8, u8, u16 value, + struct linux_hose_info *hose); +extern int mcpcia_hose_write_config_dword (u8, u8, u8, u32 value, + struct linux_hose_info *hose); extern void mcpcia_init_arch(unsigned long *, unsigned long *); extern void mcpcia_machine_check(u64, u64, struct pt_regs *); -extern void mcpcia_pci_fixup(void); /* core_pyxis.c */ -extern int pyxis_pcibios_read_config_byte (u8, u8, u8, u8 *value); -extern int pyxis_pcibios_read_config_word (u8, u8, u8, u16 *value); -extern int pyxis_pcibios_read_config_dword (u8, u8, u8, u32 *value); -extern int pyxis_pcibios_write_config_byte (u8, u8, u8, u8 value); -extern int pyxis_pcibios_write_config_word (u8, u8, u8, u16 value); -extern int pyxis_pcibios_write_config_dword (u8, u8, u8, u32 value); +extern int pyxis_hose_read_config_byte (u8, u8, u8, u8 *value, + struct linux_hose_info *hose); +extern int pyxis_hose_read_config_word (u8, u8, u8, u16 *value, + struct linux_hose_info *hose); +extern int pyxis_hose_read_config_dword (u8, u8, u8, u32 *value, + struct linux_hose_info *hose); +extern int pyxis_hose_write_config_byte (u8, u8, u8, u8 value, + struct linux_hose_info *hose); +extern int pyxis_hose_write_config_word (u8, u8, u8, u16 value, + struct linux_hose_info *hose); +extern int pyxis_hose_write_config_dword (u8, u8, u8, u32 value, + struct linux_hose_info *hose); extern void pyxis_enable_errors (void); extern int pyxis_srm_window_setup (void); extern void pyxis_native_window_setup(void); @@ -66,22 +97,34 @@ extern void pyxis_machine_check(u64, u64, struct pt_regs *); /* core_t2.c */ -extern int t2_pcibios_read_config_byte (u8, u8, u8, u8 *value); -extern int t2_pcibios_read_config_word (u8, u8, u8, u16 *value); -extern int t2_pcibios_read_config_dword (u8, u8, u8, u32 *value); -extern int t2_pcibios_write_config_byte (u8, u8, u8, u8 value); -extern int t2_pcibios_write_config_word (u8, u8, u8, u16 value); -extern int t2_pcibios_write_config_dword (u8, u8, u8, u32 value); +extern int t2_hose_read_config_byte (u8, u8, u8, u8 *value, + struct linux_hose_info *hose); +extern int t2_hose_read_config_word (u8, u8, u8, u16 *value, + struct linux_hose_info *hose); +extern int t2_hose_read_config_dword (u8, u8, u8, u32 *value, + struct linux_hose_info *hose); +extern int t2_hose_write_config_byte (u8, u8, u8, u8 value, + struct linux_hose_info *hose); +extern int t2_hose_write_config_word (u8, u8, u8, u16 value, + struct linux_hose_info *hose); +extern int t2_hose_write_config_dword (u8, u8, u8, u32 value, + struct linux_hose_info *hose); extern void t2_init_arch(unsigned long *, unsigned long *); extern void t2_machine_check(u64, u64, struct pt_regs *); /* core_tsunami.c */ -extern int tsunami_pcibios_read_config_byte (u8, u8, u8, u8 *value); -extern int tsunami_pcibios_read_config_word (u8, u8, u8, u16 *value); -extern int tsunami_pcibios_read_config_dword (u8, u8, u8, u32 *value); -extern int tsunami_pcibios_write_config_byte (u8, u8, u8, u8 value); -extern int tsunami_pcibios_write_config_word (u8, u8, u8, u16 value); -extern int tsunami_pcibios_write_config_dword (u8, u8, u8, u32 value); +extern int tsunami_hose_read_config_byte (u8, u8, u8, u8 *value, + struct linux_hose_info *hose); +extern int tsunami_hose_read_config_word (u8, u8, u8, u16 *value, + struct linux_hose_info *hose); +extern int tsunami_hose_read_config_dword (u8, u8, u8, u32 *value, + struct linux_hose_info *hose); +extern int tsunami_hose_write_config_byte (u8, u8, u8, u8 value, + struct linux_hose_info *hose); +extern int tsunami_hose_write_config_word (u8, u8, u8, u16 value, + struct linux_hose_info *hose); +extern int tsunami_hose_write_config_dword (u8, u8, u8, u32 value, + struct linux_hose_info *hose); extern void tsunami_init_arch(unsigned long *, unsigned long *); extern void tsunami_machine_check(u64, u64, struct pt_regs *); @@ -92,14 +135,14 @@ /* smp.c */ extern void setup_smp(void); -extern char *smp_info(void); +extern int smp_info(char *buffer); extern void handle_ipi(struct pt_regs *); /* bios32.c */ extern void reset_for_srm(void); /* time.c */ -extern void timer_interrupt(struct pt_regs * regs); +extern void timer_interrupt(int irq, void *dev, struct pt_regs * regs); /* smc37c93x.c */ extern void SMC93x_Init(void); @@ -118,6 +161,7 @@ extern void wrmces(unsigned long mces); extern void cserve_ena(unsigned long); extern void cserve_dis(unsigned long); +extern void __start_cpu(unsigned long); /* entry.S */ extern void entArith(void); @@ -129,3 +173,4 @@ /* process.c */ void generic_kill_arch (int mode, char *reboot_cmd); +void cpu_idle(void *) __attribute__((noreturn)); diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/setup.c linux/arch/alpha/kernel/setup.c --- v2.1.120/linux/arch/alpha/kernel/setup.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/setup.c Sun Sep 6 10:36:35 1998 @@ -20,7 +20,6 @@ #include #include #include /* CONFIG_ALPHA_LCA etc */ -#include #include #include #include @@ -30,6 +29,9 @@ #ifdef CONFIG_RTC #include #endif +#ifdef CONFIG_BLK_DEV_INITRD +#include +#endif #include #include @@ -73,11 +75,12 @@ #define PARAM ZERO_PAGE #define COMMAND_LINE ((char*)(PARAM + 0x0000)) #define COMMAND_LINE_SIZE 256 +#define INITRD_START (*(unsigned long *) (PARAM+0x100)) +#define INITRD_SIZE (*(unsigned long *) (PARAM+0x108)) static char command_line[COMMAND_LINE_SIZE]; char saved_command_line[COMMAND_LINE_SIZE]; - /* * The format of "screen_info" is strange, and due to early * i386-setup code. This is just enough to make the console @@ -93,68 +96,6 @@ orig_video_points: 16 }; - -/* - * Initialize Programmable Interval Timers with standard values. Some - * drivers depend on them being initialized (e.g., joystick driver). - */ - -/* It is (normally) only counter 1 that presents config problems, so - provide this support function to do the rest of the job. */ - -void inline -init_pit_rest(void) -{ -#if 0 - /* Leave refresh timer alone---nobody should depend on a - particular value anyway. */ - outb(0x54, 0x43); /* counter 1: refresh timer */ - outb(0x18, 0x41); -#endif - - outb(0xb6, 0x43); /* counter 2: speaker */ - outb(0x31, 0x42); - outb(0x13, 0x42); - - if ((CMOS_READ(RTC_FREQ_SELECT) & 0x3f) != 0x26) { - printk("Setting RTC_FREQ to 1024 Hz\n"); - CMOS_WRITE(0x26, RTC_FREQ_SELECT); - } -} - -#ifdef CONFIG_RTC -static inline void -rtc_init_pit (void) -{ - /* Setup interval timer if /dev/rtc is being used */ - outb(0x34, 0x43); /* binary, mode 2, LSB/MSB, ch 0 */ - outb(LATCH & 0xff, 0x40); /* LSB */ - outb(LATCH >> 8, 0x40); /* MSB */ - request_region(0x40, 0x20, "timer"); /* reserve pit */ - - init_pit_rest(); -} -#endif - -void -generic_init_pit (void) -{ - outb(0x36, 0x43); /* counter 0: system timer */ - outb(0x00, 0x40); - outb(0x00, 0x40); - request_region(RTC_PORT(0), 0x10, "timer"); /* reserve rtc */ - - init_pit_rest(); -} - -/* This probably isn't Right, but it is what the old code did. */ -#if defined(CONFIG_RTC) -# define init_pit rtc_init_pit -#else -# define init_pit alpha_mv.init_pit -#endif - - /* * Declare all of the machine vectors. */ @@ -278,6 +219,11 @@ } #endif + printk("Booting on %s%s%s using machine vector %s\n", + type_name, (*var_name ? " variation " : ""), + var_name, alpha_mv.vector_name); + printk("Command line: %s\n", command_line); + /* * Sync with the HAE */ @@ -293,17 +239,27 @@ *memory_end_p = find_end_memory(); *memory_start_p = (unsigned long) _end; +#ifdef CONFIG_BLK_DEV_INITRD + initrd_start = INITRD_START; + if (initrd_start) { + initrd_end = initrd_start+INITRD_SIZE; + printk("Initial ramdisk at: 0x%p (%lu bytes)\n", + (void *) initrd_start, INITRD_SIZE); + + if (initrd_end > *memory_end_p) { + printk("initrd extends beyond end of memory " + "(0x%08lx > 0x%08lx)\ndisabling initrd\n", + initrd_end, memory_end_p); + initrd_start = initrd_end = 0; + } + } +#endif + /* Initialize the machine. Usually has to do with setting up DMA windows and the like. */ if (alpha_mv.init_arch) alpha_mv.init_arch(memory_start_p, memory_end_p); - /* Initialize the timers. */ - init_pit(); - - /* Default root filesystem to sda2. */ - ROOT_DEV = to_kdev_t(0x0802); - /* * Give us a default console. TGA users will see nothing until * chr_dev_init is called, rather late in the boot sequence. @@ -317,11 +273,8 @@ #endif #endif - /* Delayed so that we've initialized the machine first. */ - printk("Booting on %s%s%s using machine vector %s\n", - type_name, (*var_name ? " variation " : ""), - var_name, alpha_mv.vector_name); - printk("Command line: %s\n", command_line); + /* Default root filesystem to sda2. */ + ROOT_DEV = to_kdev_t(0x0802); /* * Check ASN in HWRPB for validity, report if bad. diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/smc37c93x.c linux/arch/alpha/kernel/smc37c93x.c --- v2.1.120/linux/arch/alpha/kernel/smc37c93x.c Mon Apr 6 17:40:59 1998 +++ linux/arch/alpha/kernel/smc37c93x.c Sun Sep 6 10:34:33 1998 @@ -13,7 +13,9 @@ #include #include -#if 0 +#define SMC_DEBUG 0 + +#if SMC_DEBUG # define DBG_DEVS(args) printk args #else # define DBG_DEVS(args) @@ -75,8 +77,6 @@ #define PARP_BASE 0x3bc #define PARP_INTERRUPT 7 -#define SMC_DEBUG 0 - static unsigned long __init SMCConfigState(unsigned long baseAddr) { unsigned char devId; @@ -241,12 +241,17 @@ SMCReportDeviceStatus(SMCUltraBase); #endif SMCEnableDevice(SMCUltraBase, SER1, COM1_BASE, COM1_INTERRUPT); + DBG_DEVS(("SMC FDC37C93X: SER1 done\n")); SMCEnableDevice(SMCUltraBase, SER2, COM2_BASE, COM2_INTERRUPT); + DBG_DEVS(("SMC FDC37C93X: SER2 done\n")); SMCEnableDevice(SMCUltraBase, PARP, PARP_BASE, PARP_INTERRUPT); + DBG_DEVS(("SMC FDC37C93X: PARP done\n")); /* On PC164, IDE on the SMC is not enabled; CMD646 (PCI) on MB */ SMCEnableKYBD(SMCUltraBase); + DBG_DEVS(("SMC FDC37C93X: KYB done\n")); SMCEnableFDC(SMCUltraBase); + DBG_DEVS(("SMC FDC37C93X: FDC done\n")); #if SMC_DEBUG SMCReportDeviceStatus(SMCUltraBase); #endif @@ -254,9 +259,7 @@ return 1; } else { -#if SMC_DEBUG - printk("No SMC FDC37C93X Ultra I/O Controller found\n"); -#endif + DBG_DEVS(("No SMC FDC37C93X Ultra I/O Controller found\n")); return 0; } } diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/smp.c linux/arch/alpha/kernel/smp.c --- v2.1.120/linux/arch/alpha/kernel/smp.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/smp.c Sun Sep 6 10:34:33 1998 @@ -1,3 +1,7 @@ +/* + * linux/arch/alpha/kernel/smp.c + */ + #include #include #include @@ -30,10 +34,8 @@ struct cpuinfo_alpha cpu_data[NR_CPUS]; -/* Processor holding kernel spinlock */ -klock_info_t klock_info = { KLOCK_CLEAR, 0 }; - spinlock_t ticker_lock = SPIN_LOCK_UNLOCKED; +spinlock_t kernel_flag = SPIN_LOCK_UNLOCKED; unsigned int boot_cpu_id = 0; static int smp_activated = 0; @@ -63,11 +65,8 @@ volatile int cpu_number_map[NR_CPUS]; volatile int cpu_logical_map[NR_CPUS]; -extern int cpu_idle(void *unused); extern void calibrate_delay(void); -extern struct hwrpb_struct *hwrpb; extern struct thread_struct * original_pcb_ptr; -extern void __start_cpu(unsigned long); static void smp_setup_percpu_timer(void); static void secondary_cpu_start(int, struct task_struct *); @@ -170,7 +169,7 @@ printk("start_secondary: commencing CPU %d current %p\n", hard_smp_processor_id(), current); #endif - return cpu_idle(NULL); + cpu_idle(NULL); } /* @@ -198,7 +197,6 @@ cpu_number_map[boot_cpu_id] = 0; cpu_logical_map[0] = boot_cpu_id; current->processor = boot_cpu_id; /* ??? */ - klock_info.akp = boot_cpu_id; smp_store_cpu_info(boot_cpu_id); #ifdef NOT_YET @@ -739,9 +737,8 @@ int smp_info(char *buffer) { - return sprintf(buffer, "CPUs probed %d active %d map 0x%x AKP %d\n", - smp_num_probed, smp_num_cpus, cpu_present_map, - klock_info.akp); + return sprintf(buffer, "CPUs probed %d active %d map 0x%x\n", + smp_num_probed, smp_num_cpus, cpu_present_map); } /* wrapper for call from panic() */ @@ -766,12 +763,6 @@ unsigned int to_whom = cpu_present_map ^ (1 << smp_processor_id()); int timeout = 10000; -#if 1 - if (!kernel_lock_held()) { - printk("flush_tlb_all: kernel_flag %d (cpu %d akp %d)!\n", - klock_info.kernel_flag, smp_processor_id(), klock_info.akp); - } -#endif ipi_msg_flush_tb.flush_tb_mask = to_whom; send_ipi_message(to_whom, TLB_ALL); tbia(); @@ -794,12 +785,6 @@ unsigned int to_whom = cpu_present_map ^ (1 << smp_processor_id()); int timeout = 10000; -#if 1 - if (!kernel_lock_held()) { - printk("flush_tlb_mm: kernel_flag %d (cpu %d akp %d)!\n", - klock_info.kernel_flag, smp_processor_id(), klock_info.akp); - } -#endif ipi_msg_flush_tb.p.flush_mm = mm; ipi_msg_flush_tb.flush_tb_mask = to_whom; send_ipi_message(to_whom, TLB_MM); @@ -829,12 +814,6 @@ struct mm_struct * mm = vma->vm_mm; int timeout = 10000; -#if 1 - if (!kernel_lock_held()) { - printk("flush_tlb_page: kernel_flag %d (cpu %d akp %d)!\n", - klock_info.kernel_flag, cpu, klock_info.akp); - } -#endif ipi_msg_flush_tb.p.flush_vma = vma; ipi_msg_flush_tb.flush_addr = addr; ipi_msg_flush_tb.flush_tb_mask = to_whom; @@ -847,9 +826,9 @@ while (ipi_msg_flush_tb.flush_tb_mask) { if (--timeout < 0) { - printk("flush_tlb_page: STUCK on CPU %d [0x%x,0x%lx,%d,%d]\n", + printk("flush_tlb_page: STUCK on CPU %d [0x%x,0x%lx,%d]\n", cpu, ipi_msg_flush_tb.flush_tb_mask, addr, - klock_info.akp, global_irq_holder); + global_irq_holder); ipi_msg_flush_tb.flush_tb_mask = 0; break; } @@ -866,20 +845,10 @@ #else unsigned int to_whom; int timeout; - unsigned long where; - - __asm__("mov $26, %0" : "=r" (where)); timeout = 10000; to_whom = cpu_present_map ^ (1 << smp_processor_id()); -#if 1 - if (!kernel_lock_held()) { - printk("flush_tlb_range: kernel_flag %d (cpu %d akp %d) @ 0x%lx\n", - klock_info.kernel_flag, smp_processor_id(), klock_info.akp, - where); - } -#endif ipi_msg_flush_tb.p.flush_mm = mm; ipi_msg_flush_tb.flush_tb_mask = to_whom; send_ipi_message(to_whom, TLB_MM); @@ -896,68 +865,17 @@ ipi_msg_flush_tb.flush_tb_mask = 0; break; } - udelay(100); - ; /* Wait for all clear from other CPUs. */ + udelay(100); /* Wait for all clear from other CPUs. */ } #endif } -#ifdef DEBUG_KERNEL_LOCK -void ___lock_kernel(klock_info_t *klip, int cpu, long ipl) -{ - long regx; - int stuck_lock; - unsigned long inline_pc; - - __asm__("mov $26, %0" : "=r" (inline_pc)); - - try_again: - - stuck_lock = 1<<26; - - __asm__ __volatile__( - "1: ldl_l %1,%0;" - " blbs %1,6f;" - " or %1,1,%1;" - " stl_c %1,%0;" - " beq %1,6f;" - "4: mb\n" - ".section .text2,\"ax\"\n" - "6: mov %5,$16;" - " call_pal %4;" - "7: ldl %1,%0;" - " blt %2,4b # debug\n" - " subl %2,1,%2 # debug\n" - " blbs %1,7b;" - " bis $31,7,$16;" - " call_pal %4;" - " br 1b\n" - ".previous" - : "=m,=m" (__dummy_lock(klip)), "=&r,=&r" (regx), - "=&r,=&r" (stuck_lock) - : "0,0" (__dummy_lock(klip)), "i,i" (PAL_swpipl), - "i,r" (ipl), "2,2" (stuck_lock) - : "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory"); - - if (stuck_lock < 0) { - printk("___kernel_lock stuck at %lx(%d) held %lx(%d)\n", - inline_pc, cpu, klip->pc, klip->cpu); - goto try_again; - } else { - klip->pc = inline_pc; - klip->cpu = cpu; - } -} -#endif - -#ifdef DEBUG_SPINLOCK +#if DEBUG_SPINLOCK void spin_lock(spinlock_t * lock) { long tmp; long stuck; - unsigned long inline_pc; - - __asm__("mov $26, %0" : "=r" (inline_pc)); + void *inline_pc = __builtin_return_address(0); try_again: @@ -987,30 +905,22 @@ : "2" (stuck)); if (stuck < 0) { - printk("spinlock stuck at %lx (cur=%lx, own=%lx)\n", - inline_pc, -#if 0 - lock->previous, lock->task -#else - (unsigned long) current, lock->task -#endif - ); + printk("spinlock stuck at %p (cur=%p, own=%p, prev=%p)\n", + inline_pc, current, lock->task, lock->previous); goto try_again; } else { - lock->previous = (unsigned long) inline_pc; - lock->task = (unsigned long) current; + lock->previous = inline_pc; + lock->task = current; } } #endif /* DEBUG_SPINLOCK */ -#ifdef DEBUG_RWLOCK +#if DEBUG_RWLOCK void write_lock(rwlock_t * lock) { long regx, regy; int stuck_lock, stuck_reader; - unsigned long inline_pc; - - __asm__("mov $26, %0" : "=r" (inline_pc)); + void *inline_pc = __builtin_return_address(0); try_again: @@ -1018,24 +928,24 @@ stuck_reader = 1<<26; __asm__ __volatile__( - "1: ldl_l %1,%0;" - " blbs %1,6f;" - " or %1,1,%2;" - " stl_c %2,%0;" - " beq %2,6f;" - " blt %1,8f;" + "1: ldl_l %1,%0\n" + " blbs %1,6f\n" + " or %1,1,%2\n" + " stl_c %2,%0\n" + " beq %2,6f\n" + " blt %1,8f\n" "4: mb\n" ".section .text2,\"ax\"\n" - "6: ldl %1,%0;" + "6: ldl %1,%0\n" " blt %3,4b # debug\n" " subl %3,1,%3 # debug\n" - " blbs %1,6b;" - " br 1b;" - "8: ldl %1,%0;" + " blbs %1,6b\n" + " br 1b\n" + "8: ldl %1,%0\n" " blt %4,4b # debug\n" " subl %4,1,%4 # debug\n" - " blt %1,8b;" - "9: br 4b\n" + " blt %1,8b\n" + " br 4b\n" ".previous" : "=m" (__dummy_lock(lock)), "=&r" (regx), "=&r" (regy) , "=&r" (stuck_lock), "=&r" (stuck_reader) @@ -1044,22 +954,20 @@ ); if (stuck_lock < 0) { - printk("write_lock stuck at %lx\n", inline_pc); + printk("write_lock stuck at %p\n", inline_pc); goto try_again; } if (stuck_reader < 0) { - printk("write_lock stuck on readers at %lx\n", inline_pc); + printk("write_lock stuck on readers at %p\n", inline_pc); goto try_again; } } -void _read_lock(rwlock_t * lock) +void read_lock(rwlock_t * lock) { long regx; int stuck_lock; - unsigned long inline_pc; - - __asm__("mov $26, %0" : "=r" (inline_pc)); + void *inline_pc = __builtin_return_address(0); try_again: @@ -1084,7 +992,7 @@ ); if (stuck_lock < 0) { - printk("_read_lock stuck at %lx\n", inline_pc); + printk("read_lock stuck at %p\n", inline_pc); goto try_again; } } diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_alcor.c linux/arch/alpha/kernel/sys_alcor.c --- v2.1.120/linux/arch/alpha/kernel/sys_alcor.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_alcor.c Sun Sep 6 10:34:33 1998 @@ -75,9 +75,6 @@ { unsigned long pld; unsigned int i; - unsigned long flags; - - save_and_cli(flags); /* Read the interrupt summary register of the GRU */ pld = (*(vuip)GRU_INT_REQ) & GRU_INT_REQ_BITS; @@ -95,7 +92,6 @@ handle_irq(16 + i, 16 + i, regs); } } - restore_flags(flags); } static void diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_cabriolet.c linux/arch/alpha/kernel/sys_cabriolet.c --- v2.1.120/linux/arch/alpha/kernel/sys_cabriolet.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_cabriolet.c Sun Sep 6 10:34:33 1998 @@ -72,9 +72,6 @@ { unsigned long pld; unsigned int i; - unsigned long flags; - - save_and_cli(flags); /* Read the interrupt summary registers */ pld = inb(0x804) | (inb(0x805) << 8) | (inb(0x806) << 16); @@ -92,7 +89,6 @@ handle_irq(16 + i, 16 + i, r); } } - restore_flags(flags); } static void diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_dp264.c linux/arch/alpha/kernel/sys_dp264.c --- v2.1.120/linux/arch/alpha/kernel/sys_dp264.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_dp264.c Sun Sep 6 10:34:33 1998 @@ -22,6 +22,7 @@ #include #include #include +#include #include #include @@ -39,12 +40,22 @@ dp264_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p) { if (irq >= 16) { - /* Make CERTAIN none of the bogus ints get enabled */ - *(vulp)TSUNAMI_CSR_DIM0 = - ~(mask) & ~0x0000000000000000UL; + volatile unsigned long *csr; + + if (TSUNAMI_bootcpu < 2) + if (!TSUNAMI_bootcpu) + csr = &TSUNAMI_cchip->dim0.csr; + else + csr = &TSUNAMI_cchip->dim1.csr; + else + if (TSUNAMI_bootcpu == 2) + csr = &TSUNAMI_cchip->dim2.csr; + else + csr = &TSUNAMI_cchip->dim3.csr; + + *csr = ~mask; mb(); - /* ... and read it back to make sure it got written. */ - *(vulp)TSUNAMI_CSR_DIM0; + *csr; } else if (irq >= 8) outb(mask >> 8, 0xA1); /* ISA PIC2 */ @@ -55,14 +66,14 @@ static void dp264_device_interrupt(unsigned long vector, struct pt_regs * regs) { +#if 1 + printk("dp264_device_interrupt: NOT IMPLEMENTED YET!! \n"); +#else unsigned long pld; unsigned int i; - unsigned long flags; - - __save_and_cli(flags); /* Read the interrupt summary register of TSUNAMI */ - pld = (*(vulp)TSUNAMI_CSR_DIR0); + pld = TSUNAMI_cchip->dir0.csr; /* * Now for every possible bit set, work through them and call @@ -77,20 +88,18 @@ handle_irq(16 + i, 16 + i, regs); } #if 0 - *(vulp)TSUNAMI_CSR_DIR0 = 1UL << i; mb(); - tmp = *(vulp)TSUNAMI_CSR_DIR0; + TSUNAMI_cchip->dir0.csr = 1UL << i; mb(); + tmp = TSUNAMI_cchip->dir0.csr; #endif } - __restore_flags(flags); +#endif } static void dp264_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq, ack; - unsigned long flags; - __save_and_cli(flags); ack = irq = (vector - 0x800) >> 4; /* @@ -104,20 +113,35 @@ ack = irq = irq - 16; handle_irq(irq, ack, regs); - __restore_flags(flags); } static void __init dp264_init_irq(void) { - STANDARD_INIT_IRQ_PROLOG; + volatile unsigned long *csr; + + outb(0, DMA1_RESET_REG); + outb(0, DMA2_RESET_REG); + outb(DMA_MODE_CASCADE, DMA2_MODE_REG); if (alpha_using_srm) alpha_mv.device_interrupt = dp264_srm_device_interrupt; + if (TSUNAMI_bootcpu < 2) + if (!TSUNAMI_bootcpu) + csr = &TSUNAMI_cchip->dim0.csr; + else + csr = &TSUNAMI_cchip->dim1.csr; + else + if (TSUNAMI_bootcpu == 2) + csr = &TSUNAMI_cchip->dim2.csr; + else + csr = &TSUNAMI_cchip->dim3.csr; + /* Note invert on MASK bits. */ - *(vulp)TSUNAMI_CSR_DIM0 = ~(alpha_irq_mask) & ~0UL; mb(); - *(vulp)TSUNAMI_CSR_DIM0; + *csr = ~(alpha_irq_mask); + mb(); + *csr; enable_irq(55); /* Enable CYPRESS interrupt controller (ISA). */ enable_irq(2); @@ -173,25 +197,29 @@ * IdSel * 5 Cypress Bridge I/O * 6 SCSI Adaptec builtin - * 7 64 bit PCI option slot 0 - * 8 64 bit PCI option slot 1 - * 9 64 bit PCI option slot 2 - * + * 7 64 bit PCI option slot 0 (all busses) + * 8 64 bit PCI option slot 1 (all busses) + * 9 64 bit PCI option slot 2 (all busses) + * 10 64 bit PCI option slot 3 (not bus 0) */ static int __init dp264_map_irq(struct pci_dev *dev, int slot, int pin) { - static char irq_tab[5][5] __initlocaldata = { + static char irq_tab[6][5] __initlocaldata = { /*INT INTA INTB INTC INTD */ { -1, -1, -1, -1, -1}, /* IdSel 5 ISA Bridge */ - { 16+ 2, 16+ 2, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/ + { 16+ 3, 16+ 3, 16+ 2, 16+ 2, 16+ 2}, /* IdSel 6 SCSI builtin*/ { 16+15, 16+15, 16+14, 16+13, 16+12}, /* IdSel 7 slot 0 */ { 16+11, 16+11, 16+10, 16+ 9, 16+ 8}, /* IdSel 8 slot 1 */ - { 16+ 7, 16+ 7, 16+ 6, 16+ 5, 16+ 4} /* IdSel 9 slot 2 */ + { 16+ 7, 16+ 7, 16+ 6, 16+ 5, 16+ 4}, /* IdSel 9 slot 2 */ + { 16+ 3, 16+ 3, 16+ 2, 16+ 1, 16+ 0} /* IdSel 10 slot 3 */ }; - const long min_idsel = 5, max_idsel = 9, irqs_per_slot = 5; - return COMMON_TABLE_LOOKUP; + const long min_idsel = 5, max_idsel = 10, irqs_per_slot = 5; + int irq = COMMON_TABLE_LOOKUP; + if (irq >= 0) + irq += 16 * bus2hose[dev->bus->number]->pci_hose_index; + return irq; } static void __init diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_eb64p.c linux/arch/alpha/kernel/sys_eb64p.c --- v2.1.120/linux/arch/alpha/kernel/sys_eb64p.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_eb64p.c Sun Sep 6 10:34:33 1998 @@ -52,9 +52,6 @@ { unsigned long pld; unsigned int i; - unsigned long flags; - - save_and_cli(flags); /* Read the interrupt summary registers */ pld = inb(0x26) | (inb(0x27) << 8); @@ -72,12 +69,28 @@ handle_irq(16 + i, 16 + i, regs); } } - restore_flags(flags); } static void __init eb64p_init_irq(void) { +#ifdef CONFIG_ALPHA_GENERIC + /* + * CABRIO SRM may not set variation correctly, so here we test + * the high word of the interrupt summary register for the RAZ + * bits, and hope that a true EB64+ would read all ones... + */ + if (inw(0x806) != 0xffff) { + extern struct alpha_machine_vector cabriolet_mv; +#if 1 + printk("eb64p_init_irq: resetting for CABRIO\n"); +#endif + alpha_mv = cabriolet_mv; + alpha_mv.init_irq(); + return; + } +#endif /* GENERIC */ + STANDARD_INIT_IRQ_PROLOG; outb(alpha_irq_mask >> 16, 0x26); diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_jensen.c linux/arch/alpha/kernel/sys_jensen.c --- v2.1.120/linux/arch/alpha/kernel/sys_jensen.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_jensen.c Sun Sep 6 10:34:33 1998 @@ -76,9 +76,7 @@ jensen_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq, ack; - unsigned long flags; - __save_and_cli(flags); ack = irq = (vector - 0x800) >> 4; switch (vector) { @@ -102,7 +100,6 @@ } handle_irq(irq, ack, regs); - __restore_flags(flags); } static void @@ -131,6 +128,7 @@ BUS(jensen), machine_check: jensen_machine_check, max_dma_address: ALPHA_MAX_DMA_ADDRESS, + rtc_port: 0x170, rtc_addr: 0, rtc_bcd: 1, nr_irqs: 16, irq_probe_mask: _PROBE_MASK(16), diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_miata.c linux/arch/alpha/kernel/sys_miata.c --- v2.1.120/linux/arch/alpha/kernel/sys_miata.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_miata.c Sun Sep 6 10:34:33 1998 @@ -52,9 +52,6 @@ { unsigned long pld, tmp; unsigned int i; - unsigned long flags; - - save_and_cli(flags); /* Read the interrupt summary register of PYXIS */ pld = *(vulp)PYXIS_INT_REQ; @@ -85,16 +82,13 @@ *(vulp)PYXIS_INT_REQ = 1UL << i; mb(); tmp = *(vulp)PYXIS_INT_REQ; } - restore_flags(flags); } static void miata_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq, ack; - unsigned long flags; - __save_and_cli(flags); ack = irq = (vector - 0x800) >> 4; /* @@ -115,7 +109,6 @@ ack = irq = irq + 8; handle_irq(irq, ack, regs); - __restore_flags(flags); } static void __init diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_mikasa.c linux/arch/alpha/kernel/sys_mikasa.c --- v2.1.120/linux/arch/alpha/kernel/sys_mikasa.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_mikasa.c Sun Sep 6 10:34:33 1998 @@ -48,9 +48,6 @@ { unsigned long pld; unsigned int i; - unsigned long flags; - - save_and_cli(flags); /* Read the interrupt summary registers */ pld = (((unsigned long) (~inw(0x534)) & 0x0000ffffUL) << 16) | @@ -70,7 +67,6 @@ handle_irq(i, i, regs); } } - restore_flags(flags); } static void __init diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_noritake.c linux/arch/alpha/kernel/sys_noritake.c --- v2.1.120/linux/arch/alpha/kernel/sys_noritake.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_noritake.c Sun Sep 6 10:34:33 1998 @@ -53,9 +53,6 @@ { unsigned long pld; unsigned int i; - unsigned long flags; - - save_and_cli(flags); /* Read the interrupt summary registers of NORITAKE */ pld = ((unsigned long) inw(0x54c) << 32) | @@ -76,16 +73,13 @@ handle_irq(i, i, regs); } } - restore_flags(flags); } static void noritake_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq, ack; - unsigned long flags; - __save_and_cli(flags); ack = irq = (vector - 0x800) >> 4; /* @@ -101,7 +95,6 @@ ack = irq = irq + 1; handle_irq(irq, ack, regs); - __restore_flags(flags); } static void __init diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_rawhide.c linux/arch/alpha/kernel/sys_rawhide.c --- v2.1.120/linux/arch/alpha/kernel/sys_rawhide.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_rawhide.c Sun Sep 6 10:34:33 1998 @@ -60,9 +60,7 @@ rawhide_srm_device_interrupt(unsigned long vector, struct pt_regs * regs) { int irq, ack; - unsigned long flags; - __save_and_cli(flags); ack = irq = (vector - 0x800) >> 4; /* @@ -84,7 +82,6 @@ } handle_irq(irq, ack, regs); - __restore_flags(flags); } static void __init @@ -162,7 +159,7 @@ static void __init rawhide_pci_fixup(void) { - mcpcia_pci_fixup(); + layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); common_pci_fixup(rawhide_map_irq, common_swizzle); } diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_ruffian.c linux/arch/alpha/kernel/sys_ruffian.c --- v2.1.120/linux/arch/alpha/kernel/sys_ruffian.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_ruffian.c Sun Sep 6 10:34:33 1998 @@ -31,7 +31,6 @@ #include "bios32.h" #include "machvec.h" - static void ruffian_update_irq_hw(unsigned long irq, unsigned long mask, int unmask_p) { @@ -75,9 +74,6 @@ { unsigned long pld; unsigned int i; - unsigned long flags; - - save_and_cli(flags); /* Read the interrupt summary register of PYXIS */ pld = *(vulp)PYXIS_INT_REQ; @@ -112,7 +108,7 @@ if (j == 7 && !(inb(0x20) & 0x80)) { /* It's only a passive release... */ } else if (j == 0) { - timer_interrupt(regs); + timer_interrupt(0, NULL, regs); ruffian_ack_irq(0); } else { handle_irq(j, j, regs); @@ -125,7 +121,6 @@ *(vulp)PYXIS_INT_REQ = 1UL << i; mb(); *(vulp)PYXIS_INT_REQ; /* read to force the write */ } - restore_flags(flags); } static void __init @@ -167,13 +162,13 @@ /* * For RUFFIAN, we do not want to make any modifications to the PCI - * setup. So just scan the busses. + * setup. But we may need to do some kind of init. */ static void __init ruffian_pci_fixup(void) { - layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); + /* layout_all_busses(DEFAULT_IO_BASE, DEFAULT_MEM_BASE); */ } @@ -194,7 +189,7 @@ /* Check BANK_ENABLE */ if (bank & 0x01) { - static unsigned long size[] __initdata = { + static unsigned long size[] __initlocaldata = { 0x40000000UL, /* 0x00, 1G */ 0x20000000UL, /* 0x02, 512M */ 0x10000000UL, /* 0x04, 256M */ @@ -227,7 +222,6 @@ pyxis_finish_init_arch(); } - static void ruffian_init_pit (void) { @@ -236,20 +230,31 @@ init_pit_rest(); } +static void +ruffian_kill_arch (int mode, char *reboot_cmd) +{ + /* Perhaps this works for other PYXIS as well? */ + *(vuip) PYXIS_RESET = 0x0000dead; + mb(); + + generic_kill_arch(mode, reboot_cmd); +} + /* * The System Vector */ -#if defined(CONFIG_ALPHA_GENERIC) || defined(CONFIG_ALPHA_RUFFIAN) struct alpha_machine_vector ruffian_mv __initmv = { vector_name: "Ruffian", DO_EV5_MMU, - DO_DEFAULT_RTC, - DO_PYXIS_IO, + /* RUFFIAN always uses BCD, like a PeeCee. */ + rtc_port: 0x70, rtc_addr: 0x80, rtc_bcd: 1, + /* For the moment, do not use BWIO on RUFFIAN. */ + IO(PYXIS,pyxis,pyxis), DO_PYXIS_BUS, machine_check: pyxis_machine_check, - max_dma_address: ALPHA_MAX_DMA_ADDRESS, + max_dma_address: ALPHA_RUFFIAN_MAX_DMA_ADDRESS, nr_irqs: 48, irq_probe_mask: RUFFIAN_PROBE_MASK, @@ -261,7 +266,6 @@ init_irq: ruffian_init_irq, init_pit: ruffian_init_pit, pci_fixup: ruffian_pci_fixup, - kill_arch: generic_kill_arch, + kill_arch: ruffian_kill_arch, }; ALIAS_MV(ruffian) -#endif diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_sable.c linux/arch/alpha/kernel/sys_sable.c --- v2.1.120/linux/arch/alpha/kernel/sys_sable.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_sable.c Sun Sep 6 10:34:33 1998 @@ -117,9 +117,7 @@ normal IRQs. */ int irq, ack; - unsigned long flags; - __save_and_cli(flags); ack = irq = (vector - 0x800) >> 4; irq = sable_irq_swizzle.mask_to_irq[(ack)]; @@ -131,7 +129,6 @@ #endif handle_irq(irq, ack, regs); - __restore_flags(flags); } static void __init diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_sx164.c linux/arch/alpha/kernel/sys_sx164.c --- v2.1.120/linux/arch/alpha/kernel/sys_sx164.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_sx164.c Sun Sep 6 10:34:33 1998 @@ -68,9 +68,6 @@ { unsigned long pld, tmp; unsigned int i; - unsigned long flags; - - save_and_cli(flags); /* Read the interrupt summary register of PYXIS */ pld = *(vulp)PYXIS_INT_REQ; @@ -101,14 +98,12 @@ *(vulp)PYXIS_INT_REQ = 1UL << i; mb(); tmp = *(vulp)PYXIS_INT_REQ; } - restore_flags(flags); } static void sx164_init_irq(void) { - outb(0, DMA1_RESET_REG); - outb(0, DMA2_RESET_REG); + STANDARD_INIT_IRQ_PROLOG; if (alpha_using_srm) { alpha_mv.update_irq_hw = sx164_srm_update_irq_hw; diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/sys_takara.c linux/arch/alpha/kernel/sys_takara.c --- v2.1.120/linux/arch/alpha/kernel/sys_takara.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/kernel/sys_takara.c Sun Sep 6 10:34:33 1998 @@ -39,11 +39,8 @@ static void takara_device_interrupt(unsigned long vector, struct pt_regs *regs) { - unsigned long flags; unsigned intstatus; - save_and_cli(flags); - /* * The PALcode will have passed us vectors 0x800 or 0x810, * which are fairly arbitrary values and serve only to tell @@ -73,8 +70,6 @@ if (intstatus & 1) handle_irq(16+0, 16+0, regs); } else isa_device_interrupt (vector, regs); - - restore_flags(flags); } static void __init diff -u --recursive --new-file v2.1.120/linux/arch/alpha/kernel/time.c linux/arch/alpha/kernel/time.c --- v2.1.120/linux/arch/alpha/kernel/time.c Wed Jun 24 22:54:03 1998 +++ linux/arch/alpha/kernel/time.c Sun Sep 6 10:34:33 1998 @@ -25,6 +25,7 @@ #include #include #include +#include #include #include @@ -33,14 +34,14 @@ #include #include +#include "proto.h" + #ifdef CONFIG_RTC #define TIMER_IRQ 0 /* using pit for timer */ #else #define TIMER_IRQ 8 /* using rtc for timer */ #endif -extern struct hwrpb_struct *hwrpb; - static int set_rtc_mmss(unsigned long); @@ -156,7 +157,71 @@ )*60 + sec; /* finally seconds */ } -void time_init(void) +/* + * Initialize Programmable Interval Timers with standard values. Some + * drivers depend on them being initialized (e.g., joystick driver). + */ + +/* It is (normally) only counter 1 that presents config problems, so + provide this support function to do the rest of the job. */ + +void inline +init_pit_rest(void) +{ +#if 0 + /* Leave refresh timer alone---nobody should depend on a + particular value anyway. */ + outb(0x54, 0x43); /* counter 1: refresh timer */ + outb(0x18, 0x41); +#endif + + outb(0xb6, 0x43); /* counter 2: speaker */ + outb(0x31, 0x42); + outb(0x13, 0x42); +} + +#ifdef CONFIG_RTC +static inline void +rtc_init_pit (void) +{ + /* Setup interval timer if /dev/rtc is being used */ + outb(0x34, 0x43); /* binary, mode 2, LSB/MSB, ch 0 */ + outb(LATCH & 0xff, 0x40); /* LSB */ + outb(LATCH >> 8, 0x40); /* MSB */ + request_region(0x40, 0x20, "timer"); /* reserve pit */ + + init_pit_rest(); +} +#endif + +void +generic_init_pit (void) +{ + int x; + if ((x = (CMOS_READ(RTC_FREQ_SELECT) & 0x3f)) != 0x26) { + printk("Setting RTC_FREQ to 1024 Hz (%x)\n", x); + CMOS_WRITE(0x26, RTC_FREQ_SELECT); + } + request_region(RTC_PORT(0), 0x10, "timer"); /* reserve rtc */ + + /* Turn off the PIT. */ + outb(0x36, 0x43); /* counter 0: system timer */ + outb(0x00, 0x40); + outb(0x00, 0x40); + + init_pit_rest(); +} + +/* This probably isn't Right, but it is what the old code did. */ +#if defined(CONFIG_RTC) +# define init_pit rtc_init_pit +#else +# define init_pit alpha_mv.init_pit +#endif + + +void +time_init(void) { #ifdef CONFIG_RTC unsigned char save_control; @@ -164,6 +229,9 @@ void (*irq_handler)(int, void *, struct pt_regs *); unsigned int year, mon, day, hour, min, sec, cc1, cc2; + /* Initialize the timers. */ + init_pit(); + /* * The Linux interpretation of the CMOS clock register contents: * When the Update-In-Progress (UIP) flag goes from 1 to 0, the @@ -179,7 +247,7 @@ /* If our cycle frequency isn't valid, go another round and give a guess at what it should be. */ if (hwrpb->cycle_freq == 0) { - printk("HWPRB cycle frequency bogus. Estimating... "); + printk("HWRPB cycle frequency bogus. Estimating... "); do { } while (!(CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP)); do { } while (CMOS_READ(RTC_FREQ_SELECT) & RTC_UIP); @@ -258,7 +326,8 @@ * part. So we can't do the "find absolute time in terms of cycles" thing * that the other ports do. */ -void do_gettimeofday(struct timeval *tv) +void +do_gettimeofday(struct timeval *tv) { unsigned long flags, now, delta_cycles, delta_usec; unsigned long sec, usec; @@ -296,7 +365,8 @@ tv->tv_usec = usec; } -void do_settimeofday(struct timeval *tv) +void +do_settimeofday(struct timeval *tv) { cli(); xtime = *tv; @@ -314,7 +384,8 @@ * jump to the next second precisely 500 ms later. Check the Motorola * MC146818A or Dallas DS12887 data sheet for details. */ -static int set_rtc_mmss(unsigned long nowtime) +static int +set_rtc_mmss(unsigned long nowtime) { int retval = 0; int real_seconds, real_minutes, cmos_minutes; diff -u --recursive --new-file v2.1.120/linux/arch/alpha/lib/io.c linux/arch/alpha/lib/io.c --- v2.1.120/linux/arch/alpha/lib/io.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/lib/io.c Sun Sep 6 10:34:33 1998 @@ -477,7 +477,8 @@ count -= 4; } - /* Handle all full-sized quadwords: we're aligned (or have a small count) */ + /* Handle all full-sized quadwords: we're aligned + (or have a small count) */ count -= 8; if (count >= 0) { do { diff -u --recursive --new-file v2.1.120/linux/arch/alpha/lib/stackcheck.S linux/arch/alpha/lib/stackcheck.S --- v2.1.120/linux/arch/alpha/lib/stackcheck.S Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/lib/stackcheck.S Sun Sep 6 10:34:33 1998 @@ -0,0 +1,27 @@ +/* + * arch/alpha/lib/stackcheck.S + * Contributed by Richard Henderson (rth@tamu.edu) + * + * Verify that we have not overflowed the stack. Oops if we have. + */ + +#include + + .text + .set noat + + .align 3 + .globl _mcount + .ent _mcount +_mcount: + .frame $30, 0, $28, 0 + .prologue 0 + + lda $0, TASK_SIZE($8) + cmpult $30, $0, $0 + bne $0, 1f + ret ($28) +1: stq $31, -8($31) # oops me, damn it. + br 1b + + .end _mcount diff -u --recursive --new-file v2.1.120/linux/arch/alpha/lib/stackkill.S linux/arch/alpha/lib/stackkill.S --- v2.1.120/linux/arch/alpha/lib/stackkill.S Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/lib/stackkill.S Sun Sep 6 10:34:33 1998 @@ -0,0 +1,35 @@ +/* + * arch/alpha/lib/killstack.S + * Contributed by Richard Henderson (rth@cygnus.com) + * + * Clobber the balance of the kernel stack, hoping to catch + * uninitialized local variables in the act. + */ + +#include + + .text + .set noat + + .align 5 + .globl _mcount + .ent _mcount +_mcount: + .frame $30, 0, $28, 0 + .prologue 0 + + ldi $0, 0xdeadbeef + lda $2, -STACK_SIZE + sll $0, 32, $1 + and $30, $2, $2 + or $0, $1, $0 + lda $2, TASK_SIZE($2) + cmpult $2, $30, $1 + beq $1, 2f +1: stq $0, 0($2) + addq $2, 8, $2 + cmpult $2, $30, $1 + bne $1, 1b +2: ret ($28) + + .end _mcount diff -u --recursive --new-file v2.1.120/linux/arch/alpha/lib/stacktrace.c linux/arch/alpha/lib/stacktrace.c --- v2.1.120/linux/arch/alpha/lib/stacktrace.c Wed Dec 31 16:00:00 1969 +++ linux/arch/alpha/lib/stacktrace.c Sun Sep 6 10:34:33 1998 @@ -0,0 +1,103 @@ +#include +#include + +typedef unsigned int instr; + +#define MAJOR_OP 0xfc000000 +#define LDA_OP 0x20000000 +#define STQ_OP 0xb4000000 +#define BR_OP 0xc0000000 + +#define STK_ALLOC_1 0x23de8000 /* lda $30,-X($30) */ +#define STK_ALLOC_1M 0xffff8000 +#define STK_ALLOC_2 0x43c0153e /* subq $30,X,$30 */ +#define STK_ALLOC_2M 0xffe01fff + +#define MEM_REG 0x03e00000 +#define MEM_BASE 0x001f0000 +#define MEM_OFF 0x0000ffff +#define MEM_OFF_SIGN 0x00008000 +#define BASE_SP 0x001e0000 + +#define STK_ALLOC_MATCH(INSTR) \ + (((INSTR) & STK_ALLOC_1M) == STK_ALLOC_1 \ + || ((INSTR) & STK_ALLOC_2M) == STK_ALLOC_2) +#define STK_PUSH_MATCH(INSTR) \ + (((INSTR) & (MAJOR_OP | MEM_BASE | MEM_OFF_SIGN)) == (STQ_OP | BASE_SP)) +#define MEM_OP_OFFSET(INSTR) \ + (((long)((INSTR) & MEM_OFF) << 48) >> 48) +#define MEM_OP_REG(INSTR) \ + (((INSTR) & MEM_REG) >> 22) + +/* Branches, jumps, PAL calls, and illegal opcodes end a basic block. */ +#define BB_END(INSTR) \ + (((instr)(INSTR) >= BR_OP) | ((instr)(INSTR) < LDA_OP) | \ + ((((instr)(INSTR) ^ 0x60000000) < 0x20000000) & \ + (((instr)(INSTR) & 0x0c000000) != 0))) + +#define IS_KERNEL_TEXT(PC) ((unsigned long)(PC) > START_ADDR) + +static char reg_name[][4] = { + "v0 ", "t0 ", "t1 ", "t2 ", "t3 ", "t4 ", "t5 ", "t6 ", "t7 ", + "s0 ", "s1 ", "s2 ", "s3 ", "s4 ", "s5 ", "s6 ", "a0 ", "a1 ", + "a2 ", "a3 ", "a4 ", "a5 ", "t8 ", "t9 ", "t10", "t11", "ra ", + "pv ", "at ", "gp ", "sp ", "0" +}; + + +static instr * +display_stored_regs(instr * pro_pc, unsigned char * sp) +{ + instr * ret_pc = 0; + int reg; + unsigned long value; + + printk("Prologue [<%p>], Frame %p:\n", pro_pc, sp); + while (!BB_END(*pro_pc)) + if (STK_PUSH_MATCH(*pro_pc)) { + reg = (*pro_pc & MEM_REG) >> 21; + value = *(unsigned long *)(sp + (*pro_pc & MEM_OFF)); + if (reg == 26) + ret_pc = (instr *)value; + printk("\t\t%s / 0x%016lx\n", reg_name[reg], value); + } + return ret_pc; +} + +static instr * +seek_prologue(instr * pc) +{ + while (!STK_ALLOC_MATCH(*pc)) + --pc; + while (!BB_END(*(pc - 1))) + --pc; + return pc; +} + +static long +stack_increment(instr * prologue_pc) +{ + while (!STK_ALLOC_MATCH(*prologue_pc)) + ++prologue_pc; + + /* Count the bytes allocated. */ + if ((*prologue_pc & STK_ALLOC_1M) == STK_ALLOC_1M) + return -(((long)(*prologue_pc) << 48) >> 48); + else + return (*prologue_pc >> 13) & 0xff; +} + +void +stacktrace(void) +{ + instr * ret_pc; + instr * prologue = (instr *)stacktrace; + register unsigned char * sp __asm__ ("$30"); + + printk("\tstack trace:\n"); + do { + ret_pc = display_stored_regs(prologue, sp); + sp += stack_increment(prologue); + prologue = seek_prologue(ret_pc); + } while (IS_KERNEL_TEXT(ret_pc)); +} diff -u --recursive --new-file v2.1.120/linux/arch/alpha/math-emu/ieee-math.c linux/arch/alpha/math-emu/ieee-math.c --- v2.1.120/linux/arch/alpha/math-emu/ieee-math.c Sat May 2 14:19:52 1998 +++ linux/arch/alpha/math-emu/ieee-math.c Sun Sep 6 10:34:33 1998 @@ -786,13 +786,11 @@ break; case ROUND_PINF: - if ((temp.f[0] & 0x007fffffffffffff) != 0) - ++b; + b += ((temp.f[0] & 0x007fffffffffffff) != 0 && !temp.s); break; case ROUND_NINF: - if ((temp.f[0] & 0x007fffffffffffff) != 0) - --b; + b += ((temp.f[0] & 0x007fffffffffffff) != 0 && temp.s); break; case ROUND_CHOP: diff -u --recursive --new-file v2.1.120/linux/arch/alpha/mm/init.c linux/arch/alpha/mm/init.c --- v2.1.120/linux/arch/alpha/mm/init.c Tue Aug 18 22:02:02 1998 +++ linux/arch/alpha/mm/init.c Sun Sep 6 10:34:33 1998 @@ -16,6 +16,9 @@ #include #include #include +#ifdef CONFIG_BLK_DEV_INITRD +#include +#endif #include #include @@ -23,6 +26,8 @@ #include #include +#define DEBUG_POISON 0 + extern void die_if_kernel(char *,struct pt_regs *,long); extern void show_net_buffers(void); @@ -259,6 +264,29 @@ } #endif /* __SMP__ */ +#if DEBUG_POISON +static void +kill_page(unsigned long pg) +{ + unsigned long *p = (unsigned long *)pg; + unsigned long i = PAGE_SIZE, v = 0xdeadbeefdeadbeef; + do { + p[0] = v; + p[1] = v; + p[2] = v; + p[3] = v; + p[4] = v; + p[5] = v; + p[6] = v; + p[7] = v; + i -= 64; + p += 8; + } while (i != 0); +} +#else +#define kill_page(pg) +#endif + void mem_init(unsigned long start_mem, unsigned long end_mem) { @@ -284,6 +312,11 @@ if (PageReserved(mem_map+MAP_NR(tmp))) continue; atomic_set(&mem_map[MAP_NR(tmp)].count, 1); +#ifdef CONFIG_BLK_DEV_INITRD + if (initrd_start && tmp >= initrd_start && tmp < initrd_end) + continue; +#endif + kill_page(tmp); free_page(tmp); } tmp = nr_free_pages << PAGE_SHIFT; @@ -301,6 +334,7 @@ for (; addr < (unsigned long)(&__init_end); addr += PAGE_SIZE) { mem_map[MAP_NR(addr)].flags &= ~(1 << PG_reserved); atomic_set(&mem_map[MAP_NR(addr)].count, 1); + kill_page(addr); free_page(addr); } printk ("Freeing unused kernel memory: %ldk freed\n", diff -u --recursive --new-file v2.1.120/linux/arch/arm/Makefile linux/arch/arm/Makefile --- v2.1.120/linux/arch/arm/Makefile Tue Jul 21 00:15:29 1998 +++ linux/arch/arm/Makefile Sun Sep 6 10:44:47 1998 @@ -157,13 +157,17 @@ CORE_FILES := arch/arm/kernel/kernel.o arch/arm/mm/mm.o $(CORE_FILES) LIBS := arch/arm/lib/lib.a $(LIBS) $(GCCLIB) -BLOCK_DRIVERS := arch/arm/drivers/block/block.a +BLOCK_DRIVERS := drivers/block/block.a CDROM_DRIVERS := drivers/cdrom/cdrom.a ifeq ($(CONFIG_FB),y) CHAR_DRIVERS := arch/arm/drivers/char1/char.a else +ifeq ($(CONFIG_VGA_CONSOLE),y) +CHAR_DRIVERS := arch/arm/drivers/char1/char.a +else CHAR_DRIVERS := arch/arm/drivers/char/char.a endif +endif MISC_DRIVERS := drivers/misc/misc.a NET_DRIVERS := drivers/net/net.a PARIDE_DRIVERS := drivers/block/paride/paride.a @@ -171,6 +175,7 @@ SCSI_DRIVERS := drivers/scsi/scsi.a SOUND_DRIVERS := drivers/sound/sound.a VIDEO_DRIVERS := drivers/video/video.a +PNP_DRIVERS := drivers/pnp/pnp.a ifeq ($(CONFIG_ARCH_ACORN),y) BLOCK_DRIVERS += drivers/acorn/block/acorn-block.a @@ -183,6 +188,10 @@ ifeq ($(CONFIG_FB),y) DRIVERS := $(DRIVERS) $(VIDEO_DRIVERS) +else +ifeq ($(CONFIG_VGA_CONSOLE),y) +DRIVERS := $(DRIVERS) $(VIDEO_DRIVERS) +endif endif ifeq ($(CONFIG_SCSI),y) DRIVERS := $(DRIVERS) $(SCSI_DRIVERS) @@ -198,6 +207,9 @@ endif ifeq ($(CONFIG_PARIDE),y) DRIVERS := $(DRIVERS) $(PARIDE_DRIVERS) +endif +ifdef CONFIG_PNP +DRIVERS := $(DRIVERS) $(PNP_DRIVERS) endif symlinks:: diff -u --recursive --new-file v2.1.120/linux/arch/arm/boot/compressed/misc.c linux/arch/arm/boot/compressed/misc.c --- v2.1.120/linux/arch/arm/boot/compressed/misc.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/boot/compressed/misc.c Sun Sep 6 10:44:47 1998 @@ -203,11 +203,13 @@ static void gzip_mark(void **ptr) { + arch_decomp_wdog(); *ptr = (void *) free_mem_ptr; } static void gzip_release(void **ptr) { + arch_decomp_wdog(); free_mem_ptr = (long) *ptr; } #else diff -u --recursive --new-file v2.1.120/linux/arch/arm/config.in linux/arch/arm/config.in --- v2.1.120/linux/arch/arm/config.in Thu Aug 6 14:06:28 1998 +++ linux/arch/arm/config.in Sun Sep 6 10:44:47 1998 @@ -8,19 +8,40 @@ mainmenu_option next_comment comment 'System and processor type' + choice 'ARM system type' \ "Archimedes CONFIG_ARCH_ARC \ A5000 CONFIG_ARCH_A5K \ RiscPC CONFIG_ARCH_RPC \ EBSA-110 CONFIG_ARCH_EBSA110 \ EBSA-285 CONFIG_ARCH_EBSA285 \ - NexusPCI CONFIG_ARCH_NEXUSPCI" RiscPC -if [ "$CONFIG_ARCH_ARC" = "y" -o "$CONFIG_ARCH_A5K" = "y" -o "$CONFIG_ARCH_RPC" = "y" ]; then + NexusPCI CONFIG_ARCH_NEXUSPCI \ + Corel-VNC CONFIG_ARCH_VNC \ + Tbox CONFIG_ARCH_TBOX" RiscPC + +if [ "$CONFIG_ARCH_EBSA285" = "y" ]; then + bool ' Include support for CATS boards' CONFIG_CATS +fi + +# Select various configuration options depending on the machine type +# Easy check for Acorn-style architectures + +if [ "$CONFIG_ARCH_ARC" = "y" -o \ + "$CONFIG_ARCH_A5K" = "y" -o \ + "$CONFIG_ARCH_RPC" = "y" ]; then define_bool CONFIG_ARCH_ACORN y else define_bool CONFIG_ARCH_ACORN n fi -if [ "$CONFIG_ARCH_NEXUSPCI" = "y" ]; then + +if [ "$CONFIG_ARCH_TBOX" = "y" ]; then + define_bool CONFIG_BUS_I2C y +fi + +# These machines have PCI/may have PCI + +if [ "$CONFIG_ARCH_NEXUSPCI" = "y" -o \ + "$CONFIG_ARCH_VNC" = "y" ]; then define_bool CONFIG_PCI y else if [ "$CONFIG_ARCH_EBSA285" = "y" ]; then @@ -32,20 +53,19 @@ # ever built a machine that can take both, and now that ARM3 is obsolete # nobody is likely to either. -if [ "$CONFIG_ARCH_RPC" = "y" -o "$CONFIG_ARCH_NEXUSPCI" = "y" -o "$CONFIG_ARCH_EBSA110" = "y" -o "$CONFIG_ARCH_EBSA285" = "y" ]; then +if [ "$CONFIG_ARCH_ARC" = "y" -o \ + "$CONFIG_ARCH_A5K" = "y" ]; then + define_bool CONFIG_CPU_32 n + define_bool CONFIG_CPU_26 y +else define_bool CONFIG_CPU_32 y define_bool CONFIG_CPU_26 n -else - if [ "$CONFIG_ARCH_ARC" = "y" -o "$CONFIG_ARCH_A5K" = "y" ]; then - define_bool CONFIG_CPU_32 n - define_bool CONFIG_CPU_26 y - fi fi # Now allow the user to choose a more precise CPU. This is only used to set # the flags we pass to GCC, not in any code. -choice 'Optimise for CPU' \ +choice 'Optimise for CPU' \ "ARM2 CONFIG_CPU_ARM2 \ ARM3 CONFIG_CPU_ARM3 \ ARM6 CONFIG_CPU_ARM6 \ @@ -92,8 +112,8 @@ tristate 'Parallel port support' CONFIG_PARPORT if [ "$CONFIG_PARPORT" != "n" ]; then - dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT dep_tristate ' Archimedes hardware' CONFIG_PARPORT_ARC $CONFIG_PARPORT + dep_tristate ' PC-style hardware' CONFIG_PARPORT_PC $CONFIG_PARPORT # If exactly one hardware type is selected then parport will optimise away # support for loading any others. Defeat this if the user is keen. if [ "$CONFIG_PARPORT_PC" = "n" -o "$CONFIG_PARPORT_ARC" = "n" ]; then @@ -104,16 +124,29 @@ fi endmenu -source arch/arm/drivers/block/Config.in -source drivers/acorn/block/Config.in +source drivers/pnp/Config.in + +source drivers/block/Config.in + +if [ "$CONFIG_ARCH_ACORN" = "y" ]; then + source drivers/acorn/block/Config.in +fi source arch/arm/drivers/char/Config.in -mainmenu_option next_comment -comment 'Console drivers' -bool 'Support Frame buffer devices' CONFIG_FB -source drivers/video/Config.in -endmenu +if [ "$CONFIG_VT" = "y" ]; then + mainmenu_option next_comment + comment 'Console drivers' + if [ "$CONFIG_ARCH_ACORN" != "y" -a "$CONFIG_ARCH_EBSA110" != "y" ]; then + bool 'VGA text console' CONFIG_VGA_CONSOLE + if [ "$CONFIG_EXPERIMENTAL" = "y" ]; then + bool 'Video mode selection support' CONFIG_VIDEO_SELECT + fi + fi + bool 'Support Frame buffer devices' CONFIG_FB + source drivers/video/Config.in + endmenu +fi if [ "$CONFIG_NET" = "y" ]; then source net/Config.in @@ -140,7 +173,7 @@ fi endmenu -if [ "$CONFIG_ARCH_ACORN" = "y" ]; then +if [ "$CONFIG_ARCH_ACORN" = "y" -o "$CONFIG_PCI" = "y" ]; then mainmenu_option next_comment comment 'Sound' diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/Makefile linux/arch/arm/kernel/Makefile --- v2.1.120/linux/arch/arm/kernel/Makefile Fri May 8 23:14:41 1998 +++ linux/arch/arm/kernel/Makefile Sun Sep 6 10:44:47 1998 @@ -9,7 +9,8 @@ ENTRY_OBJ = entry-$(PROCESSOR).o O_TARGET := kernel.o -O_OBJS := $(ENTRY_OBJ) ioport.o irq.o process.o ptrace.o signal.o sys_arm.o time.o traps.o +O_OBJS := $(ENTRY_OBJ) ioport.o irq.o process.o ptrace.o setup.o \ + signal.o sys_arm.o time.o traps.o fiq.o all: lib kernel.o $(HEAD_OBJ) init_task.o @@ -20,7 +21,7 @@ endif ifdef CONFIG_ARCH_ACORN - O_OBJS += setup.o ecard.o iic.o + O_OBJS += ecard.o iic.o ifdef CONFIG_ARCH_ARC O_OBJS += oldlatches.o endif @@ -29,25 +30,26 @@ endif ifeq ($(MACHINE),ebsa110) - O_OBJS += setup-ebsa110.o dma-dummy.o + O_OBJS += dma-dummy.o leds-ebsa110.o endif ifeq ($(MACHINE),ebsa285) - O_OBJS += dma-dummy.o leds-ebsa285.o setup-ebsa110.o + OX_OBJS += dma.o + O_OBJS += dma-ebsa285.o leds-ebsa285.o ifdef CONFIG_PCI O_OBJS += dec21285.o endif endif ifeq ($(MACHINE),nexuspci) - O_OBJS += setup-ebsa110.o dma-dummy.o + O_OBJS += dma-dummy.o ifdef CONFIG_PCI O_OBJS += plx9080.o endif endif $(HEAD_OBJ): $(HEAD_OBJ:.o=.S) - $(CC) -D__ASSEMBLY__ -traditional -c $(HEAD_OBJ:.o=.S) -o $@ + $(CC) -D__ASSEMBLY__ -DTEXTADDR=$(TEXTADDR) -traditional -c $(HEAD_OBJ:.o=.S) -o $@ $(ENTRY_OBJ): $(ENTRY_OBJ:.o=.S) $(CC) $(CFLAGS) -D__ASSEMBLY__ -c $(ENTRY_OBJ:.o=.S) -o $@ diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/armksyms.c linux/arch/arm/kernel/armksyms.c --- v2.1.120/linux/arch/arm/kernel/armksyms.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/armksyms.c Sun Sep 6 10:44:47 1998 @@ -12,10 +12,13 @@ #include #include #include +#include #include extern void dump_thread(struct pt_regs *, struct user *); extern int dump_fpu(struct pt_regs *, struct user_fp_struct *); +extern void inswb(unsigned int port, void *to, int len); +extern void outswb(unsigned int port, const void *to, int len); /* * libgcc functions - functions that are used internally by the @@ -40,33 +43,27 @@ extern void __umoddi3(void); extern void __umodsi3(void); -extern void inswb(unsigned int port, void *to, int len); -extern void outswb(unsigned int port, const void *to, int len); - -/* - * floating point math emulator support. - * These will not change. If they do, then a new version - * of the emulator will have to be compiled... - * fp_current is never actually dereferenced - it is just - * used as a pointer to pass back for send_sig(). - */ -extern void (*fp_save)(unsigned char *); -extern void (*fp_restore)(unsigned char *); -extern void fp_setup(void); -extern void fpreturn(void); -extern void fpundefinstr(void); extern void fp_enter(void); -extern void fp_printk(void); -extern struct task_struct *fp_current; -extern void fp_send_sig(int); +#define EXPORT_SYMBOL_ALIAS(sym,orig) \ + const char __kstrtab_##sym##[] __attribute__((section(".kstrtab"))) = \ + __MODULE_STRING(##sym##); \ + const struct module_symbol __ksymtab_##sym __attribute__((section("__ksymtab"))) = \ + { (unsigned long)&##orig, __kstrtab_##sym }; + /* + * floating point math emulator support. + * These symbols will never change their calling convention... + */ +EXPORT_SYMBOL_ALIAS(kern_fp_enter,fp_enter); +EXPORT_SYMBOL_ALIAS(fp_printk,printk); +EXPORT_SYMBOL_ALIAS(fp_send_sig,send_sig); -/* platform dependent support */ + /* platform dependent support */ EXPORT_SYMBOL(dump_thread); EXPORT_SYMBOL(dump_fpu); EXPORT_SYMBOL(udelay); EXPORT_SYMBOL(xchg_str); -/* expansion card support */ + /* expansion card support */ #ifdef CONFIG_ARCH_ACORN EXPORT_SYMBOL(ecard_startfind); EXPORT_SYMBOL(ecard_find); @@ -77,16 +74,17 @@ EXPORT_SYMBOL(enable_irq); EXPORT_SYMBOL(disable_irq); -/* processor dependencies */ + /* processor dependencies */ EXPORT_SYMBOL(processor); +EXPORT_SYMBOL(machine_type); -/* io */ + /* io */ EXPORT_SYMBOL(outswb); EXPORT_SYMBOL(outsw); EXPORT_SYMBOL(inswb); EXPORT_SYMBOL(insw); -/* address translation */ + /* address translation */ #ifndef __virt_to_phys__is_a_macro EXPORT_SYMBOL(__virt_to_phys); #endif @@ -104,27 +102,7 @@ EXPORT_SYMBOL(__bad_pmd); EXPORT_SYMBOL(__bad_pmd_kernel); -#define EXPORT_VERS0(sym,orig) \ - const char __kstrtab_##sym##[] __attribute__((section(".kstrtab"))) = \ - __MODULE_STRING(##sym##_R00000000); \ - const struct module_symbol __ksymtab_##sym __attribute__((section("__ksymtab"))) = \ - { (unsigned long)&##orig, __kstrtab_##sym }; -/* - * floating point math emulator support. - * These symbols will never change their calling convention... - */ -EXPORT_VERS0(fpreturn,fpreturn); -EXPORT_VERS0(fpundefinstr,fpundefinstr); -EXPORT_VERS0(fp_enter,fp_enter); -EXPORT_VERS0(fp_save,fp_save); -EXPORT_VERS0(fp_restore,fp_restore); -EXPORT_VERS0(fp_setup,fp_setup); -EXPORT_VERS0(fp_printk,printk); -EXPORT_VERS0(fp_send_sig,send_sig); - - /* - * string / mem functions - */ + /* string / mem functions */ EXPORT_SYMBOL_NOVERS(strcpy); EXPORT_SYMBOL_NOVERS(strncpy); EXPORT_SYMBOL_NOVERS(strcat); diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/dec21285.c linux/arch/arm/kernel/dec21285.c --- v2.1.120/linux/arch/arm/kernel/dec21285.c Thu Aug 6 14:06:28 1998 +++ linux/arch/arm/kernel/dec21285.c Sun Sep 6 10:44:47 1998 @@ -1,31 +1,42 @@ /* * arch/arm/kernel/dec21285.c: PCI functions for DEC 21285 * - * Copyright (C) 1998 Russell King + * Copyright (C) 1998 Russell King, Phil Blundell */ #include #include #include -int pcibios_present(void) +#include + +#define MAX_SLOTS 20 + +int +pcibios_present(void) { return 1; } -static unsigned long pcibios_base_address(unsigned char dev_fn) +static unsigned long +pcibios_base_address(unsigned char bus, unsigned char dev_fn) { - int slot = PCI_SLOT(dev_fn); - - if (slot < 4) - return 0xf8000000 + (1 << (19 - slot)); - else - return 0; + if (bus == 0) { + int slot = PCI_SLOT(dev_fn); + + if (slot < MAX_SLOTS) + return 0xf8c00000 + (slot << 11); + else + return 0; + } else { + return 0xf9000000 | (bus << 16) | (dev_fn << 8); + } } -int pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char *val) +int +pcibios_read_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned char *val) { - unsigned long addr = pcibios_base_address(dev_fn); + unsigned long addr = pcibios_base_address(bus, dev_fn); unsigned char v; if (addr) @@ -38,10 +49,11 @@ return PCIBIOS_SUCCESSFUL; } -int pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short *val) +int +pcibios_read_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned short *val) { - unsigned long addr = pcibios_base_address(dev_fn); + unsigned long addr = pcibios_base_address(bus, dev_fn); unsigned short v; if (addr) @@ -54,10 +66,11 @@ return PCIBIOS_SUCCESSFUL; } -int pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int *val) +int +pcibios_read_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned int *val) { - unsigned long addr = pcibios_base_address(dev_fn); + unsigned long addr = pcibios_base_address(bus, dev_fn); unsigned int v; if (addr) @@ -70,10 +83,11 @@ return PCIBIOS_SUCCESSFUL; } -int pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned char val) +int +pcibios_write_config_byte(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned char val) { - unsigned long addr = pcibios_base_address(dev_fn); + unsigned long addr = pcibios_base_address(bus, dev_fn); if (addr) __asm__("str%?b %0, [%1, %2]" @@ -81,10 +95,11 @@ return PCIBIOS_SUCCESSFUL; } -int pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned short val) +int +pcibios_write_config_word(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned short val) { - unsigned long addr = pcibios_base_address(dev_fn); + unsigned long addr = pcibios_base_address(bus, dev_fn); if (addr) __asm__("str%?h %0, [%1, %2]" @@ -92,10 +107,11 @@ return PCIBIOS_SUCCESSFUL; } -int pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, - unsigned char where, unsigned int val) +int +pcibios_write_config_dword(unsigned char bus, unsigned char dev_fn, + unsigned char where, unsigned int val) { - unsigned long addr = pcibios_base_address(dev_fn); + unsigned long addr = pcibios_base_address(bus, dev_fn); if (addr) __asm__("str%? %0, [%1, %2]" @@ -103,35 +119,72 @@ return PCIBIOS_SUCCESSFUL; } -static int irq[] = { 18, 8, 9, 11 }; +static int irqmap_ebsa[] __initdata = { 9, 8, 18, 11 }; +static int irqmap_cats[] __initdata = { 18, 8, 9, 11 }; + +__initfunc(static int ebsa_irqval(struct pci_dev *dev)) +{ + unsigned char pin; + + pcibios_read_config_byte(dev->bus->number, + dev->devfn, + PCI_INTERRUPT_PIN, + &pin); + + return irqmap_ebsa[(PCI_SLOT(dev->devfn) + pin) & 3]; +} + +__initfunc(static int cats_irqval(struct pci_dev *dev)) +{ + if (dev->irq >= 128) + return 32 + (dev->irq & 0x1f); + + switch (dev->irq) { + case 1: + case 2: + case 3: + case 4: + return irqmap_cats[dev->irq - 1]; + case 0: + return 0; + } + + printk("PCI: device %02x:%02x has unknown irq line %x\n", + dev->bus->number, dev->devfn, dev->irq); + return 0; +} __initfunc(void pcibios_fixup(void)) { struct pci_dev *dev; - unsigned char pin; - unsigned int cmd; + unsigned char cmd; for (dev = pci_devices; dev; dev = dev->next) { - pcibios_read_config_byte(dev->bus->number, - dev->devfn, - PCI_INTERRUPT_PIN, - &pin); - - dev->irq = irq[(PCI_SLOT(dev->devfn) + pin) & 3]; - - pcibios_write_config_byte(dev->bus->number, - dev->devfn, - PCI_INTERRUPT_LINE, - dev->irq); + /* sort out the irq mapping for this device */ + switch (machine_type) { + case MACH_TYPE_EBSA285: + dev->irq = ebsa_irqval(dev); + break; + case MACH_TYPE_CATS: + dev->irq = cats_irqval(dev); + break; + } + pcibios_write_config_byte(dev->bus->number, dev->devfn, + PCI_INTERRUPT_LINE, dev->irq); - printk("PCI: %02x:%02x [%04x/%04x] pin %d irq %d\n", + printk(KERN_DEBUG + "PCI: %02x:%02x [%04x/%04x] on irq %d\n", dev->bus->number, dev->devfn, - dev->vendor, dev->device, - pin, dev->irq); + dev->vendor, dev->device, dev->irq); - /* Turn on bus mastering - boot loader doesn't - perhaps it should! */ - pcibios_read_config_byte(dev->bus->number, dev->devfn, PCI_COMMAND, &cmd); - pcibios_write_config_byte(dev->bus->number, dev->devfn, PCI_COMMAND, cmd | PCI_COMMAND_MASTER); + /* Turn on bus mastering - boot loader doesn't + * - perhaps it should! - dag + */ + pcibios_read_config_byte(dev->bus->number, dev->devfn, + PCI_COMMAND, &cmd); + cmd |= PCI_COMMAND_MASTER; + pcibios_write_config_byte(dev->bus->number, dev->devfn, + PCI_COMMAND, cmd); } } @@ -141,10 +194,16 @@ rev = *(unsigned char *)0xfe000008; printk("DEC21285 PCI revision %02X\n", rev); -} -__initfunc(void pcibios_fixup_bus(struct pci_bus *bus)) -{ + /* + * Map our SDRAM at a known address in PCI space, just in case + * the firmware had other ideas. Using a nonzero base is slightly + * bizarre but apparently necessary to avoid problems with some + * video cards. + * + * We should really only do this if we are the configuration master. + */ + *((unsigned long *)0xfe000018) = 0x10000000; } __initfunc(void pcibios_fixup_bus(struct pci_bus *bus)) diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/dma-ebsa285.c linux/arch/arm/kernel/dma-ebsa285.c --- v2.1.120/linux/arch/arm/kernel/dma-ebsa285.c Wed Dec 31 16:00:00 1969 +++ linux/arch/arm/kernel/dma-ebsa285.c Sun Sep 6 10:44:47 1998 @@ -0,0 +1,183 @@ +/* + * arch/arm/kernel/dma-ebsa285.c + * + * Copyright (C) 1998 Phil Blundell + * + * DMA functions specific to EBSA-285/CATS architectures + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "dma.h" + +/* 8237 DMA controllers */ +#define IO_DMA1_BASE 0x00 /* 8 bit slave DMA, channels 0..3 */ +#define IO_DMA2_BASE 0xC0 /* 16 bit master DMA, ch 4(=slave input)..7 */ + +/* 8237 DMA controller registers */ +#define DMA1_CMD_REG 0x08 /* command register (w) */ +#define DMA1_STAT_REG 0x08 /* status register (r) */ +#define DMA1_REQ_REG 0x09 /* request register (w) */ +#define DMA1_MASK_REG 0x0A /* single-channel mask (w) */ +#define DMA1_MODE_REG 0x0B /* mode register (w) */ +#define DMA1_CLEAR_FF_REG 0x0C /* clear pointer flip-flop (w) */ +#define DMA1_TEMP_REG 0x0D /* Temporary Register (r) */ +#define DMA1_RESET_REG 0x0D /* Master Clear (w) */ +#define DMA1_CLR_MASK_REG 0x0E /* Clear Mask */ +#define DMA1_MASK_ALL_REG 0x0F /* all-channels mask (w) */ + +#define DMA2_CMD_REG 0xD0 /* command register (w) */ +#define DMA2_STAT_REG 0xD0 /* status register (r) */ +#define DMA2_REQ_REG 0xD2 /* request register (w) */ +#define DMA2_MASK_REG 0xD4 /* single-channel mask (w) */ +#define DMA2_MODE_REG 0xD6 /* mode register (w) */ +#define DMA2_CLEAR_FF_REG 0xD8 /* clear pointer flip-flop (w) */ +#define DMA2_TEMP_REG 0xDA /* Temporary Register (r) */ +#define DMA2_RESET_REG 0xDA /* Master Clear (w) */ +#define DMA2_CLR_MASK_REG 0xDC /* Clear Mask */ +#define DMA2_MASK_ALL_REG 0xDE /* all-channels mask (w) */ + +int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_name) +{ + /* 21285 internal channels */ + if (channel == 0 || channel == 1) + return 0; + + /* ISA channels */ +// if (machine_is_cats() && ((channel >= 2 && channel <= 5) || +// (channel >= 7 && channel <= 9))) +// return 0; + + return -EINVAL; +} + +void arch_free_dma(dmach_t channel, dma_t *dma) +{ + /* nothing to do */ +} + +int arch_get_dma_residue(dmach_t channel, dma_t *dma) +{ + int residue = 0; + + switch (channel) { + case 0: + case 1: + break; +#ifdef CONFIG_CATS + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: +#endif + } + return residue; +} + +void arch_enable_dma(dmach_t channel, dma_t *dma) +{ + switch (channel) { + case 0: + case 1: + /* + * Not yet implemented + */ + break; +#ifdef CONFIG_CATS + case 2: + case 3: + case 4: + case 5: + case 7: + case 8: + case 9: + if (dma->invalid) { + static unsigned char dma_page[] = { 0x87, 0x83, 0x81, 0x82, + 0x00, 0x8b, 0x89, 0x8a }; + unsigned long int address = dma->buf.address, + length = dma->buf.length - 1; + outb(address >> 24, dma_page[channel - DMA_ISA_BASE] | 0x400); + outb(address >> 16, dma_page[channel - DMA_ISA_BASE]); + if (channel >= DMA_ISA_BASE + 5) { + outb(0, DMA2_CLEAR_FF_REG); + outb(address >> 1, + IO_DMA2_BASE + ((channel - DMA_ISA_BASE - 4) << 2)); + outb(address >> 9, + IO_DMA2_BASE + ((channel - DMA_ISA_BASE - 4) << 2)); + outb((length >> 1) & 0xfe, + IO_DMA2_BASE + 1 + ((channel - DMA_ISA_BASE - 4) << 2)); + outb(length >> 9, + IO_DMA2_BASE + 1 + ((channel - DMA_ISA_BASE - 4) << 2)); + outb(dma->dma_mode | (channel - DMA_ISA_BASE - 4), DMA2_MODE_REG); + } else { + outb(0, DMA1_CLEAR_FF_REG); + outb(address >> 0, IO_DMA1_BASE + ((channel - DMA_ISA_BASE) << 1)); + outb(address >> 8, IO_DMA1_BASE + ((channel - DMA_ISA_BASE) << 1)); + outb(length >> 0, + IO_DMA1_BASE + 1 + ((channel - DMA_ISA_BASE) << 1)); + outb(length >> 8, + IO_DMA1_BASE + 1 + ((channel - DMA_ISA_BASE) << 1)); + outb(dma->dma_mode | (channel - DMA_ISA_BASE), DMA1_MODE_REG); + } + switch (dma->dma_mode) { + case DMA_MODE_READ: + dma_cache_inv(__bus_to_virt(address), length + 1); + break; + case DMA_MODE_WRITE: + dma_cache_wback(__bus_to_virt(address), length + 1); + break; + } + dma->invalid = 0; + } + + if (channel >= DMA_ISA_BASE + 5) + outb(channel - DMA_ISA_BASE - 4, DMA2_MASK_REG); + else + outb(channel - DMA_ISA_BASE, DMA1_MASK_REG); +#endif + } +} + +void arch_disable_dma(dmach_t channel, dma_t *dma) +{ + switch (channel) { + case 0: + case 1: + /* + * Not yet implemented + */ + break; +#ifdef CONFIG_CATS + case 2: + case 3: + case 4: + case 5: + case 6: + case 7: + case 8: + case 9: + if (channel >= DMA_ISA_BASE + 5) + outb(channel - DMA_ISA_BASE, DMA2_MASK_REG); + else + outb((channel - DMA_ISA_BASE) | 4, DMA1_MASK_REG); +#endif + } +} + +__initfunc(void arch_dma_init(dma_t *dma)) +{ + /* Nothing to do */ +} diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/dma-rpc.c linux/arch/arm/kernel/dma-rpc.c --- v2.1.120/linux/arch/arm/kernel/dma-rpc.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/dma-rpc.c Sun Sep 6 10:44:47 1998 @@ -20,7 +20,7 @@ #include "dma.h" -static struct fiq_handler fh = { "floppydma", NULL }; +static struct fiq_handler fh = { NULL, "floppydma", NULL, NULL }; #if 0 typedef enum { @@ -155,8 +155,8 @@ } } while (dma->sg && (status & DMA_ST_INT)); - if (!no_buffer) - enable_irq(irq); + if (no_buffer) + disable_irq(irq); } int arch_request_dma(dmach_t channel, dma_t *dma, const char *dev_name) @@ -172,7 +172,8 @@ case DMA_S0: case DMA_S1: save_flags_cli(flags); - ret = request_irq(dma->dma_irq, arch_dma_handle, SA_INTERRUPT, dev_name, dma); + ret = request_irq(dma->dma_irq, arch_dma_handle, + SA_INTERRUPT, dev_name, dma); if (!ret) disable_irq(dma->dma_irq); restore_flags(flags); @@ -261,8 +262,7 @@ case DMA_VIRTUAL_FLOPPY: { void *fiqhandler_start; unsigned int fiqhandler_length; - extern void floppy_fiqsetup(unsigned long len, unsigned long addr, - unsigned long port); + struct pt_regs regs; if (dma->dma_mode == DMA_MODE_READ) { extern unsigned char floppy_fiqin_start, floppy_fiqin_end; @@ -273,21 +273,20 @@ fiqhandler_start = &floppy_fiqout_start; fiqhandler_length = &floppy_fiqout_end - &floppy_fiqout_start; } + + regs.ARM_r9 = dma->buf.length; + regs.ARM_r10 = __bus_to_virt(dma->buf.address); + regs.ARM_fp = (int)PCIO_FLOPPYDMABASE; + if (claim_fiq(&fh)) { printk("floppydma: couldn't claim FIQ.\n"); return; } - /* Allow access to page 0 via domains */ - __asm__ __volatile__("mcr p15, 0, %0, c3, c0" : - : "r" (DOMAIN_USER_MANAGER | - DOMAIN_KERNEL_CLIENT | - DOMAIN_IO_CLIENT)); - memcpy((void *)0x1c, fiqhandler_start, fiqhandler_length); - /* set domain register to normal */ - set_fs(get_fs()); - flush_page_to_ram(0); - floppy_fiqsetup(dma->buf.length, __bus_to_virt(dma->buf.address), (int)PCIO_FLOPPYDMABASE); + + set_fiq_handler(fiqhandler_start, fiqhandler_length); + set_fiq_regs(®s); enable_irq(dma->dma_irq); + } break; @@ -315,6 +314,7 @@ case DMA_VIRTUAL_FLOPPY: disable_irq(dma->dma_irq); + release_fiq(&fh); break; } } diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/ecard.c linux/arch/arm/kernel/ecard.c --- v2.1.120/linux/arch/arm/kernel/ecard.c Tue Apr 14 14:29:19 1998 +++ linux/arch/arm/kernel/ecard.c Sun Sep 6 10:44:47 1998 @@ -29,7 +29,6 @@ #include #include -#include #include #include #include @@ -46,7 +45,7 @@ #define BUS_ADDR(x) ((((unsigned long)(x)) << 2) + IO_BASE) extern unsigned long atomwide_serial_loader[], oak_scsi_loader[], noloader[]; -static const char blacklisted_str[] = "*loader blacklisted - not 32-bit compliant*"; +static const char blacklisted_str[] = "*loader s/w is not 32-bit compliant*"; static const struct expcard_blacklist { unsigned short manufacturer; @@ -62,7 +61,7 @@ BLACKLIST_LOADER(MANU_OAK, PROD_OAK_SCSI, oak_scsi_loader), /* Supported cards with broken loader */ - { MANU_ALSYSTEMS, PROD_ALSYS_SCSIATAPI, noloader, "AlSystems PowerTec SCSI (loader blacklisted)" }, + { MANU_ALSYSTEMS, PROD_ALSYS_SCSIATAPI, noloader, "AlSystems PowerTec SCSI" }, /* Unsupported cards with no loader */ BLACKLIST_NOLOADER(MANU_MCS, PROD_MCS_CONNECT32) @@ -125,6 +124,7 @@ */ void ecard_enableirq (unsigned int irqnr) { + irqnr &= 7; if (irqnr < MAX_ECARDS && irqno_to_expcard[irqnr] != -1) { ecard_t *ec = expcard + irqno_to_expcard[irqnr]; @@ -141,6 +141,7 @@ void ecard_disableirq (unsigned int irqnr) { + irqnr &= 7; if (irqnr < MAX_ECARDS && irqno_to_expcard[irqnr] != -1) { ecard_t *ec = expcard + irqno_to_expcard[irqnr]; @@ -154,6 +155,7 @@ void ecard_enablefiq (unsigned int fiqnr) { + fiqnr &= 7; if (fiqnr < MAX_ECARDS && irqno_to_expcard[fiqnr] != -1) { ecard_t *ec = expcard + irqno_to_expcard[fiqnr]; @@ -170,6 +172,7 @@ void ecard_disablefiq (unsigned int fiqnr) { + fiqnr &= 7; if (fiqnr < MAX_ECARDS && irqno_to_expcard[fiqnr] != -1) { ecard_t *ec = expcard + irqno_to_expcard[fiqnr]; @@ -186,7 +189,6 @@ const int num_cards = ecard_numirqcards; int i, called = 0; - mask_irq (IRQ_EXPANSIONCARD); for (i = 0; i < num_cards; i++) { if (expcard[i].claimed && expcard[i].irq && (!expcard[i].irqmask || @@ -195,8 +197,7 @@ called ++; } } - cli (); - unmask_irq (IRQ_EXPANSIONCARD); + cli(); if (called == 0) printk (KERN_WARNING "Wild interrupt from backplane?\n"); } @@ -433,10 +434,7 @@ unsigned int ecard_address (ecard_t *ec, card_type_t type, card_speed_t speed) { switch (ec->slot_no) { - case 0: - case 1: - case 2: - case 3: + case 0 ... 3: switch (type) { case ECARD_MEMC: return MEMCECIO_BASE + (ec->slot_no << 12); @@ -449,20 +447,11 @@ } #ifdef IOCEC4IO_BASE - case 4: - case 5: - case 6: - case 7: - switch (type) { - case ECARD_MEMC: + case 4 ... 7: + if (type != ECARD_IOC) return 0; - case ECARD_IOC: - return IOCEC4IO_BASE + (speed << 17) + ((ec->slot_no - 4) << 12); - - default: - return 0; - } + return IOCEC4IO_BASE + (speed << 17) + ((ec->slot_no - 4) << 12); #endif #ifdef MEMCEC8IO_BASE case 8: @@ -558,7 +547,14 @@ return 1; } -static struct irqaction irqexpansioncard = { ecard_irq_noexpmask, SA_INTERRUPT, 0, "expansion cards", NULL, NULL }; +static struct irqaction irqexpansioncard = { + ecard_irq_noexpmask, + SA_INTERRUPT, + 0, + "expansion cards", + NULL, + NULL +}; /* * Initialise the expansion card system. @@ -575,6 +571,7 @@ if (ecard_checkirqhw()) { printk (KERN_DEBUG "Expansion card interrupt management hardware found\n"); irqexpansioncard.handler = ecard_irq_expmask; + irqexpansioncard.flags |= SA_IRQNOMASK; have_expmask = -1; } #endif diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/entry-armv.S linux/arch/arm/kernel/entry-armv.S --- v2.1.120/linux/arch/arm/kernel/entry-armv.S Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/entry-armv.S Sun Sep 6 10:44:47 1998 @@ -320,11 +320,19 @@ .macro mask_pc, rd, rm .endm + /* If we're optimising for StrongARM the resulting code won't + run on an ARM7 and we can save a couple of instructions. + --pb */ +#ifdef __ARM_ARCH_4__ + .macro arm700_bug_check, instr, temp + .endm +#else .macro arm700_bug_check, instr, temp and \temp, \instr, #0x0f000000 @ check for SWI teq \temp, #0x0f000000 bne .Larm700bug .endm +#endif .macro enable_irqs, temp mrs \temp, cpsr @@ -340,6 +348,7 @@ .endm +#ifndef __ARM_ARCH_4__ .Larm700bug: str lr, [r8] ldr r0, [sp, #S_PSR] @ Get calling cpsr msr spsr, r0 @@ -348,7 +357,7 @@ add sp, sp, #S_PC ldr lr, [sp], #S_FRAME_SIZE - S_PC @ Get PC and jump over PC, PSR, OLD_R0 movs pc, lr - +#endif .macro get_current_task, rd mov \rd, sp, lsr #13 @@ -672,6 +681,8 @@ *----------------------------------------------------------------------------- * Handles floating point instructions */ +.LC2: .word SYMBOL_NAME(fp_enter) + __und_usr: sub sp, sp, #S_FRAME_SIZE @ Allocate frame size in one go stmia sp, {r0 - r12} @ Save r0 - r12 add r8, sp, #S_PC @@ -681,25 +692,15 @@ stmia r8, {r5 - r7} @ Save USR pc, cpsr, old_r0 mov fp, #0 - adr r1, .LC2 - ldmia r1, {r1, r4} - ldr r1, [r1] - get_current_task r2 - teq r1, r2 - blne SYMBOL_NAME(math_state_restore) - adrsvc al, r9, SYMBOL_NAME(fpreturn) - adrsvc al, lr, SYMBOL_NAME(fpundefinstr) - ldr pc, [r4] @ Call FP module USR entry point + adrsvc al, r9, ret_from_exception @ r9 = normal FP return + adrsvc al, lr, fpundefinstr @ lr = undefined instr return - .globl SYMBOL_NAME(fpundefinstr) -SYMBOL_NAME(fpundefinstr): @ Called by FP module on undefined instr - mov r0, lr - mov r1, sp - mrs r4, cpsr @ Enable interrupts - bic r4, r4, #I_BIT - msr cpsr, r4 - bl SYMBOL_NAME(do_undefinstr) - b ret_from_exception @ Normal FP exit +1: get_current_task r10 + mov lr, #1 + strb lr, [r10, #TSK_USED_MATH] @ set current->used_math + add r10, r10, #TSS_FPESAVE @ r10 = workspace + ldr r4, .LC2 + ldr pc, [r4] @ Call FP module USR entry point __und_svc: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - r12} @ save r0 - r12 @@ -710,31 +711,24 @@ add r4, sp, #S_SP stmia r4, {r5 - r9} @ save sp_SVC, lr_SVC, pc, cpsr, old_ro - adr r1, .LC2 - ldmia r1, {r1, r4} - ldr r1, [r1] - mov r2, sp, lsr #13 - mov r2, r2, lsl #13 - teq r1, r2 - blne SYMBOL_NAME(math_state_restore) - adrsvc al, r9, SYMBOL_NAME(fpreturnsvc) - adrsvc al, lr, SYMBOL_NAME(fpundefinstrsvc) - ldr pc, [r4] @ Call FP module SVC entry point + adrsvc al, r9, 3f @ r9 = normal FP return + bl 1b @ lr = undefined instr return - .globl SYMBOL_NAME(fpundefinstrsvc) -SYMBOL_NAME(fpundefinstrsvc): mov r0, r5 @ unsigned long pc mov r1, sp @ struct pt_regs *regs bl SYMBOL_NAME(do_undefinstr) - .globl SYMBOL_NAME(fpreturnsvc) -SYMBOL_NAME(fpreturnsvc): - ldr lr, [sp, #S_PSR] @ Get SVC cpsr +3: ldr lr, [sp, #S_PSR] @ Get SVC cpsr msr spsr, lr ldmia sp, {r0 - pc}^ @ Restore SVC registers -.LC2: .word SYMBOL_NAME(last_task_used_math) - .word SYMBOL_NAME(fp_enter) +fpundefinstr: mov r0, lr + mov r1, sp + mrs r4, cpsr @ Enable interrupts + bic r4, r4, #I_BIT + msr cpsr, r4 + adrsvc al, lr, ret_from_exception + b SYMBOL_NAME(do_undefinstr) __und_invalid: sub sp, sp, #S_FRAME_SIZE stmia sp, {r0 - lr} diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/entry-common.S linux/arch/arm/kernel/entry-common.S --- v2.1.120/linux/arch/arm/kernel/entry-common.S Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/entry-common.S Sun Sep 6 10:44:47 1998 @@ -6,8 +6,6 @@ .globl ret_from_sys_call - .globl SYMBOL_NAME(fpreturn) -SYMBOL_NAME(fpreturn): ret_from_exception: adr r0, 1f ldmia r0, {r0, r1} @@ -36,12 +34,10 @@ bne SYMBOL_NAME(do_bottom_half) ret_with_reschedule: - ldr r0, 1f + 8 - ldr r0, [r0] + get_current_task r1 + ldr r0, [r1, #TSK_NEED_RESCHED] teq r0, #0 bne 2b - - get_current_task r1 ldr r1, [r1, #TSK_SIGPENDING] teq r1, #0 bne ret_signal @@ -50,7 +46,6 @@ 1: .word SYMBOL_NAME(bh_mask) .word SYMBOL_NAME(bh_active) - .word SYMBOL_NAME(need_resched) /*============================================================================= * SWI handler @@ -211,8 +206,11 @@ * What we need to put into 0-0x1c are ldrs to branch to 0xC0000000 * (the kernel). * 0x1c onwards is reserved for FIQ, so I think that I will allocate 0xe0 onwards for - * the actuall address to jump to. + * the actual address to jump to. */ + + .section ".text.init",#alloc,#execinstr + #if defined(CONFIG_CPU_32) /* * these go into 0x00 @@ -281,39 +279,13 @@ ldmfd sp!, {r4 - r7, pc}^ #endif + .previous + /*============================================================================ * FP support */ -1: .word SYMBOL_NAME(fp_save) - .word SYMBOL_NAME(fp_restore) - -.Lfpnull: mov pc, lr - - -/* - * Function to call when switching tasks to save FP state - */ -ENTRY(fpe_save) - ldr r1, 1b - ldr pc, [r1] - -/* - * Function to call when switching tasks to restore FP state - */ -ENTRY(fpe_restore) - ldr r1, 1b + 4 - ldr pc, [r1] - - .data ENTRY(fp_enter) - .word SYMBOL_NAME(fpundefinstr) - .word SYMBOL_NAME(fpundefinstrsvc) - -ENTRY(fp_save) - .word .Lfpnull -ENTRY(fp_restore) - .word .Lfpnull - + .word fpundefinstr diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/fiq.c linux/arch/arm/kernel/fiq.c --- v2.1.120/linux/arch/arm/kernel/fiq.c Wed Dec 31 16:00:00 1969 +++ linux/arch/arm/kernel/fiq.c Sun Sep 6 10:44:47 1998 @@ -0,0 +1,179 @@ +/* + * linux/arch/arm/kernel/fiq.c + * + * Copyright (C) 1998 Russell King + * FIQ support written by Philip Blundell , 1998. + * + * FIQ support re-written by Russell King to be more generic + * + * We now properly support a method by which the FIQ handlers can + * be stacked onto the vector. We still do not support sharing + * the FIQ vector itself. + * + * Operation is as follows: + * 1. Owner A claims FIQ: + * - default_fiq relinquishes control. + * 2. Owner A: + * - inserts code. + * - sets any registers, + * - enables FIQ. + * 3. Owner B claims FIQ: + * - if owner A has a relinquish function. + * - disable FIQs. + * - saves any registers. + * - returns zero. + * 4. Owner B: + * - inserts code. + * - sets any registers, + * - enables FIQ. + * 5. Owner B releases FIQ: + * - Owner A is asked to reacquire FIQ: + * - inserts code. + * - restores saved registers. + * - enables FIQ. + * 6. Goto 3 + */ +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#define FIQ_VECTOR 0x1c + +static unsigned long no_fiq_insn; + +#ifdef CONFIG_CPU_32 +static inline void unprotect_page_0(void) +{ + __asm__ __volatile__("mcr p15, 0, %0, c3, c0" : + : "r" (DOMAIN_USER_MANAGER | + DOMAIN_KERNEL_CLIENT | + DOMAIN_IO_CLIENT)); +} + +static inline void protect_page_0(void) +{ + set_fs(get_fs()); +} +#else + +#define unprotect_page_0() +#define protect_page_0() + +#endif + +/* Default reacquire function + * - we always relinquish FIQ control + * - we always reacquire FIQ control + */ +int fiq_def_op(void *ref, int relinquish) +{ + if (!relinquish) { + unprotect_page_0(); + *(unsigned long *)FIQ_VECTOR = no_fiq_insn; + protect_page_0(); + __flush_entry_to_ram(FIQ_VECTOR); + } + + return 0; +} + +static struct fiq_handler default_owner = + { NULL, "default", fiq_def_op, NULL }; +static struct fiq_handler *current_fiq = &default_owner; + +int get_fiq_list(char *buf) +{ + char *p = buf; + + if (current_fiq != &default_owner) + p += sprintf(p, "FIQ: %s\n", + current_fiq->name); + + return p - buf; +} + +void set_fiq_handler(void *start, unsigned int length) +{ + unprotect_page_0(); + + memcpy((void *)FIQ_VECTOR, start, length); + + protect_page_0(); +#if 0 + /* This doesn'w work correctly. Ok, it's a misuse + * of the DMA flushing code, but it ought to work. + * More investigation required. Maybe it really + * needs the cache flushed. + */ + dma_cache_wback(FIQ_VECTOR, length); +#else + processor.u.armv3v4._flush_cache_area(FIQ_VECTOR, FIQ_VECTOR + length, 1); +#endif +} + +void set_fiq_regs(struct pt_regs *regs) +{ + /* not yet - + * this is temporary to get the floppy working + * again on RiscPC. It *will* become more + * generic. + */ +#ifdef CONFIG_ARCH_ACORN + extern void floppy_fiqsetup(unsigned long len, unsigned long addr, + unsigned long port); + floppy_fiqsetup(regs->ARM_r9, regs->ARM_r10, regs->ARM_fp); +#endif +} + +void get_fiq_regs(struct pt_regs *regs) +{ + /* not yet */ +} + +int claim_fiq(struct fiq_handler *f) +{ + int ret = 0; + + if (current_fiq) { + ret = -EBUSY; + + if (current_fiq->fiq_op != NULL) + ret = current_fiq->fiq_op(current_fiq->dev_id, 1); + } + + if (!ret) { + f->next = current_fiq; + current_fiq = f; + } + + return ret; +} + +void release_fiq(struct fiq_handler *f) +{ + if (current_fiq != f) { + printk(KERN_ERR "%s FIQ trying to release %s FIQ\n", + f->name, current_fiq->name); +#ifdef CONFIG_DEBUG_ERRORS + __backtrace(); +#endif + return; + } + + do + current_fiq = current_fiq->next; + while (current_fiq->fiq_op(current_fiq->dev_id, 0)); +} + +__initfunc(void init_FIQ(void)) +{ + no_fiq_insn = *(unsigned long *)FIQ_VECTOR; + set_fs(get_fs()); +} diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/head-armo.S linux/arch/arm/kernel/head-armo.S --- v2.1.120/linux/arch/arm/kernel/head-armo.S Tue Apr 14 14:29:19 1998 +++ linux/arch/arm/kernel/head-armo.S Sun Sep 6 10:44:47 1998 @@ -43,7 +43,7 @@ LC1: .word SYMBOL_NAME(_stext) LC0: .word SYMBOL_NAME(__bss_start) - .word SYMBOL_NAME(arm_id) + .word SYMBOL_NAME(processor_id) .word SYMBOL_NAME(_end) .word SYMBOL_NAME(init_task_union)+8192 Larm2_id: .long 0x41560200 diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/head-armv.S linux/arch/arm/kernel/head-armv.S --- v2.1.120/linux/arch/arm/kernel/head-armv.S Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/head-armv.S Sun Sep 6 10:44:47 1998 @@ -1,58 +1,54 @@ /* * linux/arch/arm/kernel/head32.S * - * Copyright (C) 1994, 1995, 1996, 1997 Russell King + * Copyright (C) 1994-1998 Russell King * * Kernel 32 bit startup code for ARM6 / ARM7 / StrongARM */ #include #include -#define DEBUG +#if (TEXTADDR & 0xffff) != 0x8000 +#error TEXTADDR must start at 0xXXXX8000 +#endif - .text - .align +#define DEBUG .globl SYMBOL_NAME(swapper_pg_dir) - .equ SYMBOL_NAME(swapper_pg_dir), 0xc0004000 + .equ SYMBOL_NAME(swapper_pg_dir), TEXTADDR - 0x4000 - .globl __stext + .text /* * Entry point and restart point. Entry *must* be called with r0 == 0, * MMU off. Note! These should be unique!!! Please read Documentation/ARM-README * for more information. * - * r1 = 0 -> ebsa110 - * r1 = 1 -> RPC + * r1 = 0 -> DEC EBSA-110 + * r1 = 1 -> Acorn RiscPC * r1 = 2 -> ebsit * r1 = 3 -> nexuspci - * r1 = 4 -> ebsa285 - * r1 = 5 -> vnc + * r1 = 4 -> DEC EBSA-285 + * r1 = 5 -> Corel Netwinder * r1 = 6 -> CATS + * r1 = 7 -> tbox */ + ENTRY(stext) ENTRY(_stext) -__entry: - teq r0, #0 @ check for illegal entry... +__entry: teq r0, #0 @ check for illegal entry... bne .Lerror @ loop indefinitely - cmp r1, #7 @ Unknown machine architecture + cmp r1, #8 @ Unknown machine architecture bge .Lerror -@ -@ First thing to do is to get the page tables set up so that we can call the kernel -@ in the correct place. This is relocatable code... -@ +/* First thing to do is to get the page tables set up so that we can call the kernel + * in the correct place. This is relocatable code... + * - Read processor ID register (CP#15, CR0). + */ mrc p15, 0, r9, c0, c0 @ get Processor ID -@ -@ Read processor ID register (CP#15, CR0). -@ NOTE: ARM2 & ARM250 cause an undefined instruction exception... -@ Values are: -@ XX01XXXX = ARMv4 architecture (StrongARM) -@ XX00XXXX = ARMv3 architecture -@ 4156061X = ARM 610 -@ 4156030X = ARM 3 -@ 4156025X = ARM 250 -@ 4156020X = ARM 2 -@ +/* Values are: + * XX01XXXX = ARMv4 architecture (StrongARM) + * XX00XXXX = ARMv3 architecture + * 4156061X = ARM 610 + */ adr r10, .LCProcTypes 1: ldmia r10!, {r5, r6, r8} @ Get Set, Mask, MMU Flags teq r5, #0 @ End of list? @@ -71,44 +67,51 @@ * r6 = I/O address */ mov r0, r4 - mov r1, #0 + mov r3, #0 add r2, r0, #0x4000 -1: str r1, [r0], #4 @ Clear page table +1: str r3, [r0], #4 @ Clear page table teq r0, r2 bne 1b /* * Add enough entries to allow the kernel to be called. * It will sort out the real mapping in paging_init. - * We map in 2MB of memory into 0xC0000000 - 0xC0200000 + * We map in 2MB of memory into (TEXTADDR-0x8000) + 2MB + */ + add r0, r4, #(TEXTADDR - 0x8000) >> 18 + mov r3, #0x0000000c @ SECT_CACHEABLE | SECT_BUFFERABLE + orr r3, r3, r8 + add r3, r3, r5 + str r3, [r0], #4 + add r3, r3, #1 << 20 + str r3, [r0], #4 + add r3, r3, #1 << 20 +#ifdef DEBUG +/* Map in IO space + * This allows debug messages to be output via a serial + * before/while paging_init. */ - add r0, r4, #0x3000 - mov r1, #0x0000000c @ SECT_CACHEABLE | SECT_BUFFERABLE - orr r1, r1, r8 - add r1, r1, r5 - str r1, [r0], #4 - add r1, r1, #1 << 20 - str r1, [r0], #4 - add r1, r1, #1 << 20 -@ -@ Map in IO space -@ add r0, r4, #0x3800 - orr r1, r6, r8 + orr r3, r6, r8 add r2, r0, #0x0800 -1: str r1, [r0], #4 - add r1, r1, #1 << 20 +1: str r3, [r0], #4 + add r3, r3, #1 << 20 teq r0, r2 bne 1b -@ -@ Map in screen at 0x02000000 & SCREEN2_BASE -@ +#endif +#ifdef CONFIG_ARCH_RPC +/* Map in screen at 0x02000000 & SCREEN2_BASE + * Similar reasons here - for debug, and when things go + * wrong to a certain extent. This is of limited use to + * non-Acorn RiscPC architectures though. + */ teq r5, #0 addne r0, r4, #0x80 @ 02000000 - movne r1, #0x02000000 - orrne r1, r1, r8 - strne r1, [r0] + movne r3, #0x02000000 + orrne r3, r3, r8 + strne r3, [r0] addne r0, r4, #0x3600 @ d8000000 - strne r1, [r0] + strne r3, [r0] +#endif @ @ The following should work on both v3 and v4 implementations @ @@ -122,25 +125,29 @@ mov pc, lr .Lerror: +#ifdef CONFIG_ARCH_RPC +/* Turn the screen red on a error - RiscPC only. + */ 1: mov r0, #0x02000000 - mov r1, #0x11 - orr r1, r1, r1, lsl #8 - orr r1, r1, r1, lsl #16 - str r1, [r0], #4 - str r1, [r0], #4 - str r1, [r0], #4 - str r1, [r0], #4 + mov r3, #0x11 + orr r3, r3, r3, lsl #8 + orr r3, r3, r3, lsl #16 + str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 + str r3, [r0], #4 +#endif b 1b .Lbranch: .long .Lalready_done_mmap @ Real address of routine - @ EBSA110 (pg dir phys, phys ram start, phys i/o) + @ DEC EBSA110 (pg dir phys, phys ram start, phys i/o) .LCMachTypes: .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical) .long 0 @ Address of RAM .long 0xe0000000 @ I/O address .long 0 - @ RPC + @ Acorn RiscPC .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 + 0x10000000 .long 0x10000000 .long 0x03000000 @@ -158,7 +165,7 @@ .long 0x10000000 .long 0 - @ EBSA285 + @ DEC EBSA285 .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 @ Address of page tables (physical) .long 0 @ Address of RAM .long 0x24000000 @ I/O base address (0x42000000 -> 0xFE000000) @@ -176,6 +183,12 @@ .long 0x24000000 @ I/O base address (0x42000000 -> 0xfe000000) .long 0 + @ tbox + .long SYMBOL_NAME(swapper_pg_dir) - 0xc0000000 + 0x80000000 + .long 0x80000000 @ Address of RAM + .long 0x00400000 @ Uart + .long 0 + .LCProcTypes: @ ARM6 / 610 .long 0x41560600 .long 0xffffff00 @@ -205,11 +218,6 @@ b .Lsa_fastclock .long 0 - -.LC0: .long SYMBOL_NAME(__bss_start) - .long SYMBOL_NAME(arm_id) - .long SYMBOL_NAME(_end) - .long SYMBOL_NAME(init_task_union)+8192 .align .Larmv3_flush_early: @@ -249,25 +257,36 @@ orr r0, r0, #0x1100 @ v4 supports separate I cache mov pc, lr + .section ".text.init",#alloc,#execinstr + .Lsa_fastclock: mcr p15, 0, r4, c15, c1, 2 @ Enable clock switching mov pc, lr +.LC0: .long SYMBOL_NAME(__entry) + .long SYMBOL_NAME(machine_type) + .long SYMBOL_NAME(__bss_start) + .long SYMBOL_NAME(processor_id) + .long SYMBOL_NAME(_end) + .long SYMBOL_NAME(init_task_union)+8192 + .align + .Lalready_done_mmap: - adr r5, __entry @ Add base back in - add r10, r10, r5 - adr r5, .LC0 - ldmia r5, {r5, r6, r8, sp} @ Setup stack - mov r4, #0 + adr r4, .LC0 + ldmia r4, {r3, r4, r5, r6, r8, sp} @ Setup stack + add r10, r10, r3 @ Add base back in + mov fp, #0 1: cmp r5, r8 @ Clear BSS - strcc r4, [r5],#4 + strcc fp, [r5],#4 bcc 1b + str r1, [r4] @ Save machine type str r9, [r6] @ Save processor ID mov lr, pc add pc, r10, #4 @ Call post-processor init mov fp, #0 b SYMBOL_NAME(start_kernel) + .text #ifdef DEBUG /* * Some debugging routines (useful if you've got MM problems and @@ -385,6 +404,9 @@ teq r3, r2 bne 1b mov r0, r2 + b printascii + + .ltorg ENTRY(printascii) addruart r3 @@ -413,7 +435,3 @@ hexbuf: .space 16 #endif - - .text - .align 13 -ENTRY(this_must_match_init_task) diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/init_task.c linux/arch/arm/kernel/init_task.c --- v2.1.120/linux/arch/arm/kernel/init_task.c Tue Mar 17 22:18:13 1998 +++ linux/arch/arm/kernel/init_task.c Sun Sep 6 10:44:47 1998 @@ -6,7 +6,7 @@ static struct vm_area_struct init_mmap = INIT_MMAP; static struct fs_struct init_fs = INIT_FS; -static struct files * init_fd_array[NR_OPEN] = { NULL, }; +static struct file * init_fd_array[NR_OPEN] = { NULL, }; static struct files_struct init_files = INIT_FILES; static struct signal_struct init_signals = INIT_SIGNALS; struct mm_struct init_mm = INIT_MM; @@ -21,4 +21,4 @@ * * The things we do for performance.. */ -union task_union init_task_union __attribute__((__section__(".text"))) = { INIT_TASK }; +union task_union init_task_union __attribute__((__section__(".init.task"))) = { INIT_TASK }; diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/ioport.c linux/arch/arm/kernel/ioport.c --- v2.1.120/linux/arch/arm/kernel/ioport.c Thu May 7 22:51:46 1998 +++ linux/arch/arm/kernel/ioport.c Sun Sep 6 10:44:47 1998 @@ -1,10 +1,7 @@ /* * linux/arch/arm/kernel/ioport.c * - * This contains the io-permission bitmap code - written by obz, with changes - * by Linus. - * - * Modifications for ARM processor Copyright (C) 1995, 1996 Russell King + * Io-port support is not used for ARM */ #include @@ -14,85 +11,19 @@ #include /* Set EXTENT bits starting at BASE in BITMAP to value TURN_ON. */ -asmlinkage void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value) +/*asmlinkage void set_bitmap(unsigned long *bitmap, short base, short extent, int new_value) { - int mask; - unsigned long *bitmap_base = bitmap + (base >> 5); - unsigned short low_index = base & 0x1f; - int length = low_index + extent; +}*/ - if (low_index != 0) { - mask = (~0 << low_index); - if (length < 32) - mask &= ~(~0 << length); - if (new_value) - *bitmap_base++ |= mask; - else - *bitmap_base++ &= ~mask; - length -= 32; - } - - mask = (new_value ? ~0 : 0); - while (length >= 32) { - *bitmap_base++ = mask; - length -= 32; - } - - if (length > 0) { - mask = ~(~0 << length); - if (new_value) - *bitmap_base++ |= mask; - else - *bitmap_base++ &= ~mask; - } -} - -/* - * this changes the io permissions bitmap in the current task. - */ asmlinkage int sys_ioperm(unsigned long from, unsigned long num, int turn_on) { - if (from + num <= from) - return -EINVAL; -#ifndef __arm__ - if (from + num > IO_BITMAP_SIZE*32) - return -EINVAL; -#endif - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - -#ifdef IODEBUG - printk("io: from=%d num=%d %s\n", from, num, (turn_on ? "on" : "off")); -#endif -#ifndef __arm__ - set_bitmap((unsigned long *)current->tss.io_bitmap, from, num, !turn_on); -#endif - return 0; + return -ENOSYS; } -unsigned int *stack; - -/* - * sys_iopl has to be used when you want to access the IO ports - * beyond the 0x3ff range: to get the full 65536 ports bitmapped - * you'd need 8kB of bitmaps/process, which is a bit excessive. - * - * Here we just change the eflags value on the stack: we allow - * only the super-user to do it. This depends on the stack-layout - * on system-call entry - see also fork() and the signal handling - * code. - */ asmlinkage int sys_iopl(long ebx,long ecx,long edx, long esi, long edi, long ebp, long eax, long ds, long es, long fs, long gs, long orig_eax, long eip,long cs,long eflags,long esp,long ss) { - unsigned int level = ebx; - - if (level > 3) - return -EINVAL; - if (!capable(CAP_SYS_RAWIO)) - return -EPERM; - *(&eflags) = (eflags & 0xffffcfff) | (level << 12); - return 0; + return -ENOSYS; } diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/irq.c linux/arch/arm/kernel/irq.c --- v2.1.120/linux/arch/arm/kernel/irq.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/irq.c Sun Sep 6 10:44:47 1998 @@ -3,7 +3,6 @@ * * Copyright (C) 1992 Linus Torvalds * Modifications for ARM processor Copyright (C) 1995-1998 Russell King. - * FIQ support written by Philip Blundell , 1998. * * This file contains the code used by various IRQ handling routines: * asking for different IRQ's should be done through these routines @@ -31,20 +30,10 @@ #include #include -#include #include #include #include #include -#include - -unsigned int local_bh_count[NR_CPUS]; -unsigned int local_irq_count[NR_CPUS]; -spinlock_t irq_controller_lock; -static struct fiq_handler *current_fiq; -static unsigned long no_fiq_insn; - -#define FIQ_VECTOR ((unsigned long *)0x1c) #ifndef SMP #define irq_enter(cpu, irq) (++local_irq_count[cpu]) @@ -53,48 +42,65 @@ #error SMP not supported #endif -#ifdef CONFIG_ARCH_ACORN -/* Bitmask indicating valid interrupt numbers - * (to be moved to include/asm-arm/arch-*) - */ -unsigned long validirqs[NR_IRQS / 32] = { - 0x003ffe7f, 0x000001ff, 0x000000ff, 0x00000000 +#ifndef cliIF +#define cliIF() +#endif + +unsigned int local_bh_count[NR_CPUS]; +unsigned int local_irq_count[NR_CPUS]; +spinlock_t irq_controller_lock; + +extern int get_fiq_list(char *); +extern void init_FIQ(void); + +struct irqdesc { + unsigned int nomask : 1; /* IRQ does not mask in IRQ */ + unsigned int enabled : 1; /* IRQ is currently enabled */ + unsigned int triggered: 1; /* IRQ has occurred */ + unsigned int probing : 1; /* IRQ in use for a probe */ + unsigned int probe_ok : 1; /* IRQ can be used for probe */ + unsigned int valid : 1; /* IRQ claimable */ + unsigned int unused :26; + void (*mask_ack)(unsigned int irq); /* Mask and acknowledge IRQ */ + void (*mask)(unsigned int irq); /* Mask IRQ */ + void (*unmask)(unsigned int irq); /* Unmask IRQ */ + struct irqaction *action; + unsigned int unused2[3]; }; -#define valid_irq(x) ((x) < NR_IRQS && validirqs[(x) >> 5] & (1 << ((x) & 31))) -#else +static struct irqdesc irq_desc[NR_IRQS]; -#define valid_irq(x) ((x) < NR_IRQS) -#endif +/* + * Dummy mask/unmask handler + */ +static void dummy_mask_unmask_irq(unsigned int irq) +{ +} -void disable_irq(unsigned int irq_nr) +void disable_irq(unsigned int irq) { unsigned long flags; spin_lock_irqsave(&irq_controller_lock, flags); -#ifdef cliIF - save_flags(flags); cliIF(); -#endif - mask_irq(irq_nr); + irq_desc[irq].enabled = 0; + irq_desc[irq].mask(irq); spin_unlock_irqrestore(&irq_controller_lock, flags); } -void enable_irq(unsigned int irq_nr) +void enable_irq(unsigned int irq) { unsigned long flags; spin_lock_irqsave(&irq_controller_lock, flags); -#ifdef cliIF - save_flags (flags); cliIF(); -#endif - unmask_irq(irq_nr); + irq_desc[irq].enabled = 1; + irq_desc[irq].probing = 0; + irq_desc[irq].triggered = 0; + irq_desc[irq].unmask(irq); spin_unlock_irqrestore(&irq_controller_lock, flags); } -struct irqaction *irq_action[NR_IRQS]; - int get_irq_list(char *buf) { int i; @@ -102,7 +108,7 @@ char *p = buf; for (i = 0 ; i < NR_IRQS ; i++) { - action = irq_action[i]; + action = irq_desc[i].action; if (!action) continue; p += sprintf(p, "%3d: %10u %s", @@ -112,8 +118,8 @@ } *p++ = '\n'; } - p += sprintf(p, "FIQ: %s\n", - current_fiq?current_fiq->name:"unused"); + + p += get_fiq_list(p); return p - buf; } @@ -122,26 +128,30 @@ */ asmlinkage void do_IRQ(int irq, struct pt_regs * regs) { + struct irqdesc * desc = irq_desc + irq; struct irqaction * action; int status, cpu; -#if defined(HAS_IOMD) || defined(HAS_IOC) - if (irq != IRQ_EXPANSIONCARD) -#endif - { - spin_lock(&irq_controller_lock); - mask_and_ack_irq(irq); - spin_unlock(&irq_controller_lock); - } + spin_lock(&irq_controller_lock); + desc->mask_ack(irq); + spin_unlock(&irq_controller_lock); cpu = smp_processor_id(); irq_enter(cpu, irq); kstat.irqs[cpu][irq]++; + desc->triggered = 1; /* Return with this interrupt masked if no action */ status = 0; - action = *(irq + irq_action); + action = desc->action; + if (action) { + if (desc->nomask) { + spin_lock(&irq_controller_lock); + desc->unmask(irq); + spin_unlock(&irq_controller_lock); + } + if (!(action->flags & SA_INTERRUPT)) __sti(); @@ -150,33 +160,20 @@ action->handler(irq, action->dev_id, regs); action = action->next; } while (action); + if (status & SA_SAMPLE_RANDOM) add_interrupt_randomness(irq); __cli(); - switch (irq) { -#if defined(HAS_IOMD) || defined(HAS_IOC) - case IRQ_KEYBOARDTX: - case IRQ_EXPANSIONCARD: - break; -#endif -#ifdef HAS_IOMD - case IRQ_DMA0: - case IRQ_DMA1: - case IRQ_DMA2: - case IRQ_DMA3: - break; -#endif - - default: + if (!desc->nomask && desc->enabled) { spin_lock(&irq_controller_lock); - unmask_irq(irq); + desc->unmask(irq); spin_unlock(&irq_controller_lock); - break; } } irq_exit(cpu, irq); + /* * This should be conditional: we should really get * a return code from the irq handler to tell us @@ -197,9 +194,18 @@ #if defined(CONFIG_ARCH_ACORN) void do_ecard_IRQ(int irq, struct pt_regs *regs) { + struct irqdesc * desc; struct irqaction * action; + int cpu; + + desc = irq_desc + irq; + + cpu = smp_processor_id(); + kstat.irqs[cpu][irq]++; + desc->triggered = 1; + + action = desc->action; - action = *(irq + irq_action); if (action) { do { action->handler(irq, action->dev_id, regs); @@ -207,7 +213,7 @@ } while (action); } else { spin_lock(&irq_controller_lock); - mask_irq (irq); + desc->mask(irq); spin_unlock(&irq_controller_lock); } } @@ -219,11 +225,18 @@ struct irqaction *old, **p; unsigned long flags; - p = irq_action + irq; + if (new->flags & SA_SAMPLE_RANDOM) + rand_initialize_irq(irq); + + spin_lock_irqsave(&irq_controller_lock, flags); + + p = &irq_desc[irq].action; if ((old = *p) != NULL) { /* Can't share interrupts unless both agree to */ - if (!(old->flags & new->flags & SA_SHIRQ)) + if (!(old->flags & new->flags & SA_SHIRQ)) { + spin_unlock_irqrestore(&irq_controller_lock, flags); return -EBUSY; + } /* add new interrupt at end of irq queue */ do { @@ -233,18 +246,16 @@ shared = 1; } - if (new->flags & SA_SAMPLE_RANDOM) - rand_initialize_irq(irq); - - save_flags_cli(flags); *p = new; if (!shared) { - spin_lock(&irq_controller_lock); - unmask_irq(irq); - spin_unlock(&irq_controller_lock); + irq_desc[irq].nomask = (new->flags & SA_IRQNOMASK) ? 1 : 0; + irq_desc[irq].enabled = 1; + irq_desc[irq].probing = 0; + irq_desc[irq].unmask(irq); } - restore_flags(flags); + + spin_unlock_irqrestore(&irq_controller_lock, flags); return 0; } @@ -257,8 +268,8 @@ { unsigned long retval; struct irqaction *action; - - if (!valid_irq(irq)) + + if (!irq_desc[irq].valid) return -EINVAL; if (!handler) return -EINVAL; @@ -286,14 +297,14 @@ struct irqaction * action, **p; unsigned long flags; - if (!valid_irq(irq)) { + if (!irq_desc[irq].valid) { printk(KERN_ERR "Trying to free IRQ%d\n",irq); #ifdef CONFIG_DEBUG_ERRORS __backtrace(); #endif return; } - for (p = irq + irq_action; (action = *p) != NULL; p = &action->next) { + for (p = &irq_desc[irq].action; (action = *p) != NULL; p = &action->next) { if (action->dev_id != dev_id) continue; @@ -310,75 +321,109 @@ #endif } -unsigned long probe_irq_on (void) +/* Start the interrupt probing. Unlike other architectures, + * we don't return a mask of interrupts from probe_irq_on, + * but return the number of interrupts enabled for the probe. + * The interrupts which have been enabled for probing is + * instead recorded in the irq_desc structure. + */ +unsigned long probe_irq_on(void) { unsigned int i, irqs = 0; unsigned long delay; - /* first snaffle up any unassigned irqs */ - for (i = 15; i > 0; i--) { - if (!irq_action[i] && valid_irq(i)) { - enable_irq(i); - irqs |= 1 << i; - } + /* + * first snaffle up any unassigned but + * probe-able interrupts + */ + spin_lock_irq(&irq_controller_lock); + for (i = 0; i < NR_IRQS; i++) { + if (!irq_desc[i].valid || + !irq_desc[i].probe_ok || + irq_desc[i].action) + continue; + + irq_desc[i].probing = 1; + irq_desc[i].enabled = 1; + irq_desc[i].triggered = 0; + irq_desc[i].unmask(i); + irqs += 1; } + spin_unlock_irq(&irq_controller_lock); - /* wait for spurious interrupts to mask themselves out again */ + /* + * wait for spurious interrupts to mask themselves out again + */ for (delay = jiffies + HZ/10; delay > jiffies; ) /* min 100ms delay */; + /* + * now filter out any obviously spurious interrupts + */ + spin_lock_irq(&irq_controller_lock); + for (i = 0; i < NR_IRQS; i++) { + if (irq_desc[i].probing && irq_desc[i].triggered) { + irq_desc[i].probing = 0; + irqs -= 1; + } + } + spin_unlock_irq(&irq_controller_lock); + /* now filter out any obviously spurious interrupts */ - return irqs & get_enabled_irqs(); + return irqs; } -int probe_irq_off (unsigned long irqs) +/* + * Possible return values: + * >= 0 - interrupt number + * -1 - no interrupt/many interrupts + */ +int probe_irq_off(unsigned long irqs) { unsigned int i; + int irq_found = -1; - irqs &= ~get_enabled_irqs(); - if (!irqs) - return 0; - i = ffz (~irqs); - if (irqs != (irqs & (1 << i))) - i = -i; - return i; -} - -int claim_fiq(struct fiq_handler *f) -{ - if (current_fiq) { - if (current_fiq->callback == NULL || (*current_fiq->callback)()) - return -EBUSY; - } - current_fiq = f; - return 0; -} - -void release_fiq(struct fiq_handler *f) -{ - if (current_fiq != f) { - printk(KERN_ERR "%s tried to release FIQ when not owner!\n", - f->name); -#ifdef CONFIG_DEBUG_ERRORS - __backtrace(); -#endif - return; + /* + * look at the interrupts, and find exactly one + * that we were probing has been triggered + */ + spin_lock_irq(&irq_controller_lock); + for (i = 0; i < NR_IRQS; i++) { + if (irq_desc[i].probing && + irq_desc[i].triggered) { + if (irq_found != -1) { + irq_found = NO_IRQ; + goto out; + } + irq_found = i; + } } - current_fiq = NULL; - *FIQ_VECTOR = no_fiq_insn; - __flush_entry_to_ram(FIQ_VECTOR); + if (irq_found == -1) + irq_found = NO_IRQ; +out: + spin_unlock_irq(&irq_controller_lock); + return irq_found; } +/* + * Get architecture specific interrupt handlers + * and interrupt initialisation. + */ +#include + __initfunc(void init_IRQ(void)) { extern void init_dma(void); + int irq; - irq_init_irq(); - - current_fiq = NULL; - no_fiq_insn = *FIQ_VECTOR; + for (irq = 0; irq < NR_IRQS; irq++) { + irq_desc[irq].mask_ack = dummy_mask_unmask_irq; + irq_desc[irq].mask = dummy_mask_unmask_irq; + irq_desc[irq].unmask = dummy_mask_unmask_irq; + } + irq_init_irq(); + init_FIQ(); init_dma(); } - diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/leds-ebsa110.c linux/arch/arm/kernel/leds-ebsa110.c --- v2.1.120/linux/arch/arm/kernel/leds-ebsa110.c Wed Dec 31 16:00:00 1969 +++ linux/arch/arm/kernel/leds-ebsa110.c Sun Sep 6 10:44:47 1998 @@ -0,0 +1,30 @@ +/* + * arch/arm/kernel/leds-ebsa110.c + * + * Copyright (C) 1998 Russell King + * + * EBSA-110 LED control routines. We use the led as follows: + * + * - Red - toggles state every 50 timer interrupts + */ +#include +#include +#include + +void leds_event(led_event_t ledevt) +{ + unsigned long flags; + + save_flags_cli(flags); + + switch(ledevt) { + case led_timer: + *(volatile unsigned char *)0xf2400000 ^= 128; + break; + + default: + break; + } + + restore_flags(flags); +} diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/leds-ebsa285.c linux/arch/arm/kernel/leds-ebsa285.c --- v2.1.120/linux/arch/arm/kernel/leds-ebsa285.c Tue Apr 14 14:29:19 1998 +++ linux/arch/arm/kernel/leds-ebsa285.c Sun Sep 6 10:44:47 1998 @@ -1,5 +1,5 @@ /* - * arch/arm/kernel/leds-285.c + * arch/arm/kernel/leds-ebsa285.c * * Copyright (C) 1998 Russell King * diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/process.c linux/arch/arm/kernel/process.c --- v2.1.120/linux/arch/arm/kernel/process.c Thu Aug 6 14:06:28 1998 +++ linux/arch/arm/kernel/process.c Sun Sep 6 10:44:47 1998 @@ -38,9 +38,6 @@ #include #include -struct task_struct *last_task_used_math; - -extern void fpe_save(struct fp_soft_struct *); extern char *processor_modes[]; asmlinkage void ret_from_sys_call(void) __asm__("ret_from_sys_call"); @@ -108,7 +105,6 @@ { } - void show_regs(struct pt_regs * regs) { unsigned long flags; @@ -158,18 +154,14 @@ */ void exit_thread(void) { - if (last_task_used_math == current) - last_task_used_math = NULL; } void flush_thread(void) { int i; - for (i = 0; i < 8; i++) - current->debugreg[i] = 0; - if (last_task_used_math == current) - last_task_used_math = NULL; + for (i = 0; i < NR_DEBUGS; i++) + current->tss.debug[i] = 0; current->used_math = 0; current->flags &= ~PF_USEDFPU; } @@ -189,13 +181,8 @@ childregs->ARM_r0 = 0; save = ((struct context_save_struct *)(childregs)) - 1; - copy_thread_css (save); + copy_thread_css(save); p->tss.save = save; - /* - * Save current math state in p->tss.fpe_save if not already there. - */ - if (last_task_used_math == current) - fpe_save (&p->tss.fpstate.soft); return 0; } @@ -207,12 +194,8 @@ { int fpvalid = 0; - if (current->used_math) { - if (last_task_used_math == current) - fpe_save (¤t->tss.fpstate.soft); - + if (current->used_math) memcpy (fp, ¤t->tss.fpstate.soft, sizeof (fp)); - } return fpvalid; } @@ -232,8 +215,8 @@ dump->u_dsize = (current->mm->brk - current->mm->start_data + PAGE_SIZE - 1) >> PAGE_SHIFT; dump->u_ssize = 0; - for (i = 0; i < 8; i++) - dump->u_debugreg[i] = current->debugreg[i]; + for (i = 0; i < NR_DEBUGS; i++) + dump->u_debugreg[i] = current->tss.debug[i]; if (dump->start_stack < 0x04000000) dump->u_ssize = (0x04000000 - dump->start_stack) >> PAGE_SHIFT; diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/ptrace.c linux/arch/arm/kernel/ptrace.c --- v2.1.120/linux/arch/arm/kernel/ptrace.c Thu May 7 22:51:46 1998 +++ linux/arch/arm/kernel/ptrace.c Sun Sep 6 10:44:47 1998 @@ -376,7 +376,7 @@ if (res < 0) return res; - child->debugreg[nsaved++] = alt = pc + 4; + child->tss.debug[nsaved++] = alt = pc + 4; printk ("ptrace_set_bpt: insn=%08lX pc=%08lX ", insn, pc); switch (insn & 0x0e100000) { case 0x00000000: @@ -515,20 +515,20 @@ } printk ("=%08lX\n", alt); if (alt != pc + 4) - child->debugreg[nsaved++] = alt; + child->tss.debug[nsaved++] = alt; for (i = 0; i < nsaved; i++) { - res = read_long (child, child->debugreg[i], &insn); + res = read_long (child, child->tss.debug[i], &insn); if (res >= 0) { - child->debugreg[i + 2] = insn; - res = write_long (child, child->debugreg[i], BREAKINST); + child->tss.debug[i + 2] = insn; + res = write_long (child, child->tss.debug[i], BREAKINST); } if (res < 0) { - child->debugreg[4] = 0; + child->tss.debug[4] = 0; return res; } } - child->debugreg[4] = nsaved; + child->tss.debug[4] = nsaved; return 0; } @@ -537,16 +537,16 @@ */ int ptrace_cancel_bpt (struct task_struct *child) { - int i, nsaved = child->debugreg[4]; + int i, nsaved = child->tss.debug[4]; - child->debugreg[4] = 0; + child->tss.debug[4] = 0; if (nsaved > 2) { printk ("ptrace_cancel_bpt: bogus nsaved: %d!\n", nsaved); nsaved = 2; } for (i = 0; i < nsaved; i++) - write_long (child, child->debugreg[i], child->debugreg[i + 2]); + write_long (child, child->tss.debug[i], child->tss.debug[i + 2]); return nsaved != 0; } @@ -680,7 +680,7 @@ ret = -EIO; if ((unsigned long) data > _NSIG) goto out; - child->debugreg[4] = -1; + child->tss.debug[4] = -1; child->flags &= ~PF_TRACESYS; wake_up_process(child); child->exit_code = data; diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/setup-ebsa110.c linux/arch/arm/kernel/setup-ebsa110.c --- v2.1.120/linux/arch/arm/kernel/setup-ebsa110.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/setup-ebsa110.c Wed Dec 31 16:00:00 1969 @@ -1,191 +0,0 @@ -/* - * linux/arch/arm/kernel/setup-sa.c - * - * Copyright (C) 1995, 1996 Russell King - */ - -/* - * This file obtains various parameters about the system that the kernel - * is running on. - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#ifndef CONFIG_CMDLINE -#define CONFIG_CMDLINE "root=nfs rw console=ttyS1,38400n8" -#endif -#define COMMAND_LINE_SIZE 256 - -#define MEM_SIZE (16*1024*1024) - -struct screen_info screen_info; -struct processor processor; -unsigned char aux_device_present; - -extern const struct processor sa110_processor_functions; - -struct armversions armidlist[] = { - { 0x4401a100, 0xfffffff0, F_MMU|F_32BIT , "DEC", "sa110" , &sa110_processor_functions , "sa1x"}, - { 0x00000000, 0x00000000, 0 , "***", "*unknown*" , NULL , NULL } -}; - -unsigned long arm_id; -int armidindex; - -extern int root_mountflags; -extern int _etext, _edata, _end; - -static char command_line[COMMAND_LINE_SIZE] __initdata = { 0, }; - char saved_command_line[COMMAND_LINE_SIZE]; - -#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 */ - -static inline void setup_ramdisk(int start, int prompt, int load) -{ - rd_image_start = start; - rd_prompt = prompt; - rd_doload = load; -} -#else -#define setup_ramdisk(start,prompt,load) -#endif - -#ifdef PARAMS_BASE -static struct param_struct *params = (struct param_struct *)PARAMS_BASE; - -static inline char *setup_params(unsigned long *mem_end_p) -{ - ROOT_DEV = to_kdev_t(params->u1.s.rootdev); - ORIG_X = params->u1.s.video_x; - ORIG_Y = params->u1.s.video_y; - ORIG_VIDEO_COLS = params->u1.s.video_num_cols; - ORIG_VIDEO_LINES = params->u1.s.video_num_rows; - - setup_ramdisk(params->u1.s.rd_start, - (params->u1.s.flags & FLAG_RDPROMPT) == 0, - (params->u1.s.flags & FLAG_RDLOAD) == 0); - - *mem_end_p = 0xc0000000 + MEM_SIZE; - - return params->commandline; -} -#else -static char default_command_line[] = CONFIG_CMDLINE; - -static inline char *setup_params(unsigned long *mem_end_p) -{ - ROOT_DEV = 0x00ff; - - setup_ramdisk(0, 1, 1); - - *mem_end_p = 0xc0000000 + MEM_SIZE; - - return default_command_line; -} -#endif - -__initfunc(void setup_arch(char **cmdline_p, - unsigned long * memory_start_p, unsigned long * memory_end_p)) -{ - unsigned long memory_start, memory_end; - char c = ' ', *to = command_line, *from; - int len = 0; - - memory_start = (unsigned long)&_end; - - armidindex = 0; - - processor = sa110_processor_functions; - processor._proc_init(); - - from = setup_params(&memory_end); - - init_task.mm->start_code = TASK_SIZE; - init_task.mm->end_code = TASK_SIZE + (unsigned long) &_etext; - init_task.mm->end_data = TASK_SIZE + (unsigned long) &_edata; - init_task.mm->brk = TASK_SIZE + (unsigned long) &_end; - - /* Save unparsed command line copy for /proc/cmdline */ - memcpy(saved_command_line, from, COMMAND_LINE_SIZE); - saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; - - for (;;) { - if (c == ' ' && - from[0] == 'm' && - from[1] == 'e' && - from[2] == 'm' && - from[3] == '=') { - memory_end = simple_strtoul(from+4, &from, 0); - if ( *from == 'K' || *from == 'k' ) { - memory_end = memory_end << 10; - from++; - } else if ( *from == 'M' || *from == 'm' ) { - memory_end = memory_end << 20; - from++; - } - memory_end = memory_end + PAGE_OFFSET; - } - c = *from++; - if (!c) - break; - if (COMMAND_LINE_SIZE <= ++len) - break; - *to++ = c; - } - - *to = '\0'; - *cmdline_p = command_line; - *memory_start_p = memory_start; - *memory_end_p = memory_end; - strcpy (system_utsname.machine, "sa110"); - -#ifdef CONFIG_FB - conswitchp = &fb_con; -#endif -} - -int get_cpuinfo(char * buffer) -{ - int len; - - len = sprintf (buffer, "CPU:\n" - "Type\t\t: %s\n" - "Revision\t: %d\n" - "Manufacturer\t: %s\n" - "32bit modes\t: %s\n" - "BogoMips\t: %lu.%02lu\n", - "sa110", - (int)arm_id & 15, - "DEC", - "yes", - (loops_per_sec+2500) / 500000, - ((loops_per_sec+2500) / 5000) % 100); - return len; -} diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/setup.c linux/arch/arm/kernel/setup.c --- v2.1.120/linux/arch/arm/kernel/setup.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/setup.c Sun Sep 6 10:44:47 1998 @@ -1,7 +1,7 @@ /* * linux/arch/arm/kernel/setup.c * - * Copyright (C) 1995, 1996, 1997 Russell King + * Copyright (C) 1995-1998 Russell King */ /* @@ -37,11 +37,37 @@ #include #include #include -#include + +/* Work out which CPUs to support */ +#ifdef CONFIG_ARCH_ACORN +#define SUPPORT_CPU_ARM6 +#define SUPPORT_CPU_ARM7 +#define SUPPORT_CPU_SA110 +#else +#define SUPPORT_CPU_SA110 +#endif +#ifdef CONFIG_CPU_ARM6 +#define SUPPORT_CPU_ARM6 +#endif +#ifdef CONFIG_CPU_ARM7 +#define SUPPORT_CPU_ARM7 +#endif +#ifdef CONFIG_CPU_SA110 +#define SUPPORT_CPU_SA110 +#endif + +#ifndef CONFIG_CMDLINE +#define CONFIG_CMDLINE "root=nfs rw console=ttyS1,38400n8" +#endif +#define MEM_SIZE (16*1024*1024) +#define COMMAND_LINE_SIZE 256 struct drive_info_struct { char dummy[32]; } drive_info; struct screen_info screen_info = { - 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 8 + orig_video_mode: 0, + orig_video_ega_bx: 0, + orig_video_isVGA: 1, + orig_video_points: 8 }; struct processor processor; unsigned char aux_device_present; @@ -66,35 +92,36 @@ { 0x41560300, 0xfffffff0, "ARM/VLSI", "arm3" , "armv2" , "v2", HWCAP_SWP, &arm3_processor_functions }, #elif defined(CONFIG_CPU_32) +#ifdef SUPPORT_CPU_ARM6 { 0x41560600, 0xfffffff0, "ARM/VLSI", "arm6" , "armv3" , "v3", HWCAP_SWP, &arm6_processor_functions }, { 0x41560610, 0xfffffff0, "ARM/VLSI", "arm610" , "armv3" , "v3", HWCAP_SWP, &arm6_processor_functions }, +#endif +#ifdef SUPPORT_CPU_ARM7 { 0x41007000, 0xffffff00, "ARM/VLSI", "arm7" , "armv3" , "v3", HWCAP_SWP, &arm7_processor_functions }, /* ARM710 IDs are non-standard */ { 0x41007100, 0xfff8ff00, "ARM/VLSI", "arm710" , "armv3" , "v3", HWCAP_SWP, &arm7_processor_functions }, +#endif +#ifdef SUPPORT_CPU_SA110 { 0x4401a100, 0xfffffff0, "DEC", "sa110" , "armv4" , "v3", HWCAP_SWP|HWCAP_HALF, &sa110_processor_functions }, #endif +#endif { 0x00000000, 0x00000000, "***", "unknown", "unknown", "**", 0, NULL } }; -static const struct param_struct *params = (struct param_struct *)PARAMS_BASE; - -unsigned long arm_id; -unsigned int vram_half_sam; +/* + * From head-armv.S + */ +unsigned int processor_id; +unsigned int machine_type; int armidindex; -int memc_ctrl_reg; -int number_ide_drives; -int number_mfm_drives; -extern int bytes_per_char_h; -extern int bytes_per_char_v; extern int root_mountflags; extern int _etext, _edata, _end; -extern unsigned long real_end_mem; /*------------------------------------------------------------------------- * Early initialisation routines for various configurable items in the @@ -107,12 +134,15 @@ */ #ifdef CONFIG_ARCH_RPC -extern void -init_dram_banks(const struct param_struct *params); +#include + +unsigned int vram_half_sam; static void -setup_rpc(const struct param_struct *params) +setup_rpc(struct param_struct *params) { + extern void init_dram_banks(const struct param_struct *params); + init_dram_banks(params); switch (params->u1.s.pages_in_vram) { @@ -123,41 +153,103 @@ default: vram_half_sam = 2048; } - - /* - * Set ROM speed to maximum - */ - outb (0x1d, IOMD_ROMCR0); } #else #define setup_rpc(x) #endif -/* - * ram disk - */ -#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 */ +#ifdef PARAMS_BASE -static void -setup_ramdisk(const struct param_struct *params) +#ifdef CONFIG_ARCH_ACORN +int memc_ctrl_reg; +int number_ide_drives; +int number_mfm_drives; +#endif + +static struct param_struct *params = (struct param_struct *)PARAMS_BASE; + +__initfunc(static char * +setup_params(unsigned long *mem_end_p)) { - rd_image_start = params->u1.s.rd_start; - rd_prompt = (params->u1.s.flags & FLAG_RDPROMPT) == 0; - rd_doload = (params->u1.s.flags & FLAG_RDLOAD) == 0; + ROOT_DEV = to_kdev_t(params->u1.s.rootdev); + ORIG_X = params->u1.s.video_x; + ORIG_Y = params->u1.s.video_y; + ORIG_VIDEO_COLS = params->u1.s.video_num_cols; + ORIG_VIDEO_LINES = params->u1.s.video_num_rows; + +#ifdef CONFIG_ARCH_ACORN +#ifndef CONFIG_FB + { + extern int bytes_per_char_h; + extern int bytes_per_char_v; + + bytes_per_char_h = params->u1.s.bytes_per_char_h; + bytes_per_char_v = params->u1.s.bytes_per_char_v; + } +#endif + memc_ctrl_reg = params->u1.s.memc_control_reg; + number_ide_drives = (params->u1.s.adfsdrives >> 6) & 3; + number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3; + + setup_rpc(params); + + if (!(params->u1.s.flags & FLAG_READONLY)) + root_mountflags &= ~MS_RDONLY; +#endif +#ifdef CONFIG_BLK_DEV_RAM + { + extern int rd_doload; + extern int rd_prompt; + extern int rd_image_start; + + rd_image_start = params->u1.s.rd_start; + rd_prompt = (params->u1.s.flags & FLAG_RDPROMPT) == 0; + rd_doload = (params->u1.s.flags & FLAG_RDLOAD) == 0; + } +#endif + +#ifdef CONFIG_ARCH_ACORN + *mem_end_p = GET_MEMORY_END(params); +#else + *mem_end_p = PAGE_OFFSET + MEM_SIZE; +#endif + + return params->commandline; } + #else -#define setup_ramdisk(p) + +static char default_command_line[] __initdata = CONFIG_CMDLINE; + +__initfunc(static char * +setup_params(unsigned long *mem_end_p)) +{ + ROOT_DEV = 0x00ff; + +#ifdef CONFIG_BLK_DEV_RAM + { + extern int rd_doload; + extern int rd_prompt; + extern int rd_image_start; + + rd_image_start = 0; + rd_prompt = 1; + rd_doload = 1; + } +#endif + + *mem_end_p = PAGE_OFFSET + MEM_SIZE; + + return default_command_line; +} #endif /* * initial ram disk */ #ifdef CONFIG_BLK_DEV_INITRD -static void -setup_initrd(const struct param_struct *params, unsigned long memory_end) +__initfunc(static void +setup_initrd(const struct param_struct *params)) { if (params->u1.s.initrd_start) { initrd_start = params->u1.s.initrd_start; @@ -166,130 +258,130 @@ initrd_start = 0; initrd_end = 0; } +} - if (initrd_end > memory_end) { +__initfunc(static void +check_initrd(unsigned long mem_start, unsigned long mem_end)) +{ + if (initrd_end > mem_end) { printk ("initrd extends beyond end of memory " "(0x%08lx > 0x%08lx) - disabling initrd\n", - initrd_end, memory_end); + initrd_end, mem_end); initrd_start = 0; } } + #else -#define setup_initrd(p,m) +#define setup_initrd(p) +#define check_initrd(ms,me) #endif -static inline void -get_processor_type(void) +__initfunc(void +setup_processor(void)) { - for (armidindex = 0; ; armidindex ++) - if (!((armidlist[armidindex].id ^ arm_id) & - armidlist[armidindex].mask)) - break; + armidindex = 0; + + while ((armidlist[armidindex].id ^ processor_id) & + armidlist[armidindex].mask) + armidindex += 1; if (armidlist[armidindex].id == 0) { +#ifdef CONFIG_ARCH_ACORN int i; for (i = 0; i < 3200; i++) ((unsigned long *)SCREEN2_BASE)[i] = 0x77113322; - +#endif while (1); } + processor = *armidlist[armidindex].proc; + processor._proc_init(); } -#define COMMAND_LINE_SIZE 256 - -/* Can this be initdata? --pb - * command_line can be, saved_command_line can't though - */ -static char command_line[COMMAND_LINE_SIZE] __initdata = { 0, }; +static char command_line[COMMAND_LINE_SIZE] = { 0, }; char saved_command_line[COMMAND_LINE_SIZE]; -__initfunc(void setup_arch(char **cmdline_p, - unsigned long * memory_start_p, unsigned long * memory_end_p)) +__initfunc(static void +setup_mem(char *cmd_line, unsigned long *mem_start, unsigned long *mem_end)) +{ + char c = ' ', *to = command_line; + int len = 0; + + *mem_start = (unsigned long)&_end; + + for (;;) { + if (c == ' ' && + cmd_line[0] == 'm' && + cmd_line[1] == 'e' && + cmd_line[2] == 'm' && + cmd_line[3] == '=') { + *mem_end = simple_strtoul(cmd_line+4, &cmd_line, 0); + switch(*cmd_line) { + case 'M': + case 'm': + *mem_end <<= 10; + case 'K': + case 'k': + *mem_end <<= 10; + cmd_line++; + } + *mem_end = *mem_end + PAGE_OFFSET; + } + c = *cmd_line++; + if (!c) + break; + if (COMMAND_LINE_SIZE <= ++len) + break; + *to++ = c; + } + + *to = '\0'; +} + +__initfunc(void +setup_arch(char **cmdline_p, unsigned long * memory_start_p, unsigned long * memory_end_p)) { static unsigned char smptrap; - unsigned long memory_start, memory_end; - char endian = 'l', c = ' ', *to = command_line; + unsigned long memory_end; + char endian = 'l'; char *from; - int len = 0; if (smptrap == 1) return; smptrap = 1; - get_processor_type (); - processor._proc_init (); + setup_processor(); -#ifndef CONFIG_FB - bytes_per_char_h = params->u1.s.bytes_per_char_h; - bytes_per_char_v = params->u1.s.bytes_per_char_v; -#endif - from = (char *)params->commandline; - ROOT_DEV = to_kdev_t (params->u1.s.rootdev); - ORIG_X = params->u1.s.video_x; - ORIG_Y = params->u1.s.video_y; - ORIG_VIDEO_COLS = params->u1.s.video_num_cols; - ORIG_VIDEO_LINES = params->u1.s.video_num_rows; - memc_ctrl_reg = params->u1.s.memc_control_reg; - number_ide_drives = (params->u1.s.adfsdrives >> 6) & 3; - number_mfm_drives = (params->u1.s.adfsdrives >> 3) & 3; + from = setup_params(&memory_end); + setup_initrd(params); - setup_rpc(params); - setup_ramdisk(params); - - if (!(params->u1.s.flags & FLAG_READONLY)) - root_mountflags &= ~MS_RDONLY; + /* Save unparsed command line copy for /proc/cmdline */ + memcpy(saved_command_line, from, COMMAND_LINE_SIZE); + saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; - memory_start = MAPTOPHYS((unsigned long)&_end); - memory_end = GET_MEMORY_END(params); + setup_mem(from, memory_start_p, &memory_end); + check_initrd(*memory_start_p, memory_end); init_task.mm->start_code = TASK_SIZE; init_task.mm->end_code = TASK_SIZE + (unsigned long) &_etext; init_task.mm->end_data = TASK_SIZE + (unsigned long) &_edata; init_task.mm->brk = TASK_SIZE + (unsigned long) &_end; - /* Save unparsed command line copy for /proc/cmdline */ - memcpy(saved_command_line, from, COMMAND_LINE_SIZE); - saved_command_line[COMMAND_LINE_SIZE-1] = '\0'; - - for (;;) { - if (c == ' ' && - from[0] == 'm' && - from[1] == 'e' && - from[2] == 'm' && - from[3] == '=') { - memory_end = simple_strtoul(from+4, &from, 0); - if (*from == 'K' || *from == 'k') { - memory_end = memory_end << 10; - from++; - } else if (*from == 'M' || *from == 'm') { - memory_end = memory_end << 20; - from++; - } - memory_end = memory_end + PAGE_OFFSET; - } - c = *from++; - if (!c) - break; - if (COMMAND_LINE_SIZE <= ++len) - break; - *to++ = c; - } - - *to = '\0'; *cmdline_p = command_line; - *memory_start_p = memory_start; *memory_end_p = memory_end; - setup_initrd(params, memory_end); - sprintf(system_utsname.machine, "%s%c", armidlist[armidindex].arch_vsn, endian); sprintf(elf_platform, "%s%c", armidlist[armidindex].elf_vsn, endian); -#ifdef CONFIG_FB - conswitchp = &fb_con; +#ifdef CONFIG_VT +#if defined(CONFIG_VGA_CONSOLE) + conswitchp = &vga_con; +#elif defined(CONFIG_DUMMY_CONSOLE) + conswitchp = &dummy_con; +#endif #endif +printascii("setup_arch done\n"); } #if defined(CONFIG_ARCH_ARC) @@ -341,10 +433,10 @@ "BogoMips\t: %lu.%02lu\n" "Hardware\t: %s\n" "Optimisation\t: %s\n" - "IO Bus\t: %s\n", + "IO Bus\t\t: %s\n", armidlist[armidindex].manu, armidlist[armidindex].name, - (int)arm_id & 15, + (int)processor_id & 15, (loops_per_sec+2500) / 500000, ((loops_per_sec+2500) / 5000) % 100, HARDWARE, diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/signal.c linux/arch/arm/kernel/signal.c --- v2.1.120/linux/arch/arm/kernel/signal.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/signal.c Sun Sep 6 10:44:47 1998 @@ -21,6 +21,17 @@ #include #include +void checksignals(void) +{ + sigset_t *blocked = ¤t->blocked; + unsigned long mask = blocked->sig[0] | sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT); + mask &= blocked->sig[1]; + if (~mask) { + printk("Bad signal mask\n"); + __backtrace(); + } +} + #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) #define SWI_SYS_SIGRETURN (0xef000000|(__NR_sigreturn)) @@ -137,31 +148,35 @@ static int restore_sigcontext(struct pt_regs *regs, struct sigcontext *sc) { - __get_user(regs->ARM_r0, &sc->arm_r0); - __get_user(regs->ARM_r1, &sc->arm_r1); - __get_user(regs->ARM_r2, &sc->arm_r2); - __get_user(regs->ARM_r3, &sc->arm_r3); - __get_user(regs->ARM_r4, &sc->arm_r4); - __get_user(regs->ARM_r5, &sc->arm_r5); - __get_user(regs->ARM_r6, &sc->arm_r6); - __get_user(regs->ARM_r7, &sc->arm_r7); - __get_user(regs->ARM_r8, &sc->arm_r8); - __get_user(regs->ARM_r9, &sc->arm_r9); - __get_user(regs->ARM_r10, &sc->arm_r10); - __get_user(regs->ARM_fp, &sc->arm_fp); - __get_user(regs->ARM_ip, &sc->arm_ip); - __get_user(regs->ARM_sp, &sc->arm_sp); - __get_user(regs->ARM_lr, &sc->arm_lr); - __get_user(regs->ARM_pc, &sc->arm_pc); /* security! */ + int err = 0; + + err |= __get_user(regs->ARM_r0, &sc->arm_r0); + err |= __get_user(regs->ARM_r1, &sc->arm_r1); + err |= __get_user(regs->ARM_r2, &sc->arm_r2); + err |= __get_user(regs->ARM_r3, &sc->arm_r3); + err |= __get_user(regs->ARM_r4, &sc->arm_r4); + err |= __get_user(regs->ARM_r5, &sc->arm_r5); + err |= __get_user(regs->ARM_r6, &sc->arm_r6); + err |= __get_user(regs->ARM_r7, &sc->arm_r7); + err |= __get_user(regs->ARM_r8, &sc->arm_r8); + err |= __get_user(regs->ARM_r9, &sc->arm_r9); + err |= __get_user(regs->ARM_r10, &sc->arm_r10); + err |= __get_user(regs->ARM_fp, &sc->arm_fp); + err |= __get_user(regs->ARM_ip, &sc->arm_ip); + err |= __get_user(regs->ARM_sp, &sc->arm_sp); + err |= __get_user(regs->ARM_lr, &sc->arm_lr); + err |= __get_user(regs->ARM_pc, &sc->arm_pc); #ifdef CONFIG_CPU_32 - __get_user(regs->ARM_cpsr, &sc->arm_cpsr); /* security! */ + err |= __get_user(regs->ARM_cpsr, &sc->arm_cpsr); #endif + if (!valid_user_regs(regs)) + return 1; /* send SIGTRAP if we're single-stepping */ if (ptrace_cancel_bpt (current)) send_sig (SIGTRAP, current, 1); - return regs->ARM_r0; + return err; } asmlinkage int sys_sigreturn(struct pt_regs *regs) @@ -185,11 +200,14 @@ recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - return restore_sigcontext(regs, &frame->sc); + if (restore_sigcontext(regs, &frame->sc)) + goto badframe; + + return regs->ARM_r0; badframe: - lock_kernel(); - do_exit(SIGSEGV); + force_sig(SIGSEGV, current); + return 0; } asmlinkage int sys_rt_sigreturn(struct pt_regs *regs) @@ -210,40 +228,47 @@ recalc_sigpending(current); spin_unlock_irq(¤t->sigmask_lock); - return restore_sigcontext(regs, &frame->uc.uc_mcontext); + if (restore_sigcontext(regs, &frame->uc.uc_mcontext)) + goto badframe; + + return regs->ARM_r0; badframe: - lock_kernel(); - do_exit(SIGSEGV); + force_sig(SIGSEGV, current); + return 0; } -static void +static int setup_sigcontext(struct sigcontext *sc, /*struct _fpstate *fpstate,*/ struct pt_regs *regs, unsigned long mask) { - __put_user (regs->ARM_r0, &sc->arm_r0); - __put_user (regs->ARM_r1, &sc->arm_r1); - __put_user (regs->ARM_r2, &sc->arm_r2); - __put_user (regs->ARM_r3, &sc->arm_r3); - __put_user (regs->ARM_r4, &sc->arm_r4); - __put_user (regs->ARM_r5, &sc->arm_r5); - __put_user (regs->ARM_r6, &sc->arm_r6); - __put_user (regs->ARM_r7, &sc->arm_r7); - __put_user (regs->ARM_r8, &sc->arm_r8); - __put_user (regs->ARM_r9, &sc->arm_r9); - __put_user (regs->ARM_r10, &sc->arm_r10); - __put_user (regs->ARM_fp, &sc->arm_fp); - __put_user (regs->ARM_ip, &sc->arm_ip); - __put_user (regs->ARM_sp, &sc->arm_sp); - __put_user (regs->ARM_lr, &sc->arm_lr); - __put_user (regs->ARM_pc, &sc->arm_pc); /* security! */ + int err = 0; + + err |= __put_user (regs->ARM_r0, &sc->arm_r0); + err |= __put_user (regs->ARM_r1, &sc->arm_r1); + err |= __put_user (regs->ARM_r2, &sc->arm_r2); + err |= __put_user (regs->ARM_r3, &sc->arm_r3); + err |= __put_user (regs->ARM_r4, &sc->arm_r4); + err |= __put_user (regs->ARM_r5, &sc->arm_r5); + err |= __put_user (regs->ARM_r6, &sc->arm_r6); + err |= __put_user (regs->ARM_r7, &sc->arm_r7); + err |= __put_user (regs->ARM_r8, &sc->arm_r8); + err |= __put_user (regs->ARM_r9, &sc->arm_r9); + err |= __put_user (regs->ARM_r10, &sc->arm_r10); + err |= __put_user (regs->ARM_fp, &sc->arm_fp); + err |= __put_user (regs->ARM_ip, &sc->arm_ip); + err |= __put_user (regs->ARM_sp, &sc->arm_sp); + err |= __put_user (regs->ARM_lr, &sc->arm_lr); + err |= __put_user (regs->ARM_pc, &sc->arm_pc); #ifdef CONFIG_CPU_32 - __put_user (regs->ARM_cpsr, &sc->arm_cpsr); /* security! */ + err |= __put_user (regs->ARM_cpsr, &sc->arm_cpsr); #endif - __put_user (current->tss.trap_no, &sc->trap_no); - __put_user (current->tss.error_code, &sc->error_code); - __put_user (mask, &sc->oldmask); + err |= __put_user (current->tss.trap_no, &sc->trap_no); + err |= __put_user (current->tss.error_code, &sc->error_code); + err |= __put_user (mask, &sc->oldmask); + + return err; } static void setup_frame(int sig, struct k_sigaction *ka, @@ -251,41 +276,47 @@ { struct sigframe *frame; unsigned long retcode; + int err = 0; frame = (struct sigframe *)regs->ARM_sp - 1; if (!access_ok(VERIFT_WRITE, frame, sizeof (*frame))) goto segv_and_exit; - setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]); + err |= setup_sigcontext(&frame->sc, /*&frame->fpstate,*/ regs, set->sig[0]); if (_NSIG_WORDS > 1) { - __copy_to_user(frame->extramask, &set->sig[1], - sizeof(frame->extramask)); + err |= __copy_to_user(frame->extramask, &set->sig[1], + sizeof(frame->extramask)); } /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - retcode = (unsigned long)ka->sa.sa_restorer; /* security! */ + retcode = (unsigned long)ka->sa.sa_restorer; } else { retcode = (unsigned long)&frame->retcode; - __put_user(SWI_SYS_SIGRETURN, &frame->retcode); + err |= __put_user(SWI_SYS_SIGRETURN, &frame->retcode); __flush_entry_to_ram (&frame->retcode); } + if (err) + goto segv_and_exit; + if (current->exec_domain && current->exec_domain->signal_invmap && sig < 32) regs->ARM_r0 = current->exec_domain->signal_invmap[sig]; else regs->ARM_r0 = sig; regs->ARM_sp = (unsigned long)frame; regs->ARM_lr = retcode; - regs->ARM_pc = (unsigned long)ka->sa.sa_handler; /* security! */ - return; + regs->ARM_pc = (unsigned long)ka->sa.sa_handler; + if (valid_user_regs(regs)) + return; segv_and_exit: - lock_kernel(); - do_exit (SIGSEGV); + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); } static void setup_rt_frame(int sig, struct k_sigaction *ka, siginfo_t *info, @@ -293,44 +324,50 @@ { struct rt_sigframe *frame; unsigned long retcode; + int err = 0; frame = (struct rt_sigframe *)regs->ARM_sp - 1; if (!access_ok(VERIFY_WRITE, frame, sizeof (*frame))) goto segv_and_exit; - __put_user(&frame->info, &frame->pinfo); - __put_user(&frame->uc, &frame->puc); - __copy_to_user(&frame->info, info, sizeof(*info)); + err |= __put_user(&frame->info, &frame->pinfo); + err |= __put_user(&frame->uc, &frame->puc); + err |= __copy_to_user(&frame->info, info, sizeof(*info)); /* Clear all the bits of the ucontext we don't use. */ - __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); + err |= __clear_user(&frame->uc, offsetof(struct ucontext, uc_mcontext)); - setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/ - regs, set->sig[0]); - __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); + err |= setup_sigcontext(&frame->uc.uc_mcontext, /*&frame->fpstate,*/ + regs, set->sig[0]); + err |= __copy_to_user(&frame->uc.uc_sigmask, set, sizeof(*set)); /* Set up to return from userspace. If provided, use a stub already in userspace. */ if (ka->sa.sa_flags & SA_RESTORER) { - retcode = (unsigned long)ka->sa.sa_restorer; /* security! */ + retcode = (unsigned long)ka->sa.sa_restorer; } else { retcode = (unsigned long)&frame->retcode; - __put_user(SWI_SYS_RT_SIGRETURN, &frame->retcode); + err |= __put_user(SWI_SYS_RT_SIGRETURN, &frame->retcode); __flush_entry_to_ram (&frame->retcode); } + if (err) + goto segv_and_exit; + if (current->exec_domain && current->exec_domain->signal_invmap && sig < 32) regs->ARM_r0 = current->exec_domain->signal_invmap[sig]; else regs->ARM_r0 = sig; regs->ARM_sp = (unsigned long)frame; regs->ARM_lr = retcode; - regs->ARM_pc = (unsigned long)ka->sa.sa_handler; /* security! */ - return; + regs->ARM_pc = (unsigned long)ka->sa.sa_handler; + if (valid_user_regs(regs)) + return; segv_and_exit: - lock_kernel(); - do_exit (SIGSEGV); + if (sig == SIGSEGV) + ka->sa.sa_handler = SIG_DFL; + force_sig(SIGSEGV, current); } /* diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/sys_arm.c linux/arch/arm/kernel/sys_arm.c --- v2.1.120/linux/arch/arm/kernel/sys_arm.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/sys_arm.c Sun Sep 6 10:44:47 1998 @@ -363,14 +363,6 @@ asmlinkage int sys_pause(void) { - static int warned = 0; - - if (warned == 0) { - warned ++; - printk (KERN_NOTICE "%s (%d): obsolete pause call\n", - current->comm, current->pid); - } - current->state = TASK_INTERRUPTIBLE; schedule(); return -ERESTARTNOHAND; diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/time.c linux/arch/arm/kernel/time.c --- v2.1.120/linux/arch/arm/kernel/time.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/time.c Sun Sep 6 10:44:47 1998 @@ -62,7 +62,7 @@ * machines were long is 32-bit! (However, as time_t is signed, we * will already get problems at other places on 2038-01-19 03:14:08) */ -static inline unsigned long mktime(unsigned int year, unsigned int mon, +unsigned long mktime(unsigned int year, unsigned int mon, unsigned int day, unsigned int hour, unsigned int min, unsigned int sec) { diff -u --recursive --new-file v2.1.120/linux/arch/arm/kernel/traps.c linux/arch/arm/kernel/traps.c --- v2.1.120/linux/arch/arm/kernel/traps.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/kernel/traps.c Sun Sep 6 10:44:47 1998 @@ -24,9 +24,6 @@ #include #include -extern struct task_struct *last_task_used_math; -extern void fpe_save(struct fp_soft_struct *); -extern void fpe_restore(struct fp_soft_struct *); extern void die_if_kernel(char *str, struct pt_regs *regs, int err, int ret); extern void c_backtrace (unsigned long fp, int pmode); extern int ptrace_cancel_bpt (struct task_struct *); @@ -252,26 +249,7 @@ */ asmlinkage void math_state_restore (void) { - if (last_task_used_math == current) - return; - if (last_task_used_math) - /* - * Save current fp state into last_task_used_math->tss.fpe_save - */ - fpe_save (&last_task_used_math->tss.fpstate.soft); - last_task_used_math = current; - if (current->used_math) { - /* - * Restore current fp state from current->tss.fpe_save - */ - fpe_restore (¤t->tss.fpstate.soft); - } else { - /* - * initialise fp state - */ - fpe_restore (&init_task.tss.fpstate.soft); - current->used_math = 1; - } + current->used_math = 1; } asmlinkage void arm_syscall (int no, struct pt_regs *regs) diff -u --recursive --new-file v2.1.120/linux/arch/arm/lib/Makefile linux/arch/arm/lib/Makefile --- v2.1.120/linux/arch/arm/lib/Makefile Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/lib/Makefile Sun Sep 6 10:44:47 1998 @@ -5,15 +5,15 @@ # L_TARGET := lib.a -L_OBJS := backtrace.o bitops.o checksum.o delay.o fp_support.o \ - loaders.o memcpy.o system.o string.o uaccess.o io.o +L_OBJS := backtrace.o bitops.o checksum.o delay.o io.o memcpy.o \ + system.o string.o uaccess.o ifeq ($(PROCESSOR),armo) L_OBJS += uaccess-armo.o endif ifdef CONFIG_ARCH_ACORN - L_OBJS += ll_char_wr.o io-acorn.o + L_OBJS += loaders.o ll_char_wr.o io-acorn.o ifdef CONFIG_ARCH_A5K L_OBJS += floppydma.o endif diff -u --recursive --new-file v2.1.120/linux/arch/arm/lib/checksum.S linux/arch/arm/lib/checksum.S --- v2.1.120/linux/arch/arm/lib/checksum.S Sun Jun 7 11:16:26 1998 +++ linux/arch/arm/lib/checksum.S Sun Sep 6 10:44:47 1998 @@ -1,5 +1,5 @@ /* - * linux/arch/arm/lib/iputils.S + * linux/arch/arm/lib/checksum.S * * Copyright (C) 1995, 1996, 1997, 1998 Russell King */ @@ -71,11 +71,11 @@ #if defined(CONFIG_CPU_32) .macro save_regs - stmfd sp!, {r4 - r8, fp, ip, lr, pc} + stmfd sp!, {r1 - r2, r4 - r8, fp, ip, lr, pc} .endm #define LOAD_REGS(cond) \ - LOADREGS(##cond##ea,fp,{r4 - r8, fp, sp, pc}) + LOADREGS(##cond##ea,fp,{r1 - r2, r4 - r8, fp, sp, pc}) .macro load1b, reg1 9999: ldrbt \reg1, [r0], $1 @@ -127,7 +127,7 @@ #elif defined(CONFIG_CPU_26) .macro save_regs - stmfd sp!, {r4 - r9, fp, ip, lr, pc} + stmfd sp!, {r1 - r2, r4 - r9, fp, ip, lr, pc} mov r9, sp, lsr #13 mov r9, r9, lsl #13 ldr r9, [r9, #TSK_ADDR_LIMIT] @@ -135,7 +135,7 @@ .endm #define LOAD_REGS(cond) \ - LOADREGS(##cond##ea,fp,{r4 - r9, fp, sp, pc}) + LOADREGS(##cond##ea,fp,{r1 - r2, r4 - r9, fp, sp, pc}) .macro load1b, reg1 tst r9, #0x01 @@ -448,13 +448,23 @@ mov r4, r4, lsr #8 b .exit +#if defined(CONFIG_CPU_32) .section .fixup,"ax" +#endif .align 4 6001: mov r4, #-EFAULT ldr r5, [fp, #4] str r4, [r5] + ldmia sp, {r1, r2} @ retrieve original arguments + add r2, r2, r1 + mov r3, #0 @ zero the buffer +6002: teq r2, r1 + strneb r3, [r1], #1 + bne 6002b LOAD_REGS(al) +#if defined(CONFIG_CPU_32) .previous +#endif /* Function: __u32 csum_partial_copy (const char *src, char *dst, int len, __u32 sum) * Params : r0 = src, r1 = dst, r2 = len, r3 = checksum @@ -701,7 +711,7 @@ mov r4, r4, lsr #8 b Lexit -ENTRY(csum_ipv6_magic) +ENTRY(__csum_ipv6_magic) stmfd sp!, {lr} adds ip, r2, r3 ldmia r1, {r1 - r3, lr} diff -u --recursive --new-file v2.1.120/linux/arch/arm/lib/fp_support.c linux/arch/arm/lib/fp_support.c --- v2.1.120/linux/arch/arm/lib/fp_support.c Tue Jan 20 16:39:41 1998 +++ linux/arch/arm/lib/fp_support.c Wed Dec 31 16:00:00 1969 @@ -1,22 +0,0 @@ -/* - * linux/arch/arm/lib/fp_support.c - * - * Copyright (C) 1995, 1996 Russell King - */ - -#include -#include - -extern void (*fp_save)(struct fp_soft_struct *); - -asmlinkage void fp_setup(void) -{ - struct task_struct *p; - - p = &init_task; - do { - fp_save(&p->tss.fpstate.soft); - p = p->next_task; - } - while (p != &init_task); -} diff -u --recursive --new-file v2.1.120/linux/arch/arm/lib/getconsdata.c linux/arch/arm/lib/getconsdata.c --- v2.1.120/linux/arch/arm/lib/getconsdata.c Fri May 8 23:14:42 1998 +++ linux/arch/arm/lib/getconsdata.c Sun Sep 6 10:44:47 1998 @@ -24,8 +24,10 @@ unsigned long TSK_STATE = OFF_TSK(state); unsigned long TSK_FLAGS = OFF_TSK(flags); +unsigned long TSK_NEED_RESCHED = OFF_TSK(need_resched); unsigned long TSK_SIGPENDING = OFF_TSK(sigpending); unsigned long TSK_ADDR_LIMIT = OFF_TSK(addr_limit); +unsigned long TSK_USED_MATH = OFF_TSK(used_math); unsigned long MM = OFF_TSK(mm); unsigned long PGD = OFF_MM(pgd); diff -u --recursive --new-file v2.1.120/linux/arch/arm/lib/io-acorn.S linux/arch/arm/lib/io-acorn.S --- v2.1.120/linux/arch/arm/lib/io-acorn.S Wed May 20 19:10:37 1998 +++ linux/arch/arm/lib/io-acorn.S Sun Sep 6 10:44:47 1998 @@ -166,6 +166,13 @@ bgt 3b LOADREGS(ea, fp, {r4 - r8, fp, sp, pc}) +/* + * These make no sense on Acorn machines atm. + */ +ENTRY(insl) +ENTRY(outsl) + RETINSTR(mov,pc,lr) + @ Purpose: write a memc register @ Proto : void memc_write(int register, int value); @ Returns: nothing diff -u --recursive --new-file v2.1.120/linux/arch/arm/lib/io.c linux/arch/arm/lib/io.c --- v2.1.120/linux/arch/arm/lib/io.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/lib/io.c Sun Sep 6 10:44:47 1998 @@ -40,4 +40,3 @@ dst++; } } - diff -u --recursive --new-file v2.1.120/linux/arch/arm/lib/system.S linux/arch/arm/lib/system.S --- v2.1.120/linux/arch/arm/lib/system.S Mon Feb 23 18:12:02 1998 +++ linux/arch/arm/lib/system.S Sun Sep 6 10:44:47 1998 @@ -16,5 +16,5 @@ b SYMBOL_NAME(panic) .abort_msg: .ascii "Eek! Got to an abort() from %p! " - .ascii "(Please report to rmk@ecs.soton.ac.uk)\n\0" + .ascii "(Please report to rmk@arm.uk.linux.org)\n\0" .align diff -u --recursive --new-file v2.1.120/linux/arch/arm/lib/testm.c linux/arch/arm/lib/testm.c --- v2.1.120/linux/arch/arm/lib/testm.c Tue Jan 20 16:39:42 1998 +++ linux/arch/arm/lib/testm.c Wed Dec 31 16:00:00 1969 @@ -1,81 +0,0 @@ -char buffer[1036]; -char buffer2[1036]; - -int main () -{ - char *p; - int i, o, o2, l; - - printf ("Testing memset\n"); - for (l = 1; l < 1020; l ++) { - for (o = 0; o < 4; o++) { - p = buffer + o + 4; - for (i = 0; i < l + 12; i++) - buffer[i] = 0x55; - - memset (p, 0xaa, l); - - for (i = 0; i < l; i++) - if (p[i] != 0xaa) - printf ("Error: %X+%d\n", p, i); - if (p[-1] != 0x55 || p[-2] != 0x55 || p[-3] != 0x55 || p[-4] != 0x55) - printf ("Error before %X\n", p); - if (p[l] != 0x55 || p[l+1] != 0x55 || p[l+2] != 0x55 || p[l+3] != 0x55) - printf ("Error at end: %p: %02X %02X %02X %02X\n", p+l, p[l], p[l+1], p[l+2], p[l+3]); - } - } - - printf ("Testing memcpy s > d\n"); - for (l = 1; l < 1020; l++) { - for (o = 0; o < 4; o++) { - for (o2 = 0; o2 < 4; o2++) { - char *d, *s; - - for (i = 0; i < l + 12; i++) - buffer[i] = (i & 0x3f) + 0x40; - for (i = 0; i < 1036; i++) - buffer2[i] = 0; - - s = buffer + o; - d = buffer2 + o2 + 4; - - memcpy (d, s, l); - - for (i = 0; i < l; i++) - if (s[i] != d[i]) - printf ("Error at %X+%d -> %X+%d (%02X != %02X)\n", s, i, d, i, s[i], d[i]); - if (d[-1] || d[-2] || d[-3] || d[-4]) - printf ("Error before %X\n", d); - if (d[l] || d[l+1] || d[l+2] || d[l+3]) - printf ("Error after %X\n", d+l); - } - } - } - - printf ("Testing memcpy s < d\n"); - for (l = 1; l < 1020; l++) { - for (o = 0; o < 4; o++) { - for (o2 = 0; o2 < 4; o2++) { - char *d, *s; - - for (i = 0; i < l + 12; i++) - buffer2[i] = (i & 0x3f) + 0x40; - for (i = 0; i < 1036; i++) - buffer[i] = 0; - - s = buffer2 + o; - d = buffer + o2 + 4; - - memcpy (d, s, l); - - for (i = 0; i < l; i++) - if (s[i] != d[i]) - printf ("Error at %X+%d -> %X+%d (%02X != %02X)\n", s, i, d, i, s[i], d[i]); - if (d[-1] || d[-2] || d[-3] || d[-4]) - printf ("Error before %X\n", d); - if (d[l] || d[l+1] || d[l+2] || d[l+3]) - printf ("Error after %X\n", d+l); - } - } - } -} diff -u --recursive --new-file v2.1.120/linux/arch/arm/lib/uaccess.S linux/arch/arm/lib/uaccess.S --- v2.1.120/linux/arch/arm/lib/uaccess.S Wed May 20 19:10:37 1998 +++ linux/arch/arm/lib/uaccess.S Sun Sep 6 10:44:47 1998 @@ -312,7 +312,7 @@ b .cfu_dest_aligned ENTRY(__arch_copy_from_user) - stmfd sp!, {r2, r4 - r7, lr} + stmfd sp!, {r0, r2, r4 - r7, lr} cmp r2, #4 blt .cfu_not_enough ands ip, r0, #3 @@ -375,7 +375,8 @@ movs ip, r2 bne .cfu_nowords .cfu_finished: mov r0, #0 - LOADREGS(fd,sp!,{r2, r4 - r7, pc}) + add sp, sp, #8 + LOADREGS(fd,sp!,{r4 - r7, pc}) .cfu_src_not_aligned: bic r1, r1, #3 @@ -548,7 +549,12 @@ #ifndef TESTING .section .fixup,"ax" .align 0 -9001: LOADREGS(fd,sp!, {r0, r4 - r7, pc}) + /* We took an exception. Zero out the buffer and pretend no + data was copied. */ +9001: ldr r0, [sp], #4 + ldr r1, [sp] + bl SYMBOL_NAME(memzero) + LOADREGS(fd,sp!, {r0, r4 - r7, pc}) .previous #endif @@ -636,7 +642,11 @@ .section .fixup,"ax" .align 0 -9001: mov r0, #-EFAULT +9001: mov ip, #0 +1: strb ip, [r0], #1 + subs r2, r2, #1 + bpl 1b + mov r0, #-EFAULT LOADREGS(fd, sp!, {pc}) .previous diff -u --recursive --new-file v2.1.120/linux/arch/arm/mm/fault-armv.c linux/arch/arm/mm/fault-armv.c --- v2.1.120/linux/arch/arm/mm/fault-armv.c Fri May 8 23:14:42 1998 +++ linux/arch/arm/mm/fault-armv.c Sun Sep 6 10:44:47 1998 @@ -25,8 +25,6 @@ #define FAULT_CODE_READ 0x02 #define FAULT_CODE_USER 0x01 -#define USER_PTRS_PER_PGD (TASK_SIZE / PGDIR_SIZE) - struct pgtable_cache_struct quicklists; void __bad_pmd(pmd_t *pmd) diff -u --recursive --new-file v2.1.120/linux/arch/arm/mm/mm-armv.c linux/arch/arm/mm/mm-armv.c --- v2.1.120/linux/arch/arm/mm/mm-armv.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/mm/mm-armv.c Sun Sep 6 10:44:47 1998 @@ -68,4 +68,3 @@ return start_mem; } - diff -u --recursive --new-file v2.1.120/linux/arch/arm/mm/mm-ebsa110.c linux/arch/arm/mm/mm-ebsa110.c --- v2.1.120/linux/arch/arm/mm/mm-ebsa110.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/mm/mm-ebsa110.c Sun Sep 6 10:44:47 1998 @@ -5,8 +5,14 @@ * * Copyright (C) 1998 Russell King */ +#include +#include #include + +#include +#include #include +#include #define MAPPING \ { IO_BASE - PGDIR_SIZE , 0xc0000000 , PGDIR_SIZE , DOMAIN_IO, 0, 1 }, \ diff -u --recursive --new-file v2.1.120/linux/arch/arm/mm/mm-rpc.c linux/arch/arm/mm/mm-rpc.c --- v2.1.120/linux/arch/arm/mm/mm-rpc.c Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/mm/mm-rpc.c Sun Sep 6 10:44:47 1998 @@ -68,7 +68,8 @@ return phys + rambank[bank].phys_offset; } -void init_dram_banks(struct param_struct *params) +__initfunc(void +init_dram_banks(struct param_struct *params)) { unsigned int bank; unsigned int bytes = 0; diff -u --recursive --new-file v2.1.120/linux/arch/arm/mm/proc-arm6,7.S linux/arch/arm/mm/proc-arm6,7.S --- v2.1.120/linux/arch/arm/mm/proc-arm6,7.S Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/mm/proc-arm6,7.S Sun Sep 6 10:44:47 1998 @@ -431,6 +431,8 @@ .word _arm6_7_flush_tlb_all @ 44 .word _arm6_7_flush_tlb_area @ 48 .word _arm7_set_pmd @ 52 - .word _arm6_7_reset @ 54 - .word _arm6_7_flush_cache @ 58 + .word _arm6_7_reset @ 56 + .word _arm6_7_flush_cache @ 60 + .word _arm6_7_flush_cache @ 64 + .word _arm6_7_flush_cache @ 68 diff -u --recursive --new-file v2.1.120/linux/arch/arm/mm/proc-sa110.S linux/arch/arm/mm/proc-sa110.S --- v2.1.120/linux/arch/arm/mm/proc-sa110.S Tue Apr 14 14:29:20 1998 +++ linux/arch/arm/mm/proc-sa110.S Sun Sep 6 10:44:47 1998 @@ -21,19 +21,22 @@ */ .align 5 _sa110_flush_cache_all: @ preserves r0 + mov r2, #1 +_sa110_flush_cache_all_r2: ldr r3, =Lclean_switch - ldr r2, [r3] - ands r2, r2, #1 - eor r2, r2, #1 - str r2, [r3] + ldr r1, [r3] + ands r1, r1, #1 + eor r1, r1, #1 + str r1, [r3] ldr ip, =0xdf000000 addne ip, ip, #32768 add r1, ip, #16384 @ only necessary for 16k -1: ldr r2, [ip], #32 +1: ldr r3, [ip], #32 teq r1, ip bne 1b mov ip, #0 - mcr p15, 0, ip, c7, c5, 0 @ flush I cache + tst r2, #1 + mcrne p15, 0, ip, c7, c5, 0 @ flush I cache mcr p15, 0, ip, c7, c10, 4 @ drain WB mov pc, lr @@ -50,7 +53,7 @@ _sa110_flush_cache_area: sub r3, r1, r0 cmp r3, #32768 - bgt _sa110_flush_cache_all + bgt _sa110_flush_cache_all_r2 1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry mcr p15, 0, r0, c7, c6, 1 @ flush D entry add r0, r0, #32 @@ -65,6 +68,55 @@ mov pc, lr /* + * Function: sa110_cache_wback_area(unsigned long address, unsigned long end) + * + * Params : address Area start address + * : end Area end address + * + * Purpose : ensure all dirty cachelines in the specified area have been + * written out to memory (for DMA) + */ + .align 5 +_sa110_cache_wback_area: + sub r3, r1, r0 + cmp r3, #32768 + movgt r2, #0 + bgt _sa110_flush_cache_all +1: mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #32 + mcr p15, 0, r0, c7, c10, 1 @ clean D entry + add r0, r0, #32 + cmp r0, r1 + blt 1b + mcr p15, 0, r0, c7, c10, 4 @ drain WB + mov pc, lr + +/* + * Function: sa110_cache_purge_area(unsigned long address, unsigned long end) + * + * Params : address Area start address + * : end Area end address + * + * Purpose : throw away all D-cached data in specified region without + * an obligation to write it ack. + * + * Note : Must clean the D-cached entries around the boundaries if the + * start and/or end address are not cache aligned. + */ + .align 5 +_sa110_cache_purge_area: + tst r0, #31 + bic r0, r0, #31 + mcrne p15, 0, r0, c7, c10, 1 @ clean D entry + tst r1, #31 + mcrne p15, 0, r1, c7, c10, 1 @ clean D entry +1: mcr p15, 0, r0, c7, c6, 1 @ flush D entry + add r0, r0, #32 + cmp r0, r1 + blt 1b + mov pc, lr + +/* * Function: sa110_flush_cache_entry (unsigned long address) * * Params : address Address of cache line to flush @@ -129,7 +181,7 @@ mov pc, lr /* - * Function: sa110_flush_tlb_area (unsigned long address, int end, int flags) + * Function: sa110_flush_tlb_area (unsigned long address, unsigned long end, int flags) * * Params : address Area start address * : end Area end address @@ -266,6 +318,7 @@ orr r1, r1, #F_BIT | I_BIT msr cpsr, r1 stmfd sp!, {r1, lr} + mov r2, #1 bl _sa110_flush_cache_all bl _sa110_flush_tlb_all mcr p15, 0, ip, c7, c7, 0 @ flush I,D caches @@ -297,5 +350,8 @@ .word _sa110_flush_tlb_area @ 48 .word _sa110_set_pmd @ 52 - .word _sa110_reset @ 54 - .word _sa110_flush_icache_area @ 58 + .word _sa110_reset @ 56 + .word _sa110_flush_icache_area @ 60 + + .word _sa110_cache_wback_area @ 64 + .word _sa110_cache_purge_area @ 68 diff -u --recursive --new-file v2.1.120/linux/arch/arm/vmlinux-armo.lds linux/arch/arm/vmlinux-armo.lds --- v2.1.120/linux/arch/arm/vmlinux-armo.lds Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/vmlinux-armo.lds Sun Sep 6 10:44:47 1998 @@ -1,5 +1,5 @@ /* ld script to make ARM Linux kernel - * taken from the i386 version + * taken from the i386 version by Russell King * Written by Martin Mares */ OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm") @@ -28,17 +28,15 @@ _etext = .; /* End of text section */ + . = ALIGN(8192); .data : { /* Data */ + *(.init.task) *(.data) CONSTRUCTORS } _edata = .; /* End of data section */ - /* This has to be aligned to a page boundary to do us any good. This - alignment is overkill for ARM6 up but needed for ARM3. Since all this - data will be thrown away I don't think the extra padding will hurt. - -- pb */ . = ALIGN(32768); /* Init code and data */ __init_begin = .; .text.init : { *(.text.init) } diff -u --recursive --new-file v2.1.120/linux/arch/arm/vmlinux-armv.lds linux/arch/arm/vmlinux-armv.lds --- v2.1.120/linux/arch/arm/vmlinux-armv.lds Tue Jul 21 00:15:30 1998 +++ linux/arch/arm/vmlinux-armv.lds Sun Sep 6 10:44:47 1998 @@ -1,5 +1,5 @@ /* ld script to make ARM Linux kernel - * taken from the i386 version + * taken from the i386 version by Russell King * Written by Martin Mares */ OUTPUT_FORMAT("elf32-arm", "elf32-arm", "elf32-arm") @@ -28,17 +28,15 @@ _etext = .; /* End of text section */ + . = ALIGN(8192); .data : { /* Data */ + *(.init.task) *(.data) CONSTRUCTORS } _edata = .; /* End of data section */ - /* This has to be aligned to a page boundary to do us any good. This - alignment is overkill for ARM6 up but needed for ARM3. Since all this - data will be thrown away I don't think the extra padding will hurt. - -- pb */ . = ALIGN(4096); /* Init code and data */ __init_begin = .; .text.init : { *(.text.init) } diff -u --recursive --new-file v2.1.120/linux/arch/i386/defconfig linux/arch/i386/defconfig --- v2.1.120/linux/arch/i386/defconfig Thu Aug 6 14:06:28 1998 +++ linux/arch/i386/defconfig Sun Sep 6 11:06:34 1998 @@ -198,6 +198,7 @@ # CONFIG_SLIP is not set # CONFIG_NET_RADIO is not set # CONFIG_TR is not set +# CONFIG_HOSTESS_SV11 is not set # CONFIG_WAN_DRIVERS is not set # CONFIG_LAPBETHER is not set # CONFIG_X25_ASY is not set diff -u --recursive --new-file v2.1.120/linux/arch/i386/kernel/bios32.c linux/arch/i386/kernel/bios32.c --- v2.1.120/linux/arch/i386/kernel/bios32.c Wed Aug 26 11:37:33 1998 +++ linux/arch/i386/kernel/bios32.c Tue Sep 8 13:46:33 1998 @@ -1044,24 +1044,20 @@ #ifdef __SMP__ /* * Recalculate IRQ numbers if we use the I/O APIC - * - * NOTE! If the "original" interrupt is marked as an old-fashioned - * irq, we have to keep it old-fashioned even if it's a PCI device - * and we could have found it in the MP-table transform. */ - if (IO_APIC_IRQ(dev->irq)) { + { int irq; unsigned char pin; pci_read_config_byte(dev, PCI_INTERRUPT_PIN, &pin); if (pin) { pin--; /* interrupt pins are numbered starting from 1 */ - irq = IO_APIC_get_PCI_irq_vector (dev->bus->number, PCI_SLOT(dev->devfn), pin); + irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, PCI_SLOT(dev->devfn), pin); if (irq >= 0) { printk("PCI->APIC IRQ transform: (B%d,I%d,P%d) -> %d\n", dev->bus->number, PCI_SLOT(dev->devfn), pin, irq); dev->irq = irq; - } + } } } #endif diff -u --recursive --new-file v2.1.120/linux/arch/i386/kernel/entry.S linux/arch/i386/kernel/entry.S --- v2.1.120/linux/arch/i386/kernel/entry.S Sat Sep 5 16:46:40 1998 +++ linux/arch/i386/kernel/entry.S Sun Sep 6 13:04:57 1998 @@ -364,7 +364,7 @@ .data ENTRY(sys_call_table) - .long SYMBOL_NAME(sys_setup) /* 0 */ + .long SYMBOL_NAME(sys_ni_syscall) /* 0 - old "setup()" system call*/ .long SYMBOL_NAME(sys_exit) .long SYMBOL_NAME(sys_fork) .long SYMBOL_NAME(sys_read) diff -u --recursive --new-file v2.1.120/linux/arch/i386/kernel/io_apic.c linux/arch/i386/kernel/io_apic.c --- v2.1.120/linux/arch/i386/kernel/io_apic.c Sat Sep 5 16:46:40 1998 +++ linux/arch/i386/kernel/io_apic.c Tue Sep 8 14:46:50 1998 @@ -514,6 +514,8 @@ return 0; } +int irq_vector[NR_IRQS] = { IRQ0_TRAP_VECTOR , 0 }; + static int __init assign_irq_vector(int irq) { static int current_vector = IRQ0_TRAP_VECTOR, offset = 0; @@ -957,7 +959,7 @@ mask_IO_APIC_irq(irq); } -static void do_edge_ioapic_IRQ(unsigned int irq, int cpu, struct pt_regs * regs) +static void do_edge_ioapic_IRQ(unsigned int irq, struct pt_regs * regs) { irq_desc_t *desc = irq_desc + irq; struct irqaction * action; @@ -991,14 +993,12 @@ if (!action) return; - irq_enter(cpu, irq); - /* * Edge triggered interrupts need to remember * pending events. */ for (;;) { - handle_IRQ_event(irq, regs); + handle_IRQ_event(irq, regs, action); spin_lock(&irq_controller_lock); if (!(desc->status & IRQ_PENDING)) @@ -1008,12 +1008,9 @@ } desc->status &= ~IRQ_INPROGRESS; spin_unlock(&irq_controller_lock); - - irq_exit(cpu, irq); } -static void do_level_ioapic_IRQ(unsigned int irq, int cpu, - struct pt_regs * regs) +static void do_level_ioapic_IRQ(unsigned int irq, struct pt_regs * regs) { irq_desc_t *desc = irq_desc + irq; struct irqaction * action; @@ -1048,17 +1045,13 @@ if (!action) return; - irq_enter(cpu, irq); - - handle_IRQ_event(irq, regs); + handle_IRQ_event(irq, regs, action); spin_lock(&irq_controller_lock); desc->status &= ~IRQ_INPROGRESS; if (!(desc->status & IRQ_DISABLED)) unmask_IO_APIC_irq(irq); spin_unlock(&irq_controller_lock); - - irq_exit(cpu, irq); } /* diff -u --recursive --new-file v2.1.120/linux/arch/i386/kernel/irq.c linux/arch/i386/kernel/irq.c --- v2.1.120/linux/arch/i386/kernel/irq.c Sat Sep 5 16:46:40 1998 +++ linux/arch/i386/kernel/irq.c Tue Sep 8 14:48:11 1998 @@ -79,14 +79,14 @@ */ unsigned long long io_apic_irqs = 0; -static void do_8259A_IRQ (unsigned int irq, int cpu, struct pt_regs * regs); +static void do_8259A_IRQ(unsigned int irq, struct pt_regs * regs); static void enable_8259A_irq(unsigned int irq); void disable_8259A_irq(unsigned int irq); /* * Dummy controller type for unused interrupts */ -static void do_none(unsigned int irq, int cpu, struct pt_regs * regs) { } +static void do_none(unsigned int irq, struct pt_regs * regs) { } static void enable_none(unsigned int irq) { } static void disable_none(unsigned int irq) { } @@ -105,12 +105,10 @@ }; irq_desc_t irq_desc[NR_IRQS] = { - [0 ... 15] = { 0, &i8259A_irq_type, }, /* default to standard ISA IRQs */ - [16 ... 63] = { 0, &no_irq_type, }, /* 'high' PCI IRQs filled in on demand */ + [0 ... 15] = { 0, &i8259A_irq_type, }, /* default to standard ISA IRQs */ + [16 ... NR_IRQS-1] = { 0, &no_irq_type, }, /* 'high' PCI IRQs filled in on demand */ }; -int irq_vector[NR_IRQS] = { IRQ0_TRAP_VECTOR , 0 }; - /* * These have to be protected by the irq controller spinlock @@ -150,52 +148,29 @@ BUILD_COMMON_IRQ() /* - * ISA PIC or IO-APIC triggered (INTA-cycle or APIC) interrupts: + * ISA PIC or low IO-APIC triggered (INTA-cycle or APIC) interrupts: */ -BUILD_IRQ(0) BUILD_IRQ(1) BUILD_IRQ(2) BUILD_IRQ(3) -BUILD_IRQ(4) BUILD_IRQ(5) BUILD_IRQ(6) BUILD_IRQ(7) -BUILD_IRQ(8) BUILD_IRQ(9) BUILD_IRQ(10) BUILD_IRQ(11) +BUILD_IRQ(0) BUILD_IRQ(1) BUILD_IRQ(2) BUILD_IRQ(3) +BUILD_IRQ(4) BUILD_IRQ(5) BUILD_IRQ(6) BUILD_IRQ(7) +BUILD_IRQ(8) BUILD_IRQ(9) BUILD_IRQ(10) BUILD_IRQ(11) BUILD_IRQ(12) BUILD_IRQ(13) BUILD_IRQ(14) BUILD_IRQ(15) #ifdef __SMP__ /* - * The IO-APIC (present only in SMP boards) has 8 more hardware - * interrupt pins, for all of them we define an IRQ vector: - * - * raw PCI interrupts 0-3, basically these are the ones used - * heavily: + * The IO-APIC gives us many more interrupt sources.. */ BUILD_IRQ(16) BUILD_IRQ(17) BUILD_IRQ(18) BUILD_IRQ(19) - -/* - * [FIXME: anyone with 2 separate PCI buses and 2 IO-APICs, please - * speak up if problems and request experimental patches. - * --mingo ] - */ - -/* - * MIRQ (motherboard IRQ) interrupts 0-1: - */ -BUILD_IRQ(20) BUILD_IRQ(21) - -/* - * 'nondefined general purpose interrupt'. - */ -BUILD_IRQ(22) -/* - * optionally rerouted SMI interrupt: - */ -BUILD_IRQ(23) - -BUILD_IRQ(24) -BUILD_IRQ(25) BUILD_IRQ(26) BUILD_IRQ(27) BUILD_IRQ(28) BUILD_IRQ(29) -BUILD_IRQ(30) BUILD_IRQ(31) BUILD_IRQ(32) BUILD_IRQ(33) BUILD_IRQ(34) -BUILD_IRQ(35) BUILD_IRQ(36) BUILD_IRQ(37) BUILD_IRQ(38) BUILD_IRQ(39) -BUILD_IRQ(40) BUILD_IRQ(41) BUILD_IRQ(42) BUILD_IRQ(43) BUILD_IRQ(44) -BUILD_IRQ(45) BUILD_IRQ(46) BUILD_IRQ(47) BUILD_IRQ(48) BUILD_IRQ(49) -BUILD_IRQ(50) BUILD_IRQ(51) BUILD_IRQ(52) BUILD_IRQ(53) BUILD_IRQ(54) -BUILD_IRQ(55) BUILD_IRQ(56) BUILD_IRQ(57) BUILD_IRQ(58) BUILD_IRQ(59) +BUILD_IRQ(20) BUILD_IRQ(21) BUILD_IRQ(22) BUILD_IRQ(23) +BUILD_IRQ(24) BUILD_IRQ(25) BUILD_IRQ(26) BUILD_IRQ(27) +BUILD_IRQ(28) BUILD_IRQ(29) BUILD_IRQ(30) BUILD_IRQ(31) +BUILD_IRQ(32) BUILD_IRQ(33) BUILD_IRQ(34) BUILD_IRQ(35) +BUILD_IRQ(36) BUILD_IRQ(37) BUILD_IRQ(38) BUILD_IRQ(39) +BUILD_IRQ(40) BUILD_IRQ(41) BUILD_IRQ(42) BUILD_IRQ(43) +BUILD_IRQ(44) BUILD_IRQ(45) BUILD_IRQ(46) BUILD_IRQ(47) +BUILD_IRQ(48) BUILD_IRQ(49) BUILD_IRQ(50) BUILD_IRQ(51) +BUILD_IRQ(52) BUILD_IRQ(53) BUILD_IRQ(54) BUILD_IRQ(55) +BUILD_IRQ(56) BUILD_IRQ(57) BUILD_IRQ(58) BUILD_IRQ(59) BUILD_IRQ(60) BUILD_IRQ(61) BUILD_IRQ(62) BUILD_IRQ(63) /* @@ -586,29 +561,35 @@ #endif -int handle_IRQ_event(unsigned int irq, struct pt_regs * regs) +/* + * This should really return information about whether + * we should do bottom half handling etc. Right now we + * end up _always_ checking the bottom half, which is a + * waste of time and is not what some drivers would + * prefer. + */ +int handle_IRQ_event(unsigned int irq, struct pt_regs * regs, struct irqaction * action) { - struct irqaction * action; int status; + int cpu = smp_processor_id(); - status = 0; - action = irq_desc[irq].action; + irq_enter(cpu, irq); - if (action) { - status |= 1; + status = 1; /* Force the "do bottom halves" bit */ - if (!(action->flags & SA_INTERRUPT)) - __sti(); + if (!(action->flags & SA_INTERRUPT)) + __sti(); - do { - status |= action->flags; - action->handler(irq, action->dev_id, regs); - action = action->next; - } while (action); - if (status & SA_SAMPLE_RANDOM) - add_interrupt_randomness(irq); - __cli(); - } + do { + status |= action->flags; + action->handler(irq, action->dev_id, regs); + action = action->next; + } while (action); + if (status & SA_SAMPLE_RANDOM) + add_interrupt_randomness(irq); + __cli(); + + irq_exit(cpu, irq); return status; } @@ -625,9 +606,9 @@ void make_8259A_irq(unsigned int irq) { + disable_irq(irq); __long(0,io_apic_irqs) &= ~(1<status & ~IRQ_REPLAY; + action = NULL; + if (!(status & (IRQ_DISABLED | IRQ_INPROGRESS))) + action = desc->action; + desc->status = status | IRQ_INPROGRESS; + } + spin_unlock(&irq_controller_lock); - if (handle_IRQ_event(irq, regs)) { - spin_lock(&irq_controller_lock); - irq_desc[irq].status &= ~IRQ_INPROGRESS; - if (!(irq_desc[irq].status & IRQ_DISABLED)) + /* Exit early if we had no action or it was disabled */ + if (!action) + return; + + handle_IRQ_event(irq, regs, action); + + spin_lock(&irq_controller_lock); + { + unsigned int status = desc->status & ~IRQ_INPROGRESS; + desc->status = status; + if (!(status & IRQ_DISABLED)) enable_8259A_irq(irq); - spin_unlock(&irq_controller_lock); } - - irq_exit(cpu, irq); + spin_unlock(&irq_controller_lock); } @@ -730,7 +724,7 @@ int cpu = smp_processor_id(); kstat.irqs[cpu][irq]++; - irq_desc[irq].handler->handle(irq, cpu, ®s); + irq_desc[irq].handler->handle(irq, ®s); /* * This should be conditional: we should really get @@ -986,9 +980,6 @@ * while so far it was a kind of broadcasted timer interrupt, * in the future it should become a CPU-to-CPU rescheduling IPI, * driven by schedule() ? - * - * [ It has to be here .. it doesn't work if you put - * it down the bottom - assembler explodes 8) ] */ /* IPI for rescheduling */ @@ -1013,9 +1004,9 @@ request_region(0xa0,0x20,"pic2"); setup_x86_irq(2, &irq2); setup_x86_irq(13, &irq13); -} +} -#ifdef __SMP__ +#ifdef __SMP__ __initfunc(void init_IRQ_SMP(void)) { diff -u --recursive --new-file v2.1.120/linux/arch/i386/kernel/irq.h linux/arch/i386/kernel/irq.h --- v2.1.120/linux/arch/i386/kernel/irq.h Sat Sep 5 16:46:40 1998 +++ linux/arch/i386/kernel/irq.h Tue Sep 8 12:51:20 1998 @@ -9,7 +9,7 @@ */ struct hw_interrupt_type { const char * typename; - void (*handle)(unsigned int irq, int cpu, struct pt_regs * regs); + void (*handle)(unsigned int irq, struct pt_regs * regs); void (*enable)(unsigned int irq); void (*disable)(unsigned int irq); }; @@ -42,9 +42,10 @@ extern irq_desc_t irq_desc[NR_IRQS]; extern int irq_vector[NR_IRQS]; +#define IO_APIC_VECTOR(irq) irq_vector[irq] extern void init_IRQ_SMP(void); -extern int handle_IRQ_event(unsigned int, struct pt_regs *); +extern int handle_IRQ_event(unsigned int, struct pt_regs *, struct irqaction *); /* * Various low-level irq details needed by irq.c, process.c, @@ -56,19 +57,17 @@ void mask_irq(unsigned int irq); void unmask_irq(unsigned int irq); void disable_8259A_irq(unsigned int irq); -int i8259A_irq_pending (unsigned int irq); -void ack_APIC_irq (void); -void setup_IO_APIC (void); -int IO_APIC_get_PCI_irq_vector (int bus, int slot, int fn); -void make_8259A_irq (unsigned int irq); -void send_IPI (int dest, int vector); -void init_pic_mode (void); -void print_IO_APIC (void); +int i8259A_irq_pending(unsigned int irq); +void ack_APIC_irq(void); +void setup_IO_APIC(void); +int IO_APIC_get_PCI_irq_vector(int bus, int slot, int fn); +void make_8259A_irq(unsigned int irq); +void send_IPI(int dest, int vector); +void init_pic_mode(void); +void print_IO_APIC(void); extern unsigned long long io_apic_irqs; -#define IO_APIC_VECTOR(irq) irq_vector[irq] - #define MAX_IRQ_SOURCES 128 #define MAX_MP_BUSSES 32 enum mp_bustype { @@ -101,7 +100,6 @@ static inline void irq_exit(int cpu, unsigned int irq) { hardirq_exit(cpu); - release_irqlock(cpu); } #define IO_APIC_IRQ(x) ((1<tarray_ptr - &task[0]; mm->segments = ldt; set_ldt_desc(gdt+(i<<1)+FIRST_LDT_ENTRY, ldt, LDT_ENTRIES); + current->tss.ldt = _LDT(i); load_ldt(i); if (atomic_read(&mm->count) > 1) printk(KERN_WARNING diff -u --recursive --new-file v2.1.120/linux/arch/i386/kernel/signal.c linux/arch/i386/kernel/signal.c --- v2.1.120/linux/arch/i386/kernel/signal.c Sat Sep 5 16:46:40 1998 +++ linux/arch/i386/kernel/signal.c Sat Sep 5 17:14:29 1998 @@ -22,17 +22,6 @@ #include #include -void checksignals(void) -{ - sigset_t *blocked = ¤t->blocked; - unsigned long mask = blocked->sig[0] | sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT); - mask &= blocked->sig[1]; - if (~mask) { - printk("Bad signal mask\n"); - *(int *) 0 = 0; - } -} - #define DEBUG_SIG 0 #define _BLOCKABLE (~(sigmask(SIGKILL) | sigmask(SIGSTOP))) diff -u --recursive --new-file v2.1.120/linux/arch/i386/kernel/smp.c linux/arch/i386/kernel/smp.c --- v2.1.120/linux/arch/i386/kernel/smp.c Sat Sep 5 16:46:40 1998 +++ linux/arch/i386/kernel/smp.c Sun Sep 6 11:49:01 1998 @@ -113,7 +113,7 @@ extern __inline int max(int a,int b) { - if(a>b) + if (a>b) return a; return b; } @@ -179,7 +179,7 @@ * SMP mode to . */ -__initfunc(void smp_setup(char *str, int *ints)) +void __init smp_setup(char *str, int *ints) { if (ints && ints[0] > 0) max_cpus = ints[1]; @@ -187,7 +187,7 @@ max_cpus = 0; } -void ack_APIC_irq (void) +void ack_APIC_irq(void) { /* Clear the IPI */ @@ -225,13 +225,13 @@ "Unknown","Unknown", "80486DX/4" }; - if(family==0x6) + if (family==0x6) return("Pentium(tm) Pro"); - if(family==0x5) + if (family==0x5) return("Pentium(tm)"); - if(family==0x0F && model==0x0F) + if (family==0x0F && model==0x0F) return("Special controller"); - if(family==0x04 && model<9) + if (family==0x04 && model<9) return model_defs[model]; sprintf(n,"Unknown CPU [%d:%d]",family, model); return n; @@ -241,14 +241,14 @@ * Read the MPC */ -__initfunc(static int smp_read_mpc(struct mp_config_table *mpc)) +static int __init smp_read_mpc(struct mp_config_table *mpc) { char str[16]; int count=sizeof(*mpc); int ioapics = 0; unsigned char *mpt=((unsigned char *)mpc)+count; - if(memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) + if (memcmp(mpc->mpc_signature,MPC_SIGNATURE,4)) { printk("Bad signature [%c%c%c%c].\n", mpc->mpc_signature[0], @@ -257,12 +257,12 @@ mpc->mpc_signature[3]); return 1; } - if(mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) + if (mpf_checksum((unsigned char *)mpc,mpc->mpc_length)) { printk("Checksum error.\n"); return 1; } - if(mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) + if (mpc->mpc_spec!=0x01 && mpc->mpc_spec!=0x04) { printk("Bad Config Table version (%d)!!\n",mpc->mpc_spec); return 1; @@ -294,7 +294,7 @@ { struct mpc_config_processor *m= (struct mpc_config_processor *)mpt; - if(m->mpc_cpuflag&CPU_ENABLED) + if (m->mpc_cpuflag&CPU_ENABLED) { printk("Processor #%d %s APIC version %d\n", m->mpc_apicid, @@ -304,16 +304,16 @@ CPU_MODEL_MASK)>>4), m->mpc_apicver); #ifdef SMP_DEBUG - if(m->mpc_featureflag&(1<<0)) + if (m->mpc_featureflag&(1<<0)) printk(" Floating point unit present.\n"); - if(m->mpc_featureflag&(1<<7)) + if (m->mpc_featureflag&(1<<7)) printk(" Machine Exception supported.\n"); - if(m->mpc_featureflag&(1<<8)) + if (m->mpc_featureflag&(1<<8)) printk(" 64 bit compare & exchange supported.\n"); - if(m->mpc_featureflag&(1<<9)) + if (m->mpc_featureflag&(1<<9)) printk(" Internal APIC present.\n"); #endif - if(m->mpc_cpuflag&CPU_BOOTPROCESSOR) + if (m->mpc_cpuflag&CPU_BOOTPROCESSOR) { SMP_PRINTK((" Bootup CPU\n")); boot_cpu_id=m->mpc_apicid; @@ -321,7 +321,7 @@ else /* Boot CPU already counted */ num_processors++; - if(m->mpc_apicid>NR_CPUS) + if (m->mpc_apicid>NR_CPUS) printk("Processor #%d unused. (Max %d processors).\n",m->mpc_apicid, NR_CPUS); else { @@ -362,7 +362,7 @@ { struct mpc_config_ioapic *m= (struct mpc_config_ioapic *)mpt; - if(m->mpc_flags&MPC_APIC_USABLE) + if (m->mpc_flags&MPC_APIC_USABLE) { ioapics++; printk("I/O APIC #%d Version %d at 0x%lX.\n", @@ -413,28 +413,28 @@ * Scan the memory blocks for an SMP configuration block. */ -__initfunc(int smp_scan_config(unsigned long base, unsigned long length)) +int __init smp_scan_config(unsigned long base, unsigned long length) { unsigned long *bp=phys_to_virt(base); struct intel_mp_floating *mpf; SMP_PRINTK(("Scan SMP from %p for %ld bytes.\n", bp,length)); - if(sizeof(*mpf)!=16) + if (sizeof(*mpf)!=16) printk("Error: MPF size\n"); - while(length>0) + while (length>0) { - if(*bp==SMP_MAGIC_IDENT) + if (*bp==SMP_MAGIC_IDENT) { mpf=(struct intel_mp_floating *)bp; - if(mpf->mpf_length==1 && + if (mpf->mpf_length==1 && !mpf_checksum((unsigned char *)bp,16) && (mpf->mpf_specification == 1 || mpf->mpf_specification == 4) ) { printk("Intel MultiProcessor Specification v1.%d\n", mpf->mpf_specification); - if(mpf->mpf_feature2&(1<<7)) + if (mpf->mpf_feature2&(1<<7)) printk(" IMCR and PIC compatibility mode.\n"); else printk(" Virtual Wire compatibility mode.\n"); @@ -442,7 +442,7 @@ /* * Now see if we need to read further. */ - if(mpf->mpf_feature1!=0) + if (mpf->mpf_feature1!=0) { unsigned long cfg; @@ -524,7 +524,7 @@ mpf->mpf_feature1); return 1; } - if(mpf->mpf_feature1>4) + if (mpf->mpf_feature1>4) { printk("Bus #1 is PCI\n"); @@ -543,7 +543,7 @@ * Anything here will override the * defaults. */ - if(mpf->mpf_physptr) + if (mpf->mpf_physptr) smp_read_mpc((void *)mpf->mpf_physptr); __cpu_logical_map[0] = boot_cpu_id; @@ -578,7 +578,7 @@ * has made sure it's suitably aligned. */ -__initfunc(static unsigned long setup_trampoline(void)) +static unsigned long __init setup_trampoline(void) { memcpy(trampoline_base, trampoline_data, trampoline_end - trampoline_data); return virt_to_phys(trampoline_base); @@ -588,7 +588,7 @@ * We are called very early to get the low memory for the * SMP bootup trampoline page. */ -__initfunc(unsigned long smp_alloc_memory(unsigned long mem_base)) +unsigned long __init smp_alloc_memory(unsigned long mem_base) { if (virt_to_phys((void *)mem_base) >= 0x9F000) panic("smp_alloc_memory: Insufficient low memory for kernel trampoline 0x%lx.", mem_base); @@ -601,7 +601,7 @@ * a given CPU */ -__initfunc(void smp_store_cpu_info(int id)) +void __init smp_store_cpu_info(int id) { struct cpuinfo_x86 *c=&cpu_data[id]; @@ -630,7 +630,7 @@ * we use to track CPUs as they power up. */ -__initfunc(void smp_commence(void)) +void __init smp_commence(void) { /* * Lets the callins below out of their loop. @@ -639,7 +639,7 @@ smp_commenced=1; } -__initfunc(void enable_local_APIC(void)) +void __init enable_local_APIC(void) { unsigned long value; @@ -658,7 +658,7 @@ udelay(100); } -__initfunc(unsigned long init_smp_mappings(unsigned long memory_start)) +unsigned long __init init_smp_mappings(unsigned long memory_start) { unsigned long apic_phys, ioapic_phys; @@ -688,7 +688,7 @@ return memory_start; } -__initfunc(void smp_callin(void)) +void __init smp_callin(void) { extern void calibrate_delay(void); int cpuid=GET_APIC_ID(apic_read(APIC_ID)); @@ -730,7 +730,7 @@ /* * Activate a secondary processor. */ -__initfunc(int start_secondary(void *unused)) +int __init start_secondary(void *unused) { #ifdef CONFIG_MTRR /* Must be done before calibration delay is computed */ @@ -747,7 +747,7 @@ * CPUs - they just need to reload everything * from the task structure */ -__initfunc(void initialize_secondary(void)) +void __init initialize_secondary(void) { struct thread_struct * p = ¤t->tss; @@ -773,7 +773,7 @@ unsigned short ss; } stack_start; -__initfunc(static void do_boot_cpu(int i)) +static void __init do_boot_cpu(int i) { unsigned long cfg; pgd_t maincfg; @@ -925,15 +925,15 @@ if (accept_status) /* Send accept error */ printk("APIC delivery error (%lx).\n", accept_status); - if( !(send_status || accept_status) ) + if ( !(send_status || accept_status) ) { for(timeout=0;timeout<50000;timeout++) { - if(cpu_callin_map[0]&(1<eip); + x86_do_profile(regs->eip); if (!--prof_counter[cpu]) { int user=0,system=0; @@ -1537,7 +1537,7 @@ if (test_and_clear_bit(smp_processor_id(), &smp_invalidate_needed)) local_flush_tlb(); - ack_APIC_irq (); + ack_APIC_irq(); } /* @@ -1547,15 +1547,15 @@ { if (cpu_data[smp_processor_id()].hlt_works_ok) for(;;) __asm__("hlt"); - for (;;) ; + for (;;) ; } void (*mtrr_hook) (void) = NULL; asmlinkage void smp_mtrr_interrupt(void) { - ack_APIC_irq (); - if (mtrr_hook) (*mtrr_hook) (); + ack_APIC_irq(); + if (mtrr_hook) (*mtrr_hook)(); } /* @@ -1563,7 +1563,7 @@ */ asmlinkage void smp_spurious_interrupt(void) { - /* ack_APIC_irq (); see sw-dev-man vol 3, chapter 7.4.13.5 */ + /* ack_APIC_irq(); see sw-dev-man vol 3, chapter 7.4.13.5 */ printk("spurious APIC interrupt, ayiee, should never happen.\n"); } @@ -1585,7 +1585,7 @@ * but we do not accept timer interrupts yet. We only allow the BP * to calibrate. */ -__initfunc(static unsigned int get_8254_timer_count (void)) +static unsigned int __init get_8254_timer_count(void) { unsigned int count; @@ -1612,7 +1612,7 @@ #define APIC_DIVISOR 16 -void setup_APIC_timer (unsigned int clocks) +void setup_APIC_timer(unsigned int clocks) { unsigned long lvtt1_value; unsigned int tmp_value; @@ -1640,7 +1640,7 @@ apic_write(APIC_TMICT, clocks/APIC_DIVISOR); } -__initfunc(void wait_8254_wraparound (void)) +void __init wait_8254_wraparound(void) { unsigned int curr_count, prev_count=~0; int delta; @@ -1674,7 +1674,7 @@ * APIC irq that way. */ -__initfunc(int calibrate_APIC_clock (void)) +int __init calibrate_APIC_clock(void) { unsigned long long t1,t2; long tt1,tt2; @@ -1745,7 +1745,7 @@ static unsigned int calibration_result; -__initfunc(void setup_APIC_clock (void)) +void __init setup_APIC_clock(void) { unsigned long flags; @@ -1800,7 +1800,7 @@ * * usually you want to run this on all CPUs ;) */ -int setup_profiling_timer (unsigned int multiplier) +int setup_profiling_timer(unsigned int multiplier) { int cpu = smp_processor_id(); unsigned long flags; @@ -1815,7 +1815,7 @@ save_flags(flags); cli(); - setup_APIC_timer (calibration_result/multiplier); + setup_APIC_timer(calibration_result/multiplier); prof_multiplier[cpu]=multiplier; restore_flags(flags); diff -u --recursive --new-file v2.1.120/linux/arch/i386/kernel/traps.c linux/arch/i386/kernel/traps.c --- v2.1.120/linux/arch/i386/kernel/traps.c Tue Aug 18 22:02:02 1998 +++ linux/arch/i386/kernel/traps.c Sun Sep 6 11:37:01 1998 @@ -484,7 +484,74 @@ __asm__ __volatile__("lidt %0": "=m" (idt_descr)); } +#define _set_gate(gate_addr,type,dpl,addr) \ +__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ + "movw %2,%%dx\n\t" \ + "movl %%eax,%0\n\t" \ + "movl %%edx,%1" \ + :"=m" (*((long *) (gate_addr))), \ + "=m" (*(1+(long *) (gate_addr))) \ + :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ + "d" ((char *) (addr)),"a" (__KERNEL_CS << 16) \ + :"ax","dx") +/* + * WARNING! If we ever start to insert IDT entries + * into the IDT at run-time, we need to be aware of + * the F0 0F bug workaround that marks the IDT + * read-only. It should be easy enough to just follow + * the page tables and set the gate directly.. + */ +void set_intr_gate(unsigned int n, void *addr) +{ + _set_gate(idt+(n),14,0,addr); +} + +static void __init set_trap_gate(unsigned int n, void *addr) +{ + _set_gate(idt+(n),15,0,addr); +} + +static void __init set_system_gate(unsigned int n, void *addr) +{ + _set_gate(idt+(n),15,3,addr); +} + +static void __init set_call_gate(void *a, void *addr) +{ + _set_gate(a,12,3,addr); +} + +#define _set_seg_desc(gate_addr,type,dpl,base,limit) {\ + *((gate_addr)+1) = ((base) & 0xff000000) | \ + (((base) & 0x00ff0000)>>16) | \ + ((limit) & 0xf0000) | \ + ((dpl)<<13) | \ + (0x00408000) | \ + ((type)<<8); \ + *(gate_addr) = (((base) & 0x0000ffff)<<16) | \ + ((limit) & 0x0ffff); } + +#define _set_tssldt_desc(n,addr,limit,type) \ +__asm__ __volatile__ ("movw %3,0(%2)\n\t" \ + "movw %%ax,2(%2)\n\t" \ + "rorl $16,%%eax\n\t" \ + "movb %%al,4(%2)\n\t" \ + "movb %4,5(%2)\n\t" \ + "movb $0,6(%2)\n\t" \ + "movb %%ah,7(%2)\n\t" \ + "rorl $16,%%eax" \ + : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type)) + +void set_tss_desc(void *n, void *addr) +{ + _set_tssldt_desc(((char *) n),((int)addr), 235, 0x89); +} + +void set_ldt_desc(void *n, void *addr, unsigned int size) +{ + _set_tssldt_desc(((char *) n), ((int)addr), ((size << 3) - 1), 0x82); +} void __init trap_init(void) { diff -u --recursive --new-file v2.1.120/linux/drivers/acorn/block/ide-ics.c linux/drivers/acorn/block/ide-ics.c --- v2.1.120/linux/drivers/acorn/block/ide-ics.c Mon Feb 23 18:12:03 1998 +++ linux/drivers/acorn/block/ide-ics.c Sun Sep 6 10:46:07 1998 @@ -163,6 +163,23 @@ return iftype; } +static int icside_register_port(unsigned long dataport, unsigned long ctrlport, int stepping, int irq) +{ + hw_regs_t hw; + int i; + + memset(&hw, 0, sizeof(hw)); + + for (i = IDE_DATA_OFFSET; i <= IDE_STATUS_OFFSET; i++) { + hw.io_ports[i] = (ide_ioreg_t)dataport; + dataport += 1 << stepping; + } + hw.io_ports[IDE_CONTROL_OFFSET] = ctrlport; + hw.irq = irq; + + return ide_register_hw(&hw, NULL); +} + /* Prototype: icside_register (struct expansion_card *ec) * Purpose : register an ICS IDE card with the IDE driver * Notes : we make sure that interrupts are disabled from the card @@ -189,11 +206,10 @@ * Be on the safe side - disable interrupts */ inb (port + ICS_ARCIN_V5_INTROFFSET); - result[index][0] = - ide_register_port (port + ICS_ARCIN_V5_IDEOFFSET, - port + ICS_ARCIN_V5_IDEALTOFFSET, - ICS_ARCIN_V5_IDESTEPPING, - ec->irq); + result[index][0] = icside_register_port(port + ICS_ARCIN_V5_IDEOFFSET, + port + ICS_ARCIN_V5_IDEALTOFFSET, + ICS_ARCIN_V5_IDESTEPPING, + ec->irq); break; case ics_if_arcin_v6: @@ -206,16 +222,15 @@ */ inb (port + ICS_ARCIN_V6_INTROFFSET_1); inb (port + ICS_ARCIN_V6_INTROFFSET_2); - result[index][0] = - ide_register_port (port + ICS_ARCIN_V6_IDEOFFSET_1, - port + ICS_ARCIN_V6_IDEALTOFFSET_1, - ICS_ARCIN_V6_IDESTEPPING, - ec->irq); - result[index][1] = - ide_register_port (port + ICS_ARCIN_V6_IDEOFFSET_2, - port + ICS_ARCIN_V6_IDEALTOFFSET_2, - ICS_ARCIN_V6_IDESTEPPING, - ec->irq); + + result[index][0] = icside_register_port(port + ICS_ARCIN_V6_IDEOFFSET_1, + port + ICS_ARCIN_V6_IDEALTOFFSET_1, + ICS_ARCIN_V6_IDESTEPPING, + ec->irq); + result[index][1] = icside_register_port(port + ICS_ARCIN_V6_IDEOFFSET_2, + port + ICS_ARCIN_V6_IDEALTOFFSET_2, + ICS_ARCIN_V6_IDESTEPPING, + ec->irq); break; } } diff -u --recursive --new-file v2.1.120/linux/drivers/acorn/block/ide-rapide.c linux/drivers/acorn/block/ide-rapide.c --- v2.1.120/linux/drivers/acorn/block/ide-rapide.c Fri May 8 23:14:46 1998 +++ linux/drivers/acorn/block/ide-rapide.c Sun Sep 6 10:46:07 1998 @@ -13,6 +13,7 @@ #include #include #include +#include #include "../../block/ide.h" @@ -27,8 +28,14 @@ static inline int rapide_register(struct expansion_card *ec) { unsigned long port = ecard_address (ec, ECARD_MEMC, 0); + ide_ioregspec_t spec; - return ide_register_port(port, port + 0x206, 4, ec->irq); + spec.base = port; + spec.ctrl = port + 0x206; + spec.offset = 1 << 4; + spec.irq = ec->irq; + + return ide_register_port(&spec); } int rapide_init(void) diff -u --recursive --new-file v2.1.120/linux/drivers/acorn/char/serial-card.c linux/drivers/acorn/char/serial-card.c --- v2.1.120/linux/drivers/acorn/char/serial-card.c Tue Jul 21 00:15:30 1998 +++ linux/drivers/acorn/char/serial-card.c Sun Sep 6 10:46:07 1998 @@ -1,5 +1,5 @@ /* - * linux/arch/arm/drivers/char/serial-module.c + * linux/arch/arm/drivers/char/serial-card.c * * Copyright (c) 1996 Russell King. * diff -u --recursive --new-file v2.1.120/linux/drivers/acorn/net/Makefile linux/drivers/acorn/net/Makefile --- v2.1.120/linux/drivers/acorn/net/Makefile Mon Feb 23 18:12:03 1998 +++ linux/drivers/acorn/net/Makefile Sun Sep 6 10:46:07 1998 @@ -4,7 +4,7 @@ # L_TARGET := acorn-net.a -L_OBJS := net-probe.o +L_OBJS := M_OBJS := MOD_LIST_NAME := ACORN_NET_MODULES diff -u --recursive --new-file v2.1.120/linux/drivers/acorn/net/ether3.c linux/drivers/acorn/net/ether3.c --- v2.1.120/linux/drivers/acorn/net/ether3.c Tue Jul 21 00:15:30 1998 +++ linux/drivers/acorn/net/ether3.c Sun Sep 6 10:46:07 1998 @@ -35,7 +35,6 @@ * never updates the transmit status correctly. * TODO: * When we detect a fatal error on the interface, we should restart it. - * Reap transmit packets after some time even if the buffer never filled. */ static char *version = "ether3 ethernet driver (c) 1995-1998 R.M.King v1.13\n"; @@ -98,15 +97,25 @@ buffer_read } buffer_rw_t; +/* + * ether3 read/write. Slow things down a bit... + */ +#define ether3_outb(v,r) { outb((v),(r)); udelay(1); } +#define ether3_outw(v,r) { outw((v),(r)); udelay(1); } + +#define ether3_inb(r) ({ unsigned int __v = inb((r)); udelay(1); __v; }) +#define ether3_inw(r) ({ unsigned int __v = inw((r)); udelay(1); __v; }) + static int ether3_setbuffer(struct device *dev, buffer_rw_t read, int start) { struct dev_priv *priv = (struct dev_priv *)dev->priv; int timeout = 1000; - outw(priv->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); - outw(priv->regs.command | CMD_FIFOWRITE, REG_COMMAND); - while ((inw(REG_STATUS) & STAT_FIFOEMPTY) == 0) { + ether3_outw(priv->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); + ether3_outw(priv->regs.command | CMD_FIFOWRITE, REG_COMMAND); + + while ((ether3_inw(REG_STATUS) & STAT_FIFOEMPTY) == 0) { if (!timeout--) { printk("%s: setbuffer broken\n", dev->name); priv->broken = 1; @@ -114,12 +123,13 @@ } udelay(1); } + if (read == buffer_read) { - outw(start, REG_DMAADDR); - outw(priv->regs.command | CMD_FIFOREAD, REG_COMMAND); + ether3_outw(start, REG_DMAADDR); + ether3_outw(priv->regs.command | CMD_FIFOREAD, REG_COMMAND); } else { - outw(priv->regs.command | CMD_FIFOWRITE, REG_COMMAND); - outw(start, REG_DMAADDR); + ether3_outw(priv->regs.command | CMD_FIFOWRITE, REG_COMMAND); + ether3_outw(start, REG_DMAADDR); } return 0; } @@ -159,7 +169,7 @@ { struct device *dev = (struct device *)data; struct dev_priv *priv = (struct dev_priv *)dev->priv; - outw(priv->regs.config2 |= CFG2_CTRLO, REG_CONFIG2); + ether3_outw(priv->regs.config2 |= CFG2_CTRLO, REG_CONFIG2); } /* @@ -174,7 +184,7 @@ priv->timer.function = ether3_ledoff; add_timer(&priv->timer); if (priv->regs.config2 & CFG2_CTRLO) - outw(priv->regs.config2 &= ~CFG2_CTRLO, REG_CONFIG2); + ether3_outw(priv->regs.config2 &= ~CFG2_CTRLO, REG_CONFIG2); } /* @@ -240,7 +250,7 @@ } else { if (bad != -1) { if (bad != i - 1) - printk(" - 0x%04X", i - 1); + printk(" - 0x%04X\n", i - 1); printk("\n"); bad = -1; } @@ -268,9 +278,9 @@ /* * Set up our hardware address */ - outw(priv->regs.config1 | CFG1_BUFSELSTAT0, REG_CONFIG1); + ether3_outw(priv->regs.config1 | CFG1_BUFSELSTAT0, REG_CONFIG1); for (i = 0; i < 6; i++) - outb(dev->dev_addr[i], REG_BUFWIN); + ether3_outb(dev->dev_addr[i], REG_BUFWIN); if (dev->flags & IFF_PROMISC) priv->regs.config1 |= CFG1_RECVPROMISC; @@ -284,14 +294,14 @@ * last two bytes. To get round this problem, we receive the CRC as * well. That way, if we do loose the last two, then it doesn't matter. */ - outw(priv->regs.config1 | CFG1_TRANSEND, REG_CONFIG1); - outw((TX_END>>8) - 1, REG_BUFWIN); - outw(priv->rx_head, REG_RECVPTR); - outw(0, REG_TRANSMITPTR); - outw(priv->rx_head >> 8, REG_RECVEND); - outw(priv->regs.config2, REG_CONFIG2); - outw(priv->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); - outw(priv->regs.command, REG_COMMAND); + ether3_outw(priv->regs.config1 | CFG1_TRANSEND, REG_CONFIG1); + ether3_outw((TX_END>>8) - 1, REG_BUFWIN); + ether3_outw(priv->rx_head, REG_RECVPTR); + ether3_outw(0, REG_TRANSMITPTR); + ether3_outw(priv->rx_head >> 8, REG_RECVEND); + ether3_outw(priv->regs.config2, REG_CONFIG2); + ether3_outw(priv->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); + ether3_outw(priv->regs.command, REG_COMMAND); i = ether3_ramtest(dev, 0x5A); if(i) @@ -314,16 +324,16 @@ memset(&priv->stats, 0, sizeof(struct enet_statistics)); /* Reset the chip */ - outw(CFG2_RESET, REG_CONFIG2); + ether3_outw(CFG2_RESET, REG_CONFIG2); udelay(4); priv->regs.command = 0; - outw(CMD_RXOFF|CMD_TXOFF, REG_COMMAND); - while (inw(REG_STATUS) & (STAT_RXON|STAT_TXON)); + ether3_outw(CMD_RXOFF|CMD_TXOFF, REG_COMMAND); + while (ether3_inw(REG_STATUS) & (STAT_RXON|STAT_TXON)); - outw(priv->regs.config1 | CFG1_BUFSELSTAT0, REG_CONFIG1); + ether3_outw(priv->regs.config1 | CFG1_BUFSELSTAT0, REG_CONFIG1); for (i = 0; i < 6; i++) - outb(dev->dev_addr[i], REG_BUFWIN); + ether3_outb(dev->dev_addr[i], REG_BUFWIN); priv->tx_used = 0; priv->tx_head = 0; @@ -331,36 +341,53 @@ priv->regs.config2 |= CFG2_CTRLO; priv->rx_head = RX_START; - outw(priv->regs.config1 | CFG1_TRANSEND, REG_CONFIG1); - outw((TX_END>>8) - 1, REG_BUFWIN); - outw(priv->rx_head, REG_RECVPTR); - outw(priv->rx_head >> 8, REG_RECVEND); - outw(0, REG_TRANSMITPTR); - outw(priv->regs.config2, REG_CONFIG2); - outw(priv->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); + ether3_outw(priv->regs.config1 | CFG1_TRANSEND, REG_CONFIG1); + ether3_outw((TX_END>>8) - 1, REG_BUFWIN); + ether3_outw(priv->rx_head, REG_RECVPTR); + ether3_outw(priv->rx_head >> 8, REG_RECVEND); + ether3_outw(0, REG_TRANSMITPTR); + ether3_outw(priv->regs.config2, REG_CONFIG2); + ether3_outw(priv->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); ether3_setbuffer(dev, buffer_write, 0); ether3_writelong(dev, 0); - priv->regs.command = CMD_ENINTRX; - outw(priv->regs.command | CMD_RXON, REG_COMMAND); + priv->regs.command = CMD_ENINTRX | CMD_ENINTTX; + ether3_outw(priv->regs.command | CMD_RXON, REG_COMMAND); } static inline int ether3_probe_bus_8(struct device *dev, int val) { - outb(val & 255, REG_RECVPTR); - outb(val >> 8, REG_RECVPTR + 1); + int write_low, write_high, read_low, read_high; - return inb(REG_RECVPTR) == (val & 255) && inb(REG_RECVPTR + 1) == (val >> 8); + write_low = val & 255; + write_high = val >> 8; + + printk(KERN_DEBUG "ether3_probe: write8 [%02X:%02X]", write_high, write_low); + + ether3_outb(write_low, REG_RECVPTR); + ether3_outb(write_high, REG_RECVPTR + 1); + + read_low = ether3_inb(REG_RECVPTR); + read_high = ether3_inb(REG_RECVPTR + 1); + + printk(", read8 [%02X:%02X]\n", read_high, read_low); + + return read_low == write_low && read_high == write_high; } static inline int ether3_probe_bus_16(struct device *dev, int val) { - outw(val, REG_RECVPTR); + int read_val; + + ether3_outw(val, REG_RECVPTR); + read_val = ether3_inw(REG_RECVPTR); - return inw(REG_RECVPTR) == val; + printk(KERN_DEBUG "ether3_probe: write16 [%04X], read16 [%04X]\n", val, read_val); + + return read_val == val; } /* @@ -373,13 +400,15 @@ struct dev_priv *priv; unsigned int i, bus_type, error = ENODEV; - if (net_debug && version_printed++ == 0) + if (net_debug && version_printed++ == 0) printk(version); if (!dev->priv) { dev->priv = kmalloc(sizeof (struct dev_priv), GFP_KERNEL); - if (!dev->priv) + if (!dev->priv) { + printk(KERN_ERR "ether3_probe1: no memory\n"); return -ENOMEM; + } } priv = (struct dev_priv *) dev->priv; @@ -389,7 +418,7 @@ /* Reset card... */ - outb(0x80, REG_CONFIG2 + 1); + ether3_outb(0x80, REG_CONFIG2 + 1); bus_type = BUS_UNKNOWN; udelay(4); @@ -506,11 +535,11 @@ disable_irq(dev->irq); - outw(CMD_RXOFF|CMD_TXOFF, REG_COMMAND); + ether3_outw(CMD_RXOFF|CMD_TXOFF, REG_COMMAND); priv->regs.command = 0; - while (inw(REG_STATUS) & (STAT_RXON|STAT_TXON)); - outb(0x80, REG_CONFIG2 + 1); - outw(0, REG_COMMAND); + while (ether3_inw(REG_STATUS) & (STAT_RXON|STAT_TXON)); + ether3_outb(0x80, REG_CONFIG2 + 1); + ether3_outw(0, REG_COMMAND); free_irq(dev->irq, dev); @@ -548,7 +577,34 @@ } else priv->regs.config1 |= CFG1_RECVSPECBROAD; - outw(priv->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); + ether3_outw(priv->regs.config1 | CFG1_LOCBUFMEM, REG_CONFIG1); +} + +/* + * Allocate memory in transmitter ring buffer. + */ +static int +ether3_alloc_tx(struct dev_priv *priv, int length, int alloc) +{ + int start, head, tail; + + tail = priv->tx_tail; + start = priv->tx_head; + head = start + length + 4; + + if (head >= TX_END) { + if (tail > priv->tx_head) + return -1; + head -= TX_END - TX_START; + if (tail < head) + return -1; + } else if (start < tail && tail < head) + return -1; + + if (alloc) + priv->tx_head = head; + + return start; } /* @@ -566,9 +622,9 @@ if (!test_and_set_bit(0, (void *)&dev->tbusy)) { unsigned long flags; unsigned int length = ETH_ZLEN < skb->len ? skb->len : ETH_ZLEN; - unsigned int ptr, nextptr; + int ptr; - length = (length + 3) & ~3; + length = (length + 1) & ~1; if (priv->broken) { dev_kfree_skb(skb); @@ -577,43 +633,32 @@ return 0; } - ptr = priv->tx_head; - nextptr = ptr + 0x600; - if (nextptr >= TX_END) - nextptr = 0; - if (nextptr == priv->tx_tail) - return 1; /* unable to queue */ - priv->tx_head = nextptr; - save_flags_cli(flags); + ptr = ether3_alloc_tx(priv, length, 1); + if (ptr == -1) + return 1; /* unable to queue */ + #define TXHDR_FLAGS (TXHDR_TRANSMIT|TXHDR_CHAINCONTINUE|TXHDR_DATAFOLLOWS|TXHDR_ENSUCCESS) - ether3_setbuffer(dev, buffer_write, nextptr); + ether3_setbuffer(dev, buffer_write, priv->tx_head); ether3_writelong(dev, 0); - ether3_setbuffer(dev, buffer_write, ptr + 4); + ether3_setbuffer(dev, buffer_write, ptr); + ether3_writelong(dev, 0); ether3_writebuffer(dev, skb->data, length); - ether3_writeword(dev, htons(nextptr)); - ether3_writeword(dev, (TXHDR_TRANSMIT|TXHDR_CHAINCONTINUE) >> 16); ether3_setbuffer(dev, buffer_write, ptr); - ether3_writeword(dev, htons(ptr + length + 4)); + ether3_writeword(dev, htons(priv->tx_head)); ether3_writeword(dev, TXHDR_FLAGS >> 16); ether3_ledon(dev, priv); - priv->tx_used ++; - if (priv->tx_used >= (MAX_TX_BUFFERED * 3 / 4)) { - priv->regs.command |= CMD_ENINTTX; - outw(priv->regs.command, REG_COMMAND); - } - - if (!(inw(REG_STATUS) & STAT_TXON)) { - outw(ptr, REG_TRANSMITPTR); - outw(priv->regs.command | CMD_TXON, REG_COMMAND); + if (!(ether3_inw(REG_STATUS) & STAT_TXON)) { + ether3_outw(ptr, REG_TRANSMITPTR); + ether3_outw(priv->regs.command | CMD_TXON, REG_COMMAND); } - if (priv->tx_used < MAX_TX_BUFFERED) + if (ether3_alloc_tx(priv, 2044, 0) != -1) dev->tbusy = 0; dev->trans_start = jiffies; @@ -641,9 +686,9 @@ save_flags_cli(flags); printk(KERN_ERR "%s: transmit timed out, network cable problem?\n", dev->name); printk(KERN_ERR "%s: state: { status=%04X cfg1=%04X cfg2=%04X }\n", dev->name, - inw(REG_STATUS), inw(REG_CONFIG1), inw(REG_CONFIG2)); + ether3_inw(REG_STATUS), ether3_inw(REG_CONFIG1), ether3_inw(REG_CONFIG2)); printk(KERN_ERR "%s: { rpr=%04X rea=%04X tpr=%04X }\n", dev->name, - inw(REG_RECVPTR), inw(REG_RECVEND), inw(REG_TRANSMITPTR)); + ether3_inw(REG_RECVPTR), ether3_inw(REG_RECVEND), ether3_inw(REG_TRANSMITPTR)); printk(KERN_ERR "%s: tx head=%04X tx tail=%04X\n", dev->name, priv->tx_head, priv->tx_tail); ether3_setbuffer(dev, buffer_read, priv->tx_tail); @@ -653,7 +698,7 @@ dev->tbusy = 0; priv->regs.config2 |= CFG2_CTRLO; priv->stats.tx_errors += 1; - outw(priv->regs.config2 , REG_CONFIG2); + ether3_outw(priv->regs.config2 , REG_CONFIG2); dev->trans_start = jiffies; goto retry; } @@ -674,31 +719,19 @@ priv = (struct dev_priv *)dev->priv; dev->interrupt = 1; - status = inw(REG_STATUS); - /* - * Dispite we disable the TX interrupt when the packet buffer is - * mostly empty, if we happen to get a RX interrupt, we might as - * well handle the TX packets as well. - */ - if (status & STAT_INTTX) { /* Packets transmitted */ - outw(CMD_ACKINTTX | priv->regs.command, REG_COMMAND); - ether3_tx(dev, priv); + + status = ether3_inw(REG_STATUS); + + if (status & STAT_INTRX) { + ether3_outw(CMD_ACKINTRX | priv->regs.command, REG_COMMAND); + ether3_rx(dev, priv, 12); } - status = inw(REG_STATUS); - if (status & STAT_INTRX && ether3_rx(dev, priv, 12)) { /* Got packet(s). */ - /* - * We only acknowledge the interrupt if we have received all packets - * in the buffer or else we run out of memory. This is to allow the - * bh routines to run. - */ - outw(CMD_ACKINTRX | priv->regs.command, REG_COMMAND); - /* - * Receive again if some have become available - we may have cleared - * a pending IRQ - */ - ether3_rx(dev, priv, 4); + if (status & STAT_INTTX) { + ether3_outw(CMD_ACKINTTX | priv->regs.command, REG_COMMAND); + ether3_tx(dev, priv); } + dev->interrupt = 0; #if NET_DEBUG > 1 @@ -741,13 +774,23 @@ ether3_setbuffer(dev, buffer_read, this_ptr); ether3_readbuffer(dev, addrs+2, 12); +if (next_ptr < RX_START || next_ptr >= RX_END) { + int i; + printk("%s: bad next pointer @%04X: ", dev->name, priv->rx_head); + printk("%02X %02X %02X %02X ", next_ptr >> 8, next_ptr & 255, status & 255, status >> 8); + for (i = 2; i < 14; i++) + printk("%02X ", addrs[i]); + printk("\n"); + next_ptr = priv->rx_head; + break; +} /* * ignore our own packets... */ if (!(*(unsigned long *)&dev->dev_addr[0] ^ *(unsigned long *)&addrs[2+6]) && !(*(unsigned short *)&dev->dev_addr[4] ^ *(unsigned short *)&addrs[2+10])) { maxcnt ++; /* compensate for loopedback packet */ - outw(next_ptr >> 8, REG_RECVEND); + ether3_outw(next_ptr >> 8, REG_RECVEND); } else if (!(status & (RXSTAT_OVERSIZE|RXSTAT_CRCERROR|RXSTAT_DRIBBLEERROR|RXSTAT_SHORTPACKET))) { unsigned int length = next_ptr - this_ptr; @@ -764,7 +807,7 @@ skb_reserve(skb, 2); buf = skb_put(skb, length); ether3_readbuffer(dev, buf + 12, length - 12); - outw(next_ptr >> 8, REG_RECVEND); + ether3_outw(next_ptr >> 8, REG_RECVEND); *(unsigned short *)(buf + 0) = *(unsigned short *)(addrs + 2); *(unsigned long *)(buf + 2) = *(unsigned long *)(addrs + 4); *(unsigned long *)(buf + 6) = *(unsigned long *)(addrs + 8); @@ -776,7 +819,7 @@ goto dropping; } else { struct enet_statistics *stats = &priv->stats; - outw(next_ptr >> 8, REG_RECVEND); + ether3_outw(next_ptr >> 8, REG_RECVEND); if (status & RXSTAT_OVERSIZE) stats->rx_over_errors ++; if (status & RXSTAT_CRCERROR) stats->rx_crc_errors ++; if (status & RXSTAT_DRIBBLEERROR) stats->rx_fifo_errors ++; @@ -793,10 +836,10 @@ * If rx went off line, then that means that the buffer may be full. We * have dropped at least one packet. */ - if (!(inw(REG_STATUS) & STAT_RXON)) { + if (!(ether3_inw(REG_STATUS) & STAT_RXON)) { priv->stats.rx_dropped ++; - outw(next_ptr, REG_RECVPTR); - outw(priv->regs.command | CMD_RXON, REG_COMMAND); + ether3_outw(next_ptr, REG_RECVPTR); + ether3_outw(priv->regs.command | CMD_RXON, REG_COMMAND); } return maxcnt; @@ -804,7 +847,7 @@ dropping:{ static unsigned long last_warned; - outw(next_ptr >> 8, REG_RECVEND); + ether3_outw(next_ptr >> 8, REG_RECVEND); /* * Don't print this message too many times... */ @@ -852,15 +895,13 @@ if (status & TXSTAT_BABBLED) priv->stats.tx_fifo_errors ++; } - /* - * Get next packet address - */ - tx_tail += 0x600; - if (tx_tail >= TX_END) - tx_tail = 0; - - if (priv->tx_used) - priv->tx_used--; + tx_tail = htons(status & TX_NEXT); + if (tx_tail < TX_START || tx_tail >= TX_END) { + printk("%s: transmit error: next pointer = %04X\n", dev->name, tx_tail); + tx_tail = TX_START; + priv->tx_head = TX_START; + priv->tx_tail = TX_END; + } } while (1); if (priv->tx_tail != tx_tail) { @@ -870,8 +911,6 @@ mark_bh(NET_BH); /* Inform upper layers. */ } } - priv->regs.command &= ~CMD_ENINTTX; - outw(priv->regs.command, REG_COMMAND); } #ifdef MODULE diff -u --recursive --new-file v2.1.120/linux/drivers/acorn/net/ether3.h linux/drivers/acorn/net/ether3.h --- v2.1.120/linux/drivers/acorn/net/ether3.h Mon Feb 23 18:12:03 1998 +++ linux/drivers/acorn/net/ether3.h Sun Sep 6 10:46:07 1998 @@ -64,6 +64,12 @@ #define CFG1_TRANSEND 0x0007 #define CFG1_LOCBUFMEM 0x0008 #define CFG1_INTVECTOR 0x0009 +#define CFG1_RECVSPECONLY 0x0000 +#define CFG1_RECVSPECBROAD 0x4000 +#define CFG1_RECVSPECBRMULTI 0x8000 +#define CFG1_RECVPROMISC 0xC000 + +/* The following aren't in 8004 */ #define CFG1_DMABURSTCONT 0x0000 #define CFG1_DMABURST800NS 0x0010 #define CFG1_DMABURST1600NS 0x0020 @@ -78,10 +84,6 @@ #define CFG1_RECVCOMPSTAT3 0x0800 #define CFG1_RECVCOMPSTAT4 0x1000 #define CFG1_RECVCOMPSTAT5 0x2000 -#define CFG1_RECVSPECONLY 0x0000 -#define CFG1_RECVSPECBROAD 0x4000 -#define CFG1_RECVSPECBRMULTI 0x8000 -#define CFG1_RECVPROMISC 0xC000 /* configuration register 2 */ #define REG_CONFIG2 (dev->base_addr + 0x20) @@ -134,6 +136,7 @@ #define RXSTAT_DONE (1 << 15) +#define TX_START 0x0000 #define TX_END 0x6000 #define RX_START 0x6000 #define RX_LEN 0xA000 diff -u --recursive --new-file v2.1.120/linux/drivers/acorn/scsi/cumana_2.c linux/drivers/acorn/scsi/cumana_2.c --- v2.1.120/linux/drivers/acorn/scsi/cumana_2.c Tue Jul 21 00:15:30 1998 +++ linux/drivers/acorn/scsi/cumana_2.c Sun Sep 6 10:46:07 1998 @@ -9,6 +9,7 @@ * 15-04-1998 RMK 0.0.1 Only do PIO if FAS216 will allow it. * 02-05-1998 RMK 0.0.2 Updated & added DMA support * 27-06-1998 RMK Changed asm/delay.h to linux/delay.h + * 18-08-1998 RMK 0.0.3 Fixed synchronous transfer depth */ #include @@ -35,7 +36,7 @@ /* Configuration */ #define CUMANASCSI2_XTALFREQ 40 #define CUMANASCSI2_ASYNC_PERIOD 200 -#define CUMANASCSI2_SYNC_DEPTH 8 +#define CUMANASCSI2_SYNC_DEPTH 7 /* * List of devices that the driver will recognise @@ -69,7 +70,7 @@ */ #define VER_MAJOR 0 #define VER_MINOR 0 -#define VER_PATCH 2 +#define VER_PATCH 3 static struct expansion_card *ecs[MAX_ECARDS]; @@ -157,13 +158,10 @@ { unsigned int page; - if (direction == DMA_OUT) { - for (page = (unsigned int) addr; len > 0; - page += PAGE_SIZE, len -= PAGE_SIZE) - flush_page_to_ram(page); - } else - flush_cache_range(current->mm, (unsigned long)addr, - (unsigned long)addr + len); + if (direction == DMA_OUT) + dma_cache_wback((unsigned long)addr, (unsigned long)len); + else + dma_cache_inv((unsigned long)addr, (unsigned long)len); } /* Prototype: fasdmatype_t cumanascsi_2_dma_setup(host, SCpnt, direction, min_type) diff -u --recursive --new-file v2.1.120/linux/drivers/acorn/scsi/eesox.c linux/drivers/acorn/scsi/eesox.c --- v2.1.120/linux/drivers/acorn/scsi/eesox.c Tue Jul 21 00:15:30 1998 +++ linux/drivers/acorn/scsi/eesox.c Sun Sep 6 10:46:07 1998 @@ -166,13 +166,10 @@ { unsigned int page; - if (direction == DMA_OUT) { - for(page = (unsigned int) addr; len > 0; - page += PAGE_SIZE, len -= PAGE_SIZE) - flush_page_to_ram(page); - } else - flush_cache_range(current->mm, (unsigned long)addr, - (unsigned long)addr + len); + if (direction == DMA_OUT) + dma_cache_wback((unsigned long)addr, (unsigned long)len); + else + dma_cache_inv((unsigned long)addr, (unsigned long)len); } /* Prototype: fasdmatype_t eesoxscsi_dma_setup(host, SCpnt, direction, min_type) diff -u --recursive --new-file v2.1.120/linux/drivers/acorn/scsi/powertec.c linux/drivers/acorn/scsi/powertec.c --- v2.1.120/linux/drivers/acorn/scsi/powertec.c Tue Jul 21 00:15:30 1998 +++ linux/drivers/acorn/scsi/powertec.c Sun Sep 6 10:46:07 1998 @@ -154,13 +154,10 @@ { unsigned int page; - if (direction == DMA_OUT) { - for (page = (unsigned int) addr; len > 0; - page += PAGE_SIZE, len -= PAGE_SIZE) - flush_page_to_ram(page); - } else - flush_cache_range(current->mm, (unsigned long)addr, - (unsigned long)addr + len); + if (direction == DMA_OUT) + dma_cache_wback((unsigned long)addr, (unsigned long)len); + else + dma_cache_inv((unsigned long)addr, (unsigned long)len); } /* Prototype: fasdmatype_t powertecscsi_dma_setup(host, SCpnt, direction, min_type) diff -u --recursive --new-file v2.1.120/linux/drivers/block/floppy.c linux/drivers/block/floppy.c --- v2.1.120/linux/drivers/block/floppy.c Wed Aug 26 11:37:35 1998 +++ linux/drivers/block/floppy.c Tue Sep 8 16:20:19 1998 @@ -233,7 +233,7 @@ /* End dma memory related stuff */ -static unsigned int fake_change = 0; +static unsigned long fake_change = 0; static int initialising=1; static inline int TYPE(kdev_t x) { diff -u --recursive --new-file v2.1.120/linux/drivers/block/ide-probe.c linux/drivers/block/ide-probe.c --- v2.1.120/linux/drivers/block/ide-probe.c Tue Aug 18 22:02:03 1998 +++ linux/drivers/block/ide-probe.c Tue Sep 8 10:39:27 1998 @@ -13,7 +13,7 @@ * Version 1.00 move drive probing code from ide.c to ide-probe.c * Version 1.01 fix compilation problem for m68k * Version 1.02 increase WAIT_PIDENTIFY to avoid CD-ROM locking at boot - * by Andrea Arcangeli + * by Andrea Arcangeli * Version 1.03 fix for (hwif->chipset == ide_4drives) */ diff -u --recursive --new-file v2.1.120/linux/drivers/block/ide-tape.c linux/drivers/block/ide-tape.c --- v2.1.120/linux/drivers/block/ide-tape.c Thu May 7 22:51:48 1998 +++ linux/drivers/block/ide-tape.c Sat Sep 5 17:01:45 1998 @@ -3708,6 +3708,7 @@ idetape_chrdev_ioctl, /* ioctl */ NULL, /* mmap */ idetape_chrdev_open, /* open */ + NULL, /* flush */ idetape_chrdev_release, /* release */ NULL, /* fsync */ NULL, /* fasync */ diff -u --recursive --new-file v2.1.120/linux/drivers/cdrom/cdrom.c linux/drivers/cdrom/cdrom.c --- v2.1.120/linux/drivers/cdrom/cdrom.c Wed Aug 26 11:37:36 1998 +++ linux/drivers/cdrom/cdrom.c Tue Sep 8 10:39:27 1998 @@ -76,7 +76,7 @@ of the drive. Thanks to Tobias Ringstr|m for pointing this out and providing a simple fix. -- Fixed the procfs-unload-module bug with the fill_inode procfs callback. - thanks to Andrea Arcangeli + thanks to Andrea Arcangeli -- Fixed it so that the /proc entry now also shows up when cdrom is compiled into the kernel. Before it only worked when loaded as a module. diff -u --recursive --new-file v2.1.120/linux/drivers/char/bttv.c linux/drivers/char/bttv.c --- v2.1.120/linux/drivers/char/bttv.c Sat Sep 5 16:46:40 1998 +++ linux/drivers/char/bttv.c Sat Sep 5 18:33:41 1998 @@ -1801,6 +1801,9 @@ case VIDIOCSYNC: if(copy_from_user((void *)&i,arg,sizeof(int))) return -EFAULT; + if(i>1 || i<0) + return -EINVAL; + switch (btv->frame_stat[i]) { case GBUFFER_UNUSED: return -EINVAL; diff -u --recursive --new-file v2.1.120/linux/drivers/char/cyclades.c linux/drivers/char/cyclades.c --- v2.1.120/linux/drivers/char/cyclades.c Sat Sep 5 16:46:40 1998 +++ linux/drivers/char/cyclades.c Sat Sep 5 17:01:45 1998 @@ -4974,7 +4974,7 @@ if (info->count) size = sprintf(buf+len, - "%3d %8lu %10lu %8lu %10lu %8lu %9lu %6d\n", + "%3d %8lu %10lu %8lu %10lu %8lu %9lu %6ld\n", info->line, JIFFIES_DIFF(info->idle_stats.in_use, cur_jifs) / HZ, info->idle_stats.xmit_bytes, diff -u --recursive --new-file v2.1.120/linux/drivers/char/lp.c linux/drivers/char/lp.c --- v2.1.120/linux/drivers/char/lp.c Wed Aug 26 11:37:37 1998 +++ linux/drivers/char/lp.c Tue Sep 8 10:39:27 1998 @@ -13,7 +13,7 @@ * lp_read (Status readback) support added by Carsten Gross, * carsten@sol.wohnheim.uni-ulm.de * Support for parport by Philip Blundell - * Parport sharing hacking by Andrea Arcangeli + * Parport sharing hacking by Andrea Arcangeli * Fixed kernel_(to/from)_user memory copy to check for errors * by Riccardo Facchetti * Interrupt handling workaround for printers with buggy handshake diff -u --recursive --new-file v2.1.120/linux/drivers/char/pc110pad.c linux/drivers/char/pc110pad.c --- v2.1.120/linux/drivers/char/pc110pad.c Wed Aug 26 11:37:37 1998 +++ linux/drivers/char/pc110pad.c Sat Sep 5 17:01:45 1998 @@ -18,7 +18,6 @@ #include #include -#include #include #include #include diff -u --recursive --new-file v2.1.120/linux/drivers/char/pc_keyb.c linux/drivers/char/pc_keyb.c --- v2.1.120/linux/drivers/char/pc_keyb.c Sat Sep 5 16:46:40 1998 +++ linux/drivers/char/pc_keyb.c Sun Sep 6 13:39:09 1998 @@ -43,194 +43,6 @@ "\r\000/"; /* 0x60 - 0x6f */ #endif -/* - * In case we run on a non-x86 hardware we need to initialize both the keyboard - * controller and the keyboard. On a x86, the BIOS will already have initialized - * them. - */ - -/* - * Some x86 BIOSes do not correctly initialize the keyboard, so the - * "kbd-reset" command line options can be given to force a reset. - * [Ranger] - */ -#ifdef __i386__ - int kbd_startup_reset __initdata = 0; -#else - int kbd_startup_reset __initdata = 1; -#endif - -__initfunc(static int kbd_wait_for_input(void)) -{ - long timeout = KBD_INIT_TIMEOUT; - int retval = -1; - - goto in_loop; - for (;;) { - unsigned char status, data; - if (--timeout < 0) - break; - mdelay(1); -in_loop: - status = inb(KBD_STATUS_REG); - - /* - * Wait for input data to become available. This bit will - * then be cleared by the following read of the DATA - * register. - */ - if (!(status & KBD_STAT_OBF)) - continue; - - data = inb(KBD_DATA_REG); - - /* - * Check to see if a timeout error has occurred. This means - * that transmission was started but did not complete in the - * normal time cycle. PERR is set when a parity error occurred - * in the last transmission. - */ - if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) - continue; - - retval = data; - break; - } - return retval; -} - -__initfunc(static void kbd_write(int address, int data)) -{ - int status; - - do { - status = inb(KBD_STATUS_REG); - } while (status & KBD_STAT_IBF); - outb(data, address); -} - -__initfunc(static char *initialize_kbd2(void)) -{ - int status; - - /* Flush any pending input. */ - - while (kbd_wait_for_input() != -1) - ; - - /* - * Test the keyboard interface. - * This seems to be the only way to get it going. - * If the test is successful a x55 is placed in the input buffer. - */ - - kbd_write(KBD_CNTL_REG, KBD_CCMD_SELF_TEST); - if (kbd_wait_for_input() != 0x55) - return "Keyboard failed self test"; - - /* - * Perform a keyboard interface test. This causes the controller - * to test the keyboard clock and data lines. The results of the - * test are placed in the input buffer. - */ - - kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_TEST); - if (kbd_wait_for_input() != 0x00) - return "Keyboard interface failed self test"; - - /* Enable the keyboard by allowing the keyboard clock to run. */ - - kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_ENABLE); - - /* - * Reset keyboard. If the read times out - * then the assumption is that no keyboard is - * plugged into the machine. - * This defaults the keyboard to scan-code set 2. - * - * Set up to try again if the keyboard asks for RESEND. - */ - - do { - kbd_write(KBD_DATA_REG, KBD_CMD_RESET); - status = kbd_wait_for_input(); - if (status == KBD_REPLY_ACK) - break; - else if (status != KBD_REPLY_RESEND) - return "Keyboard reset failed, no ACK"; - } while (1); - - if (kbd_wait_for_input() != KBD_REPLY_POR) - return "Keyboard reset failed, no POR"; - - /* - * Set keyboard controller mode. During this, the keyboard should be - * in the disabled state. - * - * Set up to try again if the keyboard asks for RESEND. - */ - - do { - kbd_write(KBD_DATA_REG, KBD_CMD_DISABLE); - status = kbd_wait_for_input(); - if (status == KBD_REPLY_ACK) - break; - else if (status != KBD_REPLY_RESEND) - return "Disable keyboard: no ACK"; - } while (1); - - kbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE); - kbd_write(KBD_DATA_REG, KBD_MODE_KBD_INT - | KBD_MODE_SYS - | KBD_MODE_DISABLE_MOUSE - | KBD_MODE_KCC); - - /* ibm powerpc portables need this to use scan-code set 1 -- Cort */ - kbd_write(KBD_CNTL_REG, KBD_CCMD_READ_MODE); - if (!(kbd_wait_for_input() & KBD_MODE_KCC)) { - /* - * If the controller does not support conversion, - * Set the keyboard to scan-code set 1. - */ - kbd_write(KBD_DATA_REG, 0xF0); - kbd_wait_for_input(); - kbd_write(KBD_DATA_REG, 0x01); - kbd_wait_for_input(); - } - - - kbd_write(KBD_DATA_REG, KBD_CMD_ENABLE); - if (kbd_wait_for_input() != KBD_REPLY_ACK) - return "Enable keyboard: no ACK"; - - /* - * Finally, set the typematic rate to maximum. - */ - - kbd_write(KBD_DATA_REG, KBD_CMD_SET_RATE); - if (kbd_wait_for_input() != KBD_REPLY_ACK) - return "Set rate: no ACK"; - kbd_write(KBD_DATA_REG, 0x00); - if (kbd_wait_for_input() != KBD_REPLY_ACK) - return "Set rate: no ACK"; - - return NULL; -} - -__initfunc(static void initialize_kbd(void)) -{ - char *msg; - - disable_irq(KEYBOARD_IRQ); - msg = initialize_kbd2(); - enable_irq(KEYBOARD_IRQ); - - if (msg) - printk(KERN_WARNING "initialize_kbd: %s\n", msg); -} - - - unsigned char pckbd_read_mask = KBD_STAT_OBF; /* Modified by psaux.c */ /* used only by send_data - set by keyboard_interrupt */ @@ -625,15 +437,189 @@ send_data(KBD_CMD_ENABLE); /* re-enable kbd if any errors */ } -__initfunc(void pckbd_init_hw(void)) -{ - request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL); - request_region(0x60, 16, "keyboard"); - if (kbd_startup_reset) initialize_kbd(); -} +/* + * In case we run on a non-x86 hardware we need to initialize both the + * keyboard controller and the keyboard. On a x86, the BIOS will + * already have initialized them. + * + * Some x86 BIOSes do not correctly initialize the keyboard, so the + * "kbd-reset" command line options can be given to force a reset. + * [Ranger] + */ +#ifdef __i386__ + int kbd_startup_reset __initdata = 0; +#else + int kbd_startup_reset __initdata = 1; +#endif /* for "kbd-reset" cmdline param */ -__initfunc(void kbd_reset_setup(char *str, int *ints)) +void __init kbd_reset_setup(char *str, int *ints) { kbd_startup_reset = 1; +} + +#define KBD_NO_DATA (-1) /* No data */ +#define KBD_BAD_DATA (-2) /* Parity or other error */ + +static int __init kbd_read_input(void) +{ + int retval = KBD_NO_DATA; + unsigned char status; + + status = inb(KBD_STATUS_REG); + if (status & KBD_STAT_OBF) { + unsigned char data = inb(KBD_DATA_REG); + + retval = data; + if (status & (KBD_STAT_GTO | KBD_STAT_PERR)) + retval = KBD_BAD_DATA; + } + return retval; +} + +static void __init kbd_clear_input(void) +{ + int maxread = 100; /* Random number */ + + do { + if (kbd_read_input() == KBD_NO_DATA) + break; + } while (--maxread); +} + +static int __init kbd_wait_for_input(void) +{ + long timeout = KBD_INIT_TIMEOUT; + + do { + int retval = kbd_read_input(); + if (retval >= 0) + return retval; + mdelay(1); + } while (--timeout); + return -1; +} + +static void __init kbd_write(int address, int data) +{ + int status; + + do { + status = inb(KBD_STATUS_REG); + } while (status & KBD_STAT_IBF); + outb(data, address); +} + +static char * __init initialize_kbd(void) +{ + int status; + + /* + * Test the keyboard interface. + * This seems to be the only way to get it going. + * If the test is successful a x55 is placed in the input buffer. + */ + kbd_write(KBD_CNTL_REG, KBD_CCMD_SELF_TEST); + if (kbd_wait_for_input() != 0x55) + return "Keyboard failed self test"; + + /* + * Perform a keyboard interface test. This causes the controller + * to test the keyboard clock and data lines. The results of the + * test are placed in the input buffer. + */ + kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_TEST); + if (kbd_wait_for_input() != 0x00) + return "Keyboard interface failed self test"; + + /* + * Enable the keyboard by allowing the keyboard clock to run. + */ + kbd_write(KBD_CNTL_REG, KBD_CCMD_KBD_ENABLE); + + /* + * Reset keyboard. If the read times out + * then the assumption is that no keyboard is + * plugged into the machine. + * This defaults the keyboard to scan-code set 2. + * + * Set up to try again if the keyboard asks for RESEND. + */ + do { + kbd_write(KBD_DATA_REG, KBD_CMD_RESET); + status = kbd_wait_for_input(); + if (status == KBD_REPLY_ACK) + break; + if (status != KBD_REPLY_RESEND) + return "Keyboard reset failed, no ACK"; + } while (1); + + if (kbd_wait_for_input() != KBD_REPLY_POR) + return "Keyboard reset failed, no POR"; + + /* + * Set keyboard controller mode. During this, the keyboard should be + * in the disabled state. + * + * Set up to try again if the keyboard asks for RESEND. + */ + do { + kbd_write(KBD_DATA_REG, KBD_CMD_DISABLE); + status = kbd_wait_for_input(); + if (status == KBD_REPLY_ACK) + break; + if (status != KBD_REPLY_RESEND) + return "Disable keyboard: no ACK"; + } while (1); + + kbd_write(KBD_CNTL_REG, KBD_CCMD_WRITE_MODE); + kbd_write(KBD_DATA_REG, KBD_MODE_KBD_INT + | KBD_MODE_SYS + | KBD_MODE_DISABLE_MOUSE + | KBD_MODE_KCC); + + /* ibm powerpc portables need this to use scan-code set 1 -- Cort */ + kbd_write(KBD_CNTL_REG, KBD_CCMD_READ_MODE); + if (!(kbd_wait_for_input() & KBD_MODE_KCC)) { + /* + * If the controller does not support conversion, + * Set the keyboard to scan-code set 1. + */ + kbd_write(KBD_DATA_REG, 0xF0); + kbd_wait_for_input(); + kbd_write(KBD_DATA_REG, 0x01); + kbd_wait_for_input(); + } + + + kbd_write(KBD_DATA_REG, KBD_CMD_ENABLE); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Enable keyboard: no ACK"; + + /* + * Finally, set the typematic rate to maximum. + */ + kbd_write(KBD_DATA_REG, KBD_CMD_SET_RATE); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Set rate: no ACK"; + kbd_write(KBD_DATA_REG, 0x00); + if (kbd_wait_for_input() != KBD_REPLY_ACK) + return "Set rate: no ACK"; + + return NULL; +} + +void __init pckbd_init_hw(void) +{ + /* Flush any pending input. */ + kbd_clear_input(); + + if (kbd_startup_reset) { + char *msg = initialize_kbd(); + if (msg) + printk(KERN_WARNING "initialize_kbd: %s\n", msg); + } + + request_irq(KEYBOARD_IRQ, keyboard_interrupt, 0, "keyboard", NULL); + request_region(0x60, 16, "keyboard"); } diff -u --recursive --new-file v2.1.120/linux/drivers/misc/parport_pc.c linux/drivers/misc/parport_pc.c --- v2.1.120/linux/drivers/misc/parport_pc.c Tue Jul 21 00:15:31 1998 +++ linux/drivers/misc/parport_pc.c Tue Sep 8 10:39:27 1998 @@ -4,7 +4,7 @@ * Tim Waugh * Jose Renau * David Campbell - * Andrea Arcangeli + * Andrea Arcangeli * * based on work by Grant Guenther and Phil Blundell. */ diff -u --recursive --new-file v2.1.120/linux/drivers/misc/parport_procfs.c linux/drivers/misc/parport_procfs.c --- v2.1.120/linux/drivers/misc/parport_procfs.c Thu Aug 6 14:06:32 1998 +++ linux/drivers/misc/parport_procfs.c Tue Sep 8 10:39:27 1998 @@ -3,7 +3,7 @@ * Authors: David Campbell * Tim Waugh * Philip Blundell - * Andrea Arcangeli + * Andrea Arcangeli * Riccardo Facchetti * * based on work by Grant Guenther diff -u --recursive --new-file v2.1.120/linux/drivers/misc/parport_share.c linux/drivers/misc/parport_share.c --- v2.1.120/linux/drivers/misc/parport_share.c Tue Jul 21 00:15:31 1998 +++ linux/drivers/misc/parport_share.c Tue Sep 8 10:39:27 1998 @@ -5,7 +5,7 @@ * Tim Waugh * Jose Renau * Philip Blundell - * Andrea Arcangeli + * Andrea Arcangeli * * based on work by Grant Guenther * and Philip Blundell diff -u --recursive --new-file v2.1.120/linux/drivers/net/Config.in linux/drivers/net/Config.in --- v2.1.120/linux/drivers/net/Config.in Mon Aug 3 12:45:45 1998 +++ linux/drivers/net/Config.in Sun Sep 6 10:47:01 1998 @@ -203,6 +203,10 @@ # # WAN drivers support # +# There is no way to detect a comtrol sv11 - force it modular for now. +# +dep_tristate 'Comtrol Hostess SV-11 support' CONFIG_HOSTESS_SV11 m +# if [ "$CONFIG_WAN_ROUTER" != "n" ]; then bool 'WAN drivers' CONFIG_WAN_DRIVERS if [ "$CONFIG_WAN_DRIVERS" = "y" ]; then diff -u --recursive --new-file v2.1.120/linux/drivers/net/Makefile linux/drivers/net/Makefile --- v2.1.120/linux/drivers/net/Makefile Mon Aug 3 12:45:45 1998 +++ linux/drivers/net/Makefile Sun Sep 6 10:47:01 1998 @@ -24,6 +24,10 @@ CONFIG_7990_MODULE := CONFIG_82596_BUILTIN := CONFIG_82596_MODULE := +CONFIG_85230_BUILTIN := +CONFIG_85230_MODULE := +CONFIG_SYNCPPP_BUILTIN := +CONFIG_SYNCPPP_MODULE := ifeq ($(CONFIG_ISDN),y) ifeq ($(CONFIG_ISDN_PPP),y) @@ -283,8 +287,8 @@ endif endif -# bsd_comp.o is *always* a module, for some undocumented reason -# (perhaps licensing). +# bsd_comp.o is *always* a module, for some documented reason +# (licensing). ifeq ($(CONFIG_PPP),y) LX_OBJS += ppp.o M_OBJS += bsd_comp.o @@ -689,6 +693,40 @@ else ifeq ($(CONFIG_EPIC100),m) M_OBJS += epic100.o + endif +endif + +ifeq ($(CONFIG_HOSTESS_SV11),y) +L_OBJS += hostess_sv11.o +CONFIG_85230_BUILTIN = y +CONFIG_SYNCPPP_BUILTIN = y +else + ifeq ($(CONFIG_HOSTESS_SV11),m) + CONFIG_85230_MODULE = y + CONFIG_SYNCPPP_MODULE = y + M_OBJS += hostess_sv11.o + endif +endif + +# If anything built-in uses syncppp, then build it into the kernel also. +# If not, but a module uses it, build as a module. + +ifdef CONFIG_SYNCPPP_BUILTIN +LX_OBJS += syncppp.o +else + ifdef CONFIG_SYNCPPP_MODULE + MX_OBJS += syncppp.o + endif +endif + +# If anything built-in uses Z85230, then build it into the kernel also. +# If not, but a module uses it, build as a module. + +ifdef CONFIG_85230_BUILTIN +LX_OBJS += z85230.o +else + ifdef CONFIG_85230_MODULE + MX_OBJS += z85230.o endif endif diff -u --recursive --new-file v2.1.120/linux/drivers/net/hostess_sv11.c linux/drivers/net/hostess_sv11.c --- v2.1.120/linux/drivers/net/hostess_sv11.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/hostess_sv11.c Sun Sep 6 10:47:01 1998 @@ -0,0 +1,386 @@ +/* + * Comtrol SV11 card driver + * + * This is a slightly odd Z85230 synchronous driver. All you need to + * know basically is + * + * Its a genuine Z85230 + * + * It supports DMA using two DMA channels in SYNC mode. The driver doesn't + * use these facilities (yet). + * + * The control port is at io+1, the data at io+3 and turning off the DMA + * is done by writing 0 to io+4 + * + * The hardware does the bus handling to avoid the need for delays between + * touching control registers. + * + * Port B isnt wired (why - beats me) + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include "syncppp.h" +#include "z85230.h" + +static int dma; + +struct sv11_device +{ + struct z8530_dev sync; + struct ppp_device netdev; + char name[16]; +}; + +/* + * Network driver support routines + */ + +/* + * Frame receive. Simple for our card as we do sync ppp and there + * is no funny garbage involved. This is very timing sensitive. + */ + +static void hostess_input(struct z8530_channel *c, struct sk_buff *skb) +{ + /* Drop the CRC - its not a good idea to try and negotiate it ;) */ + skb_trim(skb, skb->len-2); + skb->protocol=htons(ETH_P_WAN_PPP); + skb->dev=c->netdevice; + /* + * Send it to the PPP layer. We dont have time to process + * it right now. + */ + skb->mac.raw = skb->data; + + netif_rx(skb); +} + +/* + * We've been placed in the UP state + */ + +static int hostess_open(struct device *d) +{ + struct sv11_device *sv11=d->priv; + int err; + + /* + * Link layer up + */ + if(dma) + err=z8530_sync_dma_open(d, &sv11->sync.chanA); + else + err=z8530_sync_open(d, &sv11->sync.chanA); + if(err) + return err; + /* + * Begin PPP + */ + err=sppp_open(d); + if(err) + { + if(dma) + z8530_sync_dma_close(d, &sv11->sync.chanA); + else + z8530_sync_close(d, &sv11->sync.chanA); + return err; + } + sv11->sync.chanA.rx_function=hostess_input; + + /* + * Go go go + */ + d->tbusy=0; + MOD_INC_USE_COUNT; + return 0; +} + +static int hostess_close(struct device *d) +{ + struct sv11_device *sv11=d->priv; + /* + * Discard new frames + */ + sv11->sync.chanA.rx_function=z8530_null_rx; + /* + * PPP off + */ + sppp_close(d); + /* + * Link layer down + */ + d->tbusy=1; + if(dma) + z8530_sync_dma_close(d, &sv11->sync.chanA); + else + z8530_sync_close(d, &sv11->sync.chanA); + MOD_DEC_USE_COUNT; + return 0; +} + +static int hostess_ioctl(struct device *d, struct ifreq *ifr, int cmd) +{ + struct sv11_device *sv11=d->priv; + /* z8530_ioctl(d,&sv11->sync.chanA,ifr,cmd) */ + return sppp_do_ioctl(d, ifr, cmd); +} + +static struct net_device_stats *hostess_get_stats(struct device *d) +{ + struct sv11_device *sv11=d->priv; + if(sv11) + return z8530_get_stats(&sv11->sync.chanA); + else + return NULL; +} + +/* + * Passed PPP frames, fire them downwind. + */ + +static int hostess_queue_xmit(struct sk_buff *skb, struct device *d) +{ + struct sv11_device *sv11=d->priv; + return z8530_queue_xmit(&sv11->sync.chanA, skb); +} + +static int hostess_neigh_setup(struct neighbour *n) +{ + if (n->nud_state == NUD_NONE) { + n->ops = &arp_broken_ops; + n->output = n->ops->output; + } + return 0; +} + +static int hostess_neigh_setup_dev(struct device *dev, struct neigh_parms *p) +{ + if (p->tbl->family == AF_INET) { + p->neigh_setup = hostess_neigh_setup; + p->ucast_probes = 0; + p->mcast_probes = 0; + } + return 0; +} + +/* + * Description block for a Comtrol Hostess SV11 card + */ + +static struct sv11_device *sv11_init(int iobase, int irq) +{ + struct z8530_dev *dev; + struct sv11_device *sv; + int i; + unsigned long flags; + + /* + * Get the needed I/O space + */ + + if(check_region(iobase, 8)) + { + printk(KERN_WARNING "hostess: I/O 0x%X already in use.\n", iobase); + return NULL; + } + request_region(iobase, 8, "Comtrol SV11"); + + sv=(struct sv11_device *)kmalloc(sizeof(struct sv11_device), GFP_KERNEL); + if(!sv) + goto fail3; + + memset(sv, 0, sizeof(*sv)); + + dev=&sv->sync; + + /* + * Stuff in the I/O addressing + */ + + dev->active = 0; + + dev->chanA.ctrlio=iobase+1; + dev->chanA.dataio=iobase+3; + dev->chanB.ctrlio=-1; + dev->chanB.dataio=-1; + dev->chanA.irqs=&z8530_nop; + dev->chanB.irqs=&z8530_nop; + + outb(0, iobase+4); /* DMA off */ + + /* We want a fast IRQ for this device. Actually we'd like an even faster + IRQ ;) - This is one driver RtLinux is made for */ + + if(request_irq(irq, &z8530_interrupt, SA_INTERRUPT, "Hostess SV/11", dev)<0) + { + printk(KERN_WARNING "hostess: IRQ %d already in use.\n", irq); + goto fail2; + } + + dev->irq=irq; + dev->chanA.private=sv; + dev->chanA.netdevice=&sv->netdev.dev; + dev->chanA.dev=dev; + dev->chanB.dev=dev; + dev->name=sv->name; + + if(dma) + { + /* + * You can have DMA off or 1 and 3 thats the lot + * on the Comtrol. + */ + dev->chanA.txdma=1; + dev->chanA.rxdma=3; + outb(14, iobase+4); /* DMA on */ + if(request_dma(dev->chanA.txdma, "Hostess SV/11 (TX)")!=0) + goto fail; + if(request_dma(dev->chanA.rxdma, "Hostess SV/11 (RX)")!=0) + goto dmafail; + } + save_flags(flags); + cli(); + + /* + * Begin normal initialise + */ + + if(z8530_init(dev)!=0) + goto dmafail2; + z8530_channel_load(&dev->chanB, z8530_dead_port); + if(dev->type==Z85C30) + z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream); + else + z8530_channel_load(&dev->chanA, z8530_hdlc_kilostream_85230); + + restore_flags(flags); + + + printk(KERN_INFO "begin loading hdlc\n"); + + /* + * Now we can take the IRQ + */ + + for(i=0;i<999;i++) + { + sprintf(sv->name,"hdlc%d", i); + if(dev_get(sv->name)==NULL) + { + struct device *d=dev->chanA.netdevice; + + /* + * Initialise the PPP components + */ + sppp_attach(&sv->netdev); + + /* + * Local fields + */ + sprintf(sv->name,"hdlc%d", i); + printk("Filling in device '%s' at %p\n", sv->name, d); + + d->name = sv->name; + d->base_addr = iobase; + d->irq = irq; + d->priv = sv; + d->init = NULL; + + d->open = hostess_open; + d->stop = hostess_close; + d->hard_start_xmit = hostess_queue_xmit; + d->get_stats = hostess_get_stats; + d->set_multicast_list = NULL; + d->do_ioctl = hostess_ioctl; + d->neigh_setup = hostess_neigh_setup_dev; + dev_init_buffers(d); + d->set_mac_address = NULL; + + if(register_netdev(d)==-1) + { + printk(KERN_ERR "%s: unable to register device.\n", + sv->name); + goto fail; + } + + z8530_describe(dev, "I/O", iobase); + dev->active=1; + return sv; + } + } +dmafail2: + if(!dma) + goto fail; + free_dma(dev->chanA.rxdma); +dmafail: + free_dma(dev->chanA.txdma); +fail: + free_irq(irq, dev); +fail2: + kfree(sv); +fail3: + release_region(iobase,8); + return NULL; +} + +static void sv11_shutdown(struct sv11_device *dev) +{ + sppp_detach(&dev->netdev.dev); + z8530_shutdown(&dev->sync); + unregister_netdev(&dev->netdev.dev); + free_irq(dev->sync.irq, dev); + free_dma(dev->sync.chanA.rxdma); + free_dma(dev->sync.chanA.txdma); + release_region(dev->sync.chanA.ctrlio-1, 8); +} + +#ifdef MODULE + +static int io=0x200; +static int irq=9; + +MODULE_PARM(io,"i"); +MODULE_PARM_DESC(io, "The I/O base of the Comtrol Hostess SV11 card"); +MODULE_PARM(dma,"i"); +MODULE_PARM_DESC(dma, "Set this to 1 to use DMA1/DMA3 for TX/RX"); +MODULE_PARM(irq,"i"); +MODULE_PARM_DESC(irq, "The interrupt line setting for the Comtrol Hostess SV11 card"); + +MODULE_AUTHOR("Bulding Number Three Ltd"); +MODULE_DESCRIPTION("Modular driver for the Comtrol Hostess SV11"); + +static struct sv11_device *sv11_unit; + +int init_module(void) +{ + printk(KERN_INFO "SV-11 Z85230 Synchronous Driver v 0.02.\n"); + printk(KERN_INFO "(c) Copyright 1998, Building Number Three Ltd.\n"); + if(dma) + printk(KERN_WARNING "DMA mode probably wont work right now.\n"); + if((sv11_unit=sv11_init(io,irq))==NULL) + return -ENODEV; + return 0; +} + +void cleanup_module(void) +{ + if(sv11_unit) + sv11_shutdown(sv11_unit); +} + +#endif + diff -u --recursive --new-file v2.1.120/linux/drivers/net/plip.c linux/drivers/net/plip.c --- v2.1.120/linux/drivers/net/plip.c Sat Sep 5 16:46:40 1998 +++ linux/drivers/net/plip.c Sun Sep 6 10:09:22 1998 @@ -1178,7 +1178,7 @@ /* disable driver on "parport=" or "parport=0" */ parport[0] = -2; } else { - printk(KERN_WARNINGING "warning: 'plip=0x%x' ignored\n", + printk(KERN_WARNING "warning: 'plip=0x%x' ignored\n", ints[1]); } } diff -u --recursive --new-file v2.1.120/linux/drivers/net/sdladrv.c linux/drivers/net/sdladrv.c --- v2.1.120/linux/drivers/net/sdladrv.c Sat Sep 5 16:46:40 1998 +++ linux/drivers/net/sdladrv.c Sat Sep 5 17:01:45 1998 @@ -437,7 +437,7 @@ return -EINVAL; } printk(KERN_INFO "%s: dual-port memory window is set at 0x%lX.\n", - modname, virt_to_phys(hw->dpmbase)) + modname, virt_to_phys((void *)hw->dpmbase)) ; printk(KERN_INFO "%s: found %luK bytes of on-board memory.\n", modname, hw->memory / 1024) diff -u --recursive --new-file v2.1.120/linux/drivers/net/strip.c linux/drivers/net/strip.c --- v2.1.120/linux/drivers/net/strip.c Thu Feb 12 20:56:09 1998 +++ linux/drivers/net/strip.c Sat Sep 5 17:01:45 1998 @@ -2430,7 +2430,6 @@ dev->tx_queue_len = 30; /* Drop after 30 frames queued */ dev->flags = 0; - dev->metric = 0; dev->mtu = DEFAULT_STRIP_MTU; dev->type = ARPHRD_METRICOM; /* dtang */ dev->hard_header_len = sizeof(STRIP_Header); diff -u --recursive --new-file v2.1.120/linux/drivers/net/syncppp.c linux/drivers/net/syncppp.c --- v2.1.120/linux/drivers/net/syncppp.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/syncppp.c Sun Sep 6 10:47:01 1998 @@ -0,0 +1,1277 @@ +/* + * NET3: A (fairly minimal) implementation of synchronous PPP for Linux + * as well as a CISCO HDLC implementation. See the copyright + * message below for the original source. + * + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the license, or (at your option) any later version. + * + * Note however. This code is also used in a different form by FreeBSD. + * Therefore when making any non OS specific change please consider + * contributing it back to the original author under the terms + * below in addition. + * -- Alan + * + * Port for Linux-2.1 by Jan "Yenya" Kasprzak + */ + +/* + * Synchronous PPP/Cisco link level subroutines. + * Keepalive protocol implemented in both Cisco and PPP modes. + * + * Copyright (C) 1994 Cronyx Ltd. + * Author: Serge Vakulenko, + * + * This software is distributed with NO WARRANTIES, not even the implied + * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Authors grant any other persons or organisations permission to use + * or modify this software as long as this message is kept with the software, + * all derivative works or modified versions. + * + * Version 1.9, Wed Oct 4 18:58:15 MSK 1995 + * + * $Id: if_spppsubr.c,v 1.12 1996/06/10 23:17:45 gpalmer Exp $ + */ +#undef DEBUG + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include "syncppp.h" + +#define MAXALIVECNT 3 /* max. alive packets */ + +#define PPP_ALLSTATIONS 0xff /* All-Stations broadcast address */ +#define PPP_UI 0x03 /* Unnumbered Information */ +#define PPP_IP 0x0021 /* Internet Protocol */ +#define PPP_ISO 0x0023 /* ISO OSI Protocol */ +#define PPP_XNS 0x0025 /* Xerox NS Protocol */ +#define PPP_IPX 0x002b /* Novell IPX Protocol */ +#define PPP_LCP 0xc021 /* Link Control Protocol */ +#define PPP_IPCP 0x8021 /* Internet Protocol Control Protocol */ + +#define LCP_CONF_REQ 1 /* PPP LCP configure request */ +#define LCP_CONF_ACK 2 /* PPP LCP configure acknowledge */ +#define LCP_CONF_NAK 3 /* PPP LCP configure negative ack */ +#define LCP_CONF_REJ 4 /* PPP LCP configure reject */ +#define LCP_TERM_REQ 5 /* PPP LCP terminate request */ +#define LCP_TERM_ACK 6 /* PPP LCP terminate acknowledge */ +#define LCP_CODE_REJ 7 /* PPP LCP code reject */ +#define LCP_PROTO_REJ 8 /* PPP LCP protocol reject */ +#define LCP_ECHO_REQ 9 /* PPP LCP echo request */ +#define LCP_ECHO_REPLY 10 /* PPP LCP echo reply */ +#define LCP_DISC_REQ 11 /* PPP LCP discard request */ + +#define LCP_OPT_MRU 1 /* maximum receive unit */ +#define LCP_OPT_ASYNC_MAP 2 /* async control character map */ +#define LCP_OPT_AUTH_PROTO 3 /* authentication protocol */ +#define LCP_OPT_QUAL_PROTO 4 /* quality protocol */ +#define LCP_OPT_MAGIC 5 /* magic number */ +#define LCP_OPT_RESERVED 6 /* reserved */ +#define LCP_OPT_PROTO_COMP 7 /* protocol field compression */ +#define LCP_OPT_ADDR_COMP 8 /* address/control field compression */ + +#define IPCP_CONF_REQ LCP_CONF_REQ /* PPP IPCP configure request */ +#define IPCP_CONF_ACK LCP_CONF_ACK /* PPP IPCP configure acknowledge */ +#define IPCP_CONF_NAK LCP_CONF_NAK /* PPP IPCP configure negative ack */ +#define IPCP_CONF_REJ LCP_CONF_REJ /* PPP IPCP configure reject */ +#define IPCP_TERM_REQ LCP_TERM_REQ /* PPP IPCP terminate request */ +#define IPCP_TERM_ACK LCP_TERM_ACK /* PPP IPCP terminate acknowledge */ +#define IPCP_CODE_REJ LCP_CODE_REJ /* PPP IPCP code reject */ + +#define CISCO_MULTICAST 0x8f /* Cisco multicast address */ +#define CISCO_UNICAST 0x0f /* Cisco unicast address */ +#define CISCO_KEEPALIVE 0x8035 /* Cisco keepalive protocol */ +#define CISCO_ADDR_REQ 0 /* Cisco address request */ +#define CISCO_ADDR_REPLY 1 /* Cisco address reply */ +#define CISCO_KEEPALIVE_REQ 2 /* Cisco keepalive request */ + +struct ppp_header { + u8 address; + u8 control; + u16 protocol; +}; +#define PPP_HEADER_LEN sizeof (struct ppp_header) + +struct lcp_header { + u8 type; + u8 ident; + u16 len; +}; +#define LCP_HEADER_LEN sizeof (struct lcp_header) + +struct cisco_packet { + u32 type; + u32 par1; + u32 par2; + u16 rel; + u16 time0; + u16 time1; +}; +#define CISCO_PACKET_LEN 18 + +static struct sppp *spppq; +static struct timer_list sppp_keepalive_timer; + +static void sppp_keepalive (unsigned long dummy); +static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type, + u8 ident, u16 len, void *data); +static void sppp_cisco_send (struct sppp *sp, int type, long par1, long par2); +static void sppp_lcp_input (struct sppp *sp, struct sk_buff *m); +static void sppp_cisco_input (struct sppp *sp, struct sk_buff *m); +static void sppp_ipcp_input (struct sppp *sp, struct sk_buff *m); +static void sppp_lcp_open (struct sppp *sp); +static void sppp_ipcp_open (struct sppp *sp); +static int sppp_lcp_conf_parse_options (struct sppp *sp, struct lcp_header *h, + int len, u32 *magic); +static void sppp_cp_timeout (unsigned long arg); +static char *sppp_lcp_type_name (u8 type); +static char *sppp_ipcp_type_name (u8 type); +static void sppp_print_bytes (u8 *p, u16 len); + +static int debug = 0; + +/* + * Interface down stub + */ + +static void if_down(struct device *dev) +{ + ; +} + +/* + * Timeout routine activations. + */ + +static void sppp_set_timeout(struct sppp *p,int s) +{ + if (! (p->pp_flags & PP_TIMO)) + { + init_timer(&p->pp_timer); + p->pp_timer.function=sppp_cp_timeout; + p->pp_timer.expires=jiffies+s*HZ; + p->pp_timer.data=(unsigned long)p; + p->pp_flags |= PP_TIMO; + add_timer(&p->pp_timer); + } +} + +static void sppp_clear_timeout(struct sppp *p) +{ + if (p->pp_flags & PP_TIMO) + { + del_timer(&p->pp_timer); + p->pp_flags &= ~PP_TIMO; + } +} + +/* + * Process the received packet. + */ + +void sppp_input (struct device *dev, struct sk_buff *skb) +{ + struct ppp_header *h; + struct sppp *sp = &((struct ppp_device *)dev)->sppp; + + skb->dev=dev; + skb->mac.raw=skb->data; + + if (dev->flags & IFF_UP) + { + /* Count received bytes, add FCS and one flag */ + sp->ibytes+= skb->len + 3; + sp->ipkts++; + } + + if (skb->len <= PPP_HEADER_LEN) { + /* Too small packet, drop it. */ + if (sp->pp_flags & PP_DEBUG) + printk (KERN_DEBUG "%s: input packet is too small, %d bytes\n", + dev->name, skb->len); +drop: kfree_skb(skb); + return; + } + + /* Get PPP header. */ + h = (struct ppp_header *)skb->data; + skb_pull(skb,sizeof(struct ppp_header)); + + switch (h->address) { + default: /* Invalid PPP packet. */ +invalid: if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid input packet <0x%x 0x%x 0x%x>\n", + dev->name, + h->address, h->control, ntohs (h->protocol)); + goto drop; + case PPP_ALLSTATIONS: + if (h->control != PPP_UI) + goto invalid; + if (sp->pp_flags & PP_CISCO) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: PPP packet in Cisco mode <0x%x 0x%x 0x%x>\n", + dev->name, + h->address, h->control, ntohs (h->protocol)); + goto drop; + } + switch (ntohs (h->protocol)) { + default: + if (sp->lcp.state == LCP_STATE_OPENED) + sppp_cp_send (sp, PPP_LCP, LCP_PROTO_REJ, + ++sp->pp_seq, skb->len + 2, + &h->protocol); + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid input protocol <0x%x 0x%x 0x%x>\n", + dev->name, + h->address, h->control, ntohs (h->protocol)); + goto drop; + case PPP_LCP: + sppp_lcp_input (sp, skb); + kfree_skb(skb); + return; + case PPP_IPCP: + if (sp->lcp.state == LCP_STATE_OPENED) + sppp_ipcp_input (sp, skb); + else + printk(KERN_DEBUG "IPCP when still waiting LCP finish.\n"); + kfree_skb(skb); + return; + case PPP_IP: + if (sp->ipcp.state == IPCP_STATE_OPENED) { + if(sp->pp_flags&PP_DEBUG) + printk(KERN_DEBUG "Yow an IP frame.\n"); + skb->protocol=htons(ETH_P_IP); + netif_rx(skb); + return; + } + break; +#ifdef IPX + case PPP_IPX: + /* IPX IPXCP not implemented yet */ + if (sp->lcp.state == LCP_STATE_OPENED) { + skb->protocol=htons(ETH_P_IPX); + netif_rx(skb); + return; + } + break; +#endif + } + break; + case CISCO_MULTICAST: + case CISCO_UNICAST: + /* Don't check the control field here (RFC 1547). */ + if (! (sp->pp_flags & PP_CISCO)) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: Cisco packet in PPP mode <0x%x 0x%x 0x%x>\n", + dev->name, + h->address, h->control, ntohs (h->protocol)); + goto drop; + } + switch (ntohs (h->protocol)) { + default: + goto invalid; + case CISCO_KEEPALIVE: + sppp_cisco_input (sp, skb); + kfree_skb(skb); + return; +#ifdef CONFIG_INET + case ETH_P_IP: + skb->protocol=htons(ETH_P_IP); + netif_rx(skb); + return; +#endif +#ifdef CONFIG_IPX + case ETH_P_IPX: + skb->protocol=htons(ETH_P_IPX); + netif_rx(skb); + return; +#endif + } + break; + } + kfree_skb(skb); +} + +EXPORT_SYMBOL(sppp_input); + +/* + * Handle transmit packets. + */ + +static int sppp_hard_header(struct sk_buff *skb, struct device *dev, __u16 type, + void *daddr, void *saddr, unsigned int len) +{ + struct sppp *sp = &((struct ppp_device *)dev)->sppp; + struct ppp_header *h; + skb_push(skb,sizeof(struct ppp_header)); + h=(struct ppp_header *)skb->data; + if(sp->pp_flags&PP_CISCO) + { + h->address = CISCO_MULTICAST; + h->control = 0; + } + else + { + h->address = PPP_ALLSTATIONS; + h->control = PPP_UI; + } + if(sp->pp_flags & PP_CISCO) + { + h->protocol = htons(type); + } + else switch(type) + { + case ETH_P_IP: + h->protocol = htons(PPP_IP); + break; + case ETH_P_IPX: + h->protocol = htons(PPP_IPX); + break; + } + return sizeof(struct ppp_header); +} + +static int sppp_rebuild_header(struct sk_buff *skb) +{ + return 0; +} + +/* + * Send keepalive packets, every 10 seconds. + */ + +static void sppp_keepalive (unsigned long dummy) +{ + struct sppp *sp; + unsigned long flags; + save_flags(flags); + cli(); + + for (sp=spppq; sp; sp=sp->pp_next) + { + struct device *dev = sp->pp_if; + + /* Keepalive mode disabled or channel down? */ + if (! (sp->pp_flags & PP_KEEPALIVE) || + ! (dev->flags & IFF_RUNNING)) + continue; + + /* No keepalive in PPP mode if LCP not opened yet. */ + if (! (sp->pp_flags & PP_CISCO) && + sp->lcp.state != LCP_STATE_OPENED) + continue; + + if (sp->pp_alivecnt == MAXALIVECNT) { + /* No keepalive packets got. Stop the interface. */ + printk (KERN_WARNING "%s: down\n", dev->name); + if_down (dev); + if (! (sp->pp_flags & PP_CISCO)) { + /* Shut down the PPP link. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + sppp_clear_timeout (sp); + /* Initiate negotiation. */ + sppp_lcp_open (sp); + } + } + if (sp->pp_alivecnt <= MAXALIVECNT) + ++sp->pp_alivecnt; + if (sp->pp_flags & PP_CISCO) + sppp_cisco_send (sp, CISCO_KEEPALIVE_REQ, ++sp->pp_seq, + sp->pp_rseq); + else if (sp->lcp.state == LCP_STATE_OPENED) { + long nmagic = htonl (sp->lcp.magic); + sp->lcp.echoid = ++sp->pp_seq; + sppp_cp_send (sp, PPP_LCP, LCP_ECHO_REQ, + sp->lcp.echoid, 4, &nmagic); + } + } + restore_flags(flags); + sppp_keepalive_timer.expires=jiffies+10*HZ; + add_timer(&sppp_keepalive_timer); +} + +/* + * Handle incoming PPP Link Control Protocol packets. + */ + +static void sppp_lcp_input (struct sppp *sp, struct sk_buff *skb) +{ + struct lcp_header *h; + struct device *dev = sp->pp_if; + int len = skb->len; + u8 *p, opt[6]; + u32 rmagic; + + if (len < 4) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid lcp packet length: %d bytes\n", + dev->name, len); + return; + } + h = (struct lcp_header *)skb->data; + skb_pull(skb,sizeof(struct lcp_header *)); + + if (sp->pp_flags & PP_DEBUG) + { + char state = '?'; + switch (sp->lcp.state) { + case LCP_STATE_CLOSED: state = 'C'; break; + case LCP_STATE_ACK_RCVD: state = 'R'; break; + case LCP_STATE_ACK_SENT: state = 'S'; break; + case LCP_STATE_OPENED: state = 'O'; break; + } + printk (KERN_WARNING "%s: lcp input(%c): %d bytes <%s id=%xh len=%xh", + dev->name, state, len, + sppp_lcp_type_name (h->type), h->ident, ntohs (h->len)); + if (len > 4) + sppp_print_bytes ((u8*) (h+1), len-4); + printk (">\n"); + } + if (len > ntohs (h->len)) + len = ntohs (h->len); + switch (h->type) { + default: + /* Unknown packet type -- send Code-Reject packet. */ + sppp_cp_send (sp, PPP_LCP, LCP_CODE_REJ, ++sp->pp_seq, + skb->len, h); + break; + case LCP_CONF_REQ: + if (len < 4) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_DEBUG"%s: invalid lcp configure request packet length: %d bytes\n", + dev->name, len); + break; + } + if (len>4 && !sppp_lcp_conf_parse_options (sp, h, len, &rmagic)) + goto badreq; + if (rmagic == sp->lcp.magic) { + /* Local and remote magics equal -- loopback? */ + if (sp->pp_loopcnt >= MAXALIVECNT*5) { + printk (KERN_WARNING "%s: loopback\n", + dev->name); + sp->pp_loopcnt = 0; + if (dev->flags & IFF_UP) { + if_down (dev); + } + } else if (sp->pp_flags & PP_DEBUG) + printk (KERN_DEBUG "%s: conf req: magic glitch\n", + dev->name); + ++sp->pp_loopcnt; + + /* MUST send Conf-Nack packet. */ + rmagic = ~sp->lcp.magic; + opt[0] = LCP_OPT_MAGIC; + opt[1] = sizeof (opt); + opt[2] = rmagic >> 24; + opt[3] = rmagic >> 16; + opt[4] = rmagic >> 8; + opt[5] = rmagic; + sppp_cp_send (sp, PPP_LCP, LCP_CONF_NAK, + h->ident, sizeof (opt), &opt); +badreq: + switch (sp->lcp.state) { + case LCP_STATE_OPENED: + /* Initiate renegotiation. */ + sppp_lcp_open (sp); + /* fall through... */ + case LCP_STATE_ACK_SENT: + /* Go to closed state. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + } + break; + } + /* Send Configure-Ack packet. */ + sp->pp_loopcnt = 0; + sppp_cp_send (sp, PPP_LCP, LCP_CONF_ACK, + h->ident, len-4, h+1); + /* Change the state. */ + switch (sp->lcp.state) { + case LCP_STATE_CLOSED: + sp->lcp.state = LCP_STATE_ACK_SENT; + break; + case LCP_STATE_ACK_RCVD: + sp->lcp.state = LCP_STATE_OPENED; + sppp_ipcp_open (sp); + break; + case LCP_STATE_OPENED: +#if 0 + /* Remote magic changed -- close session. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + /* Initiate renegotiation. */ + sppp_lcp_open (sp); + /* An ACK has already been sent. */ + sp->lcp.state = LCP_STATE_ACK_SENT; +#endif + break; + } + break; + case LCP_CONF_ACK: + if (h->ident != sp->lcp.confid) + break; + sppp_clear_timeout (sp); + if (! (dev->flags & IFF_UP) && + (dev->flags & IFF_RUNNING)) { + /* Coming out of loopback mode. */ + dev->flags |= IFF_UP; + printk (KERN_INFO "%s: up\n", dev->name); + } + switch (sp->lcp.state) { + case LCP_STATE_CLOSED: + sp->lcp.state = LCP_STATE_ACK_RCVD; + sppp_set_timeout (sp, 5); + break; + case LCP_STATE_ACK_SENT: + sp->lcp.state = LCP_STATE_OPENED; + sppp_ipcp_open (sp); + break; + } + break; + case LCP_CONF_NAK: + if (h->ident != sp->lcp.confid) + break; + p = (u8*) (h+1); + if (len>=10 && p[0] == LCP_OPT_MAGIC && p[1] >= 4) { + rmagic = (u32)p[2] << 24 | + (u32)p[3] << 16 | p[4] << 8 | p[5]; + if (rmagic == ~sp->lcp.magic) { + int newmagic; + if (sp->pp_flags & PP_DEBUG) + printk (KERN_DEBUG "%s: conf nak: magic glitch\n", + dev->name); + get_random_bytes(&newmagic, sizeof(newmagic)); + sp->lcp.magic += newmagic; + } else + sp->lcp.magic = rmagic; + } + if (sp->lcp.state != LCP_STATE_ACK_SENT) { + /* Go to closed state. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + } + /* The link will be renegotiated after timeout, + * to avoid endless req-nack loop. */ + sppp_clear_timeout (sp); + sppp_set_timeout (sp, 2); + break; + case LCP_CONF_REJ: + if (h->ident != sp->lcp.confid) + break; + sppp_clear_timeout (sp); + /* Initiate renegotiation. */ + sppp_lcp_open (sp); + if (sp->lcp.state != LCP_STATE_ACK_SENT) { + /* Go to closed state. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + } + break; + case LCP_TERM_REQ: + sppp_clear_timeout (sp); + /* Send Terminate-Ack packet. */ + sppp_cp_send (sp, PPP_LCP, LCP_TERM_ACK, h->ident, 0, 0); + /* Go to closed state. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + /* Initiate renegotiation. */ + sppp_lcp_open (sp); + break; + case LCP_TERM_ACK: + case LCP_CODE_REJ: + case LCP_PROTO_REJ: + /* Ignore for now. */ + break; + case LCP_DISC_REQ: + /* Discard the packet. */ + break; + case LCP_ECHO_REQ: + if (sp->lcp.state != LCP_STATE_OPENED) + break; + if (len < 8) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid lcp echo request packet length: %d bytes\n", + dev->name, len); + break; + } + if (ntohl (*(long*)(h+1)) == sp->lcp.magic) { + /* Line loopback mode detected. */ + printk (KERN_WARNING "%s: loopback\n", dev->name); + if_down (dev); + + /* Shut down the PPP link. */ + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + sppp_clear_timeout (sp); + /* Initiate negotiation. */ + sppp_lcp_open (sp); + break; + } + *(long*)(h+1) = htonl (sp->lcp.magic); + sppp_cp_send (sp, PPP_LCP, LCP_ECHO_REPLY, h->ident, len-4, h+1); + break; + case LCP_ECHO_REPLY: + if (h->ident != sp->lcp.echoid) + break; + if (len < 8) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid lcp echo reply packet length: %d bytes\n", + dev->name, len); + break; + } + if (ntohl (*(long*)(h+1)) != sp->lcp.magic) + sp->pp_alivecnt = 0; + break; + } +} + +/* + * Handle incoming Cisco keepalive protocol packets. + */ + +static void sppp_cisco_input (struct sppp *sp, struct sk_buff *skb) +{ + struct cisco_packet *h; + struct device *dev = sp->pp_if; + + if (skb->len != CISCO_PACKET_LEN) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid cisco packet length: %d bytes\n", + dev->name, skb->len); + return; + } + h = (struct cisco_packet *)skb->data; + skb_pull(skb, sizeof(struct cisco_packet*)); + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: cisco input: %d bytes <%lxh %xh %xh %xh %xh-%xh>\n", + dev->name, skb->len, + ntohl (h->type), h->par1, h->par2, h->rel, + h->time0, h->time1); + switch (ntohl (h->type)) { + default: + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: unknown cisco packet type: 0x%lx\n", + dev->name, ntohl (h->type)); + break; + case CISCO_ADDR_REPLY: + /* Reply on address request, ignore */ + break; + case CISCO_KEEPALIVE_REQ: + sp->pp_alivecnt = 0; + sp->pp_rseq = ntohl (h->par1); + if (sp->pp_seq == sp->pp_rseq) { + /* Local and remote sequence numbers are equal. + * Probably, the line is in loopback mode. */ + int newseq; + if (sp->pp_loopcnt >= MAXALIVECNT) { + printk (KERN_WARNING "%s: loopback\n", + dev->name); + sp->pp_loopcnt = 0; + if (dev->flags & IFF_UP) { + if_down (dev); + } + } + ++sp->pp_loopcnt; + + /* Generate new local sequence number */ + get_random_bytes(&newseq, sizeof(newseq)); + sp->pp_seq ^= newseq; + break; + } + sp->pp_loopcnt = 0; + if (! (dev->flags & IFF_UP) && + (dev->flags & IFF_RUNNING)) { + dev->flags |= IFF_UP; + printk (KERN_INFO "%s: up\n", dev->name); + } + break; + case CISCO_ADDR_REQ: + /* Stolen from net/ipv4/devinet.c -- SIOCGIFADDR ioctl */ + { + struct in_device *in_dev; + struct in_ifaddr *ifa, **ifap; + u32 addr = 0, mask = ~0; /* FIXME: is the mask correct? */ + + if ((in_dev=dev->ip_ptr) != NULL) + { + for (ifap=&in_dev->ifa_list; (ifa=*ifap) != NULL; + ifap=&ifa->ifa_next) + if (strcmp(dev->name, ifa->ifa_label) == 0) + { + addr = ifa->ifa_local; + mask = ifa->ifa_mask; + break; + } + } + /* I hope both addr and mask are in the net order */ + sppp_cisco_send (sp, CISCO_ADDR_REPLY, addr, mask); + break; + } + } +} + +/* + * Send PPP LCP packet. + */ + +static void sppp_cp_send (struct sppp *sp, u16 proto, u8 type, + u8 ident, u16 len, void *data) +{ + struct ppp_header *h; + struct lcp_header *lh; + struct sk_buff *skb; + struct device *dev = sp->pp_if; + + skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+LCP_HEADER_LEN+len, + GFP_ATOMIC); + if (skb==NULL) + return; + + skb_reserve(skb,dev->hard_header_len); + + h = (struct ppp_header *)skb_put(skb, sizeof(struct ppp_header)); + h->address = PPP_ALLSTATIONS; /* broadcast address */ + h->control = PPP_UI; /* Unnumbered Info */ + h->protocol = htons (proto); /* Link Control Protocol */ + + lh = (struct lcp_header *)skb_put(skb, sizeof(struct lcp_header)); + lh->type = type; + lh->ident = ident; + lh->len = htons (LCP_HEADER_LEN + len); + + if (len) + memcpy(skb_put(skb,len),data, len); + + if (sp->pp_flags & PP_DEBUG) { + printk (KERN_WARNING "%s: %s output <%s id=%xh len=%xh", + dev->name, + proto==PPP_LCP ? "lcp" : "ipcp", + proto==PPP_LCP ? sppp_lcp_type_name (lh->type) : + sppp_ipcp_type_name (lh->type), lh->ident, + ntohs (lh->len)); + if (len) + sppp_print_bytes ((u8*) (lh+1), len); + printk (">\n"); + } + sp->obytes += skb->len; + /* Control is high priority so it doesnt get queued behind data */ + skb->priority=1; + dev_queue_xmit(skb); +} + +/* + * Send Cisco keepalive packet. + */ + +static void sppp_cisco_send (struct sppp *sp, int type, long par1, long par2) +{ + struct ppp_header *h; + struct cisco_packet *ch; + struct sk_buff *skb; + struct device *dev = sp->pp_if; + u32 t = jiffies * 1000/HZ; + + skb=alloc_skb(dev->hard_header_len+PPP_HEADER_LEN+CISCO_PACKET_LEN, + GFP_ATOMIC); + + if(skb==NULL) + return; + + skb_reserve(skb, dev->hard_header_len); + h = (struct ppp_header *)skb_put (skb, sizeof(struct ppp_header)); + h->address = CISCO_MULTICAST; + h->control = 0; + h->protocol = htons (CISCO_KEEPALIVE); + + ch = (struct cisco_packet*)skb_put(skb, CISCO_PACKET_LEN); + ch->type = htonl (type); + ch->par1 = htonl (par1); + ch->par2 = htonl (par2); + ch->rel = -1; + ch->time0 = htons ((u16) (t >> 16)); + ch->time1 = htons ((u16) t); + + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: cisco output: <%lxh %xh %xh %xh %xh-%xh>\n", + dev->name, ntohl (ch->type), ch->par1, + ch->par2, ch->rel, ch->time0, ch->time1); + sp->obytes += skb->len; + skb->priority=1; + dev_queue_xmit(skb); +} + + +int sppp_close (struct device *dev) +{ + struct sppp *sp = &((struct ppp_device *)dev)->sppp; + dev->flags &= ~IFF_RUNNING; + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + sppp_clear_timeout (sp); + return 0; +} + +EXPORT_SYMBOL(sppp_close); + + +int sppp_open (struct device *dev) +{ + struct sppp *sp = &((struct ppp_device *)dev)->sppp; + sppp_close(dev); + dev->flags |= IFF_RUNNING; + if (!(sp->pp_flags & PP_CISCO)) + sppp_lcp_open (sp); + return 0; +} + +EXPORT_SYMBOL(sppp_open); + +int sppp_change_mtu(struct device *dev, int new_mtu) +{ + if(new_mtu<128||new_mtu>PPP_MTU||(dev->flags&IFF_UP)) + return -EINVAL; + dev->mtu=new_mtu; + return 0; +} + +EXPORT_SYMBOL(sppp_change_mtu); + +int sppp_do_ioctl(struct device *dev, struct ifreq *ifr, int cmd) +{ + struct sppp *sp = &((struct ppp_device *)dev)->sppp; + + if(dev->flags&IFF_UP) + return -EBUSY; + + switch(cmd) + { + case SPPPIOCCISCO: + sp->pp_flags|=PP_CISCO; + break; + case SPPPIOCPPP: + sp->pp_flags&=~PP_CISCO; + break; + default: + return -EINVAL; + } + return 0; +} + +EXPORT_SYMBOL(sppp_do_ioctl); + +void sppp_attach(struct ppp_device *pd) +{ + struct device *dev=&pd->dev; + struct sppp *sp = &pd->sppp; + + /* Initialize keepalive handler. */ + if (! spppq) + { + init_timer(&sppp_keepalive_timer); + sppp_keepalive_timer.expires=jiffies+10*HZ; + sppp_keepalive_timer.function=sppp_keepalive; + add_timer(&sppp_keepalive_timer); + } + /* Insert new entry into the keepalive list. */ + sp->pp_next = spppq; + spppq = sp; + + sp->pp_loopcnt = 0; + sp->pp_alivecnt = 0; + sp->pp_seq = 0; + sp->pp_rseq = 0; + sp->pp_flags = PP_KEEPALIVE|PP_CISCO|debug;/*PP_DEBUG;*/ + sp->lcp.magic = 0; + sp->lcp.state = LCP_STATE_CLOSED; + sp->ipcp.state = IPCP_STATE_CLOSED; + sp->pp_if = dev; + + /* + * Device specific setup. All but interrupt handler and + * hard_start_xmit. + */ + + dev->hard_header = sppp_hard_header; + dev->rebuild_header = sppp_rebuild_header; + dev->tx_queue_len = 10; + dev->type = ARPHRD_PPP; + dev->addr_len = 0; + dev->hard_header_len = sizeof(struct ppp_header); + dev->mtu = PPP_MTU; + /* + * These 4 are callers but MUST also call sppp_ functions + */ + dev->do_ioctl = sppp_do_ioctl; +#if 0 + dev->get_stats = NULL; /* Let the driver override these */ + dev->open = sppp_open; + dev->stop = sppp_close; +#endif + dev->change_mtu = sppp_change_mtu; + dev->hard_header_cache = NULL; + dev->header_cache_update = NULL; + dev->flags = IFF_MULTICAST; + dev_init_buffers(dev); +} + +EXPORT_SYMBOL(sppp_attach); + +void sppp_detach (struct device *dev) +{ + struct sppp **q, *p, *sp = &((struct ppp_device *)dev)->sppp; + + + /* Remove the entry from the keepalive list. */ + for (q = &spppq; (p = *q); q = &p->pp_next) + if (p == sp) { + *q = p->pp_next; + break; + } + + /* Stop keepalive handler. */ + if (! spppq) + del_timer(&sppp_keepalive_timer); + sppp_clear_timeout (sp); +} + +EXPORT_SYMBOL(sppp_detach); + +/* + * Analyze the LCP Configure-Request options list + * for the presence of unknown options. + * If the request contains unknown options, build and + * send Configure-reject packet, containing only unknown options. + */ +static int +sppp_lcp_conf_parse_options (struct sppp *sp, struct lcp_header *h, + int len, u32 *magic) +{ + u8 *buf, *r, *p; + int rlen; + + len -= 4; + buf = r = kmalloc (len, GFP_ATOMIC); + if (! buf) + return (0); + + p = (void*) (h+1); + for (rlen=0; len>1 && p[1]; len-=p[1], p+=p[1]) { + switch (*p) { + case LCP_OPT_MAGIC: + /* Magic number -- extract. */ + if (len >= 6 && p[1] == 6) { + *magic = (u32)p[2] << 24 | + (u32)p[3] << 16 | p[4] << 8 | p[5]; + continue; + } + break; + case LCP_OPT_ASYNC_MAP: + /* Async control character map -- check to be zero. */ + if (len >= 6 && p[1] == 6 && ! p[2] && ! p[3] && + ! p[4] && ! p[5]) + continue; + break; + case LCP_OPT_MRU: + /* Maximum receive unit -- always OK. */ + continue; + default: + /* Others not supported. */ + break; + } + /* Add the option to rejected list. */ + memcpy(r, p, p[1]); + r += p[1]; + rlen += p[1]; + } + if (rlen) + sppp_cp_send (sp, PPP_LCP, LCP_CONF_REJ, h->ident, rlen, buf); + kfree(buf); + return (rlen == 0); +} + +static void sppp_ipcp_input (struct sppp *sp, struct sk_buff *skb) +{ + struct lcp_header *h; + struct device *dev = sp->pp_if; + int len = skb->len; + + if (len < 4) + { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid ipcp packet length: %d bytes\n", + dev->name, len); + return; + } + h = (struct lcp_header *)skb->data; + skb_pull(skb,sizeof(struct lcp_header)); + if (sp->pp_flags & PP_DEBUG) { + printk (KERN_WARNING "%s: ipcp input: %d bytes <%s id=%xh len=%xh", + dev->name, len, + sppp_ipcp_type_name (h->type), h->ident, ntohs (h->len)); + if (len > 4) + sppp_print_bytes ((u8*) (h+1), len-4); + printk (">\n"); + } + if (len > ntohs (h->len)) + len = ntohs (h->len); + switch (h->type) { + default: + /* Unknown packet type -- send Code-Reject packet. */ + sppp_cp_send (sp, PPP_IPCP, IPCP_CODE_REJ, ++sp->pp_seq, len, h); + break; + case IPCP_CONF_REQ: + if (len < 4) { + if (sp->pp_flags & PP_DEBUG) + printk (KERN_WARNING "%s: invalid ipcp configure request packet length: %d bytes\n", + dev->name, len); + return; + } + if (len > 4) { + sppp_cp_send (sp, PPP_IPCP, LCP_CONF_REJ, h->ident, + len-4, h+1); + + switch (sp->ipcp.state) { + case IPCP_STATE_OPENED: + /* Initiate renegotiation. */ + sppp_ipcp_open (sp); + /* fall through... */ + case IPCP_STATE_ACK_SENT: + /* Go to closed state. */ + sp->ipcp.state = IPCP_STATE_CLOSED; + } + } else { + /* Send Configure-Ack packet. */ + sppp_cp_send (sp, PPP_IPCP, IPCP_CONF_ACK, h->ident, + 0, 0); + /* Change the state. */ + if (sp->ipcp.state == IPCP_STATE_ACK_RCVD) + sp->ipcp.state = IPCP_STATE_OPENED; + else + sp->ipcp.state = IPCP_STATE_ACK_SENT; + } + break; + case IPCP_CONF_ACK: + if (h->ident != sp->ipcp.confid) + break; + sppp_clear_timeout (sp); + switch (sp->ipcp.state) { + case IPCP_STATE_CLOSED: + sp->ipcp.state = IPCP_STATE_ACK_RCVD; + sppp_set_timeout (sp, 5); + break; + case IPCP_STATE_ACK_SENT: + sp->ipcp.state = IPCP_STATE_OPENED; + break; + } + break; + case IPCP_CONF_NAK: + case IPCP_CONF_REJ: + if (h->ident != sp->ipcp.confid) + break; + sppp_clear_timeout (sp); + /* Initiate renegotiation. */ + sppp_ipcp_open (sp); + if (sp->ipcp.state != IPCP_STATE_ACK_SENT) + /* Go to closed state. */ + sp->ipcp.state = IPCP_STATE_CLOSED; + break; + case IPCP_TERM_REQ: + /* Send Terminate-Ack packet. */ + sppp_cp_send (sp, PPP_IPCP, IPCP_TERM_ACK, h->ident, 0, 0); + /* Go to closed state. */ + sp->ipcp.state = IPCP_STATE_CLOSED; + /* Initiate renegotiation. */ + sppp_ipcp_open (sp); + break; + case IPCP_TERM_ACK: + /* Ignore for now. */ + case IPCP_CODE_REJ: + /* Ignore for now. */ + break; + } +} + +static void sppp_lcp_open (struct sppp *sp) +{ + char opt[6]; + + if (! sp->lcp.magic) + sp->lcp.magic = jiffies; + opt[0] = LCP_OPT_MAGIC; + opt[1] = sizeof (opt); + opt[2] = sp->lcp.magic >> 24; + opt[3] = sp->lcp.magic >> 16; + opt[4] = sp->lcp.magic >> 8; + opt[5] = sp->lcp.magic; + sp->lcp.confid = ++sp->pp_seq; + sppp_cp_send (sp, PPP_LCP, LCP_CONF_REQ, sp->lcp.confid, + sizeof (opt), &opt); + sppp_set_timeout (sp, 2); +} + +static void sppp_ipcp_open (struct sppp *sp) +{ + sp->ipcp.confid = ++sp->pp_seq; + sppp_cp_send (sp, PPP_IPCP, IPCP_CONF_REQ, sp->ipcp.confid, 0, 0); + sppp_set_timeout (sp, 2); +} + +/* + * Process PPP control protocol timeouts. + */ + +static void sppp_cp_timeout (unsigned long arg) +{ + struct sppp *sp = (struct sppp*) arg; + unsigned long flags; + save_flags(flags); + cli(); + + sp->pp_flags &= ~PP_TIMO; + if (! (sp->pp_if->flags & IFF_RUNNING) || (sp->pp_flags & PP_CISCO)) { + restore_flags(flags); + return; + } + switch (sp->lcp.state) { + case LCP_STATE_CLOSED: + /* No ACK for Configure-Request, retry. */ + sppp_lcp_open (sp); + break; + case LCP_STATE_ACK_RCVD: + /* ACK got, but no Configure-Request for peer, retry. */ + sppp_lcp_open (sp); + sp->lcp.state = LCP_STATE_CLOSED; + break; + case LCP_STATE_ACK_SENT: + /* ACK sent but no ACK for Configure-Request, retry. */ + sppp_lcp_open (sp); + break; + case LCP_STATE_OPENED: + /* LCP is already OK, try IPCP. */ + switch (sp->ipcp.state) { + case IPCP_STATE_CLOSED: + /* No ACK for Configure-Request, retry. */ + sppp_ipcp_open (sp); + break; + case IPCP_STATE_ACK_RCVD: + /* ACK got, but no Configure-Request for peer, retry. */ + sppp_ipcp_open (sp); + sp->ipcp.state = IPCP_STATE_CLOSED; + break; + case IPCP_STATE_ACK_SENT: + /* ACK sent but no ACK for Configure-Request, retry. */ + sppp_ipcp_open (sp); + break; + case IPCP_STATE_OPENED: + /* IPCP is OK. */ + break; + } + break; + } + restore_flags(flags); +} + +static char *sppp_lcp_type_name (u8 type) +{ + static char buf [8]; + switch (type) { + case LCP_CONF_REQ: return ("conf-req"); + case LCP_CONF_ACK: return ("conf-ack"); + case LCP_CONF_NAK: return ("conf-nack"); + case LCP_CONF_REJ: return ("conf-rej"); + case LCP_TERM_REQ: return ("term-req"); + case LCP_TERM_ACK: return ("term-ack"); + case LCP_CODE_REJ: return ("code-rej"); + case LCP_PROTO_REJ: return ("proto-rej"); + case LCP_ECHO_REQ: return ("echo-req"); + case LCP_ECHO_REPLY: return ("echo-reply"); + case LCP_DISC_REQ: return ("discard-req"); + } + sprintf (buf, "%xh", type); + return (buf); +} + +static char *sppp_ipcp_type_name (u8 type) +{ + static char buf [8]; + switch (type) { + case IPCP_CONF_REQ: return ("conf-req"); + case IPCP_CONF_ACK: return ("conf-ack"); + case IPCP_CONF_NAK: return ("conf-nack"); + case IPCP_CONF_REJ: return ("conf-rej"); + case IPCP_TERM_REQ: return ("term-req"); + case IPCP_TERM_ACK: return ("term-ack"); + case IPCP_CODE_REJ: return ("code-rej"); + } + sprintf (buf, "%xh", type); + return (buf); +} + +static void sppp_print_bytes (u_char *p, u16 len) +{ + printk (" %x", *p++); + while (--len > 0) + printk ("-%x", *p++); +} + +/* + * Protocol glue. This drives the deferred processing mode the poorer + * cards use. + */ + +int sppp_rcv(struct sk_buff *skb, struct device *dev, struct packet_type *p) +{ + sppp_input(dev,skb); + return 0; +} + +EXPORT_SYMBOL(sppp_rcv); + +struct packet_type sppp_packet_type= +{ + 0, + NULL, + sppp_rcv, + NULL, + NULL +}; + + +void sync_ppp_init(void) +{ + printk(KERN_INFO "Cronyx Ltd, Synchronous PPP and CISCO HDLC (c) 1994\n"); + printk(KERN_INFO "Linux port (c) 1998 Building Number Three Ltd & Jan 'Yenya' Kasprzak.\n"); + sppp_packet_type.type=htons(ETH_P_WAN_PPP); + dev_add_pack(&sppp_packet_type); +} + +#ifdef MODULE + +int init_module(void) +{ + if(debug) + debug=PP_DEBUG; + sync_ppp_init(); + return 0; +} + +void cleanup_module(void) +{ + dev_remove_pack(&sppp_packet_type); +} + +#endif diff -u --recursive --new-file v2.1.120/linux/drivers/net/syncppp.h linux/drivers/net/syncppp.h --- v2.1.120/linux/drivers/net/syncppp.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/syncppp.h Sun Sep 6 10:47:01 1998 @@ -0,0 +1,89 @@ +/* + * Defines for synchronous PPP/Cisco link level subroutines. + * + * Copyright (C) 1994 Cronyx Ltd. + * Author: Serge Vakulenko, + * + * This software is distributed with NO WARRANTIES, not even the implied + * warranties for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. + * + * Authors grant any other persons or organizations permission to use + * or modify this software as long as this message is kept with the software, + * all derivative works or modified versions. + * + * Version 1.7, Wed Jun 7 22:12:02 MSD 1995 + * + * + * + */ + +#ifndef _SYNCPPP_H_ +#define _SYNCPPP_H_ 1 + +struct slcp { + u16 state; /* state machine */ + u32 magic; /* local magic number */ + u_char echoid; /* id of last keepalive echo request */ + u_char confid; /* id of last configuration request */ +}; + +struct sipcp { + u16 state; /* state machine */ + u_char confid; /* id of last configuration request */ +}; + +struct sppp +{ + struct sppp * pp_next; /* next interface in keepalive list */ + u32 pp_flags; /* use Cisco protocol instead of PPP */ + u16 pp_alivecnt; /* keepalive packets counter */ + u16 pp_loopcnt; /* loopback detection counter */ + u32 pp_seq; /* local sequence number */ + u32 pp_rseq; /* remote sequence number */ + struct slcp lcp; /* LCP params */ + struct sipcp ipcp; /* IPCP params */ + u32 ibytes,obytes; /* Bytes in/out */ + u32 ipkts,opkts; /* Packets in/out */ + struct timer_list pp_timer; + struct device *pp_if; +}; + +struct ppp_device +{ + struct device dev; /* Network device */ + struct sppp sppp; /* Synchronous PPP */ +}; + +#define PP_KEEPALIVE 0x01 /* use keepalive protocol */ +#define PP_CISCO 0x02 /* use Cisco protocol instead of PPP */ +#define PP_TIMO 0x04 /* cp_timeout routine active */ +#define PP_DEBUG 0x08 + +#define PPP_MTU 1500 /* max. transmit unit */ + +#define LCP_STATE_CLOSED 0 /* LCP state: closed (conf-req sent) */ +#define LCP_STATE_ACK_RCVD 1 /* LCP state: conf-ack received */ +#define LCP_STATE_ACK_SENT 2 /* LCP state: conf-ack sent */ +#define LCP_STATE_OPENED 3 /* LCP state: opened */ + +#define IPCP_STATE_CLOSED 0 /* IPCP state: closed (conf-req sent) */ +#define IPCP_STATE_ACK_RCVD 1 /* IPCP state: conf-ack received */ +#define IPCP_STATE_ACK_SENT 2 /* IPCP state: conf-ack sent */ +#define IPCP_STATE_OPENED 3 /* IPCP state: opened */ + +#ifdef __KERNEL__ +void sppp_attach (struct ppp_device *pd); +void sppp_detach (struct device *dev); +void sppp_input (struct device *dev, struct sk_buff *m); +int sppp_do_ioctl (struct device *dev, struct ifreq *ifr, int cmd); +struct sk_buff *sppp_dequeue (struct device *dev); +int sppp_isempty (struct device *dev); +void sppp_flush (struct device *dev); +int sppp_open (struct device *dev); +int sppp_close (struct device *dev); +#endif + +#define SPPPIOCCISCO (SIOCDEVPRIVATE) +#define SPPPIOCPPP (SIOCDEVPRIVATE+1) + +#endif /* _SYNCPPP_H_ */ diff -u --recursive --new-file v2.1.120/linux/drivers/net/z85230.c linux/drivers/net/z85230.c --- v2.1.120/linux/drivers/net/z85230.c Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/z85230.c Sun Sep 6 10:47:01 1998 @@ -0,0 +1,1205 @@ +/* + * This program is free software; you can redistribute it and/or + * modify it under the terms of the GNU General Public License + * as published by the Free Software Foundation; either version + * 2 of the License, or (at your option) any later version. + * + * (c) Copyright 1998 Building Number Three Ltd + * + * Development of this driver was funded by Equiinet Ltd + * http://www.equiinet.com + * + * ChangeLog: + * + * Asynchronous mode dropped for 2.2. For 2.3 we will attempt the + * unification of all the Z85x30 asynchronous drivers for real. + * + * To Do: + * + * Finish DMA mode support. + * + * Performance + * + * Z85230: + * Non DMA you want a 486DX50 or better to do 64Kbits. 9600 baud + * X.25 is not unrealistic on all machines. DMA mode can in theory + * handle T1/E1 quite nicely. + * + * Z85C30: + * 64K will take DMA, 9600 baud X.25 should be ok. + * + * Z8530: + * Synchronous mode without DMA is unlikely to pass about 2400 baud. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#define RT_LOCK +#define RT_UNLOCK +#include + +#include "z85230.h" + + +static spinlock_t z8530_buffer_lock = SPIN_LOCK_UNLOCKED; + +/* + * Provided port access methods. The Comtrol SV11 requires no delays + * between accesses and uses PC I/O. Some drivers may need a 5uS delay + */ + +extern __inline__ int z8530_read_port(int p) +{ + u8 r=inb(Z8530_PORT_OF(p)); + if(p&Z8530_PORT_SLEEP) /* gcc should figure this out efficiently ! */ + udelay(5); + return r; +} + +extern __inline__ void z8530_write_port(int p, u8 d) +{ + outb(d,Z8530_PORT_OF(p)); + if(p&Z8530_PORT_SLEEP) + udelay(5); +} + + + +static void z8530_rx_done(struct z8530_channel *c); +static void z8530_tx_done(struct z8530_channel *c); + + +/* + * Port accesses + */ + +extern inline u8 read_zsreg(struct z8530_channel *c, u8 reg) +{ + u8 r; + unsigned long flags; + save_flags(flags); + cli(); + if(reg) + z8530_write_port(c->ctrlio, reg); + r=z8530_read_port(c->ctrlio); + restore_flags(flags); + return r; +} + +extern inline u8 read_zsdata(struct z8530_channel *c) +{ + u8 r; + r=z8530_read_port(c->dataio); + return r; +} + +extern inline void write_zsreg(struct z8530_channel *c, u8 reg, u8 val) +{ + unsigned long flags; + save_flags(flags); + cli(); + if(reg) + z8530_write_port(c->ctrlio, reg); + z8530_write_port(c->ctrlio, val); + restore_flags(flags); +} + +extern inline void write_zsctrl(struct z8530_channel *c, u8 val) +{ + z8530_write_port(c->ctrlio, val); +} + +extern inline void write_zsdata(struct z8530_channel *c, u8 val) +{ + z8530_write_port(c->dataio, val); +} + +/* + * Register loading parameters for a dead port + */ + +u8 z8530_dead_port[]= +{ + 255 +}; + +EXPORT_SYMBOL(z8530_dead_port); + +/* + * Register loading parameters for currently supported circuit types + */ + + +/* + * Data clocked by telco end. This is the correct data for the UK + * "kilostream" service, and most other similar services. + */ + +u8 z8530_hdlc_kilostream[]= +{ + 4, SYNC_ENAB|SDLC|X1CLK, + 2, 0, /* No vector */ + 1, 0, + 3, ENT_HM|RxCRC_ENAB|Rx8, + 5, TxCRC_ENAB|RTS|TxENAB|Tx8|DTR, + 9, 0, /* Disable interrupts */ + 7, FLAG, + 10, ABUNDER|MARKIDLE|NRZ|CRCPS, + 11, TCTRxCP, + 14, DISDPLL, + 15, DCDIE|SYNCIE|CTSIE|TxUIE|BRKIE, + 1, EXT_INT_ENAB|TxINT_ENAB|INT_ALL_Rx, + 9, NV|MIE|NORESET, + 255 +}; + +EXPORT_SYMBOL(z8530_hdlc_kilostream); + +/* + * As above but for enhanced chips. + */ + +u8 z8530_hdlc_kilostream_85230[]= +{ + 4, SYNC_ENAB|SDLC|X1CLK, + 2, 0, /* No vector */ + 1, 0, + 3, ENT_HM|RxCRC_ENAB|Rx8, + 5, TxCRC_ENAB|RTS|TxENAB|Tx8|DTR, + 9, 0, /* Disable interrupts */ + 7, FLAG, + 10, ABUNDER|MARKIDLE|NRZ|CRCPS, + 11, TCTRxCP, + 14, DISDPLL, + 15, DCDIE|SYNCIE|CTSIE|TxUIE|BRKIE, + 1, EXT_INT_ENAB|TxINT_ENAB|INT_ALL_Rx, + 9, NV|MIE|NORESET, + 23, 3, /* Extended mode AUTO TX and EOM*/ + 31, 3, /* Extended mode AUTO TX and EOM*/ + + 255 +}; + +EXPORT_SYMBOL(z8530_hdlc_kilostream_85230); + +/* + * Flush the FIFO + */ + +static void z8530_flush_fifo(struct z8530_channel *c) +{ + read_zsreg(c, R1); + read_zsreg(c, R1); + read_zsreg(c, R1); + read_zsreg(c, R1); + if(c->dev->type==Z85230) + { + read_zsreg(c, R1); + read_zsreg(c, R1); + read_zsreg(c, R1); + read_zsreg(c, R1); + } +} + +/* Sets or clears DTR/RTS on the requested line */ + +static void z8530_rtsdtr(struct z8530_channel *c, int set) +{ + if (set) + c->regs[5] |= (RTS | DTR); + else + c->regs[5] &= ~(RTS | DTR); + write_zsreg(c, R5, c->regs[5]); +} + +/* + * Receive handler. This is much like the async one but not quite the + * same or as complex + * + * Note: Its intended that this handler can easily be seperated from + * the main code to run realtime. That'll be needed for some machines + * (eg to ever clock 64kbits on a sparc ;)). + * + * The RT_LOCK macros don't do anything now. Keep the code covered + * by them as short as possible in all circumstances - clocks cost + * baud. The interrupt handler is assumed to be atomic w.r.t. to + * other code - this is true in the RT case too. + * + * We only cover the sync cases for this. If you want 2Mbit async + * do it yourself but consider medical assistance first. + * + * This non DMA synchronous mode is portable code. + */ + +static void z8530_rx(struct z8530_channel *c) +{ + u8 ch,stat; + + while(1) + { + /* FIFO empty ? */ + if(!(read_zsreg(c, R0)&1)) + break; + ch=read_zsdata(c); + stat=read_zsreg(c, R1); + + /* + * Overrun ? + */ + if(c->count < c->max) + { + *c->dptr++=ch; + c->count++; + } + + if(stat&END_FR) + { + + /* + * Error ? + */ + if(stat&(Rx_OVR|CRC_ERR)) + { + /* Rewind the buffer and return */ + if(c->skb) + c->dptr=c->skb->data; + c->count=0; + if(stat&Rx_OVR) + { + printk(KERN_WARNING "%s: overrun\n", c->dev->name); + c->rx_overrun++; + } + if(stat&CRC_ERR) + { + c->rx_crc_err++; + /* printk("crc error\n"); */ + } + /* Shove the frame upstream */ + } + else + { + z8530_rx_done(c); + write_zsctrl(c, RES_Rx_CRC); + } + } + } + /* + * Clear irq + */ + write_zsctrl(c, ERR_RES); + write_zsctrl(c, RES_H_IUS); +} + + +/* + * Z8530 transmit interrupt handler + */ + +static void z8530_tx(struct z8530_channel *c) +{ + while(c->txcount) + { + /* FIFO full ? */ + if(!(read_zsreg(c, R0)&4)) + break; + c->txcount--; + /* + * Shovel out the byte + */ + write_zsreg(c, R8, *c->tx_ptr++); + write_zsctrl(c, RES_H_IUS); + /* We are about to underflow */ + if(c->txcount==0) + { + write_zsctrl(c, RES_EOM_L); + write_zsreg(c, R10, c->regs[10]&~ABUNDER); + } + return; + } + + /* + * End of frame TX - fire another one + */ + + write_zsctrl(c, RES_Tx_P); + + z8530_tx_done(c); +/* write_zsreg(c, R8, *c->tx_ptr++); */ + write_zsctrl(c, RES_H_IUS); +} + +static void z8530_status(struct z8530_channel *chan) +{ + u8 status=read_zsreg(chan, R0); + u8 altered=chan->status^status; + + chan->status=status; + + if(status&TxEOM) + { +/* printk("%s: Tx underrun.\n", chan->dev->name); */ + write_zsctrl(chan, ERR_RES); + z8530_tx_done(chan); + } + + if(altered&DCD) + { + if(status&DCD) + { + printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); + write_zsreg(chan, R3, chan->regs[3]|RxENABLE); + } + else + { + printk(KERN_INFO "%s: DCD lost\n", chan->dev->name); + write_zsreg(chan, R3, chan->regs[3]&~RxENABLE); + z8530_flush_fifo(chan); + } + + } + write_zsctrl(chan, RES_EXT_INT); + write_zsctrl(chan, RES_H_IUS); +} + +struct z8530_irqhandler z8530_sync= +{ + z8530_rx, + z8530_tx, + z8530_status +}; + +EXPORT_SYMBOL(z8530_sync); + +/* + * Non bus mastering DMA interfaces for the Z8x30 devices. This + * is really pretty PC specific. + */ + +static void z8530_dma_rx(struct z8530_channel *chan) +{ + if(chan->rxdma_on) + { + /* Special condition check only */ + u8 status=read_zsreg(chan, R1); + if(status&END_FR) + { + z8530_rx_done(chan); /* Fire up the next one */ + } + write_zsctrl(chan, ERR_RES); + write_zsctrl(chan, RES_H_IUS); + } + else + { + /* DMA is off right now, drain the slow way */ + z8530_rx(chan); + } +} + +static void z8530_dma_tx(struct z8530_channel *chan) +{ + if(!chan->txdma_on) + { + z8530_tx(chan); + return; + } + /* This shouldnt occur in DMA mode */ + printk(KERN_ERR "DMA tx ??\n"); + z8530_tx(chan); +} + +static void z8530_dma_status(struct z8530_channel *chan) +{ + u8 status=read_zsreg(chan, R0); + u8 altered=chan->status^status; + + chan->status=status; + + if(chan->txdma_on) + { + if(status&TxEOM) + { + /* Transmit underrun */ + disable_dma(chan->txdma); + clear_dma_ff(chan->txdma); + chan->txdma_on=0; + z8530_tx_done(chan); + } + } + if(altered&DCD) + { + if(status&DCD) + { + printk(KERN_INFO "%s: DCD raised\n", chan->dev->name); + write_zsreg(chan, R3, chan->regs[3]|RxENABLE); + } + else + { + printk(KERN_INFO "%s:DCD lost\n", chan->dev->name); + write_zsreg(chan, R3, chan->regs[3]&~RxENABLE); + z8530_flush_fifo(chan); + } + } + write_zsctrl(chan, RES_EXT_INT); + write_zsctrl(chan, RES_H_IUS); +} + +struct z8530_irqhandler z8530_dma_sync= +{ + z8530_dma_rx, + z8530_dma_tx, + z8530_dma_status +}; + +EXPORT_SYMBOL(z8530_dma_sync); + +/* + * Interrupt vectors for a Z8530 that is in 'parked' mode. + * For machines with PCI Z85x30 cards, or level triggered interrupts + * (eg the MacII) we must clear the interrupt cause or die. + */ + + +static void z8530_rx_clear(struct z8530_channel *c) +{ + /* + * Data and status bytes + */ + u8 stat; + + read_zsdata(c); + stat=read_zsreg(c, R1); + + if(stat&END_FR) + write_zsctrl(c, RES_Rx_CRC); + /* + * Clear irq + */ + write_zsctrl(c, ERR_RES); + write_zsctrl(c, RES_H_IUS); +} + +static void z8530_tx_clear(struct z8530_channel *c) +{ + write_zsctrl(c, RES_Tx_P); + write_zsctrl(c, RES_H_IUS); +} + +static void z8530_status_clear(struct z8530_channel *chan) +{ + u8 status=read_zsreg(chan, R0); + if(status&TxEOM) + write_zsctrl(chan, ERR_RES); + write_zsctrl(chan, RES_EXT_INT); + write_zsctrl(chan, RES_H_IUS); +} + +struct z8530_irqhandler z8530_nop= +{ + z8530_rx_clear, + z8530_tx_clear, + z8530_status_clear +}; + + +EXPORT_SYMBOL(z8530_nop); + +/* + * A Z85[2]30 device has stuck its hand in the air for attention + */ + +void z8530_interrupt(int irq, void *dev_id, struct pt_regs *regs) +{ + struct z8530_dev *dev=dev_id; + u8 intr; + static volatile int locker=0; + int work=0; + + if(locker) + { + printk(KERN_ERR "IRQ re-enter\n"); + return; + } + locker=1; + + while(++work<5000) + { + struct z8530_irqhandler *irqs=dev->chanA.irqs; + + intr = read_zsreg(&dev->chanA, R3); + if(!(intr & (CHARxIP|CHATxIP|CHAEXT|CHBRxIP|CHBTxIP|CHBEXT))) + break; + + /* This holds the IRQ status. On the 8530 you must read it from chan + A even though it applies to the whole chip */ + + /* Now walk the chip and see what it is wanting - it may be + an IRQ for someone else remember */ + + if(intr & (CHARxIP|CHATxIP|CHAEXT)) + { + if(intr&CHARxIP) + irqs->rx(&dev->chanA); + if(intr&CHATxIP) + irqs->tx(&dev->chanA); + if(intr&CHAEXT) + irqs->status(&dev->chanA); + } + + irqs=dev->chanB.irqs; + + if(intr & (CHBRxIP|CHBTxIP|CHBEXT)) + { + if(intr&CHBRxIP) + irqs->rx(&dev->chanB); + if(intr&CHBTxIP) + irqs->tx(&dev->chanB); + if(intr&CHBEXT) + irqs->status(&dev->chanB); + } + } + if(work==200) + printk(KERN_ERR "%s: interrupt jammed - abort(0x%X)!\n", dev->name, intr); + /* Ok all done */ + locker=0; +} + +EXPORT_SYMBOL(z8530_interrupt); + +static char reg_init[16]= +{ + 0,0,0,0, + 0,0,0,0, + 0,0,0,0, + 0x55,0,0,0 +}; + + +int z8530_sync_open(struct device *dev, struct z8530_channel *c) +{ + c->sync = 1; + c->mtu = dev->mtu; + c->count = 0; + c->skb = NULL; + c->skb2 = NULL; + c->irqs = &z8530_sync; + /* This loads the double buffer up */ + z8530_rx_done(c); /* Load the frame ring */ + z8530_rx_done(c); /* Load the backup frame */ + z8530_rtsdtr(c,1); + write_zsreg(c, R3, c->regs[R3]|RxENABLE); + return 0; +} + + +EXPORT_SYMBOL(z8530_sync_open); + +int z8530_sync_close(struct device *dev, struct z8530_channel *c) +{ + u8 chk; + c->irqs = &z8530_nop; + c->max = 0; + c->sync = 0; + + chk=read_zsreg(c,R0); + write_zsreg(c, R3, c->regs[R3]); + z8530_rtsdtr(c,0); + return 0; +} + +EXPORT_SYMBOL(z8530_sync_close); + +int z8530_sync_dma_open(struct device *dev, struct z8530_channel *c) +{ + c->sync = 1; + c->mtu = dev->mtu; + c->count = 0; + c->skb = NULL; + c->skb2 = NULL; + /* + * Load the DMA interfaces up + */ + c->rxdma_on = 0; + c->txdma_on = 0; + + /* + * Allocate the DMA flip buffers + */ + + c->rx_buf[0]=kmalloc(c->mtu, GFP_KERNEL|GFP_DMA); + if(c->rx_buf[0]==NULL) + return -ENOBUFS; + c->rx_buf[1]=kmalloc(c->mtu, GFP_KERNEL|GFP_DMA); + if(c->rx_buf[1]==NULL) + { + kfree(c->rx_buf[0]); + c->rx_buf[0]=NULL; + return -ENOBUFS; + } + + c->tx_dma_buf[0]=kmalloc(c->mtu, GFP_KERNEL|GFP_DMA); + if(c->tx_dma_buf[0]==NULL) + { + kfree(c->rx_buf[0]); + kfree(c->rx_buf[1]); + c->rx_buf[0]=NULL; + return -ENOBUFS; + } + c->tx_dma_buf[1]=kmalloc(c->mtu, GFP_KERNEL|GFP_DMA); + if(c->tx_dma_buf[1]==NULL) + { + kfree(c->tx_dma_buf[0]); + kfree(c->rx_buf[0]); + kfree(c->rx_buf[1]); + c->rx_buf[0]=NULL; + c->rx_buf[1]=NULL; + c->tx_dma_buf[0]=NULL; + return -ENOBUFS; + } + c->tx_dma_used=0; + c->dma_num=0; + c->dma_ready=1; + + /* + * Enable DMA control mode + */ + + c->regs[R1]|= WT_RDY_RT|WT_FN_RDYFN; + c->regs[R1]|= INT_ERR_Rx; + write_zsreg(c, R1, c->regs[R1]); + c->regs[R1]|= WT_RDY_ENAB; + write_zsreg(c, R1, c->regs[R1]); + c->regs[R14]|= DTRREQ; + write_zsreg(c, R14, c->regs[R14]); + + /* + * DMA interrupts + */ + + /* + * Set up the DMA configuration + */ + + disable_dma(c->rxdma); + clear_dma_ff(c->rxdma); + set_dma_mode(c->rxdma, DMA_MODE_READ); + set_dma_addr(c->rxdma, virt_to_bus(c->rx_buf[0])); + set_dma_count(c->rxdma, c->mtu); + enable_dma(c->rxdma); + + disable_dma(c->txdma); + clear_dma_ff(c->txdma); + set_dma_mode(c->txdma, DMA_MODE_WRITE); + disable_dma(c->txdma); + + /* + * Select the DMA interrupt handlers + */ + + c->rxdma_on = 1; + c->txdma_on = 1; + c->tx_dma_used = 1; + + c->irqs = &z8530_dma_sync; + z8530_rtsdtr(c,1); + write_zsreg(c, R3, c->regs[R3]|RxENABLE); + return 0; +} + +EXPORT_SYMBOL(z8530_sync_dma_open); + +int z8530_sync_dma_close(struct device *dev, struct z8530_channel *c) +{ + u8 chk; + c->irqs = &z8530_nop; + c->max = 0; + c->sync = 0; + + /* + * Disable the PC DMA channels + */ + + disable_dma(c->rxdma); + clear_dma_ff(c->rxdma); + c->rxdma_on = 0; + disable_dma(c->txdma); + clear_dma_ff(c->txdma); + c->txdma_on = 0; + c->tx_dma_used = 0; + + /* + * Disable DMA control mode + */ + + c->regs[R1]&= ~WT_RDY_ENAB; + write_zsreg(c, R1, c->regs[R1]); + c->regs[R1]&= ~(WT_RDY_RT|WT_FN_RDYFN|INT_ERR_Rx); + c->regs[R1]|= INT_ALL_Rx; + write_zsreg(c, R1, c->regs[R1]); + c->regs[R14]&= ~DTRREQ; + write_zsreg(c, R14, c->regs[R14]); + + if(c->rx_buf[0]) + { + kfree(c->rx_buf[0]); + c->rx_buf[0]=NULL; + } + if(c->rx_buf[1]) + { + kfree(c->rx_buf[1]); + c->rx_buf[1]=NULL; + } + if(c->tx_dma_buf[0]) + { + kfree(c->tx_dma_buf[0]); + c->tx_dma_buf[0]=NULL; + } + if(c->tx_dma_buf[1]) + { + kfree(c->tx_dma_buf[1]); + c->tx_dma_buf[1]=NULL; + } + chk=read_zsreg(c,R0); + write_zsreg(c, R3, c->regs[R3]); + z8530_rtsdtr(c,0); + return 0; +} + +EXPORT_SYMBOL(z8530_sync_dma_close); + +/* + * Describe a Z8530 in a standard format. We must pass the I/O as + * the port offset isnt predictable. The main reason for this function + * is to try and get a common format of report. + */ + +static char *z8530_type_name[]={ + "Z8530", + "Z85C30", + "Z85230" +}; + +void z8530_describe(struct z8530_dev *dev, char *mapping, int io) +{ + printk(KERN_INFO "%s: %s found at %s 0x%X, IRQ %d.\n", + dev->name, + z8530_type_name[dev->type], + mapping, + io, + dev->irq); +} + +EXPORT_SYMBOL(z8530_describe); + +/* + * Configure up a Z8530 + */ + + +int z8530_init(struct z8530_dev *dev) +{ + /* NOP the interrupt handlers first - we might get a + floating IRQ transition when we reset the chip */ + dev->chanA.irqs=&z8530_nop; + dev->chanB.irqs=&z8530_nop; + /* Reset the chip */ + write_zsreg(&dev->chanA, R9, 0xC0); + udelay(100); + /* Now check its valid */ + write_zsreg(&dev->chanA, R12, 0xAA); + if(read_zsreg(&dev->chanA, R12)!=0xAA) + return -ENODEV; + write_zsreg(&dev->chanA, R12, 0x55); + if(read_zsreg(&dev->chanA, R12)!=0x55) + return -ENODEV; + + dev->type=Z8530; + + /* + * See the application note. + */ + + write_zsreg(&dev->chanA, R15, 0x01); + + /* + * If we can set the low bit of R15 then + * the chip is enhanced. + */ + + if(read_zsreg(&dev->chanA, R15)==0x01) + { + /* This C30 versus 230 detect is from Klaus Kudielka's dmascc */ + /* Put a char in the fifo */ + write_zsreg(&dev->chanA, R8, 0); + if(read_zsreg(&dev->chanA, R0)&Tx_BUF_EMP) + dev->type = Z85230; /* Has a FIFO */ + else + dev->type = Z85C30; /* Z85C30, 1 byte FIFO */ + } + + /* + * The code assumes R7' and friends are + * off. Use write_zsext() for these and keep + * this bit clear. + */ + + write_zsreg(&dev->chanA, R15, 0); + + /* + * At this point it looks like the chip is behaving + */ + + memcpy(dev->chanA.regs, reg_init, 16); + memcpy(dev->chanB.regs, reg_init ,16); + + return 0; +} + + +EXPORT_SYMBOL(z8530_init); + +int z8530_shutdown(struct z8530_dev *dev) +{ + /* Reset the chip */ + dev->chanA.irqs=&z8530_nop; + dev->chanB.irqs=&z8530_nop; + write_zsreg(&dev->chanA, R9, 0xC0); + udelay(100); + return 0; +} + +EXPORT_SYMBOL(z8530_shutdown); + +/* + * Load a Z8530 channel up from the system data + * We use +16 to indicate the 'prime' registers + */ + +int z8530_channel_load(struct z8530_channel *c, u8 *rtable) +{ + while(*rtable!=255) + { + int reg=*rtable++; + if(reg>0x0F) + write_zsreg(c, R15, c->regs[15]|1); + write_zsreg(c, reg&0x0F, *rtable); + if(reg>0x0F) + write_zsreg(c, R15, c->regs[15]&~1); + c->regs[reg]=*rtable++; + } + c->rx_function=z8530_null_rx; + c->skb=NULL; + c->tx_skb=NULL; + c->tx_next_skb=NULL; + c->mtu=1500; + c->max=0; + c->count=0; + c->status=0; /* Fixme - check DCD now */ + c->sync=1; + write_zsreg(c, R3, c->regs[R3]|RxENABLE); + return 0; +} + +EXPORT_SYMBOL(z8530_channel_load); + + +/* + * Higher level shovelling - transmit chains + */ + +static void z8530_tx_begin(struct z8530_channel *c) +{ + unsigned long flags; + if(c->tx_skb) + return; + + c->tx_skb=c->tx_next_skb; + c->tx_next_skb=NULL; + c->tx_ptr=c->tx_next_ptr; + + mark_bh(NET_BH); + if(c->tx_skb==NULL) + { + /* Idle on */ + disable_dma(c->txdma); + c->txcount=0; + } + else + { + c->tx_ptr=c->tx_next_ptr; + c->txcount=c->tx_skb->len; + + + if(c->tx_dma_used) + { + /* + * FIXME. DMA is broken for the non 85230, + * on the older parts we need to set a flag and + * wait for a further TX interrupt to fire this + * stage off + */ + disable_dma(c->txdma); + clear_dma_ff(c->txdma); + set_dma_addr(c->txdma, virt_to_bus(c->tx_ptr)); + set_dma_count(c->txdma, c->txcount); + enable_dma(c->txdma); + write_zsreg(c, R5, c->regs[R5]|TxENAB); + } + else + { + save_flags(flags); + cli(); + /* ABUNDER off */ + write_zsreg(c, R10, c->regs[10]); + write_zsctrl(c, RES_Tx_CRC); + write_zsctrl(c, RES_EOM_L); + + while(c->txcount && (read_zsreg(c,R0)&Tx_BUF_EMP)) + { + write_zsreg(c, R8, *c->tx_ptr++); + c->txcount--; + } + restore_flags(flags); + } + } +} + + +static void z8530_tx_done(struct z8530_channel *c) +{ + unsigned long flags; + struct sk_buff *skb; + + spin_lock_irqsave(&z8530_buffer_lock, flags); + c->netdevice->tbusy=0; + /* Can't happen */ + if(c->tx_skb==NULL) + { + spin_unlock_irqrestore(&z8530_buffer_lock, flags); + printk(KERN_WARNING "%s: spurious tx done\n", c->dev->name); + return; + } + skb=c->tx_skb; + c->tx_skb=NULL; + z8530_tx_begin(c); + spin_unlock_irqrestore(&z8530_buffer_lock, flags); + dev_kfree_skb(skb); +} + +/* + * Higher level shovelling - receive chains + */ + +void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb) +{ + kfree_skb(skb); +} + +EXPORT_SYMBOL(z8530_null_rx); + +static void z8530_rx_done(struct z8530_channel *c) +{ + struct sk_buff *skb; + int ct; + + /* + * Is our receive engine in DMA mode + */ + + if(c->rxdma_on) + { + /* + * Save the ready state and the buffer currently + * being used as the DMA target + */ + int ready=c->dma_ready; + char *rxb=c->rx_buf[c->dma_num]; + + /* + * Complete this DMA. Neccessary to find the length + */ + disable_dma(c->rxdma); + clear_dma_ff(c->rxdma); + c->rxdma_on=0; + ct=c->mtu-get_dma_residue(c->rxdma)-4; + if(ct<0) + ct=2; /* Shit happens.. */ + c->dma_ready=0; + + /* + * Normal case: the other slot is free, start the next DMA + * into it immediately. + */ + + if(ready) + { + c->dma_num^=1; + set_dma_mode(c->rxdma, DMA_MODE_READ); + set_dma_addr(c->rxdma, virt_to_bus(c->rx_buf[c->dma_num])); + set_dma_count(c->rxdma, c->mtu); + c->rxdma_on = 1; + enable_dma(c->rxdma); + } + else + /* Can't occur as we dont reenable the DMA irq until + after the flip is done */ + printk("DMA flip overrun!\n"); + + /* + * Shove the old buffer into an sk_buff. We can't DMA + * directly into one on a PC - it might be above the 16Mb + * boundary. Optimisation - we could check to see if we + * can avoid the copy. Optimisation 2 - make the memcpy + * a copychecksum. + */ + + skb=dev_alloc_skb(ct); + if(skb==NULL) + printk("%s: Memory squeeze.\n", c->netdevice->name); + else + { + skb_put(skb, ct); + memcpy(skb->data, rxb, ct); + skb_pull(skb,2); + } + c->dma_ready=1; + } + else + { + RT_LOCK; + skb=c->skb; + + /* + * The game we play for non DMA is similar. We want to + * get the controller set up for the next packet as fast + * as possible. We potentially only have one byte + the + * fifo length for this. Thus we want to flip to the new + * buffer and then mess around copying and allocating + * things. For the current case it doesn't matter but + * if you build a system where the sync irq isnt blocked + * by the kernel IRQ disable then you need only block the + * sync IRQ for the RT_LOCK area. + * + */ + ct=c->count; + + c->skb = c->skb2; + c->count = 0; + c->max = c->mtu; + if(c->skb) + { + c->dptr = c->skb->data; + c->max = c->mtu; + } + else + { + c->count= 0; + c->max = 0; + } + RT_UNLOCK; + + c->skb2 = dev_alloc_skb(c->mtu); + if(c->skb2==NULL) + printk(KERN_WARNING "%s: memory squeeze.\n", + c->netdevice->name); + else + { + skb_put(c->skb2,c->mtu); + } + } + /* + * If we received a frame we must now process it. + */ + if(skb) + { + skb_trim(skb, ct); + c->rx_function(c,skb); + } + else + printk("Lost a frame\n"); +} + + +/* + * Queue a packet for transmission. Because we have rather + * hard to hit interrupt latencies for the Z85230 per packet + * even in DMA mode we do the flip to DMA buffer if needed here + * not in the IRQ. + */ + +int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb) +{ + unsigned long flags; + if(c->tx_next_skb) + { + skb->dev->tbusy=1; + return 1; + } + + /* PC SPECIFIC - DMA limits */ + + /* + * If we will DMA the transmit and its gone over the ISA bus + * limit, then copy to the flip buffer + */ + + if(c->dma_tx && (unsigned long)(virt_to_bus(skb->data+skb->len))>=16*1024*1024) + { + /* + * Send the flip buffer, and flip the flippy bit. + * We don't care which is used when just so long as + * we never use the same buffer twice in a row. Since + * only one buffer can be going out at a time the other + * has to be safe. + */ + c->tx_next_ptr=c->tx_dma_buf[c->tx_dma_used]; + c->tx_dma_used^=1; /* Flip temp buffer */ + memcpy(c->tx_next_ptr, skb->data, skb->len); + } + else + c->tx_next_ptr=skb->data; + RT_LOCK; + c->tx_next_skb=skb; + RT_UNLOCK; + + spin_lock_irqsave(&z8530_buffer_lock, flags); + z8530_tx_begin(c); + spin_unlock_irqrestore(&z8530_buffer_lock, flags); + return 0; +} + +EXPORT_SYMBOL(z8530_queue_xmit); + +struct net_device_stats *z8530_get_stats(struct z8530_channel *c) +{ + return &c->stats; +} + +EXPORT_SYMBOL(z8530_get_stats); + +#ifdef MODULE + +/* + * Module support + */ + +int init_module(void) +{ + printk(KERN_INFO "Generic Z85C30/Z85230 interface driver v0.02\n"); + return 0; +} + +void cleanup_module(void) +{ +} + +#endif diff -u --recursive --new-file v2.1.120/linux/drivers/net/z85230.h linux/drivers/net/z85230.h --- v2.1.120/linux/drivers/net/z85230.h Wed Dec 31 16:00:00 1969 +++ linux/drivers/net/z85230.h Sun Sep 6 10:47:01 1998 @@ -0,0 +1,444 @@ +/* + * Description of Z8530 Z85C30 and Z85230 communications chips + * + * Copyright (C) 1995 David S. Miller (davem@caip.rutgers.edu) + * Copyright (C) 1998 Alan Cox + */ + +#ifndef _Z8530_H +#define _Z8530_H + +/* Conversion routines to/from brg time constants from/to bits + * per second. + */ +#define BRG_TO_BPS(brg, freq) ((freq) / 2 / ((brg) + 2)) +#define BPS_TO_BRG(bps, freq) ((((freq) + (bps)) / (2 * (bps))) - 2) + +/* The Zilog register set */ + +#define FLAG 0x7e + +/* Write Register 0 */ +#define R0 0 /* Register selects */ +#define R1 1 +#define R2 2 +#define R3 3 +#define R4 4 +#define R5 5 +#define R6 6 +#define R7 7 +#define R8 8 +#define R9 9 +#define R10 10 +#define R11 11 +#define R12 12 +#define R13 13 +#define R14 14 +#define R15 15 + +#define RPRIME 16 /* Indicate a prime register access on 230 */ + +#define NULLCODE 0 /* Null Code */ +#define POINT_HIGH 0x8 /* Select upper half of registers */ +#define RES_EXT_INT 0x10 /* Reset Ext. Status Interrupts */ +#define SEND_ABORT 0x18 /* HDLC Abort */ +#define RES_RxINT_FC 0x20 /* Reset RxINT on First Character */ +#define RES_Tx_P 0x28 /* Reset TxINT Pending */ +#define ERR_RES 0x30 /* Error Reset */ +#define RES_H_IUS 0x38 /* Reset highest IUS */ + +#define RES_Rx_CRC 0x40 /* Reset Rx CRC Checker */ +#define RES_Tx_CRC 0x80 /* Reset Tx CRC Checker */ +#define RES_EOM_L 0xC0 /* Reset EOM latch */ + +/* Write Register 1 */ + +#define EXT_INT_ENAB 0x1 /* Ext Int Enable */ +#define TxINT_ENAB 0x2 /* Tx Int Enable */ +#define PAR_SPEC 0x4 /* Parity is special condition */ + +#define RxINT_DISAB 0 /* Rx Int Disable */ +#define RxINT_FCERR 0x8 /* Rx Int on First Character Only or Error */ +#define INT_ALL_Rx 0x10 /* Int on all Rx Characters or error */ +#define INT_ERR_Rx 0x18 /* Int on error only */ + +#define WT_RDY_RT 0x20 /* Wait/Ready on R/T */ +#define WT_FN_RDYFN 0x40 /* Wait/FN/Ready FN */ +#define WT_RDY_ENAB 0x80 /* Wait/Ready Enable */ + +/* Write Register #2 (Interrupt Vector) */ + +/* Write Register 3 */ + +#define RxENABLE 0x1 /* Rx Enable */ +#define SYNC_L_INH 0x2 /* Sync Character Load Inhibit */ +#define ADD_SM 0x4 /* Address Search Mode (SDLC) */ +#define RxCRC_ENAB 0x8 /* Rx CRC Enable */ +#define ENT_HM 0x10 /* Enter Hunt Mode */ +#define AUTO_ENAB 0x20 /* Auto Enables */ +#define Rx5 0x0 /* Rx 5 Bits/Character */ +#define Rx7 0x40 /* Rx 7 Bits/Character */ +#define Rx6 0x80 /* Rx 6 Bits/Character */ +#define Rx8 0xc0 /* Rx 8 Bits/Character */ + +/* Write Register 4 */ + +#define PAR_ENA 0x1 /* Parity Enable */ +#define PAR_EVEN 0x2 /* Parity Even/Odd* */ + +#define SYNC_ENAB 0 /* Sync Modes Enable */ +#define SB1 0x4 /* 1 stop bit/char */ +#define SB15 0x8 /* 1.5 stop bits/char */ +#define SB2 0xc /* 2 stop bits/char */ + +#define MONSYNC 0 /* 8 Bit Sync character */ +#define BISYNC 0x10 /* 16 bit sync character */ +#define SDLC 0x20 /* SDLC Mode (01111110 Sync Flag) */ +#define EXTSYNC 0x30 /* External Sync Mode */ + +#define X1CLK 0x0 /* x1 clock mode */ +#define X16CLK 0x40 /* x16 clock mode */ +#define X32CLK 0x80 /* x32 clock mode */ +#define X64CLK 0xC0 /* x64 clock mode */ + +/* Write Register 5 */ + +#define TxCRC_ENAB 0x1 /* Tx CRC Enable */ +#define RTS 0x2 /* RTS */ +#define SDLC_CRC 0x4 /* SDLC/CRC-16 */ +#define TxENAB 0x8 /* Tx Enable */ +#define SND_BRK 0x10 /* Send Break */ +#define Tx5 0x0 /* Tx 5 bits (or less)/character */ +#define Tx7 0x20 /* Tx 7 bits/character */ +#define Tx6 0x40 /* Tx 6 bits/character */ +#define Tx8 0x60 /* Tx 8 bits/character */ +#define DTR 0x80 /* DTR */ + +/* Write Register 6 (Sync bits 0-7/SDLC Address Field) */ + +/* Write Register 7 (Sync bits 8-15/SDLC 01111110) */ + +/* Write Register 8 (transmit buffer) */ + +/* Write Register 9 (Master interrupt control) */ +#define VIS 1 /* Vector Includes Status */ +#define NV 2 /* No Vector */ +#define DLC 4 /* Disable Lower Chain */ +#define MIE 8 /* Master Interrupt Enable */ +#define STATHI 0x10 /* Status high */ +#define NORESET 0 /* No reset on write to R9 */ +#define CHRB 0x40 /* Reset channel B */ +#define CHRA 0x80 /* Reset channel A */ +#define FHWRES 0xc0 /* Force hardware reset */ + +/* Write Register 10 (misc control bits) */ +#define BIT6 1 /* 6 bit/8bit sync */ +#define LOOPMODE 2 /* SDLC Loop mode */ +#define ABUNDER 4 /* Abort/flag on SDLC xmit underrun */ +#define MARKIDLE 8 /* Mark/flag on idle */ +#define GAOP 0x10 /* Go active on poll */ +#define NRZ 0 /* NRZ mode */ +#define NRZI 0x20 /* NRZI mode */ +#define FM1 0x40 /* FM1 (transition = 1) */ +#define FM0 0x60 /* FM0 (transition = 0) */ +#define CRCPS 0x80 /* CRC Preset I/O */ + +/* Write Register 11 (Clock Mode control) */ +#define TRxCXT 0 /* TRxC = Xtal output */ +#define TRxCTC 1 /* TRxC = Transmit clock */ +#define TRxCBR 2 /* TRxC = BR Generator Output */ +#define TRxCDP 3 /* TRxC = DPLL output */ +#define TRxCOI 4 /* TRxC O/I */ +#define TCRTxCP 0 /* Transmit clock = RTxC pin */ +#define TCTRxCP 8 /* Transmit clock = TRxC pin */ +#define TCBR 0x10 /* Transmit clock = BR Generator output */ +#define TCDPLL 0x18 /* Transmit clock = DPLL output */ +#define RCRTxCP 0 /* Receive clock = RTxC pin */ +#define RCTRxCP 0x20 /* Receive clock = TRxC pin */ +#define RCBR 0x40 /* Receive clock = BR Generator output */ +#define RCDPLL 0x60 /* Receive clock = DPLL output */ +#define RTxCX 0x80 /* RTxC Xtal/No Xtal */ + +/* Write Register 12 (lower byte of baud rate generator time constant) */ + +/* Write Register 13 (upper byte of baud rate generator time constant) */ + +/* Write Register 14 (Misc control bits) */ +#define BRENABL 1 /* Baud rate generator enable */ +#define BRSRC 2 /* Baud rate generator source */ +#define DTRREQ 4 /* DTR/Request function */ +#define AUTOECHO 8 /* Auto Echo */ +#define LOOPBAK 0x10 /* Local loopback */ +#define SEARCH 0x20 /* Enter search mode */ +#define RMC 0x40 /* Reset missing clock */ +#define DISDPLL 0x60 /* Disable DPLL */ +#define SSBR 0x80 /* Set DPLL source = BR generator */ +#define SSRTxC 0xa0 /* Set DPLL source = RTxC */ +#define SFMM 0xc0 /* Set FM mode */ +#define SNRZI 0xe0 /* Set NRZI mode */ + +/* Write Register 15 (external/status interrupt control) */ +#define PRIME 1 /* R5' etc register access (Z85C30/230 only) */ +#define ZCIE 2 /* Zero count IE */ +#define FIFOE 4 /* Z85230 only */ +#define DCDIE 8 /* DCD IE */ +#define SYNCIE 0x10 /* Sync/hunt IE */ +#define CTSIE 0x20 /* CTS IE */ +#define TxUIE 0x40 /* Tx Underrun/EOM IE */ +#define BRKIE 0x80 /* Break/Abort IE */ + + +/* Read Register 0 */ +#define Rx_CH_AV 0x1 /* Rx Character Available */ +#define ZCOUNT 0x2 /* Zero count */ +#define Tx_BUF_EMP 0x4 /* Tx Buffer empty */ +#define DCD 0x8 /* DCD */ +#define SYNC_HUNT 0x10 /* Sync/hunt */ +#define CTS 0x20 /* CTS */ +#define TxEOM 0x40 /* Tx underrun */ +#define BRK_ABRT 0x80 /* Break/Abort */ + +/* Read Register 1 */ +#define ALL_SNT 0x1 /* All sent */ +/* Residue Data for 8 Rx bits/char programmed */ +#define RES3 0x8 /* 0/3 */ +#define RES4 0x4 /* 0/4 */ +#define RES5 0xc /* 0/5 */ +#define RES6 0x2 /* 0/6 */ +#define RES7 0xa /* 0/7 */ +#define RES8 0x6 /* 0/8 */ +#define RES18 0xe /* 1/8 */ +#define RES28 0x0 /* 2/8 */ +/* Special Rx Condition Interrupts */ +#define PAR_ERR 0x10 /* Parity error */ +#define Rx_OVR 0x20 /* Rx Overrun Error */ +#define CRC_ERR 0x40 /* CRC/Framing Error */ +#define END_FR 0x80 /* End of Frame (SDLC) */ + +/* Read Register 2 (channel b only) - Interrupt vector */ + +/* Read Register 3 (interrupt pending register) ch a only */ +#define CHBEXT 0x1 /* Channel B Ext/Stat IP */ +#define CHBTxIP 0x2 /* Channel B Tx IP */ +#define CHBRxIP 0x4 /* Channel B Rx IP */ +#define CHAEXT 0x8 /* Channel A Ext/Stat IP */ +#define CHATxIP 0x10 /* Channel A Tx IP */ +#define CHARxIP 0x20 /* Channel A Rx IP */ + +/* Read Register 8 (receive data register) */ + +/* Read Register 10 (misc status bits) */ +#define ONLOOP 2 /* On loop */ +#define LOOPSEND 0x10 /* Loop sending */ +#define CLK2MIS 0x40 /* Two clocks missing */ +#define CLK1MIS 0x80 /* One clock missing */ + +/* Read Register 12 (lower byte of baud rate generator constant) */ + +/* Read Register 13 (upper byte of baud rate generator constant) */ + +/* Read Register 15 (value of WR 15) */ + + +/* + * Interrupt handling functions for this SCC + */ + +struct z8530_channel; + +struct z8530_irqhandler +{ + void (*rx)(struct z8530_channel *); + void (*tx)(struct z8530_channel *); + void (*status)(struct z8530_channel *); +}; + +/* + * A channel of the Z8530 + */ + +struct z8530_channel +{ + struct z8530_irqhandler *irqs; /* IRQ handlers */ + /* + * Synchronous + */ + u16 count; /* Buyes received */ + u16 max; /* Most we can receive this frame */ + u16 mtu; /* MTU of the device */ + u8 *dptr; /* Pointer into rx buffer */ + struct sk_buff *skb; /* Buffer dptr points into */ + struct sk_buff *skb2; /* Pending buffer */ + u8 status; /* Current DCD */ + u8 sync; /* Set if in sync mode */ + + u8 regs[16]; /* Register map for the chip */ + u8 pendregs[16]; /* Pending register values */ + + struct sk_buff *tx_skb; /* Buffer being transmitted */ + struct sk_buff *tx_next_skb; /* Next transmit buffer */ + u8 *tx_ptr; /* Byte pointer into the buffer */ + u8 *tx_next_ptr; /* Next pointer to use */ + u8 *tx_dma_buf[2]; /* TX flip buffers for DMA */ + u8 tx_dma_used; /* Flip buffer usage toggler */ + u16 txcount; /* Count of bytes to transmit */ + + void (*rx_function)(struct z8530_channel *, struct sk_buff *); + + /* + * Sync DMA + */ + + u8 rxdma; /* DMA channels */ + u8 txdma; + u8 rxdma_on; /* DMA active if flag set */ + u8 txdma_on; + u8 dma_num; /* Buffer we are DMAing into */ + u8 dma_ready; /* Is the other buffer free */ + u8 dma_tx; /* TX is to use DMA */ + u8 *rx_buf[2]; /* The flip buffers */ + + /* + * System + */ + + struct z8530_dev *dev; /* Z85230 chip instance we are from */ + int ctrlio; /* I/O ports */ + int dataio; + + /* + * For PC we encode this way. + */ +#define Z8530_PORT_SLEEP 0x80000000 +#define Z8530_PORT_OF(x) ((x)&0xFFFF) + + u32 rx_overrun; /* Overruns - not done yet */ + u32 rx_crc_err; + + /* + * Bound device pointers + */ + + void *private; /* For our owner */ + struct device *netdevice; /* Network layer device */ + struct net_device_stats stats; /* Network layer statistics */ + + /* + * Async features + */ + + struct tty_struct *tty; /* Attached terminal */ + int line; /* Minor number */ + struct termios normal_termios; /* Terminal settings */ + struct termios callout_termios; + struct wait_queue *open_wait; /* Tasks waiting to open */ + struct wait_queue *close_wait; /* and for close to end */ + unsigned long event; /* Pending events */ + int fdcount; /* # of fd on device */ + int blocked_open; /* # of blocked opens */ + long session; /* Session of opening process */ + long pgrp; /* pgrp of opening process */ + int x_char; /* XON/XOF char */ + unsigned char *xmit_buf; /* Transmit pointer */ + int xmit_head; /* Transmit ring */ + int xmit_tail; + int xmit_cnt; + int flags; + int timeout; + int xmit_fifo_size; /* Transmit FIFO info */ + + int close_delay; /* Do we wait for drain on close ? */ + unsigned short closing_wait; + + /* We need to know the current clock divisor + * to read the bps rate the chip has currently + * loaded. + */ + + unsigned char clk_divisor; /* May be 1, 16, 32, or 64 */ + int zs_baud; + + int magic; + int baud_base; /* Baud parameters */ + int custom_divisor; + + + unsigned char tx_active; /* character is being xmitted */ + unsigned char tx_stopped; /* output is suspended */ +}; + +/* + * Each Z853x0 device. + */ + +struct z8530_dev +{ + char *name; /* Device instance name */ + struct z8530_channel chanA; /* SCC channel A */ + struct z8530_channel chanB; /* SCC channel B */ + int type; +#define Z8530 0 /* NMOS dinosaur */ +#define Z85C30 1 /* CMOS - better */ +#define Z85230 2 /* CMOS with real FIFO */ + int irq; /* Interrupt for the device */ + int active; /* Soft interrupt enable - the Mac doesn't + always have a hard disable on its 8530s... */ +}; + + +/* + * Functions + */ + +extern u8 z8530_dead_port[]; +extern u8 z8530_hdlc_kilostream_85230[]; +extern u8 z8530_hdlc_kilostream[]; +extern void z8530_interrupt(int, void *, struct pt_regs *); +extern void z8530_describe(struct z8530_dev *, char *mapping,int io); +extern int z8530_init(struct z8530_dev *); +extern int z8530_shutdown(struct z8530_dev *); +extern int z8530_sync_open(struct device *, struct z8530_channel *); +extern int z8530_sync_close(struct device *, struct z8530_channel *); +extern int z8530_sync_dma_open(struct device *, struct z8530_channel *); +extern int z8530_sync_dma_close(struct device *, struct z8530_channel *); +extern int z8530_channel_load(struct z8530_channel *, u8 *); +extern int z8530_queue_xmit(struct z8530_channel *c, struct sk_buff *skb); +extern struct net_device_stats *z8530_get_stats(struct z8530_channel *c); +extern void z8530_null_rx(struct z8530_channel *c, struct sk_buff *skb); + + +/* + * Standard interrupt vector sets + */ + +struct z8530_irqhandler z8530_sync, z8530_async, z8530_nop; + +/* + * Asynchronous Interfacing + */ + +#define SERIAL_MAGIC 0x5301 + +/* + * The size of the serial xmit buffer is 1 page, or 4096 bytes + */ + +#define SERIAL_XMIT_SIZE 4096 +#define WAKEUP_CHARS 256 + +/* + * Events are used to schedule things to happen at timer-interrupt + * time, instead of at rs interrupt time. + */ +#define RS_EVENT_WRITE_WAKEUP 0 + +/* Internal flags used only by kernel/chr_drv/serial.c */ +#define ZILOG_INITIALIZED 0x80000000 /* Serial port was initialized */ +#define ZILOG_CALLOUT_ACTIVE 0x40000000 /* Call out device is active */ +#define ZILOG_NORMAL_ACTIVE 0x20000000 /* Normal device is active */ +#define ZILOG_BOOT_AUTOCONF 0x10000000 /* Autoconfigure port on bootup */ +#define ZILOG_CLOSING 0x08000000 /* Serial port is closing */ +#define ZILOG_CTS_FLOW 0x04000000 /* Do CTS flow control */ +#define ZILOG_CHECK_CD 0x02000000 /* i.e., CLOCAL */ + +#endif /* !(_Z8530_H) */ diff -u --recursive --new-file v2.1.120/linux/drivers/pci/pci.c linux/drivers/pci/pci.c --- v2.1.120/linux/drivers/pci/pci.c Wed Aug 26 11:37:38 1998 +++ linux/drivers/pci/pci.c Sat Sep 5 18:33:41 1998 @@ -1,5 +1,5 @@ /* - * $Id: pci.c,v 1.88 1998/08/15 10:37:12 mj Exp $ + * $Id: pci.c,v 1.90 1998/09/05 12:39:39 mj Exp $ * * PCI Bus Services, see include/linux/pci.h for further explanation. * @@ -138,7 +138,8 @@ if (l == 0xffffffff) continue; dev->base_address[reg] = l; - if ((l & PCI_MEMORY_RANGE_TYPE_MASK) == PCI_BASE_ADDRESS_MEM_TYPE_64) { + if ((l & (PCI_BASE_ADDRESS_SPACE | PCI_BASE_ADDRESS_MEM_TYPE_MASK)) + == (PCI_BASE_ADDRESS_SPACE_MEMORY | PCI_BASE_ADDRESS_MEM_TYPE_64)) { reg++; pci_read_config_dword(dev, PCI_BASE_ADDRESS_0 + (reg << 2), &l); if (l) { diff -u --recursive --new-file v2.1.120/linux/drivers/scsi/NCR5380.c linux/drivers/scsi/NCR5380.c --- v2.1.120/linux/drivers/scsi/NCR5380.c Sat Sep 5 16:46:41 1998 +++ linux/drivers/scsi/NCR5380.c Sat Sep 5 17:01:45 1998 @@ -1628,14 +1628,18 @@ NCR5380_local_declare(); struct NCR5380_hostdata *hostdata = (struct NCR5380_hostdata *) instance->hostdata; unsigned char tmp[3], phase; - unsigned char *data, value; + unsigned char *data; int len; unsigned long timeout; unsigned long flags; +#ifdef USLEEP + unsigned char value; +#endif - NCR5380_setup(instance); + NCR5380_setup(instance); #ifdef USLEEP + if (hostdata->selecting) { goto part2; /* RvC: sorry prof. Dijkstra, but it keeps the @@ -2250,8 +2254,8 @@ register unsigned char p = *phase; register unsigned char *d = *data; unsigned char tmp; - int foo; unsigned long flags; + int foo; #if defined(REAL_DMA_POLL) int cnt, toPIO; unsigned char saved_data = 0, overrun = 0, residue; diff -u --recursive --new-file v2.1.120/linux/drivers/scsi/README.st linux/drivers/scsi/README.st --- v2.1.120/linux/drivers/scsi/README.st Wed May 28 10:51:32 1997 +++ linux/drivers/scsi/README.st Sun Sep 6 09:48:30 1998 @@ -2,7 +2,7 @@ The driver is currently maintained by Kai M{kisara (email Kai.Makisara@metla.fi) -Last modified: Tue May 27 22:29:24 1997 by makisara@home +Last modified: Sun Sep 6 10:03:47 1998 by makisara@home BASICS @@ -117,9 +117,9 @@ The buffer size is defined (in 1024 byte units) by ST_BUFFER_BLOCKS or at boot time. If this size is not enough, the driver tries to allocate a large enough temporary buffer that is released when the device is -closed. The maximum buffer size is defined by the kernel memory -allocation (currently 256 kB for Alphas and 128 kB for other -architectures). +closed. Buffer allocation uses chunks of memory having sizes +2^n * (page size). Because of this the actual buffer size may be +larger than the buffer size specified with ST_BUFFER_BLOCKS. Allocation of the buffers is done at run-time when they are needed. Allocation of the specified number of buffers can be done at @@ -143,6 +143,31 @@ use pattern. The default triggers asynchronous write after three default sized writes (10 kB) from tar. +Scatter/gather buffers (buffers that consist of chunks non-contiguous +in the physical memory) are used if contiguous buffers can't be +allocated. To support all SCSI adapters (including those not +supporting scatter/gather), buffer allocation is using the following +three kinds of chunks: +1. The initial segment that is used for all SCSI adapters including +those not supporting scatter/gather. The size of this buffer will be +(PAGE_SIZE << ST_FIRST_ORDER) bytes if the system can give a chunk of +this size (and it is not larger than the buffer size specified by +ST_BUFFER_BLOCKS). If this size is not available, the driver halves +the size and tries again until the size of one page. The default +settings in st_options.h make the driver to try to allocate all of the +buffer as one chunk. +2. The scatter/gather segments to fill the specified buffer size are +allocated so that as many segments as possible are used but the number +of segments does not exceed ST_FIRST_SG. +3. The remaining segments between ST_MAX_SG (or the module parameter +max_sg_segs) and the number of segments used in phases 1 and 2 +are used to extend the buffer at run-time if this is necessary. The +number of scatter/gather segments allowed for the SCSI adapter is not +exceeded if it is smaller than the maximum number of scatter/gather +segments specified. If the maximum number allowed for the SCSI adapter +is smaller than the number of segments used in phases 1 and 2, +extending the buffer will always fail. + BOOT TIME CONFIGURATION @@ -167,6 +192,9 @@ buffer_kbs=xxx the buffer size in kilobytes is set to xxx write_threshold_kbs=xxx the write threshold in kilobytes set to xxx max_buffers=xxx the maximum number of tape buffer set to xxx +max_sg_segs=xxx the maximum number of scatter/gather + segments + IOCTLS @@ -357,7 +385,7 @@ To enable debugging messages, edit st.c and #define DEBUG 1. As seen above, debugging can be switched off with an ioctl if debugging is -compiled into the driver. The debugging output is not not voluminuous. +compiled into the driver. The debugging output is not voluminuous. If the tape seems to hang, I would be very interested to hear where the driver is waiting. With the command 'ps -l' you can see the state diff -u --recursive --new-file v2.1.120/linux/drivers/scsi/ncr53c8xx.c linux/drivers/scsi/ncr53c8xx.c --- v2.1.120/linux/drivers/scsi/ncr53c8xx.c Tue Jul 21 00:15:31 1998 +++ linux/drivers/scsi/ncr53c8xx.c Sun Sep 6 10:34:33 1998 @@ -587,8 +587,12 @@ #define remap_pci_mem(base, size) ((vm_offset_t) __va(base)) #define unmap_pci_mem(vaddr, size) #define pcivtophys(p) ((p) & pci_dvma_mask) -#else /* __sparc__ */ +#else +#if defined(__alpha__) +#define pcivtophys(p) ((p) & 0xfffffffful) +#else #define pcivtophys(p) (p) +#endif #ifndef NCR_IOMAPPED __initfunc( diff -u --recursive --new-file v2.1.120/linux/drivers/scsi/ppa.h linux/drivers/scsi/ppa.h --- v2.1.120/linux/drivers/scsi/ppa.h Fri Jul 31 17:08:24 1998 +++ linux/drivers/scsi/ppa.h Tue Sep 8 13:48:40 1998 @@ -53,12 +53,12 @@ * * Fixed all problems in the parport sharing scheme. Now ppa can be safe * used with lp or other parport devices on the same parallel port. - * 1997 by Andrea Arcangeli + * 1997 by Andrea Arcangeli * [1.39] * * Little fix in ppa engine to ensure that ppa don' t release parport * or disconnect in wrong cases. - * 1997 by Andrea Arcangeli + * 1997 by Andrea Arcangeli * [1.39a] */ /* ------ END OF USER CONFIGURABLE PARAMETERS ----- */ diff -u --recursive --new-file v2.1.120/linux/drivers/scsi/qlogicisp.c linux/drivers/scsi/qlogicisp.c --- v2.1.120/linux/drivers/scsi/qlogicisp.c Fri May 8 23:14:50 1998 +++ linux/drivers/scsi/qlogicisp.c Sun Sep 6 10:34:33 1998 @@ -1106,6 +1106,10 @@ DEBUG(printk("qlogicisp : loading risc ram\n")); #if RELOAD_FIRMWARE + /* Do not reload firmware if 1040B, i.e. revision 5 chip. */ + if (((struct isp1020_hostdata *) host->hostdata)->revision == 5) + printk("qlogicisp : 1040B chip, firmware not (re)loaded\n"); + else { int i; for (i = 0; i < risc_code_length01; i++) { @@ -1213,7 +1217,8 @@ if (inw(io_base + PCI_ID_LOW) != PCI_VENDOR_ID_QLOGIC || inw(io_base + PCI_ID_HIGH) != PCI_DEVICE_ID_QLOGIC_ISP1020) { - printk("qlogicisp : can't decode i/o address space\n"); + printk("qlogicisp : can't decode i/o address space 0x%lx\n", + io_base); return 1; } diff -u --recursive --new-file v2.1.120/linux/drivers/scsi/scsi_ioctl.c linux/drivers/scsi/scsi_ioctl.c --- v2.1.120/linux/drivers/scsi/scsi_ioctl.c Sun Jun 7 11:16:35 1998 +++ linux/drivers/scsi/scsi_ioctl.c Tue Sep 8 10:32:46 1998 @@ -226,7 +226,9 @@ if(buf_needed){ buf_needed = (buf_needed + 511) & ~511; if (buf_needed > MAX_BUF) buf_needed = MAX_BUF; + spin_lock_irqsave(&io_request_lock, flags); buf = (char *) scsi_malloc(buf_needed); + spin_unlock_irqrestore(&io_request_lock, flags); if (!buf) return -ENOMEM; memset(buf, 0, buf_needed); } else diff -u --recursive --new-file v2.1.120/linux/drivers/scsi/sr_ioctl.c linux/drivers/scsi/sr_ioctl.c --- v2.1.120/linux/drivers/scsi/sr_ioctl.c Tue Jun 23 10:01:24 1998 +++ linux/drivers/scsi/sr_ioctl.c Tue Sep 8 10:32:46 1998 @@ -55,8 +55,10 @@ int result, err = 0, retries = 0; unsigned long flags; + spin_lock_irqsave(&io_request_lock, flags); SDev = scsi_CDs[target].device; SCpnt = scsi_allocate_device(NULL, scsi_CDs[target].device, 1); + spin_unlock_irqrestore(&io_request_lock, flags); retry: if( !scsi_block_when_processing_errors(SDev) ) @@ -137,12 +139,14 @@ err = -EIO; } } - + + spin_lock_irqsave(&io_request_lock, flags); result = SCpnt->result; /* Wake up a process waiting for device*/ wake_up(&SCpnt->device->device_wait); scsi_release_command(SCpnt); SCpnt = NULL; + spin_unlock_irqrestore(&io_request_lock, flags); return err; } @@ -235,6 +239,7 @@ u_char sr_cmd[10]; char * buffer; int result; + unsigned long flags; sr_cmd[0] = SCMD_READ_SUBCHANNEL; sr_cmd[1] = ((scsi_CDs[MINOR(cdi->dev)].device->lun) << 5); @@ -245,8 +250,10 @@ sr_cmd[7] = 0; sr_cmd[8] = 24; sr_cmd[9] = 0; - + + spin_lock_irqsave(&io_request_lock, flags); buffer = (unsigned char*) scsi_malloc(512); + spin_unlock_irqrestore(&io_request_lock, flags); if(!buffer) return -ENOMEM; result = sr_do_ioctl(MINOR(cdi->dev), sr_cmd, buffer, 24, 0); @@ -254,7 +261,9 @@ memcpy (mcn->medium_catalog_number, buffer + 9, 13); mcn->medium_catalog_number[13] = 0; + spin_lock_irqsave(&io_request_lock, flags); scsi_free(buffer, 512); + spin_unlock_irqrestore(&io_request_lock, flags); return result; } @@ -384,6 +393,7 @@ { struct cdrom_tochdr* tochdr = (struct cdrom_tochdr*)arg; char * buffer; + unsigned long flags; sr_cmd[0] = SCMD_READ_TOC; sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5); @@ -393,7 +403,9 @@ sr_cmd[8] = 12; /* LSB of length */ sr_cmd[9] = 0; + spin_lock_irqsave(&io_request_lock, flags); buffer = (unsigned char *) scsi_malloc(512); + spin_unlock_irqrestore(&io_request_lock, flags); if(!buffer) return -ENOMEM; result = sr_do_ioctl(target, sr_cmd, buffer, 12, 0); @@ -401,7 +413,9 @@ tochdr->cdth_trk0 = buffer[2]; tochdr->cdth_trk1 = buffer[3]; + spin_lock_irqsave(&io_request_lock, flags); scsi_free(buffer, 512); + spin_unlock_irqrestore(&io_request_lock, flags); break; } @@ -409,6 +423,7 @@ { struct cdrom_tocentry* tocentry = (struct cdrom_tocentry*)arg; unsigned char * buffer; + unsigned long flags; sr_cmd[0] = SCMD_READ_TOC; sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | @@ -419,7 +434,9 @@ sr_cmd[8] = 12; /* LSB of length */ sr_cmd[9] = 0; + spin_lock_irqsave(&io_request_lock, flags); buffer = (unsigned char *) scsi_malloc(512); + spin_unlock_irqrestore(&io_request_lock, flags); if(!buffer) return -ENOMEM; result = sr_do_ioctl (target, sr_cmd, buffer, 12, 0); @@ -435,7 +452,9 @@ tocentry->cdte_addr.lba = (((((buffer[8] << 8) + buffer[9]) << 8) + buffer[10]) << 8) + buffer[11]; + spin_lock_irqsave(&io_request_lock, flags); scsi_free(buffer, 512); + spin_unlock_irqrestore(&io_request_lock, flags); break; } @@ -461,6 +480,7 @@ { char * buffer, * mask; struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg; + unsigned long flags; /* First we get the current params so we can just twiddle the volume */ @@ -471,12 +491,16 @@ sr_cmd[4] = 28; sr_cmd[5] = 0; + spin_lock_irqsave(&io_request_lock, flags); buffer = (unsigned char *) scsi_malloc(512); + spin_unlock_irqrestore(&io_request_lock, flags); if(!buffer) return -ENOMEM; if ((result = sr_do_ioctl (target, sr_cmd, buffer, 28, 0))) { printk ("Hosed while obtaining audio mode page\n"); + spin_lock_irqsave(&io_request_lock, flags); scsi_free(buffer, 512); + spin_unlock_irqrestore(&io_request_lock, flags); break; } @@ -487,17 +511,23 @@ sr_cmd[4] = 28; sr_cmd[5] = 0; + spin_lock_irqsave(&io_request_lock, flags); mask = (unsigned char *) scsi_malloc(512); + spin_unlock_irqrestore(&io_request_lock, flags); if(!mask) { + spin_lock_irqsave(&io_request_lock, flags); scsi_free(buffer, 512); + spin_unlock_irqrestore(&io_request_lock, flags); result = -ENOMEM; break; }; if ((result = sr_do_ioctl (target, sr_cmd, mask, 28, 0))) { printk ("Hosed while obtaining mask for audio mode page\n"); + spin_lock_irqsave(&io_request_lock, flags); scsi_free(buffer, 512); scsi_free(mask, 512); + spin_unlock_irqrestore(&io_request_lock, flags); break; } @@ -516,8 +546,10 @@ sr_cmd[5] = 0; result = sr_do_ioctl (target, sr_cmd, buffer, 28, 0); + spin_lock_irqsave(&io_request_lock, flags); scsi_free(buffer, 512); scsi_free(mask, 512); + spin_unlock_irqrestore(&io_request_lock, flags); break; } @@ -525,6 +557,7 @@ { char * buffer; struct cdrom_volctrl* volctrl = (struct cdrom_volctrl*)arg; + unsigned long flags; /* Get the current params */ @@ -535,12 +568,16 @@ sr_cmd[4] = 28; sr_cmd[5] = 0; + spin_lock_irqsave(&io_request_lock, flags); buffer = (unsigned char *) scsi_malloc(512); + spin_unlock_irqrestore(&io_request_lock, flags); if(!buffer) return -ENOMEM; if ((result = sr_do_ioctl (target, sr_cmd, buffer, 28, 0))) { printk ("(CDROMVOLREAD) Hosed while obtaining audio mode page\n"); + spin_lock_irqsave(&io_request_lock, flags); scsi_free(buffer, 512); + spin_unlock_irqrestore(&io_request_lock, flags); break; } @@ -549,7 +586,9 @@ volctrl->channel2 = buffer[25]; volctrl->channel3 = buffer[27]; + spin_lock_irqsave(&io_request_lock, flags); scsi_free(buffer, 512); + spin_unlock_irqrestore(&io_request_lock, flags); break; } @@ -557,6 +596,7 @@ { struct cdrom_subchnl* subchnl = (struct cdrom_subchnl*)arg; char * buffer; + unsigned long flags; sr_cmd[0] = SCMD_READ_SUBCHANNEL; sr_cmd[1] = ((scsi_CDs[target].device->lun) << 5) | 0x02; /* MSF format */ @@ -568,7 +608,9 @@ sr_cmd[8] = 16; sr_cmd[9] = 0; - buffer = (unsigned char*) scsi_malloc(512); + spin_lock_irqsave(&io_request_lock, flags); + buffer = (unsigned char *) scsi_malloc(512); + spin_unlock_irqrestore(&io_request_lock, flags); if(!buffer) return -ENOMEM; result = sr_do_ioctl(target, sr_cmd, buffer, 16, 0); @@ -586,7 +628,9 @@ subchnl->cdsc_absaddr.msf.second = buffer[10]; subchnl->cdsc_absaddr.msf.frame = buffer[11]; + spin_lock_irqsave(&io_request_lock, flags); scsi_free(buffer, 512); + spin_unlock_irqrestore(&io_request_lock, flags); break; } default: @@ -694,11 +738,14 @@ { unsigned char *raw_sector; int is_xa; + unsigned long flags; if (!xa_test) return 0; - + + spin_lock_irqsave(&io_request_lock, flags); raw_sector = (unsigned char *) scsi_malloc(2048+512); + spin_unlock_irqrestore(&io_request_lock, flags); if (!raw_sector) return -ENOMEM; if (0 == sr_read_sector(minor,scsi_CDs[minor].ms_offset+16, CD_FRAMESIZE_RAW1,raw_sector)) { @@ -707,7 +754,9 @@ /* read a raw sector failed for some reason. */ is_xa = -1; } + spin_lock_irqsave(&io_request_lock, flags); scsi_free(raw_sector, 2048+512); + spin_unlock_irqrestore(&io_request_lock, flags); #ifdef DEBUG printk("sr%d: sr_is_xa: %d\n",minor,is_xa); #endif @@ -730,6 +779,7 @@ struct cdrom_msf msf; int lba, rc; int blocksize = 2048; + unsigned long flags; switch (cmd) { case CDROMREADMODE2: blocksize = CD_FRAMESIZE_RAW0; break; /* 2336 */ @@ -738,7 +788,10 @@ if (copy_from_user(&msf,(void*)arg,sizeof(msf))) return -EFAULT; - if (!(raw = scsi_malloc(2048+512))) + spin_lock_irqsave(&io_request_lock, flags); + raw = scsi_malloc(2048+512); + spin_unlock_irqrestore(&io_request_lock, flags); + if (!(raw)) return -ENOMEM; lba = (((msf.cdmsf_min0 * CD_SECS) + msf.cdmsf_sec0) @@ -751,7 +804,9 @@ if (copy_to_user((void*)arg, raw, blocksize)) rc = -EFAULT; + spin_lock_irqsave(&io_request_lock, flags); scsi_free(raw,2048+512); + spin_unlock_irqrestore(&io_request_lock, flags); return rc; } case CDROMREADAUDIO: @@ -759,6 +814,7 @@ unsigned char *raw; int lba, rc=0; struct cdrom_read_audio ra; + unsigned long flags; if (!scsi_CDs[target].readcd_known || !scsi_CDs[target].readcd_cdda) return -EINVAL; /* -EDRIVE_DOES_NOT_SUPPORT_THIS ? */ @@ -774,7 +830,10 @@ if (lba < 0 || lba >= scsi_CDs[target].capacity) return -EINVAL; - if (!(raw = scsi_malloc(2048+512))) + spin_lock_irqsave(&io_request_lock, flags); + raw = scsi_malloc(2048+512); + spin_unlock_irqrestore(&io_request_lock, flags); + if (!(raw)) return -ENOMEM; while (ra.nframes > 0) { @@ -789,7 +848,9 @@ ra.nframes -= 1; lba++; } + spin_lock_irqsave(&io_request_lock, flags); scsi_free(raw,2048+512); + spin_unlock_irqrestore(&io_request_lock, flags); return rc; } case BLKRAGET: diff -u --recursive --new-file v2.1.120/linux/drivers/scsi/st.c linux/drivers/scsi/st.c --- v2.1.120/linux/drivers/scsi/st.c Wed Aug 26 11:37:38 1998 +++ linux/drivers/scsi/st.c Sun Sep 6 09:48:30 1998 @@ -8,10 +8,10 @@ order) Klaus Ehrenfried, Wolfgang Denk, Steve Hirsch, Andreas Koppenh"ofer, Michael Leodolter, Eyal Lebedinsky, J"org Weule, and Eric Youngdale. - Copyright 1992 - 1997 Kai Makisara + Copyright 1992 - 1998 Kai Makisara email Kai.Makisara@metla.fi - Last modified: Wed Nov 5 23:39:52 1997 by makisara@home + Last modified: Sun Sep 6 09:34:49 1998 by root@home Some small formal changes - aeb, 950809 */ @@ -47,24 +47,27 @@ #include "scsi.h" #include "hosts.h" #include + +#define ST_KILOBYTE 1024 + +#include "st_options.h" #include "st.h" + #include "constants.h" #ifdef MODULE MODULE_PARM(buffer_kbs, "i"); MODULE_PARM(write_threshold_kbs, "i"); MODULE_PARM(max_buffers, "i"); +MODULE_PARM(max_sg_segs, "i"); static int buffer_kbs = 0; static int write_threshold_kbs = 0; static int max_buffers = 0; +static int max_sg_segs = 0; #endif /* The default definitions have been moved to st_options.h */ -#define ST_KILOBYTE 1024 - -#include "st_options.h" - #define ST_BUFFER_SIZE (ST_BUFFER_BLOCKS * ST_KILOBYTE) #define ST_WRITE_THRESHOLD (ST_WRITE_THRESHOLD_BLOCKS * ST_KILOBYTE) @@ -98,6 +101,7 @@ static int st_buffer_size = ST_BUFFER_SIZE; static int st_write_threshold = ST_WRITE_THRESHOLD; static int st_max_buffers = ST_MAX_BUFFERS; +static int st_max_sg_segs = ST_MAX_SG; static Scsi_Tape * scsi_tapes = NULL; @@ -106,6 +110,8 @@ static ST_buffer *new_tape_buffer(int, int); static int enlarge_buffer(ST_buffer *, int, int); static void normalize_buffer(ST_buffer *); +static int append_to_buffer(const char *, ST_buffer *, int); +static int from_buffer(ST_buffer *, char *, int); static int st_init(void); static int st_attach(Scsi_Device *); @@ -142,7 +148,12 @@ if (!result /* && SCpnt->sense_buffer[0] == 0 */ ) return 0; - scode = sense[2] & 0x0f; + if (driver_byte(result) & DRIVER_SENSE) + scode = sense[2] & 0x0f; + else { + sense[0] = 0; /* We don't have sense data if this byte is zero */ + scode = 0; + } #if DEBUG if (debugging) { @@ -172,7 +183,10 @@ print_sense("st", SCpnt); } else - printk(KERN_WARNING "st%d: Error %x.\n", dev, result); + printk(KERN_WARNING + "st%d: Error %x (sugg. bt 0x%x, driver bt 0x%x, host bt 0x%x).\n", + dev, result, suggestion(result), driver_byte(result), + host_byte(result)); } if ((sense[0] & 0x70) == 0x70 && @@ -246,39 +260,54 @@ } -/* Do the scsi command */ +/* Do the scsi command. Waits until command performed if do_wait is true. + Otherwise write_behind_check() is used to check that the command + has finished. */ static Scsi_Cmnd * st_do_scsi(Scsi_Cmnd *SCpnt, Scsi_Tape *STp, unsigned char *cmd, int bytes, - int timeout, int retries) + int timeout, int retries, int do_wait) { unsigned long flags; + unsigned char *bp; spin_lock_irqsave(&io_request_lock, flags); if (SCpnt == NULL) if ((SCpnt = scsi_allocate_device(NULL, STp->device, 1)) == NULL) { printk(KERN_ERR "st%d: Can't get SCSI request.\n", TAPE_NR(STp->devt)); + spin_unlock_irqrestore(&io_request_lock, flags); return NULL; } cmd[1] |= (SCpnt->lun << 5) & 0xe0; STp->sem = MUTEX_LOCKED; + SCpnt->use_sg = (bytes > (STp->buffer)->sg[0].length) ? + (STp->buffer)->use_sg : 0; + if (SCpnt->use_sg) { + bp = (char *)&((STp->buffer)->sg[0]); + if ((STp->buffer)->sg_segs < SCpnt->use_sg) + SCpnt->use_sg = (STp->buffer)->sg_segs; + } + else + bp = (STp->buffer)->b_data; SCpnt->request.sem = &(STp->sem); SCpnt->request.rq_status = RQ_SCSI_BUSY; SCpnt->request.rq_dev = STp->devt; - scsi_do_cmd(SCpnt, (void *)cmd, (STp->buffer)->b_data, bytes, + scsi_do_cmd(SCpnt, (void *)cmd, bp, bytes, st_sleep_done, timeout, retries); spin_unlock_irqrestore(&io_request_lock, flags); - down(SCpnt->request.sem); + if (do_wait) { + down(SCpnt->request.sem); - (STp->buffer)->last_result_fatal = st_chk_result(SCpnt); + (STp->buffer)->last_result_fatal = st_chk_result(SCpnt); + } return SCpnt; } -/* Handle the write-behind checking */ +/* Handle the write-behind checking (downs the semaphore) */ static void write_behind_check(Scsi_Tape *STp) { @@ -300,9 +329,13 @@ scsi_release_command((STp->buffer)->last_SCpnt); if (STbuffer->writing < STbuffer->buffer_bytes) +#if 0 memcpy(STbuffer->b_data, STbuffer->b_data + STbuffer->writing, STbuffer->buffer_bytes - STbuffer->writing); +#else + printk(KERN_WARNING "st: write_behind_check: something left in buffer!\n"); +#endif STbuffer->buffer_bytes -= STbuffer->writing; STps = &(STp->ps[STp->partition]); if (STps->drv_block >= 0) { @@ -340,7 +373,7 @@ TAPE_NR(STp->devt), forward ? "forward" : "backward"); #endif - SCpnt = st_do_scsi(NULL, STp, cmd, 0, STp->timeout, MAX_RETRIES); + SCpnt = st_do_scsi(NULL, STp, cmd, 0, STp->timeout, MAX_RETRIES, TRUE); if (!SCpnt) return (-EBUSY); @@ -402,7 +435,8 @@ cmd[3] = blks >> 8; cmd[4] = blks; - SCpnt = st_do_scsi(NULL, STp, cmd, transfer, STp->timeout, MAX_WRITE_RETRIES); + SCpnt = st_do_scsi(NULL, STp, cmd, transfer, STp->timeout, MAX_WRITE_RETRIES, + TRUE); if (!SCpnt) return (-EBUSY); @@ -551,10 +585,9 @@ if (dev >= st_template.dev_max || !scsi_tapes[dev].device) return (-ENXIO); - if( !scsi_block_when_processing_errors(scsi_tapes[dev].device) ) - { + if( !scsi_block_when_processing_errors(scsi_tapes[dev].device) ) { return -ENXIO; - } + } STp = &(scsi_tapes[dev]); if (STp->in_use) { @@ -576,7 +609,7 @@ } STm = &(STp->modes[STp->current_mode]); - /* Allocate buffer for this user */ + /* Allocate a buffer for this user */ need_dma_buffer = STp->restr_dma; for (i=0; i < st_nbr_buffers; i++) if (!st_buffers[i]->in_use && @@ -594,6 +627,16 @@ (STp->buffer)->in_use = 1; (STp->buffer)->writing = 0; (STp->buffer)->last_result_fatal = 0; + (STp->buffer)->use_sg = STp->device->host->sg_tablesize; + + /* Compute the usable buffer size for this SCSI adapter */ + if (!(STp->buffer)->use_sg) + (STp->buffer)->buffer_size = (STp->buffer)->sg[0].length; + else { + for (i=0, (STp->buffer)->buffer_size = 0; i < (STp->buffer)->use_sg && + i < (STp->buffer)->sg_segs; i++) + (STp->buffer)->buffer_size += (STp->buffer)->sg[i].length; + } flags = filp->f_flags; STp->write_prot = ((flags & O_ACCMODE) == O_RDONLY); @@ -617,7 +660,8 @@ memset ((void *) &cmd[0], 0, 10); cmd[0] = TEST_UNIT_READY; - SCpnt = st_do_scsi(NULL, STp, cmd, 0, STp->long_timeout, MAX_READY_RETRIES); + SCpnt = st_do_scsi(NULL, STp, cmd, 0, STp->long_timeout, MAX_READY_RETRIES, + TRUE); if (!SCpnt) { if (scsi_tapes[dev].device->host->hostt->module) __MOD_DEC_USE_COUNT(scsi_tapes[dev].device->host->hostt->module); @@ -631,7 +675,8 @@ memset ((void *) &cmd[0], 0, 10); cmd[0] = TEST_UNIT_READY; - SCpnt = st_do_scsi(SCpnt, STp, cmd, 0, STp->long_timeout, MAX_READY_RETRIES); + SCpnt = st_do_scsi(SCpnt, STp, cmd, 0, STp->long_timeout, MAX_READY_RETRIES, + TRUE); (STp->device)->was_reset = 0; STp->partition = STp->new_partition = 0; @@ -675,7 +720,7 @@ memset ((void *) &cmd[0], 0, 10); cmd[0] = READ_BLOCK_LIMITS; - SCpnt = st_do_scsi(SCpnt, STp, cmd, 6, STp->timeout, MAX_READY_RETRIES); + SCpnt = st_do_scsi(SCpnt, STp, cmd, 6, STp->timeout, MAX_READY_RETRIES, TRUE); if (!SCpnt->result && !SCpnt->sense_buffer[0]) { STp->max_block = ((STp->buffer)->b_data[1] << 16) | @@ -701,7 +746,7 @@ cmd[0] = MODE_SENSE; cmd[4] = 12; - SCpnt = st_do_scsi(SCpnt, STp, cmd, 12, STp->timeout, MAX_READY_RETRIES); + SCpnt = st_do_scsi(SCpnt, STp, cmd, 12, STp->timeout, MAX_READY_RETRIES, TRUE); if ((STp->buffer)->last_result_fatal != 0) { #if DEBUG @@ -754,7 +799,7 @@ SCpnt = NULL; if (STp->block_size > 0) - (STp->buffer)->buffer_blocks = st_buffer_size / STp->block_size; + (STp->buffer)->buffer_blocks = (STp->buffer)->buffer_size / STp->block_size; else (STp->buffer)->buffer_blocks = 1; (STp->buffer)->buffer_bytes = (STp->buffer)->read_pointer = 0; @@ -830,9 +875,9 @@ } -/* Close the device*/ +/* Flush the tape buffer before close */ static int -scsi_tape_close(struct inode * inode, struct file * filp) +scsi_tape_flush(struct file * filp) { int result = 0, result2; static unsigned char cmd[10]; @@ -841,6 +886,7 @@ ST_mode * STm; ST_partstat * STps; + struct inode *inode = filp->f_dentry->d_inode; kdev_t devt = inode->i_rdev; int dev; @@ -877,7 +923,8 @@ cmd[0] = WRITE_FILEMARKS; cmd[4] = 1 + STp->two_fm; - SCpnt = st_do_scsi(NULL, STp, cmd, 0, STp->timeout, MAX_WRITE_RETRIES); + SCpnt = st_do_scsi(NULL, STp, cmd, 0, STp->timeout, MAX_WRITE_RETRIES, + TRUE); if (!SCpnt) goto out; @@ -947,6 +994,23 @@ result = result2; } + return result; +} + + +/* Close the device and release it */ + static int +scsi_tape_close(struct inode * inode, struct file * filp) +{ + int result = 0; + Scsi_Tape * STp; + + kdev_t devt = inode->i_rdev; + int dev; + + dev = TAPE_NR(devt); + STp = &(scsi_tapes[dev]); + if (STp->door_locked == ST_LOCKED_AUTO) st_int_ioctl(inode, MTUNLOCK, 0); @@ -981,7 +1045,6 @@ ST_mode * STm; ST_partstat * STps; int dev = TAPE_NR(inode->i_rdev); - unsigned long flags; STp = &(scsi_tapes[dev]); @@ -991,10 +1054,9 @@ * may try and take the device offline, in which case all further * access to the device is prohibited. */ - if( !scsi_block_when_processing_errors(STp->device) ) - { + if( !scsi_block_when_processing_errors(STp->device) ) { return -ENXIO; - } + } if (ppos != &filp->f_pos) { /* "A request was outside the capabilities of the device." */ @@ -1027,6 +1089,10 @@ } #endif + /* Write must be integral number of blocks */ + if (STp->block_size != 0 && (count % STp->block_size) != 0) + return (-EIO); + if (STp->can_partitions && (retval = update_partition(inode)) < 0) return retval; @@ -1092,8 +1158,10 @@ return (-EFAULT); if (!STm->do_buffer_writes) { +#if 0 if (STp->block_size != 0 && (count % STp->block_size) != 0) return (-EIO); /* Write must be integral number of blocks */ +#endif write_threshold = 1; } else @@ -1110,9 +1178,9 @@ STps->rw = ST_WRITING; b_point = buf; - while((STp->block_size == 0 && !STm->do_async_writes && count > 0) || - (STp->block_size != 0 && - (STp->buffer)->buffer_bytes + count > write_threshold)) + while ((STp->block_size == 0 && !STm->do_async_writes && count > 0) || + (STp->block_size != 0 && + (STp->buffer)->buffer_bytes + count > write_threshold)) { doing_write = 1; if (STp->block_size == 0) @@ -1124,21 +1192,19 @@ do_count = count; } - i = copy_from_user((STp->buffer)->b_data + - (STp->buffer)->buffer_bytes, b_point, do_count); + i = append_to_buffer(b_point, STp->buffer, do_count); if (i) { - if (SCpnt != NULL) - { + if (SCpnt != NULL) { scsi_release_command(SCpnt); SCpnt = NULL; - } - return (-EFAULT); + } + return i; } if (STp->block_size == 0) blks = transfer = do_count; else { - blks = ((STp->buffer)->buffer_bytes + do_count) / + blks = (STp->buffer)->buffer_bytes / STp->block_size; transfer = blks * STp->block_size; } @@ -1146,7 +1212,8 @@ cmd[3] = blks >> 8; cmd[4] = blks; - SCpnt = st_do_scsi(SCpnt, STp, cmd, transfer, STp->timeout, MAX_WRITE_RETRIES); + SCpnt = st_do_scsi(SCpnt, STp, cmd, transfer, STp->timeout, + MAX_WRITE_RETRIES, TRUE); if (!SCpnt) return (-EBUSY); @@ -1223,18 +1290,15 @@ } if (count != 0) { STp->dirty = 1; - i = copy_from_user((STp->buffer)->b_data + - (STp->buffer)->buffer_bytes, b_point, count); + i = append_to_buffer(b_point, STp->buffer, count); if (i) { - if (SCpnt != NULL) - { + if (SCpnt != NULL) { scsi_release_command(SCpnt); SCpnt = NULL; - } - return (-EFAULT); + } + return i; } filp->f_pos += count; - (STp->buffer)->buffer_bytes += count; count = 0; } @@ -1249,11 +1313,6 @@ (STp->buffer)->buffer_bytes >= STp->block_size) || STp->block_size == 0) ) { /* Schedule an asynchronous write */ - if (!SCpnt) { - SCpnt = scsi_allocate_device(NULL, STp->device, 1); - if (!SCpnt) - return (-EBUSY); - } if (STp->block_size == 0) (STp->buffer)->writing = (STp->buffer)->buffer_bytes; else @@ -1269,26 +1328,19 @@ cmd[2] = blks >> 16; cmd[3] = blks >> 8; cmd[4] = blks; - STp->sem = MUTEX_LOCKED; - SCpnt->request.sem = &(STp->sem); - SCpnt->request.rq_status = RQ_SCSI_BUSY; - SCpnt->request.rq_dev = STp->devt; #if DEBUG STp->write_pending = 1; #endif - spin_lock_irqsave(&io_request_lock, flags); - scsi_do_cmd (SCpnt, - (void *) cmd, (STp->buffer)->b_data, - (STp->buffer)->writing, - st_sleep_done, STp->timeout, MAX_WRITE_RETRIES); - spin_unlock_irqrestore(&io_request_lock, flags); + SCpnt = st_do_scsi(SCpnt, STp, cmd, (STp->buffer)->writing, STp->timeout, + MAX_WRITE_RETRIES, FALSE); + if (SCpnt == NULL) + return (-EIO); } - else if (SCpnt != NULL) - { + else if (SCpnt != NULL) { scsi_release_command(SCpnt); SCpnt = NULL; - } + } STps->at_sm &= (total == 0); if (total > 0) STps->eof = ST_NOEOF; @@ -1343,7 +1395,7 @@ cmd[4] = blks; SCpnt = *aSCpnt; - SCpnt = st_do_scsi(SCpnt, STp, cmd, bytes, STp->timeout, MAX_RETRIES); + SCpnt = st_do_scsi(SCpnt, STp, cmd, bytes, STp->timeout, MAX_RETRIES, TRUE); *aSCpnt = SCpnt; if (!SCpnt) return (-EBUSY); @@ -1351,7 +1403,6 @@ (STp->buffer)->read_pointer = 0; STps->at_sm = 0; - /* Something to check */ if ((STp->buffer)->last_result_fatal) { retval = 1; @@ -1507,10 +1558,9 @@ * may try and take the device offline, in which case all further * access to the device is prohibited. */ - if( !scsi_block_when_processing_errors(STp->device) ) - { + if( !scsi_block_when_processing_errors(STp->device) ) { return -ENXIO; - } + } if (ppos != &filp->f_pos) { /* "A request was outside the capabilities of the device." */ @@ -1590,10 +1640,9 @@ if ((STp->buffer)->buffer_bytes == 0) { special = read_tape(inode, count - total, &SCpnt); if (special < 0) { /* No need to continue read */ - if (SCpnt != NULL) - { + if (SCpnt != NULL) { scsi_release_command(SCpnt); - } + } return special; } } @@ -1607,21 +1656,17 @@ #endif transfer = (STp->buffer)->buffer_bytes < count - total ? (STp->buffer)->buffer_bytes : count - total; - i = copy_to_user(buf, (STp->buffer)->b_data + - (STp->buffer)->read_pointer, transfer); + i = from_buffer(STp->buffer, buf, transfer); if (i) { - if (SCpnt != NULL) - { + if (SCpnt != NULL) { scsi_release_command(SCpnt); SCpnt = NULL; - } - return (-EFAULT); + } + return i; } filp->f_pos += transfer; buf += transfer; total += transfer; - (STp->buffer)->buffer_bytes -= transfer; - (STp->buffer)->read_pointer += transfer; } if (STp->block_size == 0) @@ -1629,11 +1674,10 @@ } /* for (total = 0, special = 0; total < count && !special; ) */ - if (SCpnt != NULL) - { + if (SCpnt != NULL) { scsi_release_command(SCpnt); SCpnt = NULL; - } + } /* Change the eof state if no data from tape or buffer */ if (total == 0) { @@ -1867,7 +1911,7 @@ cmd[2] = COMPRESSION_PAGE; cmd[4] = COMPRESSION_PAGE_LENGTH + MODE_HEADER_LENGTH; - SCpnt = st_do_scsi(SCpnt, STp, cmd, cmd[4], STp->timeout, 0); + SCpnt = st_do_scsi(SCpnt, STp, cmd, cmd[4], STp->timeout, 0, TRUE); if (SCpnt == NULL) return (-EBUSY); dev = TAPE_NR(SCpnt->request.rq_dev); @@ -1912,7 +1956,7 @@ (STp->buffer)->b_data[0] = 0; /* Reserved data length */ (STp->buffer)->b_data[1] = 0; /* Reserved media type byte */ (STp->buffer)->b_data[MODE_HEADER_LENGTH] &= 0x3f; - SCpnt = st_do_scsi(SCpnt, STp, cmd, cmd[4], STp->timeout, 0); + SCpnt = st_do_scsi(SCpnt, STp, cmd, cmd[4], STp->timeout, 0, TRUE); if ((STp->buffer)->last_result_fatal != 0) { #if DEBUG @@ -2298,7 +2342,7 @@ return (-ENOSYS); } - SCpnt = st_do_scsi(NULL, STp, cmd, datalen, timeout, MAX_RETRIES); + SCpnt = st_do_scsi(NULL, STp, cmd, datalen, timeout, MAX_RETRIES, TRUE); if (!SCpnt) return (-EBUSY); @@ -2472,7 +2516,7 @@ if (!logical && !STp->scsi2_logical) scmd[1] = 1; } - SCpnt = st_do_scsi(NULL, STp, scmd, 20, STp->timeout, MAX_READY_RETRIES); + SCpnt = st_do_scsi(NULL, STp, scmd, 20, STp->timeout, MAX_READY_RETRIES, TRUE); if (!SCpnt) return (-EBUSY); @@ -2596,7 +2640,7 @@ timeout = STp->timeout; #endif - SCpnt = st_do_scsi(NULL, STp, scmd, 20, timeout, MAX_READY_RETRIES); + SCpnt = st_do_scsi(NULL, STp, scmd, 20, timeout, MAX_READY_RETRIES, TRUE); if (!SCpnt) return (-EBUSY); @@ -2692,7 +2736,7 @@ cmd[2] = PART_PAGE; cmd[4] = 200; - SCpnt = st_do_scsi(SCpnt, STp, cmd, 200, STp->timeout, MAX_READY_RETRIES); + SCpnt = st_do_scsi(SCpnt, STp, cmd, 200, STp->timeout, MAX_READY_RETRIES, TRUE); if (SCpnt == NULL) return (-EBUSY); scsi_release_command(SCpnt); @@ -2767,7 +2811,8 @@ cmd[1] = 0x10; cmd[4] = length + MODE_HEADER_LENGTH; - SCpnt = st_do_scsi(SCpnt, STp, cmd, cmd[4], STp->long_timeout, MAX_READY_RETRIES); + SCpnt = st_do_scsi(SCpnt, STp, cmd, cmd[4], STp->long_timeout, + MAX_READY_RETRIES, TRUE); if (SCpnt == NULL) return (-EBUSY); scsi_release_command(SCpnt); @@ -2815,10 +2860,9 @@ * may try and take the device offline, in which case all further * access to the device is prohibited. */ - if( !scsi_block_when_processing_errors(STp->device) ) - { + if( !scsi_block_when_processing_errors(STp->device) ) { return -ENXIO; - } + } cmd_type = _IOC_TYPE(cmd_in); cmd_nr = _IOC_NR(cmd_in); @@ -3034,29 +3078,69 @@ static ST_buffer * new_tape_buffer( int from_initialization, int need_dma ) { - int priority, a_size; + int i, priority, b_size, got = 0, segs = 0; ST_buffer *tb; if (st_nbr_buffers >= st_template.dev_max) return NULL; /* Should never happen */ - if (from_initialization) { + if (from_initialization) priority = GFP_ATOMIC; - a_size = st_buffer_size; - } - else { + else priority = GFP_KERNEL; - for (a_size = PAGE_SIZE; a_size < st_buffer_size; a_size <<= 1) - ; /* Make sure we allocate efficiently */ - } - tb = (ST_buffer *)scsi_init_malloc(sizeof(ST_buffer), priority); + + i = sizeof(ST_buffer) + (st_max_sg_segs - 1) * sizeof(struct scatterlist); + tb = (ST_buffer *)scsi_init_malloc(i, priority); if (tb) { + tb->this_size = i; if (need_dma) priority |= GFP_DMA; - tb->b_data = (unsigned char *)scsi_init_malloc(a_size, priority); - if (!tb->b_data) { - scsi_init_free((char *)tb, sizeof(ST_buffer)); - tb = NULL; + + /* Try to allocate the first segment up to ST_FIRST_ORDER and the + others big enough to reach the goal */ + for (b_size = PAGE_SIZE << ST_FIRST_ORDER; + b_size / 2 >= st_buffer_size && b_size > PAGE_SIZE; ) + b_size /= 2; + for ( ; b_size >= PAGE_SIZE; b_size /= 2) { + tb->sg[0].address = + (unsigned char *)scsi_init_malloc(b_size, priority); + if (tb->sg[0].address != NULL) { + tb->sg[0].alt_address = NULL; + tb->sg[0].length = b_size; + break; + } + } + if (tb->sg[segs].address == NULL) { + scsi_init_free((char *)tb, tb->this_size); + tb = NULL; + } + else { /* Got something, continue */ + + for (b_size = PAGE_SIZE; + st_buffer_size > tb->sg[0].length + (ST_FIRST_SG - 1) * b_size; ) + b_size *= 2; + + for (segs=1, got=tb->sg[0].length; + got < st_buffer_size && segs < ST_FIRST_SG; ) { + tb->sg[segs].address = + (unsigned char *)scsi_init_malloc(b_size, priority); + if (tb->sg[segs].address == NULL) { + if (st_buffer_size - got <= + (ST_FIRST_SG - segs) * b_size / 2) { + b_size /= 2; /* Large enough for the rest of the buffers */ + continue; + } + for (i=0; i < segs - 1; i++) + scsi_init_free(tb->sg[i].address, tb->sg[i].length); + scsi_init_free((char *)tb, tb->this_size); + tb = NULL; + break; + } + tb->sg[segs].alt_address = NULL; + tb->sg[segs].length = b_size; + got += b_size; + segs++; + } } } if (!tb) { @@ -3064,18 +3148,25 @@ st_nbr_buffers); return NULL; } + tb->sg_segs = tb->orig_sg_segs = segs; + tb->b_data = tb->sg[0].address; + #if DEBUG - if (debugging) + if (debugging) { + printk(ST_DEB_MSG + "st: Allocated tape buffer %d (%d bytes, %d segments, dma: %d, a: %p).\n", + st_nbr_buffers, got, tb->sg_segs, need_dma, tb->b_data); printk(ST_DEB_MSG - "st: Allocated tape buffer %d (%d bytes, dma: %d, a: %p).\n", - st_nbr_buffers, a_size, need_dma, tb->b_data); + "st: segment sizes: first %d, last %d bytes.\n", + tb->sg[0].length, tb->sg[segs-1].length); + } #endif tb->in_use = 0; tb->dma = need_dma; - tb->buffer_size = a_size; + tb->buffer_size = got; tb->writing = 0; - tb->orig_b_data = NULL; st_buffers[st_nbr_buffers++] = tb; + return tb; } @@ -3084,31 +3175,51 @@ static int enlarge_buffer(ST_buffer *STbuffer, int new_size, int need_dma) { - int a_size, priority; - unsigned char *tbd; + int segs, nbr, max_segs, b_size, priority, got; normalize_buffer(STbuffer); - for (a_size = PAGE_SIZE; a_size < new_size; a_size <<= 1) - ; /* Make sure that we allocate efficiently */ + max_segs = STbuffer->use_sg; + if (max_segs > st_max_sg_segs) + max_segs = st_max_sg_segs; + nbr = max_segs - STbuffer->sg_segs; + if (nbr <= 0) + return FALSE; priority = GFP_KERNEL; if (need_dma) priority |= GFP_DMA; - tbd = (unsigned char *)scsi_init_malloc(a_size, priority); - if (!tbd) - return FALSE; + for (b_size = PAGE_SIZE; b_size * nbr < new_size - STbuffer->buffer_size; ) + b_size *= 2; + + for (segs=STbuffer->sg_segs, got=STbuffer->buffer_size; + segs < max_segs && got < new_size; ) { + STbuffer->sg[segs].address = + (unsigned char *)scsi_init_malloc(b_size, priority); + if (STbuffer->sg[segs].address == NULL) { + if (new_size - got <= (max_segs - segs) * b_size / 2) { + b_size /= 2; /* Large enough for the rest of the buffers */ + continue; + } + printk(KERN_NOTICE "st: failed to enlarge buffer to %d bytes.\n", + new_size); + normalize_buffer(STbuffer); + return FALSE; + } + STbuffer->sg[segs].alt_address = NULL; + STbuffer->sg[segs].length = b_size; + STbuffer->sg_segs += 1; + got += b_size; + STbuffer->buffer_size = got; + segs++; + } #if DEBUG if (debugging) - printk(ST_DEB_MSG - "st: Buffer at %p enlarged to %d bytes (dma: %d, a: %p).\n", - STbuffer->b_data, a_size, need_dma, tbd); + printk(ST_DEB_MSG + "st: Succeeded to enlarge buffer to %d bytes (segs %d->%d, %d).\n", + got, STbuffer->orig_sg_segs, STbuffer->sg_segs, b_size); #endif - STbuffer->orig_b_data = STbuffer->b_data; - STbuffer->orig_size = STbuffer->buffer_size; - STbuffer->b_data = tbd; - STbuffer->buffer_size = a_size; return TRUE; } @@ -3117,19 +3228,87 @@ static void normalize_buffer(ST_buffer *STbuffer) { - if (STbuffer->orig_b_data == NULL) - return; - - scsi_init_free(STbuffer->b_data, STbuffer->buffer_size); - STbuffer->b_data = STbuffer->orig_b_data; - STbuffer->orig_b_data = NULL; - STbuffer->buffer_size = STbuffer->orig_size; + int i; + for (i=STbuffer->orig_sg_segs; i < STbuffer->sg_segs; i++) { + scsi_init_free(STbuffer->sg[i].address, STbuffer->sg[i].length); + STbuffer->buffer_size -= STbuffer->sg[i].length; + } #if DEBUG - if (debugging) - printk(ST_DEB_MSG "st: Buffer at %p normalized to %d bytes.\n", - STbuffer->b_data, STbuffer->buffer_size); + if (debugging && STbuffer->orig_sg_segs < STbuffer->sg_segs) + printk(ST_DEB_MSG "st: Buffer at %p normalized to %d bytes (segs %d).\n", + STbuffer->b_data, STbuffer->buffer_size, STbuffer->sg_segs); #endif + STbuffer->sg_segs = STbuffer->orig_sg_segs; +} + + +/* Move data from the user buffer to the tape buffer. Returns zero (success) or + negative error code. */ + static int +append_to_buffer(const char *ubp, ST_buffer *st_bp, int do_count) +{ + int i, cnt, res, offset; + + for (i=0, offset=st_bp->buffer_bytes; + i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) + offset -= st_bp->sg[i].length; + if (i == st_bp->sg_segs) { /* Should never happen */ + printk(KERN_WARNING "st: append_to_buffer offset overflow.\n"); + return (-EIO); + } + for ( ; i < st_bp->sg_segs && do_count > 0; i++) { + cnt = st_bp->sg[i].length - offset < do_count ? + st_bp->sg[i].length - offset : do_count; + res = copy_from_user(st_bp->sg[i].address + offset, ubp, cnt); + if (res) + return (-EFAULT); + do_count -= cnt; + st_bp->buffer_bytes += cnt; + ubp += cnt; + offset = 0; + } + if (do_count) { /* Should never happen */ + printk(KERN_WARNING "st: append_to_buffer overflow (left %d).\n", + do_count); + return (-EIO); + } + return 0; +} + + +/* Move data from the tape buffer to the user buffer. Returns zero (success) or + negative error code. */ + static int +from_buffer(ST_buffer *st_bp, char *ubp, int do_count) +{ + int i, cnt, res, offset; + + for (i=0, offset=st_bp->read_pointer; + i < st_bp->sg_segs && offset >= st_bp->sg[i].length; i++) + offset -= st_bp->sg[i].length; + if (i == st_bp->sg_segs) { /* Should never happen */ + printk(KERN_WARNING "st: from_buffer offset overflow.\n"); + return (-EIO); + } + for ( ; i < st_bp->sg_segs && do_count > 0; i++) { + cnt = st_bp->sg[i].length - offset < do_count ? + st_bp->sg[i].length - offset : do_count; + res = copy_to_user(ubp, st_bp->sg[i].address + offset, cnt); + if (res) + return (-EFAULT); + do_count -= cnt; + st_bp->buffer_bytes -= cnt; + st_bp->read_pointer += cnt; + ubp += cnt; + offset = 0; + } + if (do_count) { /* Should never happen */ + printk(KERN_WARNING "st: from_buffer overflow (left %d).\n", + do_count); + return (-EIO); + } + return 0; } @@ -3162,7 +3341,7 @@ st_ioctl, /* ioctl */ NULL, /* mmap */ scsi_tape_open, /* open */ - NULL, /* flush */ + scsi_tape_flush, /* flush */ scsi_tape_close, /* release */ NULL /* fsync */ }; @@ -3173,13 +3352,13 @@ ST_partstat * STps; int i; - if(SDp->type != TYPE_TAPE) return 1; + if (SDp->type != TYPE_TAPE) + return 1; - if(st_template.nr_dev >= st_template.dev_max) - { - SDp->attached--; - return 1; - } + if (st_template.nr_dev >= st_template.dev_max) { + SDp->attached--; + return 1; + } for(tpnt = scsi_tapes, i=0; idevice) break; @@ -3250,7 +3429,7 @@ { if(SDp->type != TYPE_TAPE) return 0; - printk(KERN_INFO + printk(KERN_WARNING "Detected scsi tape st%d at scsi%d, channel %d, id %d, lun %d\n", st_template.dev_noticed++, SDp->host->host_no, SDp->channel, SDp->id, SDp->lun); @@ -3376,11 +3555,6 @@ int init_module(void) { int result; - st_template.module = &__this_module; - result = scsi_register_module(MODULE_SCSI_DEV, &st_template); - if (result) - return result; - if (buffer_kbs > 0) st_buffer_size = buffer_kbs * ST_KILOBYTE; if (write_threshold_kbs > 0) @@ -3389,15 +3563,22 @@ st_write_threshold = st_buffer_size; if (max_buffers > 0) st_max_buffers = max_buffers; -printk(KERN_INFO "st: bufsize %d, wrt %d, max buffers %d.\n", -st_buffer_size, st_write_threshold, st_max_buffers); + if (max_sg_segs >= ST_FIRST_SG) + st_max_sg_segs = max_sg_segs; + printk(KERN_INFO "st: bufsize %d, wrt %d, max buffers %d, s/g segs %d.\n", + st_buffer_size, st_write_threshold, st_max_buffers, st_max_sg_segs); + + st_template.module = &__this_module; + result = scsi_register_module(MODULE_SCSI_DEV, &st_template); + if (result) + return result; return 0; } void cleanup_module( void) { - int i; + int i, j; scsi_unregister_module(MODULE_SCSI_DEV, &st_template); unregister_chrdev(SCSI_TAPE_MAJOR, "st"); @@ -3409,9 +3590,10 @@ if (st_buffers != NULL) { for (i=0; i < st_nbr_buffers; i++) if (st_buffers[i] != NULL) { - scsi_init_free((char *) st_buffers[i]->b_data, - st_buffers[i]->buffer_size); - scsi_init_free((char *) st_buffers[i], sizeof(ST_buffer)); + for (j=0; j < st_buffers[i]->sg_segs; j++) + scsi_init_free((char *) st_buffers[i]->sg[j].address, + st_buffers[i]->sg[j].length); + scsi_init_free((char *) st_buffers[i], st_buffers[i]->this_size); } scsi_init_free((char *) st_buffers, diff -u --recursive --new-file v2.1.120/linux/drivers/scsi/st.h linux/drivers/scsi/st.h --- v2.1.120/linux/drivers/scsi/st.h Thu Nov 13 07:23:32 1997 +++ linux/drivers/scsi/st.h Sun Sep 6 09:48:30 1998 @@ -13,6 +13,7 @@ typedef struct { unsigned char in_use; unsigned char dma; /* DMA-able buffer */ + int this_size; /* allocated size of the structure */ int buffer_size; int buffer_blocks; int buffer_bytes; @@ -22,8 +23,10 @@ int last_result_fatal; Scsi_Cmnd *last_SCpnt; unsigned char *b_data; - int orig_size; - unsigned char *orig_b_data; + unsigned short use_sg; /* zero or number of segments for this adapter */ + unsigned short sg_segs; /* total number of allocated segments */ + unsigned short orig_sg_segs; /* number of segments allocated at first try */ + struct scatterlist sg[1]; /* MUST BE last item */ } ST_buffer; diff -u --recursive --new-file v2.1.120/linux/drivers/scsi/st_options.h linux/drivers/scsi/st_options.h --- v2.1.120/linux/drivers/scsi/st_options.h Wed May 28 10:51:32 1997 +++ linux/drivers/scsi/st_options.h Sun Sep 6 09:48:30 1998 @@ -3,7 +3,7 @@ Copyright 1995 Kai Makisara. - Last modified: Tue May 27 22:29:15 1997 by makisara@home + Last modified: Wed Sep 2 21:24:07 1998 by root@home */ #ifndef _ST_OPTIONS_H @@ -53,6 +53,18 @@ is also constrained by the number of drives detected. Determines the maximum number of concurrently active tape drives. */ #define ST_MAX_BUFFERS (2 + ST_EXTRA_DEVS) + +/* Maximum number of scatter/gather segments */ +#define ST_MAX_SG 16 + +/* The number of scatter/gather segments to allocate at first try (must be + smaller or equal to the maximum). */ +#define ST_FIRST_SG 8 + +/* The size of the first scatter/gather segments (determines the maximum block + size for SCSI adapters not supporting scatter/gather). The default is set + to try to allocate the buffer as one chunk. */ +#define ST_FIRST_ORDER 5 /* The following lines define defaults for properties that can be set diff -u --recursive --new-file v2.1.120/linux/drivers/scsi/t128.c linux/drivers/scsi/t128.c --- v2.1.120/linux/drivers/scsi/t128.c Tue Apr 14 14:29:24 1998 +++ linux/drivers/scsi/t128.c Sat Sep 5 17:01:45 1998 @@ -240,7 +240,7 @@ break; instance = scsi_register (tpnt, sizeof(struct NCR5380_hostdata)); - instance->base = base; + instance->base = phys_to_virt((unsigned int)base); NCR5380_init(instance, 0); diff -u --recursive --new-file v2.1.120/linux/fs/filesystems.c linux/fs/filesystems.c --- v2.1.120/linux/fs/filesystems.c Sat Sep 5 16:46:41 1998 +++ linux/fs/filesystems.c Sun Sep 6 12:55:38 1998 @@ -47,16 +47,8 @@ extern int init_devpts_fs(void); #endif -extern void device_setup(void); -extern void binfmt_setup(void); -extern void free_initmem(void); - -static void __init do_sys_setup(void) +void __init filesystem_setup(void) { - device_setup(); - - binfmt_setup(); - #ifdef CONFIG_EXT2_FS init_ext2_fs(); #endif @@ -156,32 +148,6 @@ #ifdef CONFIG_NLS init_nls(); #endif - - mount_root(); -} - -int initmem_freed = 0; - -/* This may be used only twice, enforced by 'static int callable' */ -asmlinkage int sys_setup(int magic) -{ - static int callable = 1; - int err = -1; - - lock_kernel(); - if (magic) { - if (!initmem_freed) { - initmem_freed = 1; - free_initmem (); - err = 0; - } - } else if (callable) { - callable = 0; - do_sys_setup(); - err = 0; - } - unlock_kernel(); - return err; } #ifndef CONFIG_NFSD diff -u --recursive --new-file v2.1.120/linux/fs/inode.c linux/fs/inode.c --- v2.1.120/linux/fs/inode.c Sat Sep 5 16:46:41 1998 +++ linux/fs/inode.c Tue Sep 8 14:51:03 1998 @@ -8,6 +8,7 @@ #include #include #include +#include #include /* @@ -734,11 +735,11 @@ /* * Initialize the hash tables and default - * value for max inodes.. + * value for max inodes */ #define MAX_INODE (8192) -void inode_init(void) +void __init inode_init(void) { int i, max; struct list_head *head = inode_hashtable; diff -u --recursive --new-file v2.1.120/linux/fs/isofs/inode.c linux/fs/isofs/inode.c --- v2.1.120/linux/fs/isofs/inode.c Sat Sep 5 16:46:41 1998 +++ linux/fs/isofs/inode.c Sun Sep 6 10:10:47 1998 @@ -128,30 +128,6 @@ unsigned char utf8; }; -static int strnicmp(const char *s1, const char *s2, int len) -{ - /* Yes, Virginia, it had better be unsigned */ - unsigned char c1, c2; - - c1 = 0; c2 = 0; - while (len > 0) { - c1 = *s1; c2 = *s2; - s1++; s2++; - if (!c1) - break; - if (!c2) - break; - if (c1 == c2) - continue; - c1 = tolower(c1); - c2 = tolower(c2); - if (c1 != c2) - break; - len--; - } - return (int)c1 - (int)c2; -} - /* * Compute the hash for the isofs name corresponding to the dentry. */ diff -u --recursive --new-file v2.1.120/linux/fs/nfs/dir.c linux/fs/nfs/dir.c --- v2.1.120/linux/fs/nfs/dir.c Sat Sep 5 16:46:41 1998 +++ linux/fs/nfs/dir.c Sat Sep 5 17:17:01 1998 @@ -446,14 +446,14 @@ */ static void nfs_dentry_delete(struct dentry *dentry) { + dfprintk(VFS, "NFS: dentry_delete(%s/%s, %x)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + dentry->d_flags); + if (dentry->d_flags & DCACHE_NFSFS_RENAMED) { int error; dentry->d_flags &= ~DCACHE_NFSFS_RENAMED; -#ifdef NFS_DEBUG_VERBOSE -printk("nfs_dentry_delete: unlinking %s/%s\n", -dentry->d_parent->d_name.name, dentry->d_name.name); -#endif /* Unhash it first */ d_drop(dentry); error = nfs_safe_remove(dentry); @@ -486,6 +486,10 @@ */ static void nfs_dentry_iput(struct dentry *dentry, struct inode *inode) { + dfprintk(VFS, "NFS: dentry_iput(%s/%s, cnt=%d, ino=%ld)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + dentry->d_count, inode->i_ino); + if (NFS_WRITEBACK(inode)) { #ifdef NFS_PARANOIA printk("nfs_dentry_iput: pending writes for %s/%s, i_count=%d\n", @@ -859,6 +863,10 @@ struct dentry *sdentry; int error = -EIO; + dfprintk(VFS, "NFS: silly-rename(%s/%s, ct=%d)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + dentry->d_count); + /* * Note that a silly-renamed file can be deleted once it's * no longer in use -- it's just an ordinary file now. @@ -931,6 +939,10 @@ struct inode *inode = dentry->d_inode; int error, rehash = 0; + dfprintk(VFS, "NFS: safe_remove(%s/%s, %ld)\n", + dentry->d_parent->d_name.name, dentry->d_name.name, + inode->i_ino); + /* N.B. not needed now that d_delete is done in advance? */ error = -EBUSY; if (inode) { @@ -1130,22 +1142,13 @@ { struct inode *old_inode = old_dentry->d_inode; struct inode *new_inode = new_dentry->d_inode; + struct dentry *dentry = NULL; int error, rehash = 0, update = 1; -#ifdef NFS_DEBUG_VERBOSE -printk("nfs_rename: old %s/%s, count=%d, new %s/%s, count=%d\n", -old_dentry->d_parent->d_name.name,old_dentry->d_name.name,old_dentry->d_count, -new_dentry->d_parent->d_name.name,new_dentry->d_name.name,new_dentry->d_count); -#endif - if (!old_dir || !S_ISDIR(old_dir->i_mode)) { - printk("nfs_rename: old inode is NULL or not a directory\n"); - return -ENOENT; - } - - if (!new_dir || !S_ISDIR(new_dir->i_mode)) { - printk("nfs_rename: new inode is NULL or not a directory\n"); - return -ENOENT; - } + dfprintk(VFS, "NFS: rename(%s/%s -> %s/%s, ct=%d)\n", + old_dentry->d_parent->d_name.name, old_dentry->d_name.name, + new_dentry->d_parent->d_name.name, new_dentry->d_name.name, + new_dentry->d_count); error = -ENAMETOOLONG; if (old_dentry->d_name.len > NFS_MAXNAMLEN || @@ -1155,16 +1158,43 @@ /* * First check whether the target is busy ... we can't * safely do _any_ rename if the target is in use. + * + * For files, make a copy of the dentry and then do a + * silly-rename. If the silly-rename succeeds, the + * copied dentry is hashed and becomes the new target. + * + * For directories, prune any unused children. */ - if (new_dentry->d_count > 1 && !list_empty(&new_dentry->d_subdirs)) - shrink_dcache_parent(new_dentry); error = -EBUSY; - if (new_dentry->d_count > 1) { + if (new_dentry->d_count > 1 && new_inode) { + if (S_ISREG(new_inode->i_mode)) { + int err; + /* copy the target dentry's name */ + dentry = d_alloc(new_dentry->d_parent, + &new_dentry->d_name); + if (!dentry) + goto out; + + /* silly-rename the existing target ... */ + err = nfs_sillyrename(new_dir, new_dentry); + if (!err) { + new_dentry = dentry; + new_inode = NULL; + /* hash the replacement target */ + d_add(new_dentry, NULL); + } + } else if (!list_empty(&new_dentry->d_subdirs)) { + shrink_dcache_parent(new_dentry); + } + + /* dentry still busy? */ + if (new_dentry->d_count > 1) { #ifdef NFS_PARANOIA printk("nfs_rename: target %s/%s busy, d_count=%d\n", new_dentry->d_parent->d_name.name,new_dentry->d_name.name,new_dentry->d_count); #endif - goto out; + goto out; + } } /* @@ -1208,7 +1238,7 @@ #endif goto out; } - if (new_dentry->d_count > 1) { + if (new_dentry->d_count > 1 && new_inode) { #ifdef NFS_PARANOIA printk("nfs_rename: new dentry %s/%s busy, d_count=%d\n", new_dentry->d_parent->d_name.name,new_dentry->d_name.name,new_dentry->d_count); @@ -1251,7 +1281,11 @@ if (update) d_move(old_dentry, new_dentry); } + out: + /* new dentry created? */ + if (dentry) + dput(dentry); return error; } diff -u --recursive --new-file v2.1.120/linux/fs/nfs/write.c linux/fs/nfs/write.c --- v2.1.120/linux/fs/nfs/write.c Sat Sep 5 16:46:41 1998 +++ linux/fs/nfs/write.c Sat Sep 5 17:13:21 1998 @@ -475,7 +475,6 @@ if (!PageLocked(page)) break; retval = -ERESTARTSYS; - checksignals(); if (signalled()) break; schedule(); diff -u --recursive --new-file v2.1.120/linux/fs/nfsd/nfssvc.c linux/fs/nfsd/nfssvc.c --- v2.1.120/linux/fs/nfsd/nfssvc.c Fri Jan 30 11:28:08 1998 +++ linux/fs/nfsd/nfssvc.c Sat Sep 5 16:50:15 1998 @@ -36,8 +36,8 @@ #define NFSDDBG_FACILITY NFSDDBG_SVC #define NFSD_BUFSIZE (1024 + NFSSVC_MAXBLKSIZE) -#define ALLOWED_SIGS (sigmask(SIGKILL) | sigmask(SIGSTOP)) -#define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGTERM)) +#define ALLOWED_SIGS (sigmask(SIGKILL)) +#define SHUTDOWN_SIGS (sigmask(SIGKILL) | sigmask(SIGINT) | sigmask(SIGQUIT)) extern struct svc_program nfsd_program; static void nfsd(struct svc_rqst *rqstp); diff -u --recursive --new-file v2.1.120/linux/fs/qnx4/inode.c linux/fs/qnx4/inode.c --- v2.1.120/linux/fs/qnx4/inode.c Sat Sep 5 16:46:41 1998 +++ linux/fs/qnx4/inode.c Sat Sep 5 17:01:45 1998 @@ -134,11 +134,12 @@ #else NULL, #endif - qnx4_put_inode, #ifdef CONFIG_QNX4FS_RW + qnx4_put_inode, qnx4_delete_inode, NULL, /* notify_change */ #else + NULL, /* put_inode */ NULL, /* delete_inode */ NULL, /* notify_change */ #endif diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/asm_offsets.h linux/include/asm-alpha/asm_offsets.h --- v2.1.120/linux/include/asm-alpha/asm_offsets.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-alpha/asm_offsets.h Sun Sep 6 10:34:33 1998 @@ -0,0 +1,13 @@ +#ifndef __ASM_OFFSETS_H__ +#define __ASM_OFFSETS_H__ +#define TASK_STATE 0 +#define TASK_FLAGS 8 +#define TASK_SIGPENDING 16 +#define TASK_ADDR_LIMIT 24 +#define TASK_EXEC_DOMAIN 32 +#define TASK_NEED_RESCHED 40 +#define TASK_SIZE 1120 +#define STACK_SIZE 16384 +#define HAE_CACHE 0 +#define HAE_REG 8 +#endif /* __ASM_OFFSETS_H__ */ diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/bitops.h linux/include/asm-alpha/bitops.h --- v2.1.120/linux/include/asm-alpha/bitops.h Tue Aug 18 22:02:06 1998 +++ linux/include/asm-alpha/bitops.h Sun Sep 6 10:34:33 1998 @@ -176,6 +176,7 @@ /* Whee. EV6 can calculate it directly. */ unsigned long result; __asm__("ctlz %1,%0" : "=r"(result) : "r"(~word)); + return result; #else unsigned long bits, qofs, bofs; diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/console.h linux/include/asm-alpha/console.h --- v2.1.120/linux/include/asm-alpha/console.h Fri Jun 2 03:51:16 1995 +++ linux/include/asm-alpha/console.h Sun Sep 6 10:34:33 1998 @@ -41,7 +41,4 @@ #define ENV_LANGUAGE 0x0E #define ENV_TTY_DEV 0x0F -extern unsigned long dispatch(unsigned long code, ...); -#define puts(x,l) dispatch(CCB_PUTS,0,x,l) - #endif diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/core_mcpcia.h linux/include/asm-alpha/core_mcpcia.h --- v2.1.120/linux/include/asm-alpha/core_mcpcia.h Tue Aug 18 22:02:06 1998 +++ linux/include/asm-alpha/core_mcpcia.h Sun Sep 6 10:34:33 1998 @@ -130,6 +130,8 @@ /* * Error registers */ +#define MCPCIA_MC_ERR0(h) (IDENT_ADDR + 0xf9e0000800UL + HOSE(h)) +#define MCPCIA_MC_ERR1(h) (IDENT_ADDR + 0xf9e0000840UL + HOSE(h)) #define MCPCIA_CAP_ERR(h) (IDENT_ADDR + 0xf9e0000880UL + HOSE(h)) #define MCPCIA_PCI_ERR1(h) (IDENT_ADDR + 0xf9e0001040UL + HOSE(h)) diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/core_pyxis.h linux/include/asm-alpha/core_pyxis.h --- v2.1.120/linux/include/asm-alpha/core_pyxis.h Tue Aug 18 22:02:06 1998 +++ linux/include/asm-alpha/core_pyxis.h Sun Sep 6 10:34:33 1998 @@ -182,6 +182,7 @@ #define PYXIS_RT_COUNT (IDENT_ADDR + 0x87A0000200UL) #define PYXIS_INT_TIME (IDENT_ADDR + 0x87A0000240UL) #define PYXIS_IIC_CTRL (IDENT_ADDR + 0x87A00002C0UL) +#define PYXIS_RESET (IDENT_ADDR + 0x8780000900UL) /* * Bit definitions for I/O Controller status register 0: @@ -258,18 +259,6 @@ * a kernel virtual address and vv. */ -/* Ruffian doesn't do 1G PCI window */ - -static inline unsigned long pyxis_ruffian_virt_to_bus(void * address) -{ - return virt_to_phys(address); -} - -static inline void * pyxis_ruffian_bus_to_virt(unsigned long address) -{ - return phys_to_virt(address); -} - __EXTERN_INLINE unsigned long pyxis_virt_to_bus(void * address) { return virt_to_phys(address) + PYXIS_DMA_WIN_BASE; @@ -600,15 +589,10 @@ #ifdef __WANT_IO_DEF -#ifdef CONFIG_ALPHA_RUFFIAN -#define virt_to_bus pyxis_ruffian_virt_to_bus -#define bus_to_virt pyxis_ruffian_bus_to_virt -#else #define virt_to_bus pyxis_virt_to_bus #define bus_to_virt pyxis_bus_to_virt -#endif -#ifdef BWIO_ENABLED +#if defined(BWIO_ENABLED) && !defined(CONFIG_ALPHA_RUFFIAN) # define __inb pyxis_bw_inb # define __inw pyxis_bw_inw # define __inl pyxis_bw_inl @@ -649,7 +633,7 @@ #define dense_mem pyxis_dense_mem -#ifdef BWIO_ENABLED +#if defined(BWIO_ENABLED) && !defined(CONFIG_ALPHA_RUFFIAN) # define inb(port) __inb((port)) # define inw(port) __inw((port)) # define inl(port) __inl((port)) diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/core_tsunami.h linux/include/asm-alpha/core_tsunami.h --- v2.1.120/linux/include/asm-alpha/core_tsunami.h Tue Aug 18 22:02:06 1998 +++ linux/include/asm-alpha/core_tsunami.h Sun Sep 6 10:34:33 1998 @@ -35,91 +35,77 @@ #endif /* - * CChip and DChip registers + * CChip, DChip, and PChip registers */ -#define TSUNAMI_CSR_CSC (IDENT_ADDR + TS_BIAS + 0x1A0000000UL) -#define TSUNAMI_CSR_MTR (IDENT_ADDR + TS_BIAS + 0x1A0000040UL) -#define TSUNAMI_CSR_MISC (IDENT_ADDR + TS_BIAS + 0x1A0000080UL) -#define TSUNAMI_CSR_MPD (IDENT_ADDR + TS_BIAS + 0x1A00000C0UL) -#define TSUNAMI_CSR_AAR0 (IDENT_ADDR + TS_BIAS + 0x1A0000100UL) -#define TSUNAMI_CSR_AAR1 (IDENT_ADDR + TS_BIAS + 0x1A0000140UL) -#define TSUNAMI_CSR_AAR2 (IDENT_ADDR + TS_BIAS + 0x1A0000180UL) -#define TSUNAMI_CSR_AAR3 (IDENT_ADDR + TS_BIAS + 0x1A00001C0UL) -#define TSUNAMI_CSR_DIM0 (IDENT_ADDR + TS_BIAS + 0x1A0000200UL) -#define TSUNAMI_CSR_DIM1 (IDENT_ADDR + TS_BIAS + 0x1A0000240UL) -#define TSUNAMI_CSR_DIR0 (IDENT_ADDR + TS_BIAS + 0x1A0000280UL) -#define TSUNAMI_CSR_DIR1 (IDENT_ADDR + TS_BIAS + 0x1A00002C0UL) - -#define TSUNAMI_CSR_DRIR (IDENT_ADDR + TS_BIAS + 0x1A0000300UL) -#define TSUNAMI_CSR_PRBEN (IDENT_ADDR + TS_BIAS + 0x1A0000340UL) -#define TSUNAMI_CSR_IIC (IDENT_ADDR + TS_BIAS + 0x1A0000380UL) -#define TSUNAMI_CSR_WDR (IDENT_ADDR + TS_BIAS + 0x1A00003C0UL) -#define TSUNAMI_CSR_MPR0 (IDENT_ADDR + TS_BIAS + 0x1A0000400UL) -#define TSUNAMI_CSR_MPR1 (IDENT_ADDR + TS_BIAS + 0x1A0000440UL) -#define TSUNAMI_CSR_MPR2 (IDENT_ADDR + TS_BIAS + 0x1A0000480UL) -#define TSUNAMI_CSR_MPR3 (IDENT_ADDR + TS_BIAS + 0x1A00004C0UL) -#define TSUNAMI_CSR_TTR (IDENT_ADDR + TS_BIAS + 0x1A0000580UL) -#define TSUNAMI_CSR_TDR (IDENT_ADDR + TS_BIAS + 0x1A00005C0UL) -#define TSUNAMI_CSR_DSC (IDENT_ADDR + TS_BIAS + 0x1B0000800UL) -#define TSUNAMI_CSR_STR (IDENT_ADDR + TS_BIAS + 0x1B0000840UL) -#define TSUNAMI_CSR_DREV (IDENT_ADDR + TS_BIAS + 0x1B0000880UL) + +typedef struct { + volatile unsigned long csr __attribute__((aligned(64))); +} tsunami_64; + +typedef struct { + tsunami_64 csc; + tsunami_64 mtr; + tsunami_64 misc; + tsunami_64 mpd; + tsunami_64 aar0; + tsunami_64 aar1; + tsunami_64 aar2; + tsunami_64 aar3; + tsunami_64 dim0; + tsunami_64 dim1; + tsunami_64 dir0; + tsunami_64 dir1; + tsunami_64 drir; + tsunami_64 prben; + tsunami_64 iic; /* a.k.a. iic0 */ + tsunami_64 wdr; /* a.k.a. iic1 */ + tsunami_64 mpr0; + tsunami_64 mpr1; + tsunami_64 mpr2; + tsunami_64 mpr3; + tsunami_64 mctl; + tsunami_64 ttr; + tsunami_64 tdr; + tsunami_64 dim2; + tsunami_64 dim3; + tsunami_64 dir2; + tsunami_64 dir3; + tsunami_64 iic2; + tsunami_64 iic3; +} tsunami_cchip; + +typedef struct { + tsunami_64 dsc; + tsunami_64 str; + tsunami_64 drev; +} tsunami_dchip; + +typedef struct { + tsunami_64 wsba[4]; + tsunami_64 wsm[4]; + tsunami_64 tba[4]; + tsunami_64 pctl; + tsunami_64 plat; + tsunami_64 reserved; + tsunami_64 perror; + tsunami_64 perrmask; + tsunami_64 perrset; + tsunami_64 tlbiv; + tsunami_64 tlbia; + tsunami_64 pmonctl; + tsunami_64 pmoncnt; +} tsunami_pchip; + +#define TSUNAMI_cchip ((tsunami_cchip *)(IDENT_ADDR+TS_BIAS+0x1A0000000UL)) +#define TSUNAMI_dchip ((tsunami_dchip *)(IDENT_ADDR+TS_BIAS+0x1B0000800UL)) +#define TSUNAMI_pchip0 ((tsunami_pchip *)(IDENT_ADDR+TS_BIAS+0x180000000UL)) +#define TSUNAMI_pchip1 ((tsunami_pchip *)(IDENT_ADDR+TS_BIAS+0x380000000UL)) +extern int TSUNAMI_bootcpu; /* - * PChip registers + * TSUNAMI Pchip Error register. */ -#define TSUNAMI_PCHIP0_WSBA0 (IDENT_ADDR + TS_BIAS + 0x180000000UL) -#define TSUNAMI_PCHIP0_WSBA1 (IDENT_ADDR + TS_BIAS + 0x180000040UL) -#define TSUNAMI_PCHIP0_WSBA2 (IDENT_ADDR + TS_BIAS + 0x180000080UL) -#define TSUNAMI_PCHIP0_WSBA3 (IDENT_ADDR + TS_BIAS + 0x1800000C0UL) - -#define TSUNAMI_PCHIP0_WSM0 (IDENT_ADDR + TS_BIAS + 0x180000100UL) -#define TSUNAMI_PCHIP0_WSM1 (IDENT_ADDR + TS_BIAS + 0x180000140UL) -#define TSUNAMI_PCHIP0_WSM2 (IDENT_ADDR + TS_BIAS + 0x180000180UL) -#define TSUNAMI_PCHIP0_WSM3 (IDENT_ADDR + TS_BIAS + 0x1800001C0UL) -#define TSUNAMI_PCHIP0_TBA0 (IDENT_ADDR + TS_BIAS + 0x180000200UL) -#define TSUNAMI_PCHIP0_TBA1 (IDENT_ADDR + TS_BIAS + 0x180000240UL) -#define TSUNAMI_PCHIP0_TBA2 (IDENT_ADDR + TS_BIAS + 0x180000280UL) -#define TSUNAMI_PCHIP0_TBA3 (IDENT_ADDR + TS_BIAS + 0x1800002C0UL) - -#define TSUNAMI_PCHIP0_PCTL (IDENT_ADDR + TS_BIAS + 0x180000300UL) -#define TSUNAMI_PCHIP0_PLAT (IDENT_ADDR + TS_BIAS + 0x180000340UL) -#define TSUNAMI_PCHIP0_RESERVED (IDENT_ADDR + TS_BIAS + 0x180000380UL) -#define TSUNAMI_PCHIP0_PERROR (IDENT_ADDR + TS_BIAS + 0x1800003c0UL) -#define TSUNAMI_PCHIP0_PERRMASK (IDENT_ADDR + TS_BIAS + 0x180000400UL) -#define TSUNAMI_PCHIP0_PERRSET (IDENT_ADDR + TS_BIAS + 0x180000440UL) -#define TSUNAMI_PCHIP0_TLBIV (IDENT_ADDR + TS_BIAS + 0x180000480UL) -#define TSUNAMI_PCHIP0_TLBIA (IDENT_ADDR + TS_BIAS + 0x1800004C0UL) -#define TSUNAMI_PCHIP0_PMONCTL (IDENT_ADDR + TS_BIAS + 0x180000500UL) -#define TSUNAMI_PCHIP0_PMONCNT (IDENT_ADDR + TS_BIAS + 0x180000540UL) - -#define TSUNAMI_PCHIP1_WSBA0 (IDENT_ADDR + TS_BIAS + 0x380000000UL) -#define TSUNAMI_PCHIP1_WSBA1 (IDENT_ADDR + TS_BIAS + 0x380000040UL) -#define TSUNAMI_PCHIP1_WSBA2 (IDENT_ADDR + TS_BIAS + 0x380000080UL) -#define TSUNAMI_PCHIP1_WSBA3 (IDENT_ADDR + TS_BIAS + 0x3800000C0UL) -#define TSUNAMI_PCHIP1_WSM0 (IDENT_ADDR + TS_BIAS + 0x380000100UL) -#define TSUNAMI_PCHIP1_WSM1 (IDENT_ADDR + TS_BIAS + 0x380000140UL) -#define TSUNAMI_PCHIP1_WSM2 (IDENT_ADDR + TS_BIAS + 0x380000180UL) -#define TSUNAMI_PCHIP1_WSM3 (IDENT_ADDR + TS_BIAS + 0x3800001C0UL) - -#define TSUNAMI_PCHIP1_TBA0 (IDENT_ADDR + TS_BIAS + 0x380000200UL) -#define TSUNAMI_PCHIP1_TBA1 (IDENT_ADDR + TS_BIAS + 0x380000240UL) -#define TSUNAMI_PCHIP1_TBA2 (IDENT_ADDR + TS_BIAS + 0x380000280UL) -#define TSUNAMI_PCHIP1_TBA3 (IDENT_ADDR + TS_BIAS + 0x3800002C0UL) - -#define TSUNAMI_PCHIP1_PCTL (IDENT_ADDR + TS_BIAS + 0x380000300UL) -#define TSUNAMI_PCHIP1_PLAT (IDENT_ADDR + TS_BIAS + 0x380000340UL) -#define TSUNAMI_PCHIP1_RESERVED (IDENT_ADDR + TS_BIAS + 0x380000380UL) -#define TSUNAMI_PCHIP1_PERROR (IDENT_ADDR + TS_BIAS + 0x3800003c0UL) -#define TSUNAMI_PCHIP1_PERRMASK (IDENT_ADDR + TS_BIAS + 0x380000400UL) -#define TSUNAMI_PCHIP1_PERRSET (IDENT_ADDR + TS_BIAS + 0x380000440UL) -#define TSUNAMI_PCHIP1_TLBIV (IDENT_ADDR + TS_BIAS + 0x380000480UL) -#define TSUNAMI_PCHIP1_TLBIA (IDENT_ADDR + TS_BIAS + 0x3800004C0UL) -#define TSUNAMI_PCHIP1_PMONCTL (IDENT_ADDR + TS_BIAS + 0x380000500UL) -#define TSUNAMI_PCHIP1_PMONCNT (IDENT_ADDR + TS_BIAS + 0x380000540UL) - -/* */ -/* TSUNAMI Pchip Error register. */ -/* */ + #define perror_m_lost 0x1 #define perror_m_serr 0x2 #define perror_m_perr 0x4 @@ -137,50 +123,52 @@ #define perror_m_cmd 0xF0000000000000UL #define perror_m_syn 0xFF00000000000000UL union TPchipPERROR { - struct { - unsigned int perror_v_lost : 1; - unsigned perror_v_serr : 1; - unsigned perror_v_perr : 1; - unsigned perror_v_dcrto : 1; - unsigned perror_v_sge : 1; - unsigned perror_v_ape : 1; - unsigned perror_v_ta : 1; - unsigned perror_v_rdpe : 1; - unsigned perror_v_nds : 1; - unsigned perror_v_rto : 1; - unsigned perror_v_uecc : 1; - unsigned perror_v_cre : 1; - unsigned perror_v_rsvd1 : 4; - unsigned perror_v_addrl : 32; - unsigned perror_v_addrh : 3; - unsigned perror_v_rsvd2 : 1; - unsigned perror_v_cmd : 4; - unsigned perror_v_syn : 8; + struct { + unsigned int perror_v_lost : 1; + unsigned perror_v_serr : 1; + unsigned perror_v_perr : 1; + unsigned perror_v_dcrto : 1; + unsigned perror_v_sge : 1; + unsigned perror_v_ape : 1; + unsigned perror_v_ta : 1; + unsigned perror_v_rdpe : 1; + unsigned perror_v_nds : 1; + unsigned perror_v_rto : 1; + unsigned perror_v_uecc : 1; + unsigned perror_v_cre : 1; + unsigned perror_v_rsvd1 : 4; + unsigned perror_v_addrl : 32; + unsigned perror_v_addrh : 3; + unsigned perror_v_rsvd2 : 1; + unsigned perror_v_cmd : 4; + unsigned perror_v_syn : 8; } perror_r_bits; - int perror_q_whole [2]; - } ; -/* */ -/* TSUNAMI Pchip Window Space Base Address register. */ -/* */ + int perror_q_whole [2]; +}; + +/* + * TSUNAMI Pchip Window Space Base Address register. + */ #define wsba_m_ena 0x1 #define wsba_m_sg 0x2 #define wsba_m_ptp 0x4 #define wsba_m_addr 0xFFF00000 #define wmask_k_sz1gb 0x3FF00000 union TPchipWSBA { - struct { - unsigned wsba_v_ena : 1; - unsigned wsba_v_sg : 1; - unsigned wsba_v_ptp : 1; - unsigned wsba_v_rsvd1 : 17; - unsigned wsba_v_addr : 12; - unsigned wsba_v_rsvd2 : 32; + struct { + unsigned wsba_v_ena : 1; + unsigned wsba_v_sg : 1; + unsigned wsba_v_ptp : 1; + unsigned wsba_v_rsvd1 : 17; + unsigned wsba_v_addr : 12; + unsigned wsba_v_rsvd2 : 32; } wsba_r_bits; - int wsba_q_whole [2]; - } ; -/* */ -/* TSUNAMI Pchip Control Register */ -/* */ + int wsba_q_whole [2]; +}; + +/* + * TSUNAMI Pchip Control Register + */ #define pctl_m_fdsc 0x1 #define pctl_m_fbtb 0x2 #define pctl_m_thdis 0x4 @@ -207,37 +195,38 @@ #define pctl_m_rsvd2 0xFFFF000000000000UL union TPchipPCTL { - struct { - unsigned pctl_v_fdsc : 1; - unsigned pctl_v_fbtb : 1; - unsigned pctl_v_thdis : 1; - unsigned pctl_v_chaindis : 1; - unsigned pctl_v_tgtlat : 1; - unsigned pctl_v_hole : 1; - unsigned pctl_v_mwin : 1; - unsigned pctl_v_arbena : 1; - unsigned pctl_v_prigrp : 7; - unsigned pctl_v_ppri : 1; - unsigned pctl_v_rsvd1 : 2; - unsigned pctl_v_eccen : 1; - unsigned pctl_v_padm : 1; - unsigned pctl_v_cdqmax : 4; - unsigned pctl_v_rev : 8; - unsigned pctl_v_crqmax : 4; - unsigned pctl_v_ptpmax : 4; - unsigned pctl_v_pclkx : 2; - unsigned pctl_v_fdsdis : 1; - unsigned pctl_v_fdwdis : 1; - unsigned pctl_v_ptevrfy : 1; - unsigned pctl_v_rpp : 1; - unsigned pctl_v_pid : 2; - unsigned pctl_v_rsvd2 : 16; + struct { + unsigned pctl_v_fdsc : 1; + unsigned pctl_v_fbtb : 1; + unsigned pctl_v_thdis : 1; + unsigned pctl_v_chaindis : 1; + unsigned pctl_v_tgtlat : 1; + unsigned pctl_v_hole : 1; + unsigned pctl_v_mwin : 1; + unsigned pctl_v_arbena : 1; + unsigned pctl_v_prigrp : 7; + unsigned pctl_v_ppri : 1; + unsigned pctl_v_rsvd1 : 2; + unsigned pctl_v_eccen : 1; + unsigned pctl_v_padm : 1; + unsigned pctl_v_cdqmax : 4; + unsigned pctl_v_rev : 8; + unsigned pctl_v_crqmax : 4; + unsigned pctl_v_ptpmax : 4; + unsigned pctl_v_pclkx : 2; + unsigned pctl_v_fdsdis : 1; + unsigned pctl_v_fdwdis : 1; + unsigned pctl_v_ptevrfy : 1; + unsigned pctl_v_rpp : 1; + unsigned pctl_v_pid : 2; + unsigned pctl_v_rsvd2 : 16; } pctl_r_bits; - int pctl_q_whole [2]; -} ; -/* */ -/* TSUNAMI Pchip Error Mask Register. */ -/* */ + int pctl_q_whole [2]; +}; + +/* + * TSUNAMI Pchip Error Mask Register. + */ #define perrmask_m_lost 0x1 #define perrmask_m_serr 0x2 #define perrmask_m_perr 0x4 @@ -252,37 +241,37 @@ #define perrmask_m_cre 0x800 #define perrmask_m_rsvd 0xFFFFFFFFFFFFF000UL union TPchipPERRMASK { - struct { - unsigned int perrmask_v_lost : 1; - unsigned perrmask_v_serr : 1; - unsigned perrmask_v_perr : 1; - unsigned perrmask_v_dcrto : 1; - unsigned perrmask_v_sge : 1; - unsigned perrmask_v_ape : 1; - unsigned perrmask_v_ta : 1; - unsigned perrmask_v_rdpe : 1; - unsigned perrmask_v_nds : 1; - unsigned perrmask_v_rto : 1; - unsigned perrmask_v_uecc : 1; - unsigned perrmask_v_cre : 1; - unsigned perrmask_v_rsvd1 : 20; - unsigned perrmask_v_rsvd2 : 32; + struct { + unsigned int perrmask_v_lost : 1; + unsigned perrmask_v_serr : 1; + unsigned perrmask_v_perr : 1; + unsigned perrmask_v_dcrto : 1; + unsigned perrmask_v_sge : 1; + unsigned perrmask_v_ape : 1; + unsigned perrmask_v_ta : 1; + unsigned perrmask_v_rdpe : 1; + unsigned perrmask_v_nds : 1; + unsigned perrmask_v_rto : 1; + unsigned perrmask_v_uecc : 1; + unsigned perrmask_v_cre : 1; + unsigned perrmask_v_rsvd1 : 20; + unsigned perrmask_v_rsvd2 : 32; } perrmask_r_bits; - int perrmask_q_whole [2]; - } ; + int perrmask_q_whole [2]; +}; /* * Memory spaces: */ -#define TSUNAMI_PCI0_MEM (IDENT_ADDR + TS_BIAS + 0x000000000UL) -#define TSUNAMI_PCI0_IACK_SC (IDENT_ADDR + TS_BIAS + 0x1F8000000UL) -#define TSUNAMI_PCI0_IO (IDENT_ADDR + TS_BIAS + 0x1FC000000UL) -#define TSUNAMI_PCI0_CONF (IDENT_ADDR + TS_BIAS + 0x1FE000000UL) - -#define TSUNAMI_PCI1_MEM (IDENT_ADDR + TS_BIAS + 0x200000000UL) -#define TSUNAMI_PCI1_IACK_SC (IDENT_ADDR + TS_BIAS + 0x3F8000000UL) -#define TSUNAMI_PCI1_IO (IDENT_ADDR + TS_BIAS + 0x3FC000000UL) -#define TSUNAMI_PCI1_CONF (IDENT_ADDR + TS_BIAS + 0x3FE000000UL) +#define HOSE(h) (((unsigned long)(h)) << 33) + +#define TSUNAMI_MEM(h) (IDENT_ADDR + TS_BIAS + 0x000000000UL + HOSE(h)) +#define _TSUNAMI_IACK_SC(h) (IDENT_ADDR + TS_BIAS + 0x1F8000000UL + HOSE(h)) +#define TSUNAMI_IO(h) (IDENT_ADDR + TS_BIAS + 0x1FC000000UL + HOSE(h)) +#define TSUNAMI_CONF(h) (IDENT_ADDR + TS_BIAS + 0x1FE000000UL + HOSE(h)) + +#define TSUNAMI_IACK_SC _TSUNAMI_IACK_SC(0) /* hack! */ + /* * Data structure for handling TSUNAMI machine checks: @@ -319,51 +308,44 @@ * can only use linear accesses to get at PCI memory and I/O spaces. */ -/* HACK ALERT! HACK ALERT! */ -/* HACK ALERT! HACK ALERT! */ - -/* Only using PCI bus 0 for now in all routines. */ - -#define TSUNAMI_IACK_SC TSUNAMI_PCI0_IACK_SC - -/* HACK ALERT! HACK ALERT! */ -/* HACK ALERT! HACK ALERT! */ - #define vucp volatile unsigned char * #define vusp volatile unsigned short * #define vuip volatile unsigned int * #define vulp volatile unsigned long * +#define XADDR ((addr) & 0xffffffffUL) +#define XHOSE (((addr) >> 32) & 3UL) + __EXTERN_INLINE unsigned int tsunami_inb(unsigned long addr) { - return __kernel_ldbu(*(vucp)(addr + TSUNAMI_PCI0_IO)); + return __kernel_ldbu(*(vucp)(XADDR + TSUNAMI_IO(XHOSE))); } __EXTERN_INLINE void tsunami_outb(unsigned char b, unsigned long addr) { - __kernel_stb(b, *(vucp)(addr + TSUNAMI_PCI0_IO)); + __kernel_stb(b, *(vucp)(XADDR + TSUNAMI_IO(XHOSE))); mb(); } __EXTERN_INLINE unsigned int tsunami_inw(unsigned long addr) { - return __kernel_ldwu(*(vusp)(addr+TSUNAMI_PCI0_IO)); + return __kernel_ldwu(*(vusp)(XADDR + TSUNAMI_IO(XHOSE))); } __EXTERN_INLINE void tsunami_outw(unsigned short b, unsigned long addr) { - __kernel_stw(b, *(vusp)(addr+TSUNAMI_PCI0_IO)); + __kernel_stw(b, *(vusp)(XADDR + TSUNAMI_IO(XHOSE))); mb(); } __EXTERN_INLINE unsigned int tsunami_inl(unsigned long addr) { - return *(vuip)(addr+TSUNAMI_PCI0_IO); + return *(vuip)(XADDR + TSUNAMI_IO(XHOSE)); } __EXTERN_INLINE void tsunami_outl(unsigned int b, unsigned long addr) { - *(vuip)(addr+TSUNAMI_PCI0_IO) = b; + *(vuip)(XADDR + TSUNAMI_IO(XHOSE)) = b; mb(); } @@ -373,45 +355,45 @@ __EXTERN_INLINE unsigned long tsunami_readb(unsigned long addr) { - return __kernel_ldbu(*(vucp)(addr+TSUNAMI_PCI0_MEM)); + return __kernel_ldbu(*(vucp)(XADDR + TSUNAMI_MEM(XHOSE))); } __EXTERN_INLINE unsigned long tsunami_readw(unsigned long addr) { - return __kernel_ldwu(*(vusp)(addr+TSUNAMI_PCI0_MEM)); + return __kernel_ldwu(*(vusp)(XADDR + TSUNAMI_MEM(XHOSE))); } __EXTERN_INLINE unsigned long tsunami_readl(unsigned long addr) { - return *(vuip)(addr+TSUNAMI_PCI0_MEM); + return *(vuip)(XADDR + TSUNAMI_MEM(XHOSE)); } __EXTERN_INLINE unsigned long tsunami_readq(unsigned long addr) { - return *(vulp)(addr+TSUNAMI_PCI0_MEM); + return *(vulp)(XADDR + TSUNAMI_MEM(XHOSE)); } __EXTERN_INLINE void tsunami_writeb(unsigned char b, unsigned long addr) { - __kernel_stb(b, *(vucp)(addr+TSUNAMI_PCI0_MEM)); + __kernel_stb(b, *(vucp)(XADDR + TSUNAMI_MEM(XHOSE))); mb(); } __EXTERN_INLINE void tsunami_writew(unsigned short b, unsigned long addr) { - __kernel_stw(b, *(vusp)(addr+TSUNAMI_PCI0_MEM)); + __kernel_stw(b, *(vusp)(XADDR + TSUNAMI_MEM(XHOSE))); mb(); } __EXTERN_INLINE void tsunami_writel(unsigned int b, unsigned long addr) { - *(vuip)(addr+TSUNAMI_PCI0_MEM) = b; + *(vuip)(XADDR + TSUNAMI_MEM(XHOSE)) = b; mb(); } __EXTERN_INLINE void tsunami_writeq(unsigned long b, unsigned long addr) { - *(vulp)(addr+TSUNAMI_PCI0_MEM) = b; + *(vulp)(XADDR + TSUNAMI_MEM(XHOSE)) = b; mb(); } @@ -419,13 +401,16 @@ __EXTERN_INLINE unsigned long tsunami_dense_mem(unsigned long addr) { - return TSUNAMI_PCI0_MEM; + return TSUNAMI_MEM(XHOSE); } #undef vucp #undef vusp #undef vuip #undef vulp + +#undef XADDR +#undef XHOSE #ifdef __WANT_IO_DEF diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/dma.h linux/include/asm-alpha/dma.h --- v2.1.120/linux/include/asm-alpha/dma.h Tue Aug 18 22:02:06 1998 +++ linux/include/asm-alpha/dma.h Sun Sep 6 10:34:33 1998 @@ -78,13 +78,18 @@ due to a hardware SIO (PCI<->ISA bus bridge) chip limitation, is 64MB. See for more info. */ +/* The maximum address that we can perform a DMA transfer to on RUFFIAN, + due to a hardware SIO (PCI<->ISA bus bridge) chip limitation, is 16MB. + See for more info. +*/ /* NOTE: we must define the maximum as something less than 64Mb, to prevent virt_to_bus() from returning an address in the first window, for a data area that goes beyond the 64Mb first DMA window. Sigh... We MUST coordinate the maximum with for consistency. For now, this limit is set to 48Mb... */ -#define ALPHA_XL_MAX_DMA_ADDRESS (0xfffffc0003000000UL) +#define ALPHA_XL_MAX_DMA_ADDRESS (IDENT_ADDR+0x3000000UL) +#define ALPHA_RUFFIAN_MAX_DMA_ADDRESS (IDENT_ADDR+0x1000000UL) #define ALPHA_MAX_DMA_ADDRESS (~0UL) #ifdef CONFIG_ALPHA_GENERIC @@ -92,6 +97,8 @@ #else # ifdef CONFIG_ALPHA_XL # define MAX_DMA_ADDRESS ALPHA_XL_MAX_DMA_ADDRESS +# elif defined(CONFIG_ALPHA_RUFFIAN) +# define MAX_DMA_ADDRESS ALPHA_RUFFIAN_MAX_DMA_ADDRESS # else # define MAX_DMA_ADDRESS ALPHA_MAX_DMA_ADDRESS # endif diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/floppy.h linux/include/asm-alpha/floppy.h --- v2.1.120/linux/include/asm-alpha/floppy.h Tue Aug 18 22:02:07 1998 +++ linux/include/asm-alpha/floppy.h Sun Sep 6 10:34:33 1998 @@ -52,8 +52,8 @@ /* * Most Alphas have no problems with floppy DMA crossing 64k borders, - * except for XL. It is also the only one with DMA limits, so we use - * that to test in the generic kernel. + * except for XL and RUFFIAN. They are also the only one with DMA + * limits, so we use that to test in the generic kernel. */ #define __CROSS_64KB(a,s) \ @@ -64,7 +64,7 @@ #ifdef CONFIG_ALPHA_GENERIC # define CROSS_64KB(a,s) (__CROSS_64KB(a,s) && ~alpha_mv.max_dma_address) #else -# ifdef CONFIG_ALPHA_XL +# if defined(CONFIG_ALPHA_XL) || defined(CONFIG_ALPHA_RUFFIAN) # define CROSS_64KB(a,s) __CROSS_64KB(a,s) # else # define CROSS_64KB(a,s) (0) diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/hardirq.h linux/include/asm-alpha/hardirq.h --- v2.1.120/linux/include/asm-alpha/hardirq.h Fri May 8 23:14:54 1998 +++ linux/include/asm-alpha/hardirq.h Sun Sep 6 10:34:33 1998 @@ -1,51 +1,58 @@ #ifndef _ALPHA_HARDIRQ_H #define _ALPHA_HARDIRQ_H +/* Initially just a straight copy of the i386 code. */ + #include extern unsigned int local_irq_count[NR_CPUS]; -#define in_interrupt() (local_irq_count[smp_processor_id()] + local_bh_count[smp_processor_id()] != 0) + +/* + * Are we in an interrupt context? Either doing bottom half + * or hardware interrupt processing? + */ + +#define in_interrupt() \ +({ \ + int __cpu = smp_processor_id(); \ + (local_irq_count[__cpu] + local_bh_count[__cpu]) != 0; \ +}) #ifndef __SMP__ #define hardirq_trylock(cpu) (local_irq_count[cpu] == 0) -#define hardirq_endlock(cpu) do { } while (0) +#define hardirq_endlock(cpu) ((void) 0) -#define hardirq_enter(cpu) (local_irq_count[cpu]++) -#define hardirq_exit(cpu) (local_irq_count[cpu]--) +#define hardirq_enter(cpu, irq) (local_irq_count[cpu]++) +#define hardirq_exit(cpu, irq) (local_irq_count[cpu]--) -#define synchronize_irq() do { } while (0) +#define synchronize_irq() barrier() #else -/* initially just a straight copy if the i386 code */ - #include #include -#include -#include -extern unsigned char global_irq_holder; +extern int global_irq_holder; extern spinlock_t global_irq_lock; extern atomic_t global_irq_count; static inline void release_irqlock(int cpu) { /* if we didn't own the irq lock, just ignore.. */ - if (global_irq_holder == (unsigned char) cpu) { + if (global_irq_holder == cpu) { global_irq_holder = NO_PROC_ID; spin_unlock(&global_irq_lock); } } -/* Ordering of the counter bumps is _deadly_ important. */ -static inline void hardirq_enter(int cpu) +static inline void hardirq_enter(int cpu, int irq) { ++local_irq_count[cpu]; atomic_inc(&global_irq_count); } -static inline void hardirq_exit(int cpu) +static inline void hardirq_exit(int cpu, int irq) { atomic_dec(&global_irq_count); --local_irq_count[cpu]; @@ -53,28 +60,10 @@ static inline int hardirq_trylock(int cpu) { - unsigned long flags; - int ret = 1; - - __save_and_cli(flags); - if ((atomic_add_return(1, &global_irq_count) != 1) || - (global_irq_lock.lock != 0)) { - atomic_dec(&global_irq_count); - __restore_flags(flags); - ret = 0; - } else { - ++local_irq_count[cpu]; - __sti(); - } - return ret; + return !atomic_read(&global_irq_count) && !global_irq_lock.lock; } -#define hardirq_endlock(cpu) \ - do { \ - __cli(); \ - hardirq_exit(cpu); \ - __sti(); \ - } while (0) +#define hardirq_endlock(cpu) ((void)0) extern void synchronize_irq(void); diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/hwrpb.h linux/include/asm-alpha/hwrpb.h --- v2.1.120/linux/include/asm-alpha/hwrpb.h Tue Aug 18 22:02:07 1998 +++ linux/include/asm-alpha/hwrpb.h Sun Sep 6 10:34:33 1998 @@ -93,7 +93,7 @@ unsigned long halt_pv; unsigned long halt_reason; unsigned long res; - char ipc_buffer[168]; + unsigned long ipc_buffer[21]; unsigned long palcode_avail[16]; unsigned long compatibility; }; diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/io.h linux/include/asm-alpha/io.h --- v2.1.120/linux/include/asm-alpha/io.h Tue Aug 18 22:02:07 1998 +++ linux/include/asm-alpha/io.h Sun Sep 6 10:34:33 1998 @@ -12,11 +12,10 @@ /* * Virtual -> physical identity mapping starts at this offset */ -/* XXX: Do we need to conditionalize on this? */ #ifdef USE_48_BIT_KSEG -#define IDENT_ADDR (0xffff800000000000UL) +#define IDENT_ADDR 0xffff800000000000 #else -#define IDENT_ADDR (0xfffffc0000000000UL) +#define IDENT_ADDR 0xfffffc0000000000 #endif #ifdef __KERNEL__ @@ -52,7 +51,10 @@ */ static inline unsigned long virt_to_phys(volatile void * address) { - return 0xffffffffUL & (unsigned long) address; + /* Conditionalize this on the CPU? This here is 40 bits, + whereas EV4 only supports 34. But KSEG is farther out + so it shouldn't _really_ matter. */ + return 0xffffffffffUL & (unsigned long) address; } static inline void * phys_to_virt(unsigned long address) @@ -322,6 +324,7 @@ #ifdef CONFIG_ALPHA_GENERIC # define RTC_PORT(x) ((x) + alpha_mv.rtc_port) # define RTC_ADDR(x) ((x) | alpha_mv.rtc_addr) +# define RTC_ALWAYS_BCD (alpha_mv.rtc_bcd) #else # ifdef CONFIG_ALPHA_JENSEN # define RTC_PORT(x) (0x170+(x)) @@ -330,9 +333,13 @@ # define RTC_PORT(x) (0x70 + (x)) # define RTC_ADDR(x) (0x80 | (x)) # endif +# ifdef CONFIG_ALPHA_RUFFIAN +# define RTC_ALWAYS_BCD 1 +# else +# define RTC_ALWAYS_BCD 0 +# endif #endif -#define RTC_ALWAYS_BCD 0 #endif /* __KERNEL__ */ diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/machvec.h linux/include/asm-alpha/machvec.h --- v2.1.120/linux/include/asm-alpha/machvec.h Tue Aug 18 22:02:07 1998 +++ linux/include/asm-alpha/machvec.h Sun Sep 6 10:34:33 1998 @@ -12,6 +12,7 @@ struct mm_struct; struct pt_regs; struct vm_area_struct; +struct linux_hose_info; struct alpha_machine_vector { @@ -21,10 +22,12 @@ unsigned long hae_cache; unsigned long *hae_register; + unsigned int nr_irqs : 16; + unsigned int rtc_port : 16; + unsigned int rtc_addr : 15; + unsigned int rtc_bcd : 1; + unsigned int max_asn : 16; unsigned long max_dma_address; - unsigned int nr_irqs; - unsigned int rtc_port, rtc_addr; - unsigned int max_asn; unsigned long mmu_context_mask; unsigned long irq_probe_mask; unsigned long iack_sc; @@ -52,13 +55,19 @@ unsigned long (*mv_dense_mem)(unsigned long); - int (*pci_read_config_byte)(u8, u8, u8, u8 *value); - int (*pci_read_config_word)(u8, u8, u8, u16 *value); - int (*pci_read_config_dword)(u8, u8, u8, u32 *value); - - int (*pci_write_config_byte)(u8, u8, u8, u8 value); - int (*pci_write_config_word)(u8, u8, u8, u16 value); - int (*pci_write_config_dword)(u8, u8, u8, u32 value); + int (*hose_read_config_byte)(u8, u8, u8, u8 *value, + struct linux_hose_info *); + int (*hose_read_config_word)(u8, u8, u8, u16 *value, + struct linux_hose_info *); + int (*hose_read_config_dword)(u8, u8, u8, u32 *value, + struct linux_hose_info *); + + int (*hose_write_config_byte)(u8, u8, u8, u8 value, + struct linux_hose_info *); + int (*hose_write_config_word)(u8, u8, u8, u16 value, + struct linux_hose_info *); + int (*hose_write_config_dword)(u8, u8, u8, u32 value, + struct linux_hose_info *); void (*mv_get_mmu_context)(struct task_struct *); void (*mv_flush_tlb_current)(struct mm_struct *); diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/mmu_context.h linux/include/asm-alpha/mmu_context.h --- v2.1.120/linux/include/asm-alpha/mmu_context.h Tue Aug 18 22:02:07 1998 +++ linux/include/asm-alpha/mmu_context.h Sun Sep 6 10:34:33 1998 @@ -35,14 +35,17 @@ */ #define EV4_MAX_ASN 63 #define EV5_MAX_ASN 127 +#define EV6_MAX_ASN 255 #ifdef CONFIG_ALPHA_GENERIC # define MAX_ASN (alpha_mv.max_asn) #else # ifdef CONFIG_ALPHA_EV4 # define MAX_ASN EV4_MAX_ASN -# else +# elif defined(CONFIG_ALPHA_EV5) # define MAX_ASN EV5_MAX_ASN +# else +# define MAX_ASN EV6_MAX_ASN # endif #endif @@ -155,7 +158,8 @@ a0 = MASK_CONTEXT(tss); __asm__ __volatile__( - "call_pal %2" : "=r"(v0), "=r"(a0) + "call_pal %2 #__reload_tss" + : "=r"(v0), "=r"(a0) : "i"(PAL_swpctx), "r"(a0) : "$1", "$16", "$22", "$23", "$24", "$25"); diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/page.h linux/include/asm-alpha/page.h --- v2.1.120/linux/include/asm-alpha/page.h Sun Jul 26 11:57:18 1998 +++ linux/include/asm-alpha/page.h Sun Sep 6 10:34:33 1998 @@ -8,6 +8,8 @@ #ifdef __KERNEL__ +#ifndef __ASSEMBLY__ + #define STRICT_MM_TYPECHECKS /* @@ -102,12 +104,18 @@ #define __pgd(x) (x) #define __pgprot(x) (x) -#endif +#endif /* STRICT_MM_TYPECHECKS */ +#endif /* !ASSEMBLY */ /* to align the pointer to the (next) page boundary */ -#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) +#define PAGE_ALIGN(addr) (((addr)+PAGE_SIZE-1)&PAGE_MASK) + +#ifdef USE_48_BIT_KSEG +#define PAGE_OFFSET 0xffff800000000000 +#else +#define PAGE_OFFSET 0xfffffc0000000000 +#endif -#define PAGE_OFFSET 0xFFFFFC0000000000UL #define __pa(x) ((unsigned long) (x) - PAGE_OFFSET) #define __va(x) ((void *)((unsigned long) (x) + PAGE_OFFSET)) #define MAP_NR(addr) (__pa(addr) >> PAGE_SHIFT) diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/pgtable.h linux/include/asm-alpha/pgtable.h --- v2.1.120/linux/include/asm-alpha/pgtable.h Tue Aug 18 22:02:07 1998 +++ linux/include/asm-alpha/pgtable.h Sun Sep 6 10:34:33 1998 @@ -311,7 +311,7 @@ #define BAD_PAGETABLE __bad_pagetable() #define BAD_PAGE __bad_page() -#define ZERO_PAGE 0xfffffc000030A000 +#define ZERO_PAGE (PAGE_OFFSET+0x30A000) /* number of bits that fit into a memory pointer */ #define BITS_PER_PTR (8*sizeof(unsigned long)) @@ -327,6 +327,24 @@ ((unsigned long)(address)>>(PAGE_SHIFT-SIZEOF_PTR_LOG2)&PTR_MASK&~PAGE_MASK) /* + * On certain platforms whose physical address space can overlap KSEG, + * namely EV6 and above, we must re-twiddle the physaddr to restore the + * correct high-order bits. + */ + +#if defined(CONFIG_ALPHA_GENERIC) && defined(USE_48_BIT_KSEG) +#error "EV6-only feature in a generic kernel" +#endif +#if defined(CONFIG_ALPHA_GENERIC) || \ + (defined(CONFIG_ALPHA_EV6) && !defined(USE_48_BIT_KSEG)) +#define PHYS_TWIDDLE(phys) \ + ((((phys) & 0xc0000000000UL) == 0x40000000000UL) \ + ? ((phys) ^= 0xc0000000000UL) : (phys)) +#else +#define PHYS_TWIDDLE(phys) (phys) +#endif + +/* * Conversion functions: convert a page and protection to a page entry, * and a page entry and page directory to the page they refer to. */ @@ -334,7 +352,7 @@ { pte_t pte; pte_val(pte) = ((page-PAGE_OFFSET) << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; } extern inline pte_t mk_pte_phys(unsigned long physpage, pgprot_t pgprot) -{ pte_t pte; pte_val(pte) = (physpage << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; } +{ pte_t pte; pte_val(pte) = (PHYS_TWIDDLE(physpage) << (32-PAGE_SHIFT)) | pgprot_val(pgprot); return pte; } extern inline pte_t pte_modify(pte_t pte, pgprot_t newprot) { pte_val(pte) = (pte_val(pte) & _PAGE_CHG_MASK) | pgprot_val(newprot); return pte; } diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/processor.h linux/include/asm-alpha/processor.h --- v2.1.120/linux/include/asm-alpha/processor.h Tue Aug 18 22:02:07 1998 +++ linux/include/asm-alpha/processor.h Sun Sep 6 10:34:33 1998 @@ -62,7 +62,7 @@ long debugreg[8]; }; -#define INIT_MMAP { &init_mm, 0xfffffc0000000000, 0xfffffc0010000000, \ +#define INIT_MMAP { &init_mm, PAGE_OFFSET, PAGE_OFFSET+0x10000000, \ PAGE_SHARED, VM_READ | VM_WRITE | VM_EXEC, NULL, &init_mm.mmap } #define INIT_TSS { \ diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/smp.h linux/include/asm-alpha/smp.h --- v2.1.120/linux/include/asm-alpha/smp.h Thu Aug 6 14:06:33 1998 +++ linux/include/asm-alpha/smp.h Sun Sep 6 10:34:33 1998 @@ -4,6 +4,7 @@ #ifdef __SMP__ #include +#include struct cpuinfo_alpha { unsigned long loops_per_sec; @@ -15,38 +16,28 @@ extern struct cpuinfo_alpha cpu_data[NR_CPUS]; -typedef volatile struct { - unsigned int kernel_flag; /* 4 bytes, please */ - unsigned int akp; /* 4 bytes, please */ - unsigned long pc; - unsigned int cpu; -} klock_info_t; - -extern klock_info_t klock_info; - -#define KLOCK_HELD 0xff -#define KLOCK_CLEAR 0x00 - -extern int task_lock_depth; - #define PROC_CHANGE_PENALTY 20 extern __volatile__ int cpu_number_map[NR_CPUS]; /* HACK: Cabrio WHAMI return value is bogus if more than 8 bits used.. :-( */ -#define hard_smp_processor_id() \ -({ \ - register unsigned char __r0 __asm__("$0"); \ - __asm__ __volatile__( \ - "call_pal %0" \ - : /* no output (bound to the template) */ \ - :"i" (PAL_whami) \ - :"$0", "$1", "$22", "$23", "$24", "$25", "memory"); \ - __r0; \ -}) -#define smp_processor_id() hard_smp_processor_id() +static __inline__ unsigned char hard_smp_processor_id(void) +{ + register unsigned char __r0 __asm__("$0"); + __asm__ __volatile__( + "call_pal %1 #whami" + : "=r"(__r0) + :"i" (PAL_whami) + : "$1", "$22", "$23", "$24", "$25"); + return __r0; +} + +#define smp_processor_id() (current->processor) #define cpu_logical_map(cpu) (cpu) + +/* For the benefit of panic. */ +void smp_message_pass(int target, int msg, unsigned long data, int wait); #endif /* __SMP__ */ diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/smplock.h linux/include/asm-alpha/smplock.h --- v2.1.120/linux/include/asm-alpha/smplock.h Mon Aug 3 17:48:27 1998 +++ linux/include/asm-alpha/smplock.h Sun Sep 6 10:34:33 1998 @@ -3,6 +3,8 @@ * * Default SMP lock implementation */ + +#include #include #include @@ -11,23 +13,22 @@ /* * Release global kernel lock and global interrupt lock */ -#define release_kernel_lock(task, cpu) \ -do { \ - if (task->lock_depth >= 0) \ - spin_unlock(&kernel_flag); \ - release_irqlock(cpu); \ - __sti(); \ -} while (0) +static __inline__ void release_kernel_lock(struct task_struct *task, int cpu) +{ + if (task->lock_depth >= 0) + spin_unlock(&kernel_flag); + release_irqlock(cpu); + __sti(); +} /* * Re-acquire the kernel lock */ -#define reacquire_kernel_lock(task) \ -do { \ - if (task->lock_depth >= 0) \ - spin_lock(&kernel_flag); \ -} while (0) - +static __inline__ void reacquire_kernel_lock(struct task_struct *task) +{ + if (task->lock_depth >= 0) + spin_lock(&kernel_flag); +} /* * Getting the big kernel lock. @@ -36,13 +37,13 @@ * so we only need to worry about other * CPU's. */ -extern __inline__ void lock_kernel(void) +static __inline__ void lock_kernel(void) { if (!++current->lock_depth) spin_lock(&kernel_flag); } -extern __inline__ void unlock_kernel(void) +static __inline__ void unlock_kernel(void) { if (--current->lock_depth < 0) spin_unlock(&kernel_flag); diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/softirq.h linux/include/asm-alpha/softirq.h --- v2.1.120/linux/include/asm-alpha/softirq.h Wed Apr 1 20:11:53 1998 +++ linux/include/asm-alpha/softirq.h Sun Sep 6 10:34:33 1998 @@ -1,6 +1,7 @@ #ifndef _ALPHA_SOFTIRQ_H #define _ALPHA_SOFTIRQ_H +#include #include #include diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/spinlock.h linux/include/asm-alpha/spinlock.h --- v2.1.120/linux/include/asm-alpha/spinlock.h Wed Apr 1 20:11:53 1998 +++ linux/include/asm-alpha/spinlock.h Sun Sep 6 10:34:33 1998 @@ -1,22 +1,24 @@ #ifndef _ALPHA_SPINLOCK_H #define _ALPHA_SPINLOCK_H +#include + #ifndef __SMP__ /* gcc 2.7.2 can crash initializing an empty structure. */ typedef struct { int dummy; } spinlock_t; #define SPIN_LOCK_UNLOCKED { 0 } -#define spin_lock_init(lock) do { } while(0) -#define spin_lock(lock) do { } while(0) -#define spin_trylock(lock) do { } while(0) -#define spin_unlock_wait(lock) do { } while(0) -#define spin_unlock(lock) do { } while(0) -#define spin_lock_irq(lock) setipl(7) -#define spin_unlock_irq(lock) setipl(0) +#define spin_lock_init(lock) ((void) 0) +#define spin_lock(lock) ((void) 0) +#define spin_trylock(lock) ((void) 0) +#define spin_unlock_wait(lock) ((void) 0) +#define spin_unlock(lock) ((void) 0) +#define spin_lock_irq(lock) cli() +#define spin_unlock_irq(lock) sti() -#define spin_lock_irqsave(lock, flags) do { (flags) = swpipl(7); } while (0) -#define spin_unlock_irqrestore(lock, flags) setipl(flags) +#define spin_lock_irqsave(lock, flags) save_and_cli(flags) +#define spin_unlock_irqrestore(lock, flags) restore_flags(flags) /* * Read-write spinlocks, allowing multiple readers @@ -31,26 +33,30 @@ typedef struct { int dummy; } rwlock_t; #define RW_LOCK_UNLOCKED { 0 } -#define read_lock(lock) do { } while(0) -#define read_unlock(lock) do { } while(0) -#define write_lock(lock) do { } while(0) -#define write_unlock(lock) do { } while(0) -#define read_lock_irq(lock) cli() -#define read_unlock_irq(lock) sti() -#define write_lock_irq(lock) cli() -#define write_unlock_irq(lock) sti() - -#define read_lock_irqsave(lock, flags) do { (flags) = swpipl(7); } while (0) -#define read_unlock_irqrestore(lock, flags) setipl(flags) -#define write_lock_irqsave(lock, flags) do { (flags) = swpipl(7); } while (0) -#define write_unlock_irqrestore(lock, flags) setipl(flags) +#define read_lock(lock) ((void) 0) +#define read_unlock(lock) ((void) 0) +#define write_lock(lock) ((void) 0) +#define write_unlock(lock) ((void) 0) +#define read_lock_irq(lock) cli() +#define read_unlock_irq(lock) sti() +#define write_lock_irq(lock) cli() +#define write_unlock_irq(lock) sti() + +#define read_lock_irqsave(lock, flags) save_and_cli(flags) +#define read_unlock_irqrestore(lock, flags) restore_flags(flags) +#define write_lock_irqsave(lock, flags) save_and_cli(flags) +#define write_unlock_irqrestore(lock, flags) restore_flags(flags) #else /* __SMP__ */ #include #include -/* Simple spin lock operations. There are two variants, one clears IRQ's +#define DEBUG_SPINLOCK 1 +#define DEBUG_RWLOCK 1 + +/* + * Simple spin lock operations. There are two variants, one clears IRQ's * on the local processor, one does not. * * We make no fairness assumptions. They have a cost. @@ -58,34 +64,21 @@ typedef struct { volatile unsigned long lock; - unsigned long previous; - unsigned long task; + void *previous; + struct task_struct * task; } spinlock_t; -#define SPIN_LOCK_UNLOCKED { 0, 0 } +#define SPIN_LOCK_UNLOCKED { 0, 0, 0 } #define spin_lock_init(x) \ - do { (x)->lock = 0; (x)->previous = 0; } while(0) + ((x)->lock = 0, (x)->previous = 0, (x)->task = 0) #define spin_unlock_wait(x) \ - do { barrier(); } while(((volatile spinlock_t *)x)->lock) + ({ do { barrier(); } while(((volatile spinlock_t *)x)->lock); }) typedef struct { unsigned long a[100]; } __dummy_lock_t; #define __dummy_lock(lock) (*(__dummy_lock_t *)(lock)) -static inline void spin_unlock(spinlock_t * lock) -{ - __asm__ __volatile__( - "mb; stq $31,%0" - :"=m" (__dummy_lock(lock))); -} - -#if 1 -#define DEBUG_SPINLOCK -#else -#undef DEBUG_SPINLOCK -#endif - -#ifdef DEBUG_SPINLOCK +#if DEBUG_SPINLOCK extern void spin_lock(spinlock_t * lock); #else static inline void spin_lock(spinlock_t * lock) @@ -101,94 +94,79 @@ " or %0,1,%0\n" " stq_c %0,%1\n" " beq %0,2f\n" - "4: mb\n" + " mb\n" ".section .text2,\"ax\"\n" "2: ldq %0,%1\n" " blbs %0,2b\n" " br 1b\n" ".previous" - : "=r" (tmp), - "=m" (__dummy_lock(lock))); + : "=r" (tmp), "=m" (__dummy_lock(lock)) + : "m"(__dummy_lock(lock))); } #endif /* DEBUG_SPINLOCK */ +static inline void spin_unlock(spinlock_t * lock) +{ + mb(); + lock->lock = 0; +} + #define spin_trylock(lock) (!test_and_set_bit(0,(lock))) #define spin_lock_irq(lock) \ - do { __cli(); spin_lock(lock); } while (0) - + (__cli(), spin_lock(lock)) #define spin_unlock_irq(lock) \ - do { spin_unlock(lock); __sti(); } while (0) - + (spin_unlock(lock), __sti()) #define spin_lock_irqsave(lock, flags) \ - do { __save_and_cli(flags); spin_lock(lock); } while (0) - + (__save_and_cli(flags), spin_lock(lock)) #define spin_unlock_irqrestore(lock, flags) \ - do { spin_unlock(lock); __restore_flags(flags); } while (0) + (spin_unlock(lock), __restore_flags(flags)) /***********************************************************/ -#if 1 -#define DEBUG_RWLOCK -#else -#undef DEBUG_RWLOCK -#endif - typedef struct { volatile int write_lock:1, read_counter:31; } rwlock_t; #define RW_LOCK_UNLOCKED { 0, 0 } -#ifdef DEBUG_RWLOCK +#if DEBUG_RWLOCK extern void write_lock(rwlock_t * lock); +extern void read_lock(rwlock_t * lock); #else static inline void write_lock(rwlock_t * lock) { - long regx, regy; + long regx; __asm__ __volatile__( - "1: ldl_l %1,%0;" - " blbs %1,6f;" - " or %1,1,%2;" - " stl_c %2,%0;" - " beq %2,6f;" - " blt %1,8f;" - "4: mb\n" + "1: ldl_l %1,%0\n" + " bne %1,6f\n" + " or $31,1,%1\n" + " stl_c %1,%0\n" + " beq %1,6f\n" + " mb\n" ".section .text2,\"ax\"\n" - "6: ldl %1,%0;" - " blbs %1,6b;" - " br 1b;" - "8: ldl %1,%0;" - " blt %1,8b;" - "9: br 4b\n" + "6: ldl %1,%0\n" + " bne %1,6b\n" + " br 1b\n" ".previous" - : "=m" (__dummy_lock(lock)), "=&r" (regx), "=&r" (regy) + : "=m" (__dummy_lock(lock)), "=&r" (regx) : "0" (__dummy_lock(lock)) ); } -#endif /* DEBUG_RWLOCK */ - -static inline void write_unlock(rwlock_t * lock) -{ - __asm__ __volatile__("mb; stl $31,%0" : "=m" (__dummy_lock(lock))); -} -#ifdef DEBUG_RWLOCK -extern void _read_lock(rwlock_t * lock); -#else -static inline void _read_lock(rwlock_t * lock) +static inline void read_lock(rwlock_t * lock) { long regx; __asm__ __volatile__( - "1: ldl_l %1,%0;" - " blbs %1,6f;" - " subl %1,2,%1;" - " stl_c %1,%0;" - " beq %1,6f;" + "1: ldl_l %1,%0\n" + " blbs %1,6f\n" + " subl %1,2,%1\n" + " stl_c %1,%0\n" + " beq %1,6f\n" "4: mb\n" ".section .text2,\"ax\"\n" - "6: ldl %1,%0;" - " blbs %1,6b;" + "6: ldl %1,%0\n" + " blbs %1,6b\n" " br 1b\n" ".previous" : "=m" (__dummy_lock(lock)), "=&r" (regx) @@ -197,21 +175,20 @@ } #endif /* DEBUG_RWLOCK */ -#define read_lock(lock) \ -do { unsigned long flags; \ - __save_and_cli(flags); \ - _read_lock(lock); \ - __restore_flags(flags); \ -} while(0) +static inline void write_unlock(rwlock_t * lock) +{ + mb(); + *(volatile int *)lock = 0; +} -static inline void _read_unlock(rwlock_t * lock) +static inline void read_unlock(rwlock_t * lock) { long regx; __asm__ __volatile__( - "1: ldl_l %1,%0;" - " addl %1,2,%1;" - " stl_c %1,%0;" - " beq %1,6f;" + "1: ldl_l %1,%0\n" + " addl %1,2,%1\n" + " stl_c %1,%0\n" + " beq %1,6f\n" ".section .text2,\"ax\"\n" "6: br 1b\n" ".previous" @@ -219,26 +196,19 @@ : "0" (__dummy_lock(lock))); } -#define read_unlock(lock) \ -do { unsigned long flags; \ - __save_and_cli(flags); \ - _read_unlock(lock); \ - __restore_flags(flags); \ -} while(0) - -#define read_lock_irq(lock) do { __cli(); _read_lock(lock); } while (0) -#define read_unlock_irq(lock) do { _read_unlock(lock); __sti(); } while (0) -#define write_lock_irq(lock) do { __cli(); write_lock(lock); } while (0) -#define write_unlock_irq(lock) do { write_unlock(lock); __sti(); } while (0) +#define read_lock_irq(lock) (__cli(), read_lock(lock)) +#define read_unlock_irq(lock) (read_unlock(lock), __sti()) +#define write_lock_irq(lock) (__cli(), write_lock(lock)) +#define write_unlock_irq(lock) (write_unlock(lock), __sti()) #define read_lock_irqsave(lock, flags) \ - do { __save_and_cli(flags); _read_lock(lock); } while (0) + (__save_and_cli(flags), read_lock(lock)) #define read_unlock_irqrestore(lock, flags) \ - do { _read_unlock(lock); __restore_flags(flags); } while (0) + (read_unlock(lock), __restore_flags(flags)) #define write_lock_irqsave(lock, flags) \ - do { __save_and_cli(flags); write_lock(lock); } while (0) + (__save_and_cli(flags), write_lock(lock)) #define write_unlock_irqrestore(lock, flags) \ - do { write_unlock(lock); __restore_flags(flags); } while (0) + (write_unlock(lock), __restore_flags(flags)) #endif /* SMP */ #endif /* _ALPHA_SPINLOCK_H */ diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/system.h linux/include/asm-alpha/system.h --- v2.1.120/linux/include/asm-alpha/system.h Tue Aug 18 22:02:07 1998 +++ linux/include/asm-alpha/system.h Sun Sep 6 10:34:33 1998 @@ -1,7 +1,8 @@ #ifndef __ALPHA_SYSTEM_H #define __ALPHA_SYSTEM_H -#include /* for backwards compatibility... */ +#include +#include /* * System defines.. Note that this is included both from .c and .S @@ -13,23 +14,21 @@ * the initial process structure. Also, the console eats 3 MB for * the initial bootloader (one of which we can reclaim later). * With a few other pages for various reasons, we'll use an initial - * load address of 0xfffffc0000310000UL + * load address of PAGE_OFFSET+0x310000UL */ #define BOOT_PCB 0x20000000 #define BOOT_ADDR 0x20000000 /* Remove when official MILO sources have ELF support: */ #define BOOT_SIZE (16*1024) -#define KERNEL_START 0xfffffc0000300000 -#define SWAPPER_PGD 0xfffffc0000300000 -#define INIT_STACK 0xfffffc0000302000 -#define EMPTY_PGT 0xfffffc0000304000 -#define EMPTY_PGE 0xfffffc0000308000 -#define ZERO_PGE 0xfffffc000030A000 +#define KERNEL_START (PAGE_OFFSET+0x300000) +#define SWAPPER_PGD (PAGE_OFFSET+0x300000) +#define INIT_STACK (PAGE_OFFSET+0x302000) +#define EMPTY_PGT (PAGE_OFFSET+0x304000) +#define EMPTY_PGE (PAGE_OFFSET+0x308000) +#define ZERO_PGE (PAGE_OFFSET+0x30A000) -#define START_ADDR 0xfffffc0000310000 -/* Remove when official MILO sources have ELF support: */ -#define START_SIZE (2*1024*1024) +#define START_ADDR (PAGE_OFFSET+0x310000) #ifndef __ASSEMBLY__ @@ -96,11 +95,12 @@ extern unsigned long whami(void); extern void wripir(unsigned long); -#define halt() __asm__ __volatile__ ("call_pal %0" : : "i" (PAL_halt) : "memory") +#define halt() \ +__asm__ __volatile__ ("call_pal %0 #halt" : : "i" (PAL_halt) : "memory") -#define switch_to(prev,next) do { \ - current = next; \ - alpha_switch_to((unsigned long) ¤t->tss - IDENT_ADDR); \ +#define switch_to(prev,next) do { \ + current = next; \ + alpha_switch_to((unsigned long) ¤t->tss - IDENT_ADDR); \ } while (0) extern void alpha_switch_to(unsigned long pctxp); @@ -112,127 +112,101 @@ __asm__ __volatile__("wmb": : :"memory") #define imb() \ -__asm__ __volatile__ ("call_pal %0" : : "i" (PAL_imb) : "memory") +__asm__ __volatile__ ("call_pal %0 #imb" : : "i" (PAL_imb) : "memory") #define draina() \ -__asm__ __volatile__ ("call_pal %0" : : "i" (PAL_draina) : "memory") +__asm__ __volatile__ ("call_pal %0 #draina" : : "i" (PAL_draina) : "memory") -#define call_pal1(palno,arg) \ -({ \ - register unsigned long __r0 __asm__("$0"); \ - register unsigned long __r16 __asm__("$16"); __r16 = arg; \ - __asm__ __volatile__( \ - "call_pal %3" \ - :"=r" (__r0),"=r" (__r16) \ - :"1" (__r16),"i" (palno) \ - :"$1", "$22", "$23", "$24", "$25", "memory"); \ - __r0; \ +#define call_pal1(palno,arg) \ +({ \ + register unsigned long __r0 __asm__("$0"); \ + register unsigned long __r16 __asm__("$16"); __r16 = arg; \ + __asm__ __volatile__( \ + "call_pal %3 #call_pal1" \ + :"=r" (__r0),"=r" (__r16) \ + :"1" (__r16),"i" (palno) \ + :"$1", "$22", "$23", "$24", "$25", "memory"); \ + __r0; \ }) -#define getipl() \ -({ \ - register unsigned long r0 __asm__("$0"); \ - __asm__ __volatile__( \ - "call_pal %1" \ - :"=r" (r0) \ - :"i" (PAL_rdps) \ - :"$1", "$16", "$22", "$23", "$24", "$25", "memory"); \ - r0; \ +#define getipl() \ +({ \ + register unsigned long r0 __asm__("$0"); \ + __asm__ __volatile__( \ + "call_pal %1 #getipl" \ + :"=r" (r0) \ + :"i" (PAL_rdps) \ + :"$1", "$16", "$22", "$23", "$24", "$25", "memory"); \ + r0; \ }) -#ifdef THE_OLD_VERSION -#define setipl(ipl) \ -do { \ - register unsigned long __r16 __asm__("$16") = (ipl); \ - __asm__ __volatile__( \ - "call_pal %2" \ - :"=r" (__r16) \ - :"0" (__r16),"i" (PAL_swpipl) \ - :"$0", "$1", "$22", "$23", "$24", "$25", "memory"); \ -} while (0) - -#define swpipl(ipl) \ -({ \ - register unsigned long __r0 __asm__("$0"); \ - register unsigned long __r16 __asm__("$16") = (ipl); \ - __asm__ __volatile__( \ - "call_pal %3" \ - :"=r" (__r0),"=r" (__r16) \ - :"1" (__r16),"i" (PAL_swpipl) \ - :"$1", "$22", "$23", "$24", "$25", "memory"); \ - __r0; \ +#define setipl(ipl) \ +({ \ + register unsigned long __r16 __asm__("$16"); __r16 = (ipl); \ + __asm__ __volatile__( \ + "call_pal %2 #setipl" \ + :"=r" (__r16) \ + :"0" (__r16),"i" (PAL_swpipl) \ + :"$0", "$1", "$22", "$23", "$24", "$25", "memory"); \ }) -#else -#define setipl(ipl) \ -do { \ - __asm__ __volatile__( \ - "mov %0,$16; call_pal %1" \ - : /* no output */ \ - :"i,r" (ipl), "i,i" (PAL_swpipl) \ - :"$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory"); \ -} while (0) -#define swpipl(ipl) \ -({ \ - register unsigned long __r0 __asm__("$0"); \ - __asm__ __volatile__( \ - "mov %0,$16; call_pal %1" \ - : /* no output (bound to the template) */ \ - : "i,r" (ipl), "i,i" (PAL_swpipl) \ - : "$0", "$1", "$16", "$22", "$23", "$24", "$25", "memory"); \ - __r0; \ +#define swpipl(ipl) \ +({ \ + register unsigned long __r0 __asm__("$0"); \ + register unsigned long __r16 __asm__("$16") = (ipl); \ + __asm__ __volatile__( \ + "call_pal %3 #swpipl" \ + :"=r" (__r0),"=r" (__r16) \ + :"1" (__r16),"i" (PAL_swpipl) \ + :"$1", "$22", "$23", "$24", "$25", "memory"); \ + __r0; \ }) -#endif #define __cli() setipl(7) #define __sti() setipl(0) -#define __save_flags(flags) do { (flags) = getipl(); } while (0) -#define __save_and_cli(flags) do { (flags) = swpipl(7); } while (0) +#define __save_flags(flags) ((flags) = getipl()) +#define __save_and_cli(flags) ((flags) = swpipl(7)) #define __restore_flags(flags) setipl(flags) #ifdef __SMP__ -extern unsigned char global_irq_holder; - -#define save_flags(x) \ -do { \ - (x) = ((global_irq_holder == (unsigned char) smp_processor_id()) \ - ? 1 \ - : ((getipl() & 7) ? 2 : 0)); \ -} while (0) +extern int global_irq_holder; -#define save_and_cli(flags) do { save_flags(flags); cli(); } while(0) +#define save_and_cli(flags) (save_flags(flags), cli()) extern void __global_cli(void); extern void __global_sti(void); +extern unsigned long __global_save_flags(void); extern void __global_restore_flags(unsigned long flags); #define cli() __global_cli() #define sti() __global_sti() +#define save_flags(flags) ((flags) = __global_save_flags()) #define restore_flags(flags) __global_restore_flags(flags) #else /* __SMP__ */ -#define cli() setipl(7) -#define sti() setipl(0) -#define save_flags(flags) do { (flags) = getipl(); } while (0) -#define save_and_cli(flags) do { (flags) = swpipl(7); } while (0) -#define restore_flags(flags) setipl(flags) +#define cli() __cli() +#define sti() __sti() +#define save_flags(flags) __save_flags(flags) +#define save_and_cli(flags) __save_and_cli(flags) +#define restore_flags(flags) __restore_flags(flags) #endif /* __SMP__ */ /* * TB routines.. */ -#define __tbi(nr,arg,arg1...) do { \ - register unsigned long __r16 __asm__("$16") = (nr); \ - register unsigned long __r17 __asm__("$17"); arg; \ - __asm__ __volatile__( \ - "call_pal %3" \ - :"=r" (__r16),"=r" (__r17) \ - :"0" (__r16),"i" (PAL_tbi) ,##arg1 \ - :"$0", "$1", "$22", "$23", "$24", "$25"); \ -} while (0) +#define __tbi(nr,arg,arg1...) \ +({ \ + register unsigned long __r16 __asm__("$16") = (nr); \ + register unsigned long __r17 __asm__("$17"); arg; \ + __asm__ __volatile__( \ + "call_pal %3 #__tbi" \ + :"=r" (__r16),"=r" (__r17) \ + :"0" (__r16),"i" (PAL_tbi) ,##arg1 \ + :"$0", "$1", "$22", "$23", "$24", "$25"); \ +}) #define tbi(x,y) __tbi(x,__r17=(y),"1" (__r17)) #define tbisi(x) __tbi(1,__r17=(x),"1" (__r17)) @@ -244,10 +218,10 @@ /* * Give prototypes to shut up gcc. */ -extern __inline__ unsigned long xchg_u32 (volatile int * m, unsigned long val); -extern __inline__ unsigned long xchg_u64 (volatile long * m, unsigned long val); +extern __inline__ unsigned long xchg_u32(volatile int *m, unsigned long val); +extern __inline__ unsigned long xchg_u64(volatile long *m, unsigned long val); -extern __inline__ unsigned long xchg_u32(volatile int * m, unsigned long val) +extern __inline__ unsigned long xchg_u32(volatile int *m, unsigned long val) { unsigned long dummy; @@ -283,9 +257,6 @@ return val; } -#define xchg(ptr,x) ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) -#define tas(ptr) (xchg((ptr),1)) - /* * This function doesn't exist, so you'll get a linker error * if something tries to do an invalid xchg(). @@ -296,7 +267,8 @@ */ extern void __xchg_called_with_bad_pointer(void); -static __inline__ unsigned long __xchg(unsigned long x, volatile void * ptr, int size) +static __inline__ unsigned long +__xchg(unsigned long x, volatile void * ptr, int size) { switch (size) { case 4: @@ -307,6 +279,10 @@ __xchg_called_with_bad_pointer(); return x; } + +#define xchg(ptr,x) \ + ((__typeof__(*(ptr)))__xchg((unsigned long)(x),(ptr),sizeof(*(ptr)))) +#define tas(ptr) (xchg((ptr),1)) #endif /* __ASSEMBLY__ */ diff -u --recursive --new-file v2.1.120/linux/include/asm-alpha/unistd.h linux/include/asm-alpha/unistd.h --- v2.1.120/linux/include/asm-alpha/unistd.h Tue Jun 23 10:01:25 1998 +++ linux/include/asm-alpha/unistd.h Sun Sep 6 13:06:04 1998 @@ -23,7 +23,7 @@ #define __NR_lseek 19 #define __NR_getxpid 20 #define __NR_osf_mount 21 -#define __NR_osf_umount 22 +#define __NR_umount 22 #define __NR_setuid 23 #define __NR_getxuid 24 #define __NR_exec_with_loader 25 /* not implemented */ @@ -258,7 +258,7 @@ #define __NR_sysinfo 318 #define __NR__sysctl 319 #define __NR_idle 320 -#define __NR_umount 321 +#define __NR_oldumount 321 #define __NR_swapon 322 #define __NR_times 323 #define __NR_personality 324 @@ -506,12 +506,6 @@ static inline void idle(void) { sys_idle(); -} - -extern int sys_setup(int); -static inline int setup(int magic) -{ - return sys_setup(magic); } extern int sys_open(const char *, int, int); diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-arc/irq.h linux/include/asm-arm/arch-arc/irq.h --- v2.1.120/linux/include/asm-arm/arch-arc/irq.h Tue Apr 14 14:29:25 1998 +++ linux/include/asm-arm/arch-arc/irq.h Sun Sep 6 10:45:30 1998 @@ -8,123 +8,138 @@ * 10-10-1996 RMK Brought up to date with arch-sa110eval * 22-10-1996 RMK Changed interrupt numbers & uses new inb/outb macros * 11-01-1998 RMK Added mask_and_ack_irq + * 22-08-1998 RMK Restructured IRQ routines */ -#define BUILD_IRQ(s,n,m) \ - void IRQ##n##_interrupt(void); \ - void fast_IRQ##n##_interrupt(void); \ - void bad_IRQ##n##_interrupt(void); \ - void probe_IRQ##n##_interrupt(void); +static void arc_mask_irq_ack_a(unsigned int irq) +{ + unsigned int temp; -/* - * The timer is a special interrupt - */ -#define IRQ5_interrupt timer_IRQ_interrupt + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" bic %0, %0, %1\n" +" strb %0, [%2]\n" +" strb %1, [%3]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOC_IRQMASKA)), + "r" (ioaddr(IOC_IRQCLRA))); +} -#define IRQ_INTERRUPT(n) IRQ##n##_interrupt -#define FAST_INTERRUPT(n) fast_IRQ##n##_interrupt -#define BAD_INTERRUPT(n) bad_IRQ##n##_interrupt -#define PROBE_INTERRUPT(n) probe_IRQ##n##_interrupt - -#define X(x) (x)|0x01, (x)|0x02, (x)|0x04, (x)|0x08, (x)|0x10, (x)|0x20, (x)|0x40, (x)|0x80 -#define Z(x) (x), (x), (x), (x), (x), (x), (x), (x) - -static __inline__ void mask_and_ack_irq(unsigned int irq) -{ - static const int addrmasks[] = { - X((IOC_IRQMASKA - IOC_BASE)<<18 | (1 << 15)), - X((IOC_IRQMASKB - IOC_BASE)<<18), - Z(0), - Z(0), - Z(0), - Z(0), - Z(0), - Z(0), - X((IOC_FIQMASK - IOC_BASE)<<18), - Z(0), - Z(0), - Z(0), - Z(0), - Z(0), - Z(0), - Z(0) - }; - unsigned int temp1, temp2; - - __asm__ __volatile__( -" ldr %1, [%5, %3, lsl #2]\n" -" teq %1, #0\n" -" beq 2f\n" -" ldrb %0, [%2, %1, lsr #16]\n" +static void arc_mask_irq_a(unsigned int irq) +{ + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" " bic %0, %0, %1\n" -" strb %0, [%2, %1, lsr #16]\n" -" tst %1, #0x8000\n" /* do we need an IRQ clear? */ -" strneb %1, [%2, %4]\n" -"2:" - : "=&r" (temp1), "=&r" (temp2) - : "r" (ioaddr(IOC_BASE)), "r" (irq), - "I" ((IOC_IRQCLRA - IOC_BASE) << 2), "r" (addrmasks)); -} - -#undef X -#undef Z - -static __inline__ void mask_irq(unsigned int irq) -{ - extern void ecard_disableirq (unsigned int); - extern void ecard_disablefiq (unsigned int); - unsigned char mask = 1 << (irq & 7); - - switch (irq >> 3) { - case 0: - outb(inb(IOC_IRQMASKA) & ~mask, IOC_IRQMASKA); - break; - case 1: - outb(inb(IOC_IRQMASKB) & ~mask, IOC_IRQMASKB); - break; - case 4: - ecard_disableirq (irq & 7); - break; - case 8: - outb(inb(IOC_FIQMASK) & ~mask, IOC_FIQMASK); - break; - case 12: - ecard_disablefiq (irq & 7); - } +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOC_IRQMASKA))); } -static __inline__ void unmask_irq(unsigned int irq) +static void arc_unmask_irq_a(unsigned int irq) { - extern void ecard_enableirq (unsigned int); - extern void ecard_enablefiq (unsigned int); - unsigned char mask = 1 << (irq & 7); - - switch (irq >> 3) { - case 0: - outb(inb(IOC_IRQMASKA) | mask, IOC_IRQMASKA); - break; - case 1: - outb(inb(IOC_IRQMASKB) | mask, IOC_IRQMASKB); - break; - case 4: - ecard_enableirq (irq & 7); - break; - case 8: - outb(inb(IOC_FIQMASK) | mask, IOC_FIQMASK); - break; - case 12: - ecard_enablefiq (irq & 7); - } + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" orr %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOC_IRQMASKA))); +} + +static void arc_mask_irq_b(unsigned int irq) +{ + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" bic %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOC_IRQMASKB))); } -static __inline__ unsigned long get_enabled_irqs(void) +static void arc_unmask_irq_b(unsigned int irq) { - return inb(IOC_IRQMASKA) | inb(IOC_IRQMASKB) << 8; + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" orr %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOC_IRQMASKB))); +} + +static void arc_mask_irq_fiq(unsigned int irq) +{ + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" bic %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOC_FIQMASK))); +} + +static void arc_unmask_irq_fiq(unsigned int irq) +{ + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" orr %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOC_FIQMASK))); } static __inline__ void irq_init_irq(void) { + extern void ecard_disableirq(unsigned int irq); + extern void ecard_enableirq(unsigned int irq); + int irq; + outb(0, IOC_IRQMASKA); outb(0, IOC_IRQMASKB); outb(0, IOC_FIQMASK); + + for (irq = 0; irq < NR_IRQS; irq++) { + switch (irq & 0xf8) { + case 0 ... 6: + irq_desc[irq].probe_ok = 1; + case 7: + irq_desc[irq].valid = 1; + irq_desc[irq].mask_ack = arc_mask_irq_ack_a; + irq_desc[irq].mask = arc_mask_irq_a; + irq_desc[irq].unmask = arc_unmask_irq_a; + break; + + case 9 ... 15: + irq_desc[irq].probe_ok = 1; + case 8: + irq_desc[irq].valid = 1; + irq_desc[irq].mask_ack = arc_mask_irq_b; + irq_desc[irq].mask = arc_mask_irq_b; + irq_desc[irq].unmask = arc_unmask_irq_b; + break; + + case 32 ... 40: + irq_desc[irq].valid = 1; + irq_desc[irq].mask_ack = ecard_disableirq; + irq_desc[irq].mask = ecard_disableirq; + irq_desc[irq].unmask = ecard_enableirq; + break; + + case 64 ... 72: + irq_desc[irq].valid = 1; + irq_desc[irq].mask_ack = arc_mask_irq_fiq; + irq_desc[irq].mask = arc_mask_irq_fiq; + irq_desc[irq].unmask = arc_unmask_irq_fiq; + break; + } + } } diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-arc/uncompress.h linux/include/asm-arm/arch-arc/uncompress.h --- v2.1.120/linux/include/asm-arm/arch-arc/uncompress.h Fri May 8 23:14:54 1998 +++ linux/include/asm-arm/arch-arc/uncompress.h Sun Sep 6 10:45:30 1998 @@ -102,3 +102,8 @@ if (params->nr_pages * params->page_size < 4096*1024) error("<4M of mem\n"); } + +/* + * nothing to do + */ +#define arch_decomp_wdog() diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa110/irq.h linux/include/asm-arm/arch-ebsa110/irq.h --- v2.1.120/linux/include/asm-arm/arch-ebsa110/irq.h Tue Jan 20 16:39:42 1998 +++ linux/include/asm-arm/arch-ebsa110/irq.h Sun Sep 6 10:45:30 1998 @@ -1,39 +1,35 @@ /* * include/asm-arm/arch-ebsa110/irq.h * - * Copyright (C) 1996,1997,1998 Russell King + * Copyright (C) 1996-1998 Russell King + * + * Changelog: + * 22-08-1998 RMK Restructured IRQ routines */ #define IRQ_MCLR ((volatile unsigned char *)0xf3000000) #define IRQ_MSET ((volatile unsigned char *)0xf2c00000) #define IRQ_MASK ((volatile unsigned char *)0xf2c00000) -static __inline__ void mask_and_ack_irq(unsigned int irq) +static void ebsa110_mask_and_ack_irq(unsigned int irq) { - if (irq < 8) - *IRQ_MCLR = 1 << irq; + *IRQ_MCLR = 1 << irq; } -static __inline__ void mask_irq(unsigned int irq) +static void ebsa110_mask_irq(unsigned int irq) { - if (irq < 8) - *IRQ_MCLR = 1 << irq; + *IRQ_MCLR = 1 << irq; } -static __inline__ void unmask_irq(unsigned int irq) +static void ebsa110_unmask_irq(unsigned int irq) { - if (irq < 8) - *IRQ_MSET = 1 << irq; + *IRQ_MSET = 1 << irq; } -static __inline__ unsigned long get_enabled_irqs(void) -{ - return 0; -} - static __inline__ void irq_init_irq(void) { unsigned long flags; + int irq; save_flags_cli (flags); *IRQ_MCLR = 0xff; @@ -43,4 +39,12 @@ while (1); *IRQ_MCLR = 0xff; /* clear all interrupt enables */ restore_flags (flags); + + for (irq = 0; irq < NR_IRQS; irq++) { + irq_desc[irq].valid = 1; + irq_desc[irq].probe_ok = 1; + irq_desc[irq].mask_ack = ebsa110_mask_and_ack_irq; + irq_desc[irq].mask = ebsa110_mask_irq; + irq_desc[irq].unmask = ebsa110_unmask_irq; + } } diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa110/irqs.h linux/include/asm-arm/arch-ebsa110/irqs.h --- v2.1.120/linux/include/asm-arm/arch-ebsa110/irqs.h Fri May 8 23:14:54 1998 +++ linux/include/asm-arm/arch-ebsa110/irqs.h Sun Sep 6 10:45:30 1998 @@ -4,16 +4,13 @@ * Copyright (C) 1996 Russell King */ -#define IRQ_PRINTER 0 -#define IRQ_COM1 1 -#define IRQ_COM2 2 -#define IRQ_ETHERNET 3 -#define IRQ_TIMER0 4 -#define IRQ_TIMER1 5 -#define IRQ_PCMCIA 6 -#define IRQ_IMMEDIATE 7 - -#define IRQ_TIMER IRQ_TIMER0 - -#define irq_cannonicalize(i) (i) +#define NR_IRQS 8 +#define IRQ_EBSA110_PRINTER 0 +#define IRQ_EBSA110_COM1 1 +#define IRQ_EBSA110_COM2 2 +#define IRQ_EBSA110_ETHERNET 3 +#define IRQ_EBSA110_TIMER0 4 +#define IRQ_EBSA110_TIMER1 5 +#define IRQ_EBSA110_PCMCIA 6 +#define IRQ_EBSA110_IMMEDIATE 7 diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa110/mm-init.h linux/include/asm-arm/arch-ebsa110/mm-init.h --- v2.1.120/linux/include/asm-arm/arch-ebsa110/mm-init.h Tue Apr 14 14:29:25 1998 +++ linux/include/asm-arm/arch-ebsa110/mm-init.h Sun Sep 6 10:45:30 1998 @@ -3,4 +3,3 @@ * * Copyright (C) 1996,1997,1998 Russell King */ - diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa110/mmu.h linux/include/asm-arm/arch-ebsa110/mmu.h --- v2.1.120/linux/include/asm-arm/arch-ebsa110/mmu.h Tue Apr 14 14:29:25 1998 +++ linux/include/asm-arm/arch-ebsa110/mmu.h Sun Sep 6 10:45:30 1998 @@ -10,9 +10,6 @@ #ifndef __ASM_ARCH_MMU_H #define __ASM_ARCH_MMU_H -/* - * On ebsa, the dram is contiguous - */ #define __virt_to_phys__is_a_macro #define __virt_to_phys(vpage) ((vpage) - PAGE_OFFSET) #define __phys_to_virt__is_a_macro diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa110/param.h linux/include/asm-arm/arch-ebsa110/param.h --- v2.1.120/linux/include/asm-arm/arch-ebsa110/param.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-arm/arch-ebsa110/param.h Sun Sep 6 10:45:30 1998 @@ -0,0 +1,8 @@ +/* + * linux/include/asm-arm/arch-ebsa110/param.h + * + * Copyright (C) 1996 Russell King + * Copyright (C) 1998 Philip Blundell + */ + +#define HZ 100 diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa110/system.h linux/include/asm-arm/arch-ebsa110/system.h --- v2.1.120/linux/include/asm-arm/arch-ebsa110/system.h Tue Jan 20 16:39:42 1998 +++ linux/include/asm-arm/arch-ebsa110/system.h Sun Sep 6 10:45:30 1998 @@ -1,7 +1,7 @@ /* * linux/include/asm-arm/arch-ebsa110/system.h * - * Copyright (c) 1996,1997,1998 Russell King. + * Copyright (c) 1996-1998 Russell King. */ #ifndef __ASM_ARCH_SYSTEM_H #define __ASM_ARCH_SYSTEM_H diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa110/time.h linux/include/asm-arm/arch-ebsa110/time.h --- v2.1.120/linux/include/asm-arm/arch-ebsa110/time.h Tue Jan 20 16:39:42 1998 +++ linux/include/asm-arm/arch-ebsa110/time.h Sun Sep 6 10:45:30 1998 @@ -7,9 +7,14 @@ * * Changelog: * 10-Oct-1996 RMK Created - * 04-Dec-1997 RMK Updated for new arch/arm/time.c + * 04-Dec-1997 RMK Updated for new arch/arm/kernel/time.c + * 07-Aug-1998 RMK Updated for arch/arm/kernel/leds.c */ +#include + +#define IRQ_TIMER IRQ_EBSA110_TIMER0 + #define MCLK_47_8 #if defined(MCLK_42_3) @@ -49,7 +54,7 @@ if (--count == 0) { count = 50; - *(volatile unsigned char *)0xf2400000 ^= 128; + leds_event(led_timer); } if (divisor == 0) { diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa110/timex.h linux/include/asm-arm/arch-ebsa110/timex.h --- v2.1.120/linux/include/asm-arm/arch-ebsa110/timex.h Tue Jan 20 16:39:42 1998 +++ linux/include/asm-arm/arch-ebsa110/timex.h Sun Sep 6 10:45:30 1998 @@ -1,7 +1,7 @@ /* * linux/include/asm-arm/arch-ebsa110/timex.h * - * RiscPC architecture timex specifications + * EBSA110 architecture timex specifications * * Copyright (C) 1997, 1998 Russell King */ diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa110/uncompress.h linux/include/asm-arm/arch-ebsa110/uncompress.h --- v2.1.120/linux/include/asm-arm/arch-ebsa110/uncompress.h Tue Jan 20 16:39:42 1998 +++ linux/include/asm-arm/arch-ebsa110/uncompress.h Sun Sep 6 10:45:30 1998 @@ -31,3 +31,4 @@ * nothing to do */ #define arch_decomp_setup() +#define arch_decomp_wdog() diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa285/dma.h linux/include/asm-arm/arch-ebsa285/dma.h --- v2.1.120/linux/include/asm-arm/arch-ebsa285/dma.h Tue Apr 14 14:29:25 1998 +++ linux/include/asm-arm/arch-ebsa285/dma.h Sun Sep 6 10:45:30 1998 @@ -1,29 +1,35 @@ /* - * linux/include/asm-arm/arch-ebsa110/dma.h + * linux/include/asm-arm/arch-ebsa285/dma.h * - * Architecture DMA routes + * Architecture DMA routines * - * Copyright (C) 1997.1998 Russell King + * Copyright (C) 1998 Russell King + * Copyright (C) 1998 Philip Blundell */ #ifndef __ASM_ARCH_DMA_H #define __ASM_ARCH_DMA_H /* * This is the maximum DMA address that can be DMAd to. - * There should not be more than (0xd0000000 - 0xc0000000) - * bytes of RAM. */ -#define MAX_DMA_ADDRESS 0xd0000000 +#define MAX_DMA_ADDRESS 0xffffffff /* * DMA modes - we have two, IN and OUT */ -typedef enum { - DMA_MODE_READ, - DMA_MODE_WRITE -} dmamode_t; -#define MAX_DMA_CHANNELS 8 +typedef int dmamode_t; +#define DMA_MODE_READ 0x44 +#define DMA_MODE_WRITE 0x48 -#endif /* _ASM_ARCH_DMA_H */ +/* + * The 21285 has two internal DMA channels; we call these 0 and 1. + * On CATS hardware we have an additional eight ISA dma channels + * numbered 2..9. + */ +#define MAX_DMA_CHANNELS 10 +#define DMA_ISA_BASE 2 +#define DMA_FLOPPY (DMA_ISA_BASE + 2) + +#endif /* _ASM_ARCH_DMA_H */ diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa285/irq.h linux/include/asm-arm/arch-ebsa285/irq.h --- v2.1.120/linux/include/asm-arm/arch-ebsa285/irq.h Tue Apr 14 14:29:25 1998 +++ linux/include/asm-arm/arch-ebsa285/irq.h Sun Sep 6 10:45:30 1998 @@ -1,34 +1,34 @@ /* - * include/asm-arm/arch-ebsa110/irq.h + * include/asm-arm/arch-ebsa285/irq.h * - * Copyright (C) 1996,1997,1998 Russell King + * Copyright (C) 1996-1998 Russell King + * + * Changelog: + * 22-08-1998 RMK Restructured IRQ routines */ -static __inline__ void mask_and_ack_irq(unsigned int irq) +static void ebsa285_mask_irq(unsigned int irq) { - if (irq < 32) - *CSR_IRQ_DISABLE = 1 << irq; + *CSR_IRQ_DISABLE = 1 << irq; } -static __inline__ void mask_irq(unsigned int irq) +static void ebsa285_unmask_irq(unsigned int irq) { - if (irq < 32) - *CSR_IRQ_DISABLE = 1 << irq; -} - -static __inline__ void unmask_irq(unsigned int irq) -{ - if (irq < 32) - *CSR_IRQ_ENABLE = 1 << irq; + *CSR_IRQ_ENABLE = 1 << irq; } -static __inline__ unsigned long get_enabled_irqs(void) -{ - return 0; -} - static __inline__ void irq_init_irq(void) { + int irq; + *CSR_IRQ_DISABLE = -1; *CSR_FIQ_DISABLE = -1; + + for (irq = 0; irq < NR_IRQS; irq++) { + irq_desc[irq].valid = 1; + irq_desc[irq].probe_ok = 1; + irq_desc[irq].mask_ack = ebsa285_mask_irq; + irq_desc[irq].mask = ebsa285_mask_irq; + irq_desc[irq].unmask = ebsa285_unmask_irq; + } } diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa285/param.h linux/include/asm-arm/arch-ebsa285/param.h --- v2.1.120/linux/include/asm-arm/arch-ebsa285/param.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-arm/arch-ebsa285/param.h Sun Sep 6 10:45:30 1998 @@ -0,0 +1,8 @@ +/* + * linux/include/asm-arm/arch-ebsa285/param.h + * + * Copyright (C) 1996 Russell King + * Copyright (C) 1998 Philip Blundell + */ + +#define HZ 100 diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa285/serial.h linux/include/asm-arm/arch-ebsa285/serial.h --- v2.1.120/linux/include/asm-arm/arch-ebsa285/serial.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/arch-ebsa285/serial.h Sun Sep 6 10:45:30 1998 @@ -38,4 +38,3 @@ { 0, BASE_BAUD, 0 , 0, STD_COM_FLAGS }, /* ttyS13 */ #endif - diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-ebsa285/uncompress.h linux/include/asm-arm/arch-ebsa285/uncompress.h --- v2.1.120/linux/include/asm-arm/arch-ebsa285/uncompress.h Tue Apr 14 14:29:25 1998 +++ linux/include/asm-arm/arch-ebsa285/uncompress.h Sun Sep 6 10:45:30 1998 @@ -31,3 +31,4 @@ * nothing to do */ #define arch_decomp_setup() +#define arch_decomp_wdog() diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-nexuspci/irq.h linux/include/asm-arm/arch-nexuspci/irq.h --- v2.1.120/linux/include/asm-arm/arch-nexuspci/irq.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/arch-nexuspci/irq.h Sun Sep 6 10:45:30 1998 @@ -2,6 +2,9 @@ * include/asm-arm/arch-nexuspci/irq.h * * Copyright (C) 1998 Philip Blundell + * + * Changelog: + * 22-08-1998 RMK Restructured IRQ routines */ #include @@ -10,29 +13,28 @@ extern unsigned long soft_irq_mask; -static __inline__ void mask_irq(unsigned int irq) +static void nexuspci_mask_irq(unsigned int irq) { writel((irq << 1), INTCONT); soft_irq_mask &= ~(1<> 3) { - case 0: - outb(inb(IOMD_IRQMASKA) & ~mask, IOMD_IRQMASKA); - break; - case 1: - outb(inb(IOMD_IRQMASKB) & ~mask, IOMD_IRQMASKB); - break; - case 2: - outb(inb(IOMD_DMAMASK) & ~mask, IOMD_DMAMASK); - break; - case 4: - ecard_disableirq (irq & 7); - break; - case 8: - outb(inb(IOMD_FIQMASK) & ~mask, IOMD_FIQMASK); - break; - case 12: - ecard_disablefiq (irq & 7); - } +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOMD_IRQMASKA))); } -static __inline__ void unmask_irq(unsigned int irq) +static void rpc_unmask_irq_a(unsigned int irq) { - extern void ecard_enableirq (unsigned int); - extern void ecard_enablefiq (unsigned int); - unsigned char mask = 1 << (irq & 7); - - switch (irq >> 3) { - case 0: - outb(inb(IOMD_IRQMASKA) | mask, IOMD_IRQMASKA); - break; - case 1: - outb(inb(IOMD_IRQMASKB) | mask, IOMD_IRQMASKB); - break; - case 2: - outb(inb(IOMD_DMAMASK) | mask, IOMD_DMAMASK); - break; - case 4: - ecard_enableirq (irq & 7); - break; - case 8: - outb(inb(IOMD_FIQMASK) | mask, IOMD_FIQMASK); - break; - case 12: - ecard_enablefiq (irq & 7); - } + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" orr %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOMD_IRQMASKA))); } -static __inline__ unsigned long get_enabled_irqs(void) +static void rpc_mask_irq_b(unsigned int irq) { - return inb(IOMD_IRQMASKA) | inb(IOMD_IRQMASKB) << 8 | inb(IOMD_DMAMASK) << 16; + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" bic %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOMD_IRQMASKB))); +} + +static void rpc_unmask_irq_b(unsigned int irq) +{ + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" orr %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOMD_IRQMASKB))); +} + +static void rpc_mask_irq_dma(unsigned int irq) +{ + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" bic %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOMD_DMAMASK))); +} + +static void rpc_unmask_irq_dma(unsigned int irq) +{ + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" orr %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOMD_DMAMASK))); +} + +static void rpc_mask_irq_fiq(unsigned int irq) +{ + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" bic %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOMD_FIQMASK))); +} + +static void rpc_unmask_irq_fiq(unsigned int irq) +{ + unsigned int temp; + + __asm__ __volatile__( + "ldrb %0, [%2]\n" +" orr %0, %0, %1\n" +" strb %0, [%2]" + : "=&r" (temp) + : "r" (1 << (irq & 7)), "r" (ioaddr(IOMD_FIQMASK))); } static __inline__ void irq_init_irq(void) { + extern void ecard_disableirq(unsigned int irq); + extern void ecard_enableirq(unsigned int irq); + int irq; + outb(0, IOMD_IRQMASKA); outb(0, IOMD_IRQMASKB); outb(0, IOMD_FIQMASK); outb(0, IOMD_DMAMASK); + + for (irq = 0; irq < NR_IRQS; irq++) { + switch (irq) { + case 0 ... 6: + irq_desc[irq].probe_ok = 1; + case 7: + irq_desc[irq].valid = 1; + irq_desc[irq].mask_ack = rpc_mask_irq_ack_a; + irq_desc[irq].mask = rpc_mask_irq_a; + irq_desc[irq].unmask = rpc_unmask_irq_a; + break; + + case 9 ... 15: + irq_desc[irq].probe_ok = 1; + case 8: + irq_desc[irq].valid = 1; + irq_desc[irq].mask_ack = rpc_mask_irq_b; + irq_desc[irq].mask = rpc_mask_irq_b; + irq_desc[irq].unmask = rpc_unmask_irq_b; + break; + + case 16 ... 22: + irq_desc[irq].valid = 1; + irq_desc[irq].mask_ack = rpc_mask_irq_dma; + irq_desc[irq].mask = rpc_mask_irq_dma; + irq_desc[irq].unmask = rpc_unmask_irq_dma; + break; + + case 32 ... 40: + irq_desc[irq].valid = 1; + irq_desc[irq].mask_ack = ecard_disableirq; + irq_desc[irq].mask = ecard_disableirq; + irq_desc[irq].unmask = ecard_enableirq; + break; + + case 64 ... 72: + irq_desc[irq].valid = 1; + irq_desc[irq].mask_ack = rpc_mask_irq_fiq; + irq_desc[irq].mask = rpc_mask_irq_fiq; + irq_desc[irq].unmask = rpc_unmask_irq_fiq; + break; + } + } } diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-rpc/irqs.h linux/include/asm-arm/arch-rpc/irqs.h --- v2.1.120/linux/include/asm-arm/arch-rpc/irqs.h Fri May 8 23:14:54 1998 +++ linux/include/asm-arm/arch-rpc/irqs.h Sun Sep 6 10:45:30 1998 @@ -35,5 +35,3 @@ #define IRQ_TIMER IRQ_TIMER0 -#define irq_cannonicalize(i) (i) - diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-rpc/param.h linux/include/asm-arm/arch-rpc/param.h --- v2.1.120/linux/include/asm-arm/arch-rpc/param.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-arm/arch-rpc/param.h Sun Sep 6 10:45:30 1998 @@ -0,0 +1,8 @@ +/* + * linux/include/asm-arm/arch-rpc/param.h + * + * Copyright (C) 1996 Russell King + * Copyright (C) 1998 Philip Blundell + */ + +#define HZ 100 diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-rpc/uncompress.h linux/include/asm-arm/arch-rpc/uncompress.h --- v2.1.120/linux/include/asm-arm/arch-rpc/uncompress.h Tue Apr 14 14:29:25 1998 +++ linux/include/asm-arm/arch-rpc/uncompress.h Sun Sep 6 10:45:30 1998 @@ -141,3 +141,7 @@ } #endif +/* + * nothing to do + */ +#define arch_decomp_wdog() diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-vnc/a.out.h linux/include/asm-arm/arch-vnc/a.out.h --- v2.1.120/linux/include/asm-arm/arch-vnc/a.out.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/arch-vnc/a.out.h Sun Sep 6 10:45:30 1998 @@ -13,4 +13,3 @@ #endif #endif - diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-vnc/dma.h linux/include/asm-arm/arch-vnc/dma.h --- v2.1.120/linux/include/asm-arm/arch-vnc/dma.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/arch-vnc/dma.h Sun Sep 6 10:45:30 1998 @@ -26,4 +26,3 @@ #define MAX_DMA_CHANNELS 8 #endif /* _ASM_ARCH_DMA_H */ - diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-vnc/hardware.h linux/include/asm-arm/arch-vnc/hardware.h --- v2.1.120/linux/include/asm-arm/arch-vnc/hardware.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/arch-vnc/hardware.h Sun Sep 6 10:45:30 1998 @@ -118,4 +118,3 @@ #define PARAMS_BASE (PAGE_OFFSET + PARAMS_OFFSET) #define SAFE_ADDR 0x50000000 - diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-vnc/irq.h linux/include/asm-arm/arch-vnc/irq.h --- v2.1.120/linux/include/asm-arm/arch-vnc/irq.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/arch-vnc/irq.h Sun Sep 6 10:45:30 1998 @@ -2,6 +2,9 @@ * include/asm-arm/arch-vnc/irq.h * * Copyright (C) 1998 Russell King + * + * Changelog: + * 22-08-1998 RMK Restructured IRQ routines */ #include @@ -29,67 +32,48 @@ IRQ_MASK_PCI_ERR }; -static __inline__ void mask_and_ack_irq(unsigned int irq) +static void vnc_mask_csr_irq(unsigned int irq) { - if (irq < 16) - *CSR_IRQ_DISABLE = fb_irq_mask[irq]; - else { - unsigned int pic_mask, mask; - - if (irq < 24) - pic_mask = PIC_MASK_LO; - else - pic_mask = PIC_MASK_HI; - - mask = 1 << (irq & 7); - - outb(inb(pic_mask) | mask, pic_mask); - } + *CSR_IRQ_DISABLE = fb_irq_mask[irq]; } -static __inline__ void mask_irq(unsigned int irq) +static void vnc_unmask_csr_irq(unsigned int irq) { - if (irq < 16) - *CSR_IRQ_DISABLE = fb_irq_mask[irq]; - else { - unsigned int pic_mask, mask; - - if (irq < 24) - pic_mask = PIC_MASK_LO; - else - pic_mask = PIC_MASK_HI; + *CSR_IRQ_DISABLE = fb_irq_mask[irq]; +} - mask = 1 << (irq & 7); +static void vnc_mask_pic_lo_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq & 7); - outb(inb(pic_mask) | mask, pic_mask); - } + outb(inb(PIC_MASK_LO) | mask, PIC_MASK_LO); } -static __inline__ void unmask_irq(unsigned int irq) +static void vnc_unmask_pic_lo_irq(unsigned int irq) { - if (irq < 16) - *CSR_IRQ_ENABLE = fb_irq_mask[irq]; - else { - unsigned int pic_mask, mask; + unsigned int mask = 1 << (irq & 7); - if (irq < 24) - pic_mask = PIC_MASK_LO; - else - pic_mask = PIC_MASK_HI; + outb(inb(PIC_MASK_LO) & ~mask, PIC_MASK_LO); +} - mask = 1 << (irq & 7); +static void vnc_mask_pic_hi_irq(unsigned int irq) +{ + unsigned int mask = 1 << (irq & 7); - outb(inb(pic_mask) & ~mask, pic_mask); - } + outb(inb(PIC_MASK_HI) | mask, PIC_MASK_HI); } - -static __inline__ unsigned long get_enabled_irqs(void) + +static void vnc_unmask_pic_hi_irq(unsigned int irq) { - return 0; + unsigned int mask = 1 << (irq & 7); + + outb(inb(PIC_MASK_HI) & ~mask, PIC_MASK_HI); } static __inline__ void irq_init_irq(void) { + unsigned int irq; + outb(0x11, PIC_LO); outb(0x10, PIC_MASK_LO); outb(0x04, PIC_MASK_LO); @@ -103,4 +87,23 @@ *CSR_IRQ_DISABLE = ~IRQ_MASK_EXTERN_IRQ; *CSR_IRQ_ENABLE = IRQ_MASK_EXTERN_IRQ; *CSR_FIQ_DISABLE = -1; + + for (irq = 0; irq < NR_IRQS; irq++) { + irq_desc[irq].valid = 1; + irq_desc[irq].probe_ok = 1; + + if (irq < 16) { + irq_desc[irq].mask_ack = vnc_mask_csr_irq; + irq_desc[irq].mask = vnc_mask_csr_irq; + irq_desc[irq].unmask = vnc_unmask_csr_irq; + } else if (irq < 24) { + irq_desc[irq].mask_ack = vnc_mask_pic_lo_irq; + irq_desc[irq].mask = vnc_mask_pic_lo_irq; + irq_desc[irq].unmask = vnc_unmask_pic_lo_irq; + } else { + irq_desc[irq].mask_ack = vnc_mask_pic_hi_irq; + irq_desc[irq].mask = vnc_mask_pic_hi_irq; + irq_desc[irq].unmask = vnc_unmask_pic_hi_irq; + } + } } diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-vnc/irqs.h linux/include/asm-arm/arch-vnc/irqs.h --- v2.1.120/linux/include/asm-arm/arch-vnc/irqs.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/arch-vnc/irqs.h Sun Sep 6 10:45:30 1998 @@ -60,4 +60,3 @@ #define IRQ_TIMER IRQ_TIMER0 #define irq_cannonicalize(i) (i) - diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-vnc/keyboard.h linux/include/asm-arm/arch-vnc/keyboard.h --- v2.1.120/linux/include/asm-arm/arch-vnc/keyboard.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/arch-vnc/keyboard.h Sun Sep 6 10:45:30 1998 @@ -34,4 +34,3 @@ //#define kbd_sysrq_xlate ps2kbd_sysrq_xlate #define kbd_disable_irq() #define kbd_enable_irq() - diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-vnc/param.h linux/include/asm-arm/arch-vnc/param.h --- v2.1.120/linux/include/asm-arm/arch-vnc/param.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-arm/arch-vnc/param.h Sun Sep 6 10:45:30 1998 @@ -0,0 +1,8 @@ +/* + * linux/include/asm-arm/arch-vnc/param.h + * + * Copyright (C) 1996 Russell King + * Copyright (C) 1998 Philip Blundell + */ + +#define HZ 100 diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/arch-vnc/uncompress.h linux/include/asm-arm/arch-vnc/uncompress.h --- v2.1.120/linux/include/asm-arm/arch-vnc/uncompress.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/arch-vnc/uncompress.h Sun Sep 6 10:45:30 1998 @@ -31,3 +31,4 @@ * nothing to do */ #define arch_decomp_setup() +#define arch_decomp_wdog() diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/atomic.h linux/include/asm-arm/atomic.h --- v2.1.120/linux/include/asm-arm/atomic.h Tue Jan 20 16:39:42 1998 +++ linux/include/asm-arm/atomic.h Sun Sep 6 10:45:30 1998 @@ -7,20 +7,22 @@ * 27-06-1996 RMK Created * 13-04-1997 RMK Made functions atomic! * 07-12-1997 RMK Upgraded for v2.1. + * 26-08-1998 PJB Added #ifdef __KERNEL__ */ #ifndef __ASM_ARM_ATOMIC_H #define __ASM_ARM_ATOMIC_H +typedef struct { int counter; } atomic_t; + +#define ATOMIC_INIT(i) { (i) } + +#ifdef __KERNEL__ #include #ifdef __SMP__ #error SMP not supported #endif -typedef struct { int counter; } atomic_t; - -#define ATOMIC_INIT(i) { (i) } - #define atomic_read(v) ((v)->counter) #define atomic_set(v,i) (((v)->counter) = (i)) @@ -82,4 +84,5 @@ restore_flags (flags); } +#endif #endif diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/elf.h linux/include/asm-arm/elf.h --- v2.1.120/linux/include/asm-arm/elf.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/elf.h Sun Sep 6 10:45:30 1998 @@ -30,7 +30,7 @@ #define ELF_ARCH EM_ARM #define USE_ELF_CORE_DUMP -#define ELF_EXEC_PAGESIZE 32768 +#define ELF_EXEC_PAGESIZE 4096 /* This is the location that an ET_DYN program is loaded if exec'ed. Typical use of this is to invoke "./ld.so someprog" to test out a new version of @@ -39,6 +39,11 @@ #define ELF_ET_DYN_BASE (2 * TASK_SIZE / 3) +/* When the program starts, a1 contains a pointer to a function to be + registered with atexit, as per the SVR4 ABI. A value of 0 means we + have no such handler. */ +#define ELF_PLAT_INIT(_r) (_r)->ARM_r0 = 0 + /* This yields a mask that user programs can use to figure out what instruction set this cpu supports. */ @@ -64,18 +69,5 @@ #define SET_PERSONALITY(ex,ibcs2) \ current->personality = PER_LINUX_32BIT #endif - -#define R_ARM_NONE (0) -#define R_ARM_32 (1) /* => ld 32 */ -#define R_ARM_PC26 (2) /* => ld b/bl branches */ -#define R_ARM_PC32 (3) -#define R_ARM_GOT32 (4) /* -> object relocation into GOT */ -#define R_ARM_PLT32 (5) -#define R_ARM_COPY (6) /* => dlink copy object */ -#define R_ARM_GLOB_DAT (7) /* => dlink 32bit absolute address for .got */ -#define R_ARM_JUMP_SLOT (8) /* => dlink 32bit absolute address for .got.plt */ -#define R_ARM_RELATIVE (9) /* => ld resolved 32bit absolute address requiring load address adjustment */ -#define R_ARM_GOTOFF (10) /* => ld calculates offset of data from base of GOT */ -#define R_ARM_GOTPC (11) /* => ld 32-bit relative offset */ #endif diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/fiq.h linux/include/asm-arm/fiq.h --- v2.1.120/linux/include/asm-arm/fiq.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/fiq.h Sun Sep 6 10:45:30 1998 @@ -1,32 +1,34 @@ -/* Support for FIQ on ARM architectures. +/* + * linux/include/asm-arm/fiq.h + * + * Support for FIQ on ARM architectures. * Written by Philip Blundell , 1998 + * Re-written by Russell King */ #ifndef __ASM_FIQ_H #define __ASM_FIQ_H -struct fiq_handler { - const char *name; - int (*callback)(void); -}; - -extern int claim_fiq(struct fiq_handler *f); -extern void release_fiq(struct fiq_handler *f); - -#endif -/* Support for FIQ on ARM architectures. - * Written by Philip Blundell , 1998 - */ - -#ifndef __ASM_FIQ_H -#define __ASM_FIQ_H +#include struct fiq_handler { - const char *name; - int (*callback)(void); + struct fiq_handler *next; + /* Name + */ + const char *name; + /* Called to ask driver to relinquish/ + * reacquire FIQ + * return zero to accept, or - + */ + int (*fiq_op)(void *, int relinquish); + /* data for the relinquish/reacquire functions + */ + void *dev_id; }; extern int claim_fiq(struct fiq_handler *f); extern void release_fiq(struct fiq_handler *f); +extern void set_fiq_handler(void *start, unsigned int length); +extern void set_fiq_regs(struct pt_regs *regs); #endif diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/io.h linux/include/asm-arm/io.h --- v2.1.120/linux/include/asm-arm/io.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/io.h Sun Sep 6 10:45:30 1998 @@ -15,6 +15,7 @@ #include #include #include +#include /* unsigned long virt_to_phys(void *x) */ #define virt_to_phys(x) (__virt_to_phys((unsigned long)(x))) diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/irq.h linux/include/asm-arm/irq.h --- v2.1.120/linux/include/asm-arm/irq.h Tue Apr 14 14:29:25 1998 +++ linux/include/asm-arm/irq.h Sun Sep 6 10:45:30 1998 @@ -3,6 +3,8 @@ #include +#define irq_cannonicalize(i) (i) + #ifndef NR_IRQS #define NR_IRQS 128 #endif diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/linux_logo.h linux/include/asm-arm/linux_logo.h --- v2.1.120/linux/include/asm-arm/linux_logo.h Thu Jul 16 18:09:28 1998 +++ linux/include/asm-arm/linux_logo.h Sun Sep 6 10:45:30 1998 @@ -11,17 +11,26 @@ #define linux_logo_banner "ARM Linux version " UTS_RELEASE -#define LINUX_LOGO_COLORS 0 +#define LINUX_LOGO_COLORS 221 -unsigned char linux_logo_red[] __initdata = { }; -unsigned char linux_logo_green[] __initdata = { }; -unsigned char linux_logo_blue[] __initdata = { }; - -unsigned char linux_logo16_red[] __initdata = { }; -unsigned char linux_logo16_green[] __initdata = { }; -unsigned char linux_logo16_blue[] __initdata = { }; - -unsigned char linux_logo[] __initdata = { }; -unsigned char linux_logo16[] __initdata = { }; -unsigned char linux_logo_bw[] __initdata = { }; +#ifdef INCLUDE_LINUX_LOGO_DATA +#define INCLUDE_LINUX_LOGO16 +#include + + +/* prototypes only */ +extern unsigned char linux_logo_red[]; +extern unsigned char linux_logo_green[]; +extern unsigned char linux_logo_blue[]; +extern unsigned char linux_logo[]; +extern unsigned char linux_logo_bw[]; +extern unsigned char linux_logo16_red[]; +extern unsigned char linux_logo16_green[]; +extern unsigned char linux_logo16_blue[]; +extern unsigned char linux_logo16[]; +extern unsigned char *linux_serial_image; + +extern int (*console_show_logo)(void); + +#endif diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/pgtable.h linux/include/asm-arm/pgtable.h --- v2.1.120/linux/include/asm-arm/pgtable.h Thu Aug 6 14:06:33 1998 +++ linux/include/asm-arm/pgtable.h Sun Sep 6 10:45:30 1998 @@ -9,4 +9,7 @@ extern int do_check_pgt_cache(int, int); +/* Needs to be defined here and not in linux/mm.h, as it is arch dependent */ +#define PageSkip(page) (0) + #endif /* _ASMARM_PGTABLE_H */ diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/proc-armo/io.h linux/include/asm-arm/proc-armo/io.h --- v2.1.120/linux/include/asm-arm/proc-armo/io.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-arm/proc-armo/io.h Sun Sep 6 10:45:30 1998 @@ -0,0 +1,8 @@ +/* + * linux/include/asm-arm/proc-armo/io.h + */ + +/* Nothing to do */ +#define dma_cache_inv(_start,_size) do { } while (0) +#define dma_cache_wback(_start,_size) do { } while (0) +#define dma_cache_wback_inv(_start,_size) do { } while (0) diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/proc-armo/pgtable.h linux/include/asm-arm/proc-armo/pgtable.h --- v2.1.120/linux/include/asm-arm/proc-armo/pgtable.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/proc-armo/pgtable.h Sun Sep 6 10:45:30 1998 @@ -128,6 +128,7 @@ */ #define VMALLOC_START 0x01a00000 #define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#define VMALLOC_END 0x01c00000 #define _PAGE_PRESENT 0x01 #define _PAGE_READONLY 0x02 diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/proc-armo/ptrace.h linux/include/asm-arm/proc-armo/ptrace.h --- v2.1.120/linux/include/asm-arm/proc-armo/ptrace.h Tue Jan 20 16:39:42 1998 +++ linux/include/asm-arm/proc-armo/ptrace.h Sun Sep 6 10:45:30 1998 @@ -44,12 +44,12 @@ #define CC_Z_BIT (1 << 30) #define CC_N_BIT (1 << 31) -#define user_mode(regs) \ - (((regs)->ARM_pc & MODE_MASK) == USR26_MODE) - #define processor_mode(regs) \ ((regs)->ARM_pc & MODE_MASK) +#define user_mode(regs) \ + (processor_mode(regs) == USR26_MODE) + #define interrupts_enabled(regs) \ (!((regs)->ARM_pc & I_BIT)) @@ -59,7 +59,17 @@ #define condition_codes(regs) \ ((regs)->ARM_pc & (CC_V_BIT|CC_C_BIT|CC_Z_BIT|CC_N_BIT)) -#define instruction_pointer(regs) ((regs)->ARM_pc & 0x03fffffc) -#define pc_pointer(v) ((v) & 0x03fffffc) +#define pc_pointer(v) \ + ((v) & 0x03fffffc) + +#define instruction_pointer(regs) \ + (pc_pointer((regs)->ARM_pc)) + +/* Are the current registers suitable for user mode? + * (used to maintain security in signal handlers) + */ +#define valid_user_regs(regs) \ + (user_mode(regs) && ((regs)->ARM_sp & 3) == 0) + #endif diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/proc-armv/io.h linux/include/asm-arm/proc-armv/io.h --- v2.1.120/linux/include/asm-arm/proc-armv/io.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-arm/proc-armv/io.h Sun Sep 6 10:45:30 1998 @@ -0,0 +1,38 @@ +/* + * linux/include/asm-arm/proc-armv/io.h + */ + +/* + * The caches on some architectures aren't dma-coherent and have need to + * handle this in software. There are two types of operations that + * can be applied to dma buffers. + * + * - dma_cache_wback_inv(start, size) makes caches and RAM coherent by + * writing the content of the caches back to memory, if necessary. + * The function also invalidates the affected part of the caches as + * necessary before DMA transfers from outside to memory. + * - dma_cache_inv(start, size) invalidates the affected parts of the + * caches. Dirty lines of the caches may be written back or simply + * be discarded. This operation is necessary before dma operations + * to the memory. + * - dma_cache_wback(start, size) writes back any dirty lines but does + * not invalidate the cache. This can be used before DMA reads from + * memory, + */ + +#include + +#define dma_cache_inv(_start,_size) \ + do { \ + processor.u.armv3v4._cache_purge_area(_start,(_start+_size)); \ + } while (0) + +#define dma_cache_wback(_start,_size) \ + do { \ + processor.u.armv3v4._cache_wback_area(_start,(_start+_size)); \ + } while (0) + +#define dma_cache_wback_inv(_start,_size) \ + do { \ + processor.u.armv3v4._flush_cache_area(_start,(_start+_size),0); \ + } while (0) diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/proc-armv/param.h linux/include/asm-arm/proc-armv/param.h --- v2.1.120/linux/include/asm-arm/proc-armv/param.h Tue Jan 20 16:39:43 1998 +++ linux/include/asm-arm/proc-armv/param.h Sun Sep 6 10:45:30 1998 @@ -7,9 +7,7 @@ #ifndef __ASM_PROC_PARAM_H #define __ASM_PROC_PARAM_H -#ifndef HZ -#define HZ 100 -#endif +#include /* for HZ */ #define EXEC_PAGESIZE 4096 diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/proc-armv/pgtable.h linux/include/asm-arm/proc-armv/pgtable.h --- v2.1.120/linux/include/asm-arm/proc-armv/pgtable.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/proc-armv/pgtable.h Sun Sep 6 10:45:30 1998 @@ -145,6 +145,7 @@ #define VMALLOC_OFFSET (8*1024*1024) #define VMALLOC_START (((unsigned long)high_memory + VMALLOC_OFFSET) & ~(VMALLOC_OFFSET-1)) #define VMALLOC_VMADDR(x) ((unsigned long)(x)) +#define VMALLOC_END (PAGE_OFFSET + 0x10000000) /* PMD types (actually level 1 descriptor) */ #define PMD_TYPE_MASK 0x0003 @@ -199,7 +200,7 @@ #define PAGE_SHARED __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ | _PTE_WRITE) #define PAGE_COPY __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ) #define PAGE_READONLY __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_READ) -#define PAGE_KERNEL __pgprot(PTE_TYPE_SMALL | _PTE_YOUNG | _PTE_DIRTY | _PTE_WRITE) +#define PAGE_KERNEL __pgprot(PTE_TYPE_SMALL | _PTE_READ | _PTE_DIRTY | _PTE_WRITE) #define _PAGE_USER_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_USER)) #define _PAGE_KERNEL_TABLE (PMD_TYPE_TABLE | PMD_DOMAIN(DOMAIN_KERNEL)) diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/proc-armv/ptrace.h linux/include/asm-arm/proc-armv/ptrace.h --- v2.1.120/linux/include/asm-arm/proc-armv/ptrace.h Tue Jan 20 16:39:43 1998 +++ linux/include/asm-arm/proc-armv/ptrace.h Sun Sep 6 10:45:30 1998 @@ -71,5 +71,11 @@ #define instruction_pointer(regs) ((regs)->ARM_pc) #define pc_pointer(v) (v) +/* Are the current registers suitable for user mode? + * (used to maintain security in signal handlers) + */ +#define valid_user_regs(regs) \ + (user_mode(regs) && ((regs)->ARM_sp & 3) == 0) + #endif diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/proc-fns.h linux/include/asm-arm/proc-fns.h --- v2.1.120/linux/include/asm-arm/proc-fns.h Tue Jan 20 16:39:43 1998 +++ linux/include/asm-arm/proc-fns.h Sun Sep 6 10:45:30 1998 @@ -83,6 +83,14 @@ * flush an icached page */ void (*_flush_icache_area)(unsigned long start, unsigned long end); + /* + * write back dirty cached data + */ + void (*_cache_wback_area)(unsigned long start, unsigned long end); + /* + * purge cached data without (necessarily) writing it back + */ + void (*_cache_purge_area)(unsigned long start, unsigned long end); } armv3v4; struct { /* MEMC diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/processor.h linux/include/asm-arm/processor.h --- v2.1.120/linux/include/asm-arm/processor.h Fri May 8 23:14:54 1998 +++ linux/include/asm-arm/processor.h Sun Sep 6 10:45:30 1998 @@ -22,12 +22,15 @@ typedef unsigned long mm_segment_t; /* domain register */ +#define NR_DEBUGS 5 + #define DECLARE_THREAD_STRUCT \ struct thread_struct { \ unsigned long address; /* Address of fault */ \ unsigned long trap_no; /* Trap number */ \ unsigned long error_code; /* Error code of trap */ \ union fp_state fpstate; /* FPE save state */ \ + unsigned long debug[NR_DEBUGS]; /* Debug/ptrace */ \ EXTRA_THREAD_STRUCT \ } @@ -39,6 +42,7 @@ 0, \ 0, \ { { { 0, }, }, }, \ + { 0, }, \ EXTRA_THREAD_STRUCT_INIT \ } diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/signal.h linux/include/asm-arm/signal.h --- v2.1.120/linux/include/asm-arm/signal.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/signal.h Sun Sep 6 10:45:30 1998 @@ -115,8 +115,9 @@ * SA_INTERRUPT is also used by the irq handling routines. * SA_SHIRQ is for shared interrupt support on PCI and EISA. */ -#define SA_PROBE SA_ONESHOT -#define SA_SAMPLE_RANDOM SA_RESTART +#define SA_PROBE 0x80000000 +#define SA_SAMPLE_RANDOM 0x10000000 +#define SA_IRQNOMASK 0x08000000 #define SA_SHIRQ 0x04000000 #endif diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/spinlock.h linux/include/asm-arm/spinlock.h --- v2.1.120/linux/include/asm-arm/spinlock.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/spinlock.h Sun Sep 6 10:45:30 1998 @@ -6,8 +6,13 @@ /* * Your basic spinlocks, allowing only a single CPU anywhere */ -typedef struct { } spinlock_t; -#define SPIN_LOCK_UNLOCKED { } +#if (__GNUC__ > 2) || (__GNUC_MINOR__ >= 8) + typedef struct { } spinlock_t; +# define SPIN_LOCK_UNLOCKED { } +#else + typedef unsigned char spinlock_t; +# define SPIN_LOCK_UNLOCKED 0 +#endif #define spin_lock_init(lock) do { } while(0) #define spin_lock(lock) do { } while(0) diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/system.h linux/include/asm-arm/system.h --- v2.1.120/linux/include/asm-arm/system.h Tue Jul 21 00:15:32 1998 +++ linux/include/asm-arm/system.h Sun Sep 6 10:45:30 1998 @@ -1,6 +1,16 @@ #ifndef __ASM_ARM_SYSTEM_H #define __ASM_ARM_SYSTEM_H +/* The type of machine we're running on */ +extern unsigned int machine_type; +#define MACH_TYPE_EBSA110 0 +#define MACH_TYPE_RISCPC 1 +#define MACH_TYPE_NEXUSPCI 3 +#define MACH_TYPE_EBSA285 4 +#define MACH_TYPE_NETWINDER 5 +#define MACH_TYPE_CATS 6 +#define MACH_TYPE_TBOX 7 + #include #include diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/unistd.h linux/include/asm-arm/unistd.h --- v2.1.120/linux/include/asm-arm/unistd.h Wed Apr 8 19:36:28 1998 +++ linux/include/asm-arm/unistd.h Sun Sep 6 10:45:30 1998 @@ -319,6 +319,7 @@ static inline _syscall0(pid_t,setsid); static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count); static inline _syscall3(int,read,int,fd,char *,buf,off_t,count) +static inline _syscall3(off_t,lseek,int,fd,off_t,offset,int,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); diff -u --recursive --new-file v2.1.120/linux/include/asm-arm/vga.h linux/include/asm-arm/vga.h --- v2.1.120/linux/include/asm-arm/vga.h Wed Dec 31 16:00:00 1969 +++ linux/include/asm-arm/vga.h Sun Sep 6 10:45:30 1998 @@ -0,0 +1,11 @@ +#ifndef ASMARM_VGA_H +#define ASMARM_VGA_H + +#include + +#define VGA_MAP_MEM(x) (0xe0000000 + (x)) + +#define vga_readb(x) (*(x)) +#define vga_writeb(x,y) (*(y) = (x)) + +#endif diff -u --recursive --new-file v2.1.120/linux/include/asm-i386/system.h linux/include/asm-i386/system.h --- v2.1.120/linux/include/asm-i386/system.h Tue Aug 18 22:02:07 1998 +++ linux/include/asm-i386/system.h Sun Sep 6 11:12:59 1998 @@ -227,54 +227,9 @@ #endif -#define _set_gate(gate_addr,type,dpl,addr) \ -__asm__ __volatile__ ("movw %%dx,%%ax\n\t" \ - "movw %2,%%dx\n\t" \ - "movl %%eax,%0\n\t" \ - "movl %%edx,%1" \ - :"=m" (*((long *) (gate_addr))), \ - "=m" (*(1+(long *) (gate_addr))) \ - :"i" ((short) (0x8000+(dpl<<13)+(type<<8))), \ - "d" ((char *) (addr)),"a" (__KERNEL_CS << 16) \ - :"ax","dx") - -#define set_intr_gate(n,addr) \ - _set_gate(idt+(n),14,0,addr) - -#define set_trap_gate(n,addr) \ - _set_gate(idt+(n),15,0,addr) - -#define set_system_gate(n,addr) \ - _set_gate(idt+(n),15,3,addr) - -#define set_call_gate(a,addr) \ - _set_gate(a,12,3,addr) - -#define _set_seg_desc(gate_addr,type,dpl,base,limit) {\ - *((gate_addr)+1) = ((base) & 0xff000000) | \ - (((base) & 0x00ff0000)>>16) | \ - ((limit) & 0xf0000) | \ - ((dpl)<<13) | \ - (0x00408000) | \ - ((type)<<8); \ - *(gate_addr) = (((base) & 0x0000ffff)<<16) | \ - ((limit) & 0x0ffff); } - -#define _set_tssldt_desc(n,addr,limit,type) \ -__asm__ __volatile__ ("movw %3,0(%2)\n\t" \ - "movw %%ax,2(%2)\n\t" \ - "rorl $16,%%eax\n\t" \ - "movb %%al,4(%2)\n\t" \ - "movb %4,5(%2)\n\t" \ - "movb $0,6(%2)\n\t" \ - "movb %%ah,7(%2)\n\t" \ - "rorl $16,%%eax" \ - : "=m"(*(n)) : "a" (addr), "r"(n), "ir"(limit), "i"(type)) - -#define set_tss_desc(n,addr) \ - _set_tssldt_desc(((char *) (n)),((int)(addr)),235,0x89) -#define set_ldt_desc(n,addr,size) \ - _set_tssldt_desc(((char *) (n)),((int)(addr)),((size << 3) - 1),0x82) +extern void set_intr_gate(unsigned int irq, void * addr); +void set_ldt_desc(void *n, void *addr, unsigned int size); +void set_tss_desc(void *n, void *addr); /* * This is the ldt that every process will get unless we need diff -u --recursive --new-file v2.1.120/linux/include/asm-i386/unistd.h linux/include/asm-i386/unistd.h --- v2.1.120/linux/include/asm-i386/unistd.h Wed Aug 26 11:37:44 1998 +++ linux/include/asm-i386/unistd.h Sun Sep 6 13:05:22 1998 @@ -5,7 +5,6 @@ * 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 @@ -289,7 +288,6 @@ #define __NR__exit __NR_exit static inline _syscall0(int,idle) static inline _syscall0(int,pause) -static inline _syscall1(int,setup,int,magic) static inline _syscall0(int,sync) static inline _syscall0(pid_t,setsid) static inline _syscall3(int,write,int,fd,const char *,buf,off_t,count) diff -u --recursive --new-file v2.1.120/linux/include/linux/adfs_fs_fs.h linux/include/linux/adfs_fs_fs.h --- v2.1.120/linux/include/linux/adfs_fs_fs.h Fri Jan 30 11:28:10 1998 +++ linux/include/linux/adfs_fs_fs.h Wed Dec 31 16:00:00 1969 @@ -1,177 +0,0 @@ -#ifndef _ADFS_FS_H -#define _ADFS_FS_H - -#include -/* - * Structures of data on the disk - */ - -/* - * Disc Record at disc address 0xc00 - */ -struct adfs_discrecord { - unsigned char log2secsize; - unsigned char secspertrack; - unsigned char heads; - unsigned char density; - unsigned char idlen; - unsigned char log2bpmb; - unsigned char skew; - unsigned char bootoption; - unsigned char lowsector; - unsigned char nzones; - unsigned short zone_spare; - unsigned long root; - unsigned long disc_size; - unsigned short disc_id; - unsigned char disc_name[10]; - unsigned long disc_type; - unsigned long disc_size_high; - unsigned char log2sharesize:4; - unsigned char unused:4; - unsigned char big_flag:1; -}; - -#define ADFS_DISCRECORD (0xc00) -#define ADFS_DR_OFFSET (0x1c0) -#define ADFS_DR_SIZE 60 -#define ADFS_SUPER_MAGIC 0xadf5 -#define ADFS_FREE_FRAG 0 -#define ADFS_BAD_FRAG 1 -#define ADFS_ROOT_FRAG 2 - -/* - * Directory header - */ -struct adfs_dirheader { - unsigned char startmasseq; - unsigned char startname[4]; -}; - -#define ADFS_NEWDIR_SIZE 2048 -#define ADFS_OLDDIR_SIZE 1024 -#define ADFS_NUM_DIR_ENTRIES 77 - -/* - * Directory entries - */ -struct adfs_direntry { - char dirobname[10]; -#define ADFS_NAME_LEN 10 - __u8 dirload[4]; - __u8 direxec[4]; - __u8 dirlen[4]; - __u8 dirinddiscadd[3]; - __u8 newdiratts; -#define ADFS_NDA_OWNER_READ (1 << 0) -#define ADFS_NDA_OWNER_WRITE (1 << 1) -#define ADFS_NDA_LOCKED (1 << 2) -#define ADFS_NDA_DIRECTORY (1 << 3) -#define ADFS_NDA_EXECUTE (1 << 4) -#define ADFS_NDA_PUBLIC_READ (1 << 5) -#define ADFS_NDA_PUBLIC_WRITE (1 << 6) -}; - -#define ADFS_MAX_NAME_LEN 255 -struct adfs_idir_entry { - __u32 inode_no; /* Address */ - __u32 file_id; /* file id */ - __u32 name_len; /* name length */ - __u32 size; /* size */ - __u32 mtime; /* modification time */ - __u32 filetype; /* RiscOS file type */ - __u8 mode; /* internal mode */ - char name[ADFS_MAX_NAME_LEN]; /* file name */ -}; - -/* - * Directory tail - */ -union adfs_dirtail { - struct { - unsigned char dirlastmask; - char dirname[10]; - unsigned char dirparent[3]; - char dirtitle[19]; - unsigned char reserved[14]; - unsigned char endmasseq; - unsigned char endname[4]; - unsigned char dircheckbyte; - } old; - struct { - unsigned char dirlastmask; - unsigned char reserved[2]; - unsigned char dirparent[3]; - char dirtitle[19]; - char dirname[10]; - unsigned char endmasseq; - unsigned char endname[4]; - unsigned char dircheckbyte; - } new; -}; - -#ifdef __KERNEL__ -/* - * Calculate the boot block checksum on an ADFS drive. Note that this will - * appear to be correct if the sector contains all zeros, so also check that - * the disk size is non-zero!!! - */ -extern inline int adfs_checkbblk (unsigned char *ptr) -{ - unsigned int result = 0; - unsigned char *p = ptr + 511; - - do { - result = (result & 0xff) + (result >> 8); - result = result + *--p; - } while (p != ptr); - - return (result & 0xff) != ptr[511]; -} - -/* dir.c */ -extern unsigned int adfs_val (unsigned char *p, int len); -extern int adfs_dir_read_parent (struct inode *inode, struct buffer_head **bhp); -extern int adfs_dir_read (struct inode *inode, struct buffer_head **bhp); -extern int adfs_dir_check (struct inode *inode, struct buffer_head **bhp, - int buffers, union adfs_dirtail *dtp); -extern void adfs_dir_free (struct buffer_head **bhp, int buffers); -extern int adfs_dir_get (struct super_block *sb, struct buffer_head **bhp, - int buffers, int pos, unsigned long parent_object_id, - struct adfs_idir_entry *ide); -extern int adfs_dir_find_entry (struct super_block *sb, struct buffer_head **bhp, - int buffers, unsigned int index, - struct adfs_idir_entry *ide); - -/* inode.c */ -extern int adfs_inode_validate (struct inode *inode); -extern unsigned long adfs_inode_generate (unsigned long parent_id, int diridx); -extern unsigned long adfs_inode_objid (struct inode *inode); -extern unsigned int adfs_parent_bmap (struct inode *inode, int block); -extern int adfs_bmap (struct inode *inode, int block); -extern void adfs_read_inode (struct inode *inode); - -/* map.c */ -extern int adfs_map_lookup (struct super_block *sb, int frag_id, int offset); - -/* namei.c */ -extern int adfs_lookup (struct inode * dir, const char * name, int len, - struct inode ** result); - -/* super.c */ -extern int init_adfs_fs (void); -extern void adfs_error (struct super_block *, const char *, const char *, ...); - -/* - * Inodes and file operations - */ - -/* dir.c */ -extern struct inode_operations adfs_dir_inode_operations; - -/* file.c */ -extern struct inode_operations adfs_file_inode_operations; -#endif - -#endif - diff -u --recursive --new-file v2.1.120/linux/include/linux/sched.h linux/include/linux/sched.h --- v2.1.120/linux/include/linux/sched.h Sat Sep 5 16:46:41 1998 +++ linux/include/linux/sched.h Tue Sep 8 13:20:27 1998 @@ -1,8 +1,6 @@ #ifndef _LINUX_SCHED_H #define _LINUX_SCHED_H -extern void checksignals(void); - #include /* for HZ */ extern unsigned long event; diff -u --recursive --new-file v2.1.120/linux/include/linux/sound.h linux/include/linux/sound.h --- v2.1.120/linux/include/linux/sound.h Tue Jun 9 11:57:31 1998 +++ linux/include/linux/sound.h Sat Sep 5 17:01:45 1998 @@ -6,8 +6,10 @@ extern int register_sound_mixer(struct file_operations *fops); extern int register_sound_midi(struct file_operations *fops); extern int register_sound_dsp(struct file_operations *fops); +extern int register_sound_synth(struct file_operations *fops); extern void unregister_sound_special(int unit); extern void unregister_sound_mixer(int unit); extern void unregister_sound_midi(int unit); extern void unregister_sound_dsp(int unit); +extern void unregister_sound_synth(int unit); diff -u --recursive --new-file v2.1.120/linux/include/linux/string.h linux/include/linux/string.h --- v2.1.120/linux/include/linux/string.h Fri Jul 31 17:05:52 1998 +++ linux/include/linux/string.h Sun Sep 6 10:11:15 1998 @@ -26,6 +26,7 @@ extern __kernel_size_t strspn(const char *,const char *); extern int strcmp(const char *,const char *); extern int strncmp(const char *,const char *,__kernel_size_t); +extern int strnicmp(const char *, const char *, __kernel_size_t); extern void * memset(void *,int,__kernel_size_t); extern void * memcpy(void *,const void *,__kernel_size_t); diff -u --recursive --new-file v2.1.120/linux/init/main.c linux/init/main.c --- v2.1.120/linux/init/main.c Sat Sep 5 16:46:42 1998 +++ linux/init/main.c Sun Sep 6 12:55:38 1998 @@ -84,6 +84,11 @@ extern void filescache_init(void); extern void signals_init(void); +extern void device_setup(void); +extern void binfmt_setup(void); +extern void free_initmem(void); +extern void filesystem_setup(void); + #ifdef CONFIG_ARCH_ACORN extern void ecard_init(void); #endif @@ -1104,11 +1109,20 @@ #if defined(CONFIG_QUOTA) dquot_init_hash(); #endif - check_bugs(); printk("POSIX conformance testing by UNIFIX\n"); + check_bugs(); + smp_init(); + /* + * Ok, the machine is now initialized. None of the devices + * have been touched yet, but the CPU subsystem is up and + * running, and memory management works. + * + * Now we can finally start doing some real work.. + */ + #if defined(CONFIG_MTRR) /* Do this after SMP initialization */ /* * We should probably create some architecture-dependent "fixup after @@ -1182,7 +1196,7 @@ } #endif -static int init(void * unused) +static void __init do_basic_setup(void) { #ifdef CONFIG_BLK_DEV_INITRD int real_root_mountflags; @@ -1211,7 +1225,18 @@ if (initrd_start && mount_initrd) root_mountflags &= ~MS_RDONLY; else mount_initrd =0; #endif - setup(0); + + /* Set up devices .. */ + device_setup(); + + /* .. executable formats .. */ + binfmt_setup(); + + /* .. filesystems .. */ + filesystem_setup(); + + /* Mount the root filesystem.. */ + mount_root(); #ifdef CONFIG_UMSDOS_FS { @@ -1247,9 +1272,19 @@ } } #endif +} + +static int init(void * unused) +{ + do_basic_setup(); + + /* + * Ok, we have completed the initial bootup, and + * we're essentially up and running. Get rid of the + * initmem segments and start the user-mode stuff.. + */ + free_initmem(); - setup(1); - if (open("/dev/console", O_RDWR, 0) < 0) printk("Warning: unable to open an initial console.\n"); diff -u --recursive --new-file v2.1.120/linux/kernel/panic.c linux/kernel/panic.c --- v2.1.120/linux/kernel/panic.c Wed Aug 26 11:37:45 1998 +++ linux/kernel/panic.c Sun Sep 6 10:34:34 1998 @@ -19,6 +19,10 @@ #include #include +#ifdef __alpha__ +#include +#endif + asmlinkage void sys_sync(void); /* it's really int */ extern void unblank_console(void); extern int C_A_D; @@ -70,9 +74,12 @@ #ifdef __sparc__ printk("Press L1-A to return to the boot prom\n"); #endif +#ifdef __alpha__ + if (alpha_using_srm) + halt(); +#endif sti(); for(;;) { CHECK_EMERGENCY_SYNC } } - diff -u --recursive --new-file v2.1.120/linux/lib/string.c linux/lib/string.c --- v2.1.120/linux/lib/string.c Tue Apr 23 03:24:52 1996 +++ linux/lib/string.c Sun Sep 6 11:19:15 1998 @@ -13,6 +13,34 @@ #include #include +#include + +#ifndef __HAVE_ARCH_STRNICMP +int strnicmp(const char *s1, const char *s2, size_t len) +{ + /* Yes, Virginia, it had better be unsigned */ + unsigned char c1, c2; + + c1 = 0; c2 = 0; + if (len) { + do { + c1 = *s1; c2 = *s2; + s1++; s2++; + if (!c1) + break; + if (!c2) + break; + if (c1 == c2) + continue; + c1 = tolower(c1); + c2 = tolower(c2); + if (c1 != c2) + break; + } while (--len); + } + return (int)c1 - (int)c2; +} +#endif char * ___strtok = NULL; diff -u --recursive --new-file v2.1.120/linux/net/sunrpc/clnt.c linux/net/sunrpc/clnt.c --- v2.1.120/linux/net/sunrpc/clnt.c Sat Sep 5 16:46:42 1998 +++ linux/net/sunrpc/clnt.c Sat Sep 5 17:13:38 1998 @@ -413,7 +413,6 @@ return; printk("RPC: buffer allocation failed for task %p\n", task); - checksignals(); if (!signalled()) { xprt_release(task); task->tk_action = call_reserve; diff -u --recursive --new-file v2.1.120/linux/net/sunrpc/sched.c linux/net/sunrpc/sched.c --- v2.1.120/linux/net/sunrpc/sched.c Sat Sep 5 16:46:42 1998 +++ linux/net/sunrpc/sched.c Sat Sep 5 17:14:17 1998 @@ -420,7 +420,6 @@ * When the task received a signal, remove from * any queues etc, and make runnable again. */ - checksignals(); if (signalled()) __rpc_wake_up(task); @@ -435,7 +434,6 @@ * clean up after sleeping on some queue, we don't * break the loop here, but go around once more. */ - checksignals(); if (!RPC_IS_ASYNC(task) && signalled()) { dprintk("RPC: %4d got signal\n", task->tk_pid); rpc_exit(task, -ERESTARTSYS); @@ -555,7 +553,6 @@ if (flags & RPC_TASK_ASYNC) return NULL; current->timeout = jiffies + (HZ >> 4); - checksignals(); current->state = TASK_INTERRUPTIBLE; schedule(); } while (!signalled()); @@ -802,7 +799,6 @@ dprintk("RPC: rpciod starting (pid %d)\n", rpciod_pid); while (rpciod_users) { - checksignals(); if (signalled()) { rpciod_killall(); flush_signals(current); @@ -931,7 +927,6 @@ */ while (rpciod_pid) { dprintk("rpciod_down: waiting for pid %d to exit\n", rpciod_pid); - checksignals(); if (signalled()) { dprintk("rpciod_down: caught signal\n"); break; diff -u --recursive --new-file v2.1.120/linux/net/sunrpc/svcsock.c linux/net/sunrpc/svcsock.c --- v2.1.120/linux/net/sunrpc/svcsock.c Sat Sep 5 16:46:42 1998 +++ linux/net/sunrpc/svcsock.c Sat Sep 5 17:13:49 1998 @@ -736,7 +736,6 @@ rqstp->rq_argbuf = rqstp->rq_defbuf; rqstp->rq_resbuf = rqstp->rq_defbuf; - checksignals(); if (signalled()) return -EINTR; @@ -755,7 +754,6 @@ * We have to be able to interrupt this wait * to bring down the daemons ... */ - checksignals(); current->state = TASK_INTERRUPTIBLE; add_wait_queue(&rqstp->rq_wait, &wait); end_bh_atomic();